#include<fstream>
#include<math.h>
#include<iostream>
#define MAXNUM 100
using namespace std;
ifstream fin("input.txt");
//ofstream fout("output.txt");
int stack[MAXNUM];
int ptr[MAXNUM];
int index[MAXNUM];
int p1,p2;
int f[MAXNUM];
int g[MAXNUM];
int k[MAXNUM];
int map[MAXNUM];
bool tag[MAXNUM];
void dfs(int s){
int p,j,i;
memset(tag,false,sizeof(tag));
memset(stack,0,sizeof(stack));
stack[0] = s;
ptr[0] = 0;
tag[s] = true;
for(p=0;p>=0;){
i = stack[p];
if(ptr[p]<k[i]){
j = map[index[i]+ptr[p]];
ptr[p]++;//表示遍历过此节点
if(p==0||j!=stack[p-1]){//不是回边,无向图中有向树处理
if(tag[j]){//说明i和j是环上的一边
p1 = i;
p2 = j;
return;
}
p++;
stack[p] = j;
ptr[p] = 0;
tag[j] = true;
}
}else{
p--;
}
}
}
int workout(int s){
int p,j,i;
stack[0] = s;
ptr[0] = 0;
f[0] = 1;
g[0] = 0;
for(p=0;p>=0;){//栈底初始
i = stack[p];
if(ptr[p] < k[i]){//可以遍历节点
j = map[index[i]+ptr[p]];
ptr[p]++;
//去掉一条圈上的边形成一棵树,不需要标记了
if((i!=p1||j!=p2)&&(i!=p2||j!=p1)&&(p==0||j!=stack[p-1])){
p++;
f[p] = 1;
g[p] = 0;
stack[p] = j;
ptr[p] = 0;
}
}else//节点遍历完毕
{ //修改节点权
if(p>0){
f[p-1] += min(f[p],g[p]);
g[p-1] += f[p];
}
p--;//退栈
}
}
return f[0];
}
int main(){
int n,i,j;
int t=0;
fin>>n;
for(i=1;i<=n;i++){
index[i] = t;
fin>>k[i];
for(j=0;j<k[i];j++){
fin >> map[t++];
}
}
dfs(1);
cout<<min(workout(p1),workout(p2))<<endl;
}