import java.util.Scanner;
public class ACM_1789_2 {
/**
* @param args
*/
//define global variables
public static int[] pre = new int[30000+1];
public static int n = 0;
public static int m = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner s = new Scanner(System.in);
// learn to use while true!
while(true){
n = s.nextInt();
m = s.nextInt();
if (n==0)
break;
init();
for(int i=0; i<m; i++){
int k = s.nextInt();
int head = s.nextInt();
for(int j=1; j<k; j++){
int child = s.nextInt();
union(head,child);
}
}
//find the top parent of 0
System.out.println(-pre[find(0)]);
}
}
public static void init(){
//pre[i] means the number of child i have, or the index of the parent of i
for(int i=0; i<n; i++){
pre[i]=-1;
}
}
public static int find(int x){
int p = pre[x];
// p has no parent, which means p is newly introduce into the tree
if(p<0)
return x;
// find the top parent of x, which has pre[~]>0
while( pre[p] >=0){
p = pre[p];
}
//update the parent of x
pre[x]=p;
return p;
}
public static void union(int head, int child){
//find the top parent of two nodes, head and child
int p_head = find(head);
int p_child = find(child);
//if they have the same parent, which means child is already in the tree, then no action needed
if(p_head== p_child)
return;
//p_head has more child than p_child, add p_child to p_head
//set p_head as p_child's parent
if(p_head < p_child){
pre[p_head]+=pre[p_child];
pre[p_child]= p_head;
}else{
//p_child has more child than p_parent
pre[p_child] += pre[p_head];
pre[p_head] = p_child;
}
}
}
Summary:
1. 寻找父节点
2. 节点合并到树