#!/usr/bin/env python3
"""
Ticker Plant Challenge - Python Skeleton
Parse, normalize, deduplicate, and aggregate market data from multiple exchanges.
"""
import sys
from collections import defaultdict

def parse_message(line):
    """
    Parse a single trade message and return normalized data.
    Returns: (timestamp_ns, symbol, price, qty) or None if parse fails
    """
    parts = line.strip().split('|')
    if not parts:
        return None

    exchange = parts[0]

    try:
        if exchange == 'NYSE':
            # NYSE|timestamp_ns|symbol|price|qty|side
            timestamp_ns = int(parts[1])
            symbol = parts[2]
            price = float(parts[3])
            qty = int(parts[4])
            # side = parts[5]  # Not needed for bar computation

        elif exchange == 'NASDAQ':
            # NASDAQ|timestamp_us|symbol|side|qty|price
            timestamp_us = int(parts[1])
            timestamp_ns = timestamp_us * 1000
            symbol = parts[2]
            # side = parts[3]  # Not needed
            qty = int(parts[4])
            price = float(parts[5])

        elif exchange == 'BATS':
            # BATS|timestamp_ms|symbol|price|qty|side|trade_id
            timestamp_ms = int(parts[1])
            timestamp_ns = timestamp_ms * 1_000_000
            symbol = parts[2]
            price = float(parts[3])
            qty = int(parts[4])
            # side = parts[5]  # Not needed
            # trade_id = parts[6]  # Not needed

        elif exchange == 'IEX':
            # IEX|timestamp_s.us|symbol|price|qty|side
            timestamp_str = parts[1]
            seconds, microseconds = timestamp_str.split('.')
            seconds = int(seconds)
            microseconds = int(microseconds)
            timestamp_ns = seconds * 1_000_000_000 + microseconds * 1000
            symbol = parts[2]
            price = float(parts[3])
            qty = int(parts[4])
            # side = parts[5]  # Not needed

        else:
            return None

        return (timestamp_ns, symbol, price, qty)

    except (ValueError, IndexError):
        return None


def main():
    n = int(input())

    # Deduplication set: (symbol, timestamp_ns, price, qty)
    seen_trades = set()

    # Aggregate into bars: {(symbol, timestamp_second): [prices, quantities, trade_list]}
    bars = defaultdict(lambda: {
        'prices': [],
        'quantities': [],
        'count': 0
    })

    for _ in range(n):
        line = input()
        parsed = parse_message(line)

        if parsed is None:
            continue

        timestamp_ns, symbol, price, qty = parsed

        # Deduplication
        trade_key = (symbol, timestamp_ns, price, qty)
        if trade_key in seen_trades:
            continue
        seen_trades.add(trade_key)

        # Group into 1-second bars
        timestamp_second = timestamp_ns // 1_000_000_000
        bar_key = (symbol, timestamp_second)

        bars[bar_key]['prices'].append(price)
        bars[bar_key]['quantities'].append(qty)
        bars[bar_key]['count'] += 1

    # Compute OHLCV for each bar
    results = []
    for (symbol, timestamp_second), bar_data in bars.items():
        prices = bar_data['prices']
        quantities = bar_data['quantities']
        trade_count = bar_data['count']

        open_price = prices[0]
        high_price = max(prices)
        low_price = min(prices)
        close_price = prices[-1]
        volume = sum(quantities)

        # VWAP = sum(price * qty) / sum(qty)
        vwap = sum(p * q for p, q in zip(prices, quantities)) / volume if volume > 0 else 0.0

        results.append((
            timestamp_second,
            symbol,
            open_price,
            high_price,
            low_price,
            close_price,
            volume,
            vwap,
            trade_count
        ))

    # Sort by (timestamp_second, symbol)
    results.sort(key=lambda x: (x[0], x[1]))

    # Output
    num_symbols = len(set(sym for _, sym, *_ in results))
    num_bars = len(results)

    print(f"{num_symbols} {num_bars}")
    for timestamp_second, symbol, open_p, high, low, close, volume, vwap, count in results:
        print(f"{timestamp_second} {symbol} {open_p:.6f} {high:.6f} {low:.6f} {close:.6f} {volume} {vwap:.6f} {count}")


if __name__ == '__main__':
    main()
