#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define p_queue priority_queue
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define pb(a) push_back(a)
#define CLOSE ios::sync_with_stdio(0); cin.tie(0)
int n, m;
//素数
const int MAXN = 1000;
int prime[MAXN], vis[MAXN];
void Euler()
{
prime[1] = 1;
int cnt = 0;
for(int i = 2 ; i <= MAXN-5 ; i ++)
{
if(!vis[i])
prime[cnt ++] = i;
for(int j = 0 ; j < cnt && prime[j] <= (MAXN-5)/i ; j ++)
{
vis[i*prime[j]] = 1;
if(i % prime[j] == 0)
break;
}
}
}
//前向星
struct e{
int t, next;
}edge[MAXN*4];
int head[MAXN] , cnt;
void add(int f, int t)
{
edge[cnt].t = t;
edge[cnt].next = head[f];
head[f] = cnt ++;
}
//树hash
vector<int> hs[MAXN];
//f一次扫描hash值 , g二次扫描hash值
int size[MAXN] , f[MAXN] , g[MAXN];
//一次扫描
void dfs1(int root, int fa)
{
size[root] = f[root] = 1;
for (int i = head[root]; i != -1; i = edge[i].next)
{
int v = edge[i].t;
if (v != fa)
{
dfs1(v, root);
f[root] += f[v] * prime[size[v]];
size[root] += size[v];
}
}
}
//二次扫描换根
void dfs2(int x, int fa, int fa_f) {
g[x] = f[x] + fa_f * prime[n-size[x]];
fa_f *= prime[n-size[x]];
for (int i = head[x]; i != -1; i = edge[i].next) {
int v = edge[i].t;
if (v != fa)
dfs2(v, x, fa_f + f[x] - f[v] * prime[size[v]]);
}
}
bool check(int x, int y)
{
if (hs[x].size() != hs[y].size()) return false;
for (int i = 0; i < hs[x].size(); i++)
if (hs[x][i] != hs[y][i])
return false;
return true;
}
void Init(int i)
{
cnt = 0;
mem(head,-1);
hs[i].clear();
}
int main(void)
{
CLOSE;
Euler();
cin >> m;
for (int i = 1; i <= m ; i ++)
{
int x;
Init(i);
cin >> n;
for (int j = 1 ; j <= n ; j ++) {
cin >> x;
if(x) add(x, j), add(j, x);
}
dfs1(1,0);
dfs2(1,0,0);
for (int j = 1 ; j <= n ; j ++) hs[i].pb(g[j]);
sort(hs[i].begin(), hs[i].end());
}
puts("1");
for (int i = 2 ; i <= m ; i ++)
{
for (int j = 1 ; j <= i ; j ++)
{
if(check(i,j))
{
printf("%d\n",j);
break;
}
}
}
}