/*
Question:
It means that the student is suspected of having SARS, and contacts with all the people in the club he has been in contact with and those he has been in contact with others,
There may be sars. You need to find the list of all club members and all the suspects...
Analysis:
Use the Union query method. The specific implementation is to first define n forests and then combine the forests of the same person,
There are two ways to improve the query set. I use the compressed path method.
*/
# Include <iostream>
# Include <cstring>
# Include <cstdio>
Using namespace STD;
Const int x = 30010;
Int parent [X], a [X], rank [X], M, N, T;
Int find_set (int x) // path compression
{
If (X! = Parent [x])
Parent [x] = find_set (parent [x]);
Return parent [x];
}
Void union_set (int I, Int J)
{
I = find_set (I );
J = find_set (j );
If (I! = J)
If (rank [I]> rank [J]) // The higher the level, the higher the tree height.
Parent [J] = I;
Else
{
Parent [I] = J;
If (rank [I] = rank [J])
Rank [J] ++;
}
}
Int main ()
{
Freopen ("sum. In", "r", stdin );
Freopen ("sum. Out", "W", stdout );
Int X, pre;
While (CIN> N> M, N | m)
{
For (INT I = 0; I <n; I ++)
{
Parent [I] = I;
Rank [I] = 0;
}
For (INT I = 0; I <m; I ++)
{
Scanf ("% d", & T );
If (t) // you only need to find the first person in the club to join others.
Scanf ("% d", & Pre );
For (INT I = 0; I <T-1; I ++)
{
Scanf ("% d", & X );
Union_set (PRE, X );
}
}
Pre = find_set (0); // find the root node number of the tree where 0 is located, and then compare it with others
Int ans = 1;
For (INT I = 1; I <n; I ++)
If (pre = find_set (I ))
Ans ++;
Cout <ans <Endl;
}
Return 0;
}