Edge(int _to, int _nxt) { to = _to; nxt = _nxt; } } edge[N];
int head[N], tot;
voidInit(){ memset(head, -1, sizeof head); tot = 0; }
voidaddedge(int u, int v){ edge[tot] = Edge(v, head[u]); head[u] = tot++; } } G[2], zp;
int n; int fa[N][DEG], dep[N], du[N], sze[N];
structTree { intLCA(int u, int v){ if (u == -1) { return v; } if (v == -1) { return u; } if (dep[u] > dep[v]) { swap(u, v); } for (int det = dep[v] - dep[u], i = 0; det; det >>= 1, ++i) { if (det & 1) { v = fa[v][i]; } } if (u == v) return u; for (int i = DEG - 1; i >= 0; --i) { if (fa[u][i] == fa[v][i]) { continue; } u = fa[u][i]; v = fa[v][i]; } return fa[u][0]; }
voidDFS(int u){ sze[u] = 1; for (int i = zp.head[u]; ~i; i = zp.edge[i].nxt) { int v = zp.edge[i].to; if (sze[v] == 0) { DFS(v); } sze[u] += sze[v]; } }
voidsolve(){ queue<int> que; vector<int> Q; for (int i = 1; i <= n; ++i) { if (du[i] == 0) { que.push(i); } } while (!que.empty()) { int u = que.front(); que.pop(); Q.push_back(u); for (int i = G[0].head[u]; ~i; i = G[0].edge[i].nxt) { int v = G[0].edge[i].to; --du[v]; if (du[v] == 0) { que.push(v); } } } for (int i = 0, len = Q.size(); i < len; ++i) { int u = Q[i]; int root = -1; for (int j = G[1].head[u]; ~j; j = G[1].edge[j].nxt) { int v = G[1].edge[j].to; root = LCA(root, v); } if (root == -1) { root = 0; } zp.addedge(root, u); fa[u][0] = root; dep[u] = dep[root] + 1; for (int j = 1; j < DEG; ++j) { if (fa[u][j - 1]) { fa[u][j] = fa[fa[u][j - 1]][j - 1]; } } } DFS(0); } } tree;
intmain(){ scanf("%d", &n); G[0].Init(), G[1].Init(), zp.Init(); for (int i = 1, x; i <= n; ++i) { while (~scanf("%d", &x) && x) { G[0].addedge(x, i); G[1].addedge(i, x); du[i]++; } } tree.solve(); for (int i = 1; i <= n; ++i) { printf("%d\n", sze[i] - 1); } return0; }