#include<iostream>
#include<vector>
#include<algorithm>
#include<stdio.h> // 以防万一,使用scanf时加上这个头文件
using namespace std;
int n;
vector<int>father,isRoot;
int course[1001] = {0};//vector可以实现动态设置数组大小,但是效率比数组低
int FindFather(int x){
int a = x;
while(x != father[x]){
x = father[x];
}
while(a != father[a]){ //路径压缩
int z = a;
a = father[a];
father[z] = x;
}
return x;
}
void Union(int a,int b){
int fa = FindFather(a);
int fb = FindFather(b);
if(fa != fb) father[fa] = fb;
}
bool cmp(int &a,int &b){
return a>b;
}
int main()
{
cin>>n;
father.resize(n+1),isRoot.resize(n+1);
for(int i=1;i<=n;i++)father[i] = i;
for(int i=1;i<=n;i++){
int k ;
scanf("%d:",&k);
for(int j =0;j<k;j++){
int t;
cin>>t;
if(0 == course[t])
course[t] = i;
Union(i,FindFather(course[t]));
}
}
for(int i=1;i<=n;i++){
isRoot[FindFather(i)]++;
}
sort(isRoot.begin(),isRoot.end(),cmp);
int cnt=0;
while(isRoot[cnt++]);//下表从零开始,cnt最后的值会比非零的下标大2
printf("%d\n",cnt-1);
for(int i=0;i<cnt-1;i++){
printf("%d",isRoot[i]);
if(i !=cnt-2) printf(" ");//printf("%d%s",isRoot[i],i == cnt-2?"":" ")三目运算符的效率比较低,在汇编的时候比对应的if-else多一条指令
}
return 0;
}