/* Contribute countless wa, just because I wrote a mistake in one place. It was a miserable evening! However, it's still nice to be able to pass.
Idea: Use the trie tree to re-label the string, then use and query sets, use a [I] to record the current and query the number of knots connected to the set and the node. */
# Include <iostream>
# Include <cstdio>
# Include <cstring>
Using namespace STD;
Struct Node
{
Int flag;
Node * Next [53];
};
Const int n= 200005;
Int parent [N];
Int rank [N];
Int A [n];
Int num;
Node * newnode ()
{
Node * P = new node;
P-> flag = 0;
For (INT I = 0; I <52; I ++)
P-> next [I] = NULL;
Return P;
}
Int insert (node * root, char * s)
{
Node * P = root;
Int I, Len = strlen (s), T;
For (I = 0; I <Len; I ++)
{
If (isupper (s [I])
T = s [I]-'A ';
Else
T = s [I]-'A' + 26;
If (p-> next [T] = NULL)
P-> next [T] = newnode ();
P = p-> next [T];
}
If (p-> flag)
Return p-> flag;
Else
{
P-> flag = num ++;
Return p-> flag;
}
}
Void del (node * P)
{
If (P)
{
For (INT I = 0; I <52; I ++)
If (p-> next [I])
Del (p-> next [I]);
}
Delete P;
P = NULL;
}
Void Init ()
{
For (INT I = 0; I <n; I ++)
{
Parent [I] = I;
A [I] = 1;
}
}
Int find (int x)
{
Int K = x, r = x, J;
While (R! = Parent [R])
R = parent [R];
While (K! = R)
{
J = parent [k];
Parent [k] = R;
K = J;
}
Return R;
}
Void union_set (int x, int y)
{
X = find (X );
Y = find (y );
If (x = y) return;
Parent [x] = y;
A [y] + = A [x];
}
Int main ()
{
// Freopen ("data. In", "r", stdin );
Int t, n, x, y;
Char S1 [35], S2 [35];
Node * root;
While (scanf ("% d", & T )! = EOF)
{
While (t --)
{
Scanf ("% d", & N );
If (n = 0)
{
Printf ("0 \ n ");
Continue;
}
Init (); num = 1;
Root = newnode ();
While (n --)
{
Scanf ("% S % s", S1, S2 );
X = insert (root, S1 );
Y = insert (root, S2 );
Union_set (x, y );
Printf ("% d \ n", a [find (y)]); // always write it as a [Y], contributing countless wa !!!
}
del(root);
}
}
return 0;
}