#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
const int maxn=100000+10;
struct T{
	int l,r,id;
	bool operator<(const T &a)const{
		if(l==a.l)
			return r-l+1>a.r-a.l+1;
		return l<a.l;
	}
}A[2000000+10];
char B[2000000+10];
string s[maxn];
int main(){
	//freopen("R.in","r",stdin);
	//freopen("R.out","w",stdout);
	int n;
	scanf("%d",&n);
	int k,tot=0;
	int x;
	int maxx=0;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		scanf("%d",&k);
		int len=s[i].length();
		for(int j=1;j<=k;j++){
			scanf("%d",&x);
			++tot;
			A[tot].l=x;
			A[tot].r=x+len-1;
			A[tot].id=i;
			maxx=max(maxx,x+len-1);
		}
	}
	sort(A+1,A+tot+1);
	int now=0;
	int pl=1;
	for(;;){
		if(pl==tot+1)
			break;
		while(A[pl].r<=now)
			pl++;
		if(pl==tot+1)
			break;
		int k=max(now,A[pl].l);
		for(int i=k;i<=A[pl].r;i++)
			B[i]=s[A[pl].id][i-A[pl].l];
		now=A[pl].r;
		pl++;
	}
	for(int i=1;i<=maxx;i++)
		if(B[i]>'z'||B[i]<'a')
			printf("a");
		else printf("%c",B[i]);
return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
const int maxn=100000+10;
struct T{
	int l,r,id;
	bool operator<(const T &a)const{
		if(l==a.l)
			return r-l+1>a.r-a.l+1;
		return l<a.l;
	}
}A[2000000+10];
char B[2000000+10];
string s[maxn];
int main(){
	//freopen("R.in","r",stdin);
	//freopen("R.out","w",stdout);
	int n;
	scanf("%d",&n);
	int k,tot=0;
	int x;
	int maxx=0;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		scanf("%d",&k);
		int len=s[i].length();
		for(int j=1;j<=k;j++){
			scanf("%d",&x);
			++tot;
			A[tot].l=x;
			A[tot].r=x+len-1;
			A[tot].id=i;
			maxx=max(maxx,x+len-1);
		}
	}
	sort(A+1,A+tot+1);
	int now=0;
	int pl=1;
	for(;;){
		if(pl==tot+1)
			break;
		while(A[pl].r<=now)
			pl++;
		if(pl==tot+1)
			break;
		k=max(now,A[pl].l);
		for(int i=k;i<=A[pl].r;i++)
			B[i]=s[A[pl].id][i-A[pl].l];
		now=A[pl].r;
		pl++;
	}
	for(int i=1;i<=maxx;i++)
		if(B[i]>'z'||B[i]<'a')
			printf("a");
		else printf("%c",B[i]);
return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
const int maxn=100000+10;
struct T{
	int l,r,id;
	bool operator<(const T &a)const{
		if(l==a.l)
			return r-l+1>a.r-a.l+1;
		return l<a.l;
	}
}A[maxn*10];
char B[maxn*10];
string s[maxn];
int main(){
	//freopen("R.in","r",stdin);
	//freopen("R.out","w",stdout);
	int n;
	scanf("%d",&n);
	int k,tot=0;
	int x;
	int maxx=0;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		scanf("%d",&k);
		int len=s[i].length();
		for(int j=1;j<=k;j++){
			scanf("%d",&x);
			++tot;
			A[tot].l=x;
			A[tot].r=x+len-1;
			A[tot].id=i;
			maxx=max(maxx,x+len-1);
		}
	}
	sort(A+1,A+tot+1);
	int now=0;
	int pl=1;
	for(;;){
		if(pl==tot+1)
			break;
		while(A[pl].r<=now)
			pl++;
		if(pl==tot+1)
			break;
		int k=max(now,A[pl].l);
		for(int i=k;i<=A[pl].r;i++)
			B[i]=s[A[pl].id][i-A[pl].l];
		now=A[pl].r;
		pl++;
	}
	for(int i=1;i<=maxx;i++)
		if(B[i]>'z'||B[i]<'a')
			printf("a");
		else printf("%c",B[i]);
return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
const int maxn=100000+10;
struct T{
	int l,r,id;
	bool operator<(const T &a)const{
		if(l==a.l)
			return r-l+1>a.r-a.l+1;
		return l<a.l;
	}
}A[2000000+10];
char B[2000000+10];
string s[maxn];
int main(){
	//freopen("R.in","r",stdin);
	//freopen("R.out","w",stdout);
	int n;
	scanf("%d",&n);
	int k,tot=0;
	int x;
	int maxx=0;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		scanf("%d",&k);
		int len=s[i].length();
		for(int j=1;j<=k;j++){
			scanf("%d",&x);
			++tot;
			A[tot].l=x;
			A[tot].r=x+len-1;
			A[tot].id=i;
			maxx=max(maxx,x+len-1);
		}
	}
	sort(A+1,A+tot+1);
	int now=0;
	int pl=1;
	for(;;){
		while(A[pl].r<=now&&pl!=tot+1)
			pl++;
		if(pl==tot+1)
			break;
		k=max(now,A[pl].l);
		for(int i=k;i<=A[pl].r;i++)
			B[i]=s[A[pl].id][i-A[pl].l];
		now=A[pl].r;
		pl++;
	}
	for(int i=1;i<=maxx;i++)
		if(B[i]>'z'||B[i]<'a')
			printf("a");
		else printf("%c",B[i]);
return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
const int maxn=100000+10;
struct T{
	int l,r,id;
	bool operator<(const T &a)const{
		if(l==a.l)
			return r-l+1>a.r-a.l+1;
		return l<a.l;
	}
}A[2000000+10];
char B[2000000+10];
string s[maxn];
int main(){
	freopen("R.in","r",stdin);
	freopen("R.out","w",stdout);
	int n;
	scanf("%d",&n);
	int k,tot=0;
	int x;
	int maxx=0;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		scanf("%d",&k);
		int len=s[i].length();
		for(int j=1;j<=k;j++){
			scanf("%d",&x);
			++tot;
			A[tot].l=x;
			A[tot].r=x+len-1;
			A[tot].id=i;
			maxx=max(maxx,x+len-1);
		}
	}
	sort(A+1,A+tot+1);
	int now=0;
	int pl=1;
	for(;;){
		while(A[pl].r<=now&&pl!=tot+1)
			pl++;
		if(pl==tot+1)
			break;
		k=max(now,A[pl].l);
		for(int i=k;i<=A[pl].r;i++)
			B[i]=s[A[pl].id][i-A[pl].l];
		now=A[pl].r;
		pl++;
	}
	for(int i=1;i<=maxx;i++)
		if(B[i]>'z'||B[i]<'a')
			printf("a");
		else printf("%c",B[i]);
return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ULL;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=3e6+7;
const double eps=0.00000001;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a,T b){T ret=1;for (;b;b>>=1ll,a=a*a%M) ret=1ll*ret*a%M;return ret;}

int n,m,len;
int i,j,t;
char a[maxn],ans[maxn];
int b[maxn];
int fa[maxn];
int mx;
inline int getfa(int x){
	if (fa[x]==x) return x;
	return fa[x]=getfa(fa[x]);
}
int main(){
	scanf("%d",&n);
	FOR(i,1,3e6) fa[i]=i;
	while(n--){
		scanf("%s",a);
		len=strlen(a);
		scanf("%d",&m);
		while(m--){
			scanf("%d",&t);
			for(j=getfa(t);j<t+len;j=getfa(j+1)) {
				ans[j]=a[j-t];
				if (j>mx) mx=j;
			}
		}
	}
	FOR(i,1,mx){
		if (ans[i]) printf("%c",ans[i]);
		else printf("a");
	}
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ULL;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=1e6+7;
const double eps=0.00000001;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a,T b){T ret=1;for (;b;b>>=1ll,a=a*a%M) ret=1ll*ret*a%M;return ret;}

set<int> SET;
set<int>::iterator it;
int n,m,t;
int i;
int len;
int mx;
char a[maxn],s[maxn];
int main(){
	scanf("%d",&n);
	FOR(i,0,2e6) SET.insert(i);
	while (n--){
		scanf("%s",s);
		len=strlen(s);
		scanf("%d",&m);
		while (m--){
			scanf("%d",&t);
			t--;
			for(it=SET.lower_bound(t);it!=SET.end()&&*it<t+len;it=SET.lower_bound(t)){
				a[*it]=s[*it-t];
				if (mx<*it) mx=*it;
				SET.erase(it);
			}
		}
	}
	REP(i,mx+1){
		if (a[i]) putchar(a[i]);
		else putchar('a');
	}
}
/*
*/


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ULL;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=2e6+7;
const double eps=0.00000001;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a,T b){T ret=1;for (;b;b>>=1ll,a=a*a%M) ret=1ll*ret*a%M;return ret;}

set<int> SET;
set<int>::iterator it;
int n,m,t;
int i;
int len;
int mx;
char a[maxn],s[maxn];
int main(){
	scanf("%d",&n);
	FOR(i,0,2e6) SET.insert(i);
	while (n--){
		scanf("%s",s);
		len=strlen(s);
		scanf("%d",&m);
		while (m--){
			scanf("%d",&t);
			t--;
			for(it=SET.lower_bound(t);it!=SET.end()&&*it<t+len;it=SET.lower_bound(t)){
				a[*it]=s[*it-t];
				if (mx<*it) mx=*it;
				SET.erase(it);
			}
		}
	}
	REP(i,mx+1){
		if (a[i]) putchar(a[i]);
		else putchar('a');
	}
}
/*
*/


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ULL;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=3e6+7;
const double eps=0.00000001;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a,T b){T ret=1;for (;b;b>>=1ll,a=a*a%M) ret=1ll*ret*a%M;return ret;}

int n,m,len;
int i,j,t;
char a[maxn],ans[maxn];
int b[maxn];
int fa[maxn];
int mx;
inline int getfa(int x){
	if (fa[x]==x) return x;
	return fa[x]=getfa(fa[x]);
}
int main(){
	scanf("%d",&n);
	FOR(i,1,3e6) fa[i]=i;
	while(n--){
		scanf("%s",a);
		len=strlen(a);
		scanf("%d",&m);
		while(m--){
			scanf("%d",&t);
			for(j=getfa(t);j<t+len;j=getfa(j+1)) {
				ans[j]=a[j-t];
				if (j>mx) mx=j;
			}
		}
	}
	FOR(i,1,mx){
		if (ans[i]) putchar(ans[i]);
		else putchar('a');
	}
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ULL;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=3e6+7;
const double eps=0.00000001;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a,T b){T ret=1;for (;b;b>>=1ll,a=a*a%M) ret=1ll*ret*a%M;return ret;}

int n,m,len;
int i,j,t;
char a[maxn],ans[maxn];
int b[maxn];
int fa[maxn];
int mx;
inline int getfa(int x){
	if (fa[x]==x) return x;
	return fa[x]=getfa(fa[x]);
}
int main(){
	scanf("%d",&n);
	FOR(i,1,3e6) fa[i]=i;
	while(n--){
		scanf("%s",a);
		len=strlen(a);
		scanf("%d",&m);
		while(m--){
			scanf("%d",&t);
			for(j=getfa(t);j<t+len;j=fa[j]=getfa(j+1)) {
				ans[j]=a[j-t];
				if (j>mx) mx=j;
			}
		}
	}
	FOR(i,1,mx){
		if (ans[i]) putchar(ans[i]);
		else putchar('a');
	}
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef vector <int> vi;
typedef pair <int,int> pii;
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sz(a) (int)a.size()
#define all(c) c.begin(), c.end()
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rept(i, a, b) for(int i = (a); i < (b); i++)
#define fill(a, v) memset(a, v, sizeof(a))
#define foreach(c, it) for(__typeof(c.begin()) it = c.begin(); it != c.end(); ++it)

#define N 1000100
#define LG 22
int parent[N], P[N][LG], level[N];

inline void init(int x, int n) {
    for(int i = 0; i < LG; i++) P[x][i] = -1;
    P[x][0] = parent[x];
    for(int j = 1; (1 << j) < n; j++)
        if(P[x][j - 1] != -1) P[x][j] = P[P[x][j - 1]][j- 1];
}

inline int lca(int x, int y) {
    if(level[x] < level[y]) swap(x, y);
    int lg = 1;
    while((1 << lg) <= level[x]) lg++; lg--;
    for(int i = lg; i >= 0; i--) {
        if(level[x] - (1 << i) >= level[y]) x = P[x][i];
    }
    if(x == y) return x;
    for(int i = lg; i >= 0; i--) {
        if(P[x][i] != -1 && P[x][i] != P[y][i]) x = P[x][i], y = P[y][i];
    }
    return parent[x];
}

inline int dist(int u, int v) {
    int anc = lca(u, v);
    return level[u] + level[v] - 2 * level[anc];
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    parent[1] = -1, parent[2] = 1, parent[3] = 1, parent[4] = 1;
    level[1] = 0, level[2] = 1, level[3] = 1, level[4] = 1;
    init(1, N); init(2, N); init(3, N); init(4, N);
    int q, n = 4; cin >> q;
    int x = 2, y = 3, diameter = 2;
    while(q--) {
        int u; cin >> u;
        level[n + 1] = level[u] + 1;
        level[n + 2] = level[u] + 1;
        parent[n + 1] = parent[n + 2] = u;
        init(n + 1, N); init(n + 2, N);
        if(x == u) x = n + 1, diameter++;
        else if(y == u) y = n + 1, diameter++;
        else {
            if(dist(n + 1, x) > diameter) y = n + 1, diameter++;
            if(dist(n + 1, y) > diameter) x = n + 1, diameter++;
        }
        cout << diameter << endl; n += 2;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef vector <int> vi;
typedef pair <int,int> pii;
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sz(a) (int)a.size()
#define all(c) c.begin(), c.end()
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rept(i, a, b) for(int i = (a); i < (b); i++)
#define fill(a, v) memset(a, v, sizeof(a))
#define foreach(c, it) for(__typeof(c.begin()) it = c.begin(); it != c.end(); ++it)

#define N 1000100
#define LG 22
int parent[N], P[N][LG], level[N];

inline void init(int x, int n) {
    for(int i = 0; i < LG; i++) P[x][i] = -1;
    P[x][0] = parent[x];
    for(int j = 1; (1 << j) < n; j++)
        if(P[x][j - 1] != -1) P[x][j] = P[P[x][j - 1]][j- 1];
}

inline int lca(int x, int y) {
    if(level[x] < level[y]) swap(x, y);
    int lg = 1;
    while((1 << lg) <= level[x]) lg++; lg--;
    for(int i = lg; i >= 0; i--) {
        if(level[x] - (1 << i) >= level[y]) x = P[x][i];
    }
    if(x == y) return x;
    for(int i = lg; i >= 0; i--) {
        if(P[x][i] != -1 && P[x][i] != P[y][i]) x = P[x][i], y = P[y][i];
    }
    return parent[x];
}

inline int dist(int u, int v) {
    int anc = lca(u, v);
    return level[u] + level[v] - 2 * level[anc];
}

int main() {
    parent[1] = -1, parent[2] = 1, parent[3] = 1, parent[4] = 1;
    level[1] = 0, level[2] = 1, level[3] = 1, level[4] = 1;
    init(1, N); init(2, N); init(3, N); init(4, N);
    int q, n = 4; cin >> q;
    int x = 2, y = 3, diameter = 2;
    while(q--) {
        int u; cin >> u;
        level[n + 1] = level[u] + 1;
        level[n + 2] = level[u] + 1;
        parent[n + 1] = parent[n + 2] = u;
        init(n + 1, N); init(n + 2, N);
        if(x == u) x = n + 1, diameter++;
        else if(y == u) y = n + 1, diameter++;
        else {
            int distFromX = dist(n + 1, x);
            int distFromY = dist(n + 1, y);;
            if(distFromX > diameter) y = n + 1, diameter = distFromX;
            if(distFromY > diameter) x = n + 1, diameter = distFromY;
        }
        cout << diameter << endl; n += 2;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define logn 21

int LCA[100005][23];

int Dep[100005];

int lp,sol,sag,q,w;

int dist(int x,int y){

	if(Dep[x]<Dep[y])
		swap(x,y);

	int diff=Dep[x]-Dep[y],lca,i,qwe=Dep[x]+Dep[y];

//	cout<<x<<' '<<y<<' ';

	for(i=0 ; i<=logn ; i++)
		if(diff & (1<<i))
			x=LCA[x][i];

	if(x==y)
		return qwe-Dep[x]*2;

	for(i=logn ; i>=0 ; i--)
		if(LCA[x][i]!=LCA[y][i]){
			x=LCA[x][i];
			y=LCA[y][i];
		}

	return qwe-Dep[LCA[x][0]]*2;
}

void update(int node,int ata){

	int i;

	Dep[node]=Dep[ata]+1;

	LCA[node][0]=ata;

	for(i=1 ; i<=logn ; i++)
		LCA[node][i]=LCA[ LCA[node][i-1] ][i-1];

	q=dist(node,sol);
	w=dist(node,sag);

	if(q>lp){
		lp=q;
		sag=node;
	}
	if(w>lp){
		lp=w;
		sol=node;
	}

}

int main(){

	int n,q,x,i;

	cin>>q;

	sol=2;
	sag=4;

	lp=2;

	n=4;

	Dep[2]=Dep[3]=Dep[4]=1;

	LCA[2][0]=LCA[3][0]=LCA[4][0]=1;

	for(i=1 ; i<=q ; i++){

		scanf("%d",&x);

		update(++n,x);
		update(++n,x);

		cout<<lp<<endl;
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define logn 20

int LCA[500005][21];

int Dep[500005];

int lp,sol,sag,q,w;

int dist(int x,int y){

	if(Dep[x]<Dep[y])
		swap(x,y);

	int diff=Dep[x]-Dep[y],lca,i,qwe=Dep[x]+Dep[y];

//	cout<<x<<' '<<y<<' ';

	for(i=0 ; i<=logn ; i++)
		if(diff & (1<<i))
			x=LCA[x][i];

	if(x==y)
		return qwe-Dep[x]*2;

	for(i=logn ; i>=0 ; i--)
		if(LCA[x][i]!=LCA[y][i]){
			x=LCA[x][i];
			y=LCA[y][i];
		}

	return qwe-Dep[LCA[x][0]]*2;
}

void update(int node,int ata){

	int i;

	Dep[node]=Dep[ata]+1;

	LCA[node][0]=ata;

	for(i=1 ; i<=logn ; i++)
		LCA[node][i]=LCA[ LCA[node][i-1] ][i-1];

	q=dist(node,sol);
	w=dist(node,sag);

	if(q>lp){
		lp=q;
		sag=node;
	}
	if(w>lp){
		lp=w;
		sol=node;
	}

}

int main(){

	int n,q,x,i;

	cin>>q;

	sol=2;
	sag=4;

	lp=2;

	n=4;

	Dep[2]=Dep[3]=Dep[4]=1;

	LCA[2][0]=LCA[3][0]=LCA[4][0]=1;

	for(i=1 ; i<=q ; i++){

		scanf("%d",&x);

		update(++n,x);
		update(++n,x);

		cout<<lp<<endl;
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define logn 21

int LCA[500005][23];

int Dep[500005];

int lp,sol,sag,q,w;

int dist(int x,int y){

	if(Dep[x]<Dep[y])
		swap(x,y);

	int diff=Dep[x]-Dep[y],lca,i,qwe=Dep[x]+Dep[y];

//	cout<<x<<' '<<y<<' ';

	for(i=0 ; i<=logn ; i++)
		if(diff & (1<<i))
			x=LCA[x][i];

	if(x==y)
		return qwe-Dep[x]*2;

	for(i=logn ; i>=0 ; i--)
		if(LCA[x][i]!=LCA[y][i]){
			x=LCA[x][i];
			y=LCA[y][i];
		}

	return qwe-Dep[LCA[x][0]]*2;
}

void update(int node,int ata){

	int i;

	Dep[node]=Dep[ata]+1;

	LCA[node][0]=ata;

	for(i=1 ; i<=logn ; i++)
		LCA[node][i]=LCA[ LCA[node][i-1] ][i-1];

	q=dist(node,sol);
	w=dist(node,sag);

	if(q>lp){
		lp=q;
		sag=node;
	}
	if(w>lp){
		lp=w;
		sol=node;
	}

}

int main(){

	int n,q,x,i;

	cin>>q;

	sol=2;
	sag=4;

	lp=2;

	n=4;

	Dep[2]=Dep[3]=Dep[4]=1;

	LCA[2][0]=LCA[3][0]=LCA[4][0]=1;

	for(i=1 ; i<=q ; i++){

		scanf("%d",&x);

		update(++n,x);
		update(++n,x);

		cout<<lp<<endl;
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define logn 20

int LCA[1000010][21];

int Dep[1000010];

int lp,sol,sag,q,w;

int dist(int x,int y){

	if(Dep[x]<Dep[y])
		swap(x,y);

	int diff=Dep[x]-Dep[y],lca,i,qwe=Dep[x]+Dep[y];

//	cout<<x<<' '<<y<<' ';

	for(i=0 ; i<=logn ; i++)
		if(diff & (1<<i))
			x=LCA[x][i];

	if(x==y)
		return qwe-Dep[x]*2;

	for(i=logn ; i>=0 ; i--)
		if(LCA[x][i]!=LCA[y][i]){
			x=LCA[x][i];
			y=LCA[y][i];
		}

	return qwe-Dep[LCA[x][0]]*2;
}

void update(int node,int ata){

	int i;

	Dep[node]=Dep[ata]+1;

	LCA[node][0]=ata;

	for(i=1 ; i<=logn ; i++)
		LCA[node][i]=LCA[ LCA[node][i-1] ][i-1];

	q=dist(node,sol);
	w=dist(node,sag);

	if(q>lp){
		lp=q;
		sag=node;
	}
	if(w>lp){
		lp=w;
		sol=node;
	}

}

int main(){

	int n,q,x,i;

	cin>>q;

	sol=2;
	sag=4;

	lp=2;

	n=4;

	Dep[2]=Dep[3]=Dep[4]=1;

	LCA[2][0]=LCA[3][0]=LCA[4][0]=1;

	for(i=1 ; i<=q ; i++){

		scanf("%d",&x);

		update(++n,x);
		update(++n,x);

		cout<<lp<<endl;
	}

	return 0;
}


#include<stdio.h>
#include<algorithm>
using namespace std;
int parent[1000101][21];
int d[1000101];
void finding(int u)
{
    for(int i=1;i<20;i++)
    {
        parent[u][i]=parent[parent[u][i-1]][i-1];
    }
}
int lca(int u,int v)
{
    int i;
    if(u==v) return u;
    for(i=19;i>=0;i--) if(d[v]<=d[parent[u][i]]) u=parent[u][i];
    for(i=19;i>=0;i--) if(d[u]<=d[parent[v][i]]) v=parent[v][i];
    if(u==v) return u;
    for(i=19;i>=0;i--) if(parent[u][i]!=parent[v][i]) u=parent[u][i],v=parent[v][i];
    return parent[u][0];
}
int main()
{
    int q,i,v,n,res=2,x,y,tmp,tmp1;
    n=4;
    scanf("%d",&q);
    parent[2][0]=1;
    parent[3][0]=1;
    parent[4][0]=1;
    d[1]=0;
    d[2]=1;
    d[3]=1;
    d[4]=1;
    x=2;
    y=3;
    res=2;
    while(q--)
    {
        scanf("%d",&v);
        d[n+1]=d[v]+1;
        d[n+2]=d[v]+1;
        parent[n+1][0]=v;
        parent[n+2][0]=v;
        finding(n+1);
        finding(n+2);
        tmp=d[n+1]+d[y]-2*d[lca(n+1,y)];
        //printf("%d %d %d\n",n+1,y,lca(n+1,y));
        tmp1=d[n+1]+d[x]-2*d[lca(n+1,x)];
        //printf("%d %d %d\n",n+1,x,lca(n+1,x));
        if(tmp>tmp1&&tmp>res)
        {
            x=n+1;
            res=tmp;
        }
        else if(tmp1>tmp&&tmp1>res)
        {
            y=n+1;
            res=tmp1;
        }
        n+=2;
        printf("%d\n",res);
    }
    //printf("%d\n",res);
}


#include<stdio.h>
#include<algorithm>
using namespace std;
int parent[1000101][21];
int d[1000101];
void finding(int u)
{
    for(int i=1;i<20;i++)
    {
        parent[u][i]=parent[parent[u][i-1]][i-1];
    }
}
int lca(int u,int v)
{
    int i;
    if(u==v) return u;
    for(i=19;i>=0;i--) if(d[v]<=d[parent[u][i]]) u=parent[u][i];
    for(i=19;i>=0;i--) if(d[u]<=d[parent[v][i]]) v=parent[v][i];
    if(u==v) return u;
    for(i=19;i>=0;i--) if(parent[u][i]!=parent[v][i]) u=parent[u][i],v=parent[v][i];
    return parent[u][0];
}
int main()
{
    int q,i,v,n,res=2,x,y,tmp,tmp1;
    n=4;
    scanf("%d",&q);
    parent[2][0]=1;
    parent[3][0]=1;
    parent[4][0]=1;
    d[1]=0;
    d[2]=1;
    d[3]=1;
    d[4]=1;
    x=2;
    y=3;
    res=2;
    while(q--)
    {
        scanf("%d",&v);
        d[n+1]=d[v]+1;
        d[n+2]=d[v]+1;
        parent[n+1][0]=v;
        parent[n+2][0]=v;
        finding(n+1);
        finding(n+2);
        tmp=d[n+1]+d[y]-2*d[lca(n+1,y)];
        //printf("%d %d %d\n",n+1,y,lca(n+1,y));
        tmp1=d[n+1]+d[x]-2*d[lca(n+1,x)];
        //printf("%d %d %d\n",n+1,x,lca(n+1,x));
        if(tmp>=tmp1&&tmp>res)
        {
            x=n+1;
            res=tmp;
        }
        else if(tmp1>=tmp&&tmp1>res)
        {
            y=n+1;
            res=tmp1;
        }
        n+=2;
        printf("%d\n",res);
    }
    //printf("%d\n",res);
}


#include <bits/stdc++.h>
using namespace std;
int parent[1000101][21];
int d[1000101];
void finding(int u)
{
    for(int i=1;i<20;i++)
    {
        parent[u][i]=parent[parent[u][i-1]][i-1];
    }
}
int lca(int u,int v)
{
    int i;
    if(u==v) return u;
    for(i=19;i>=0;i--) if(d[v]<=d[parent[u][i]]) u=parent[u][i];
    for(i=19;i>=0;i--) if(d[u]<=d[parent[v][i]]) v=parent[v][i];
    if(u==v) return u;
    for(i=19;i>=0;i--) if(parent[u][i]!=parent[v][i]) u=parent[u][i],v=parent[v][i];
    return parent[u][0];
}
int main()
{
    int q,i,v,n,res=2,x,y,tmp,tmp1;
    n=4;
    scanf("%d",&q);
    parent[2][0]=1;
    parent[3][0]=1;
    parent[4][0]=1;
    d[1]=0;
    d[2]=1;
    d[3]=1;
    d[4]=1;
    x=2;
    y=3;
    res=2;
    while(q--)
    {
        scanf("%d",&v);
        d[n+1]=d[v]+1;
        d[n+2]=d[v]+1;
        parent[n+1][0]=v;
        parent[n+2][0]=v;
        finding(n+1);
        finding(n+2);
        tmp=d[n+1]+d[y]-2*lca(n+1,y);
        tmp1=d[n+1]+d[x]-2*lca(n+1,x);
        if(tmp>res)
        {
            if(tmp>tmp1)
            {
                x=n+1;
                res=tmp;
            }
            else
            {
                y=n+1;
                res=tmp1;
            }
        }
        n+=2;
        printf("%d\n",res);
    }
    //printf("%d\n",res);
}


//In the name of God
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <cstdio>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <map>

#define X first
#define Y second

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
const int maxn = 1e6 + 1e2;

int q, n, d, head, tail, depth[maxn], par[30][maxn];
vector<int> child[maxn];

inline void prepare (int u)
{
  for(int i = 1 ; i < 30 ; i++)
    if(par[i - 1][u] != -1)
      par[i][u] = par[i - 1][par[i - 1][u]];
}

inline void addedge (int v, int u)
{
  child[v].push_back(u);
  depth[u] = depth[v] + 1;
  par[0][u] = v;
  prepare(u);
}

inline int LCA (int v, int u)
{
  if(depth[u] < depth[v])
    swap(u, v);
  for(int i = 29 ; i >= 0 ; i--)
    if(depth[v] + (1<<i) <= depth[u])
      u = par[i][u];
  if(u == v)
    return v;
  for(int i = 29 ; i >= 0 ; i--)
    if(par[i][u] != par[i][v])
      {
    u = par[i][u];
    v = par[i][v];
      }
  return par[0][u];
}

int main ()
{
  par[0][0] = -1;
  depth[0] = 0;
  addedge(0, 1);
  addedge(0, 2);
  addedge(0, 3);
  n = 4;
  d = 2;
  head = 2, tail = 3;
  cin >> q ;
  for(int v, i = 0 ; i < q ; i++)
    {
      cin >> v ;
      v --;
      addedge(v, n ++);
      addedge(v, n ++);
      int dis1 = depth[n - 1] + depth[head] - 2 * depth[LCA(n - 1, head)];
      int dis2 = depth[n - 1] + depth[tail] - 2 * depth[LCA(n - 1, tail)];
      if(dis2 > dis1)
    {
      swap(dis1, dis2);
      swap(head, tail);
    }
      if(dis1 > d)
    {
      tail = n - 1;
      d = dis1;
    }
      cout << d << endl ;
    }
}


//In the name of God
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>

#define X first
#define Y second
// #define X real()
// #define Y imag()
// #define cin fin
// #define cout fout

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
const int maxn = 1e6 + 1e2;

int q, n, d, head, tail, depth[maxn], par[30][maxn];
vector<int> child[maxn];

inline void prepare (int u)
{
  for(int i = 1 ; i < 30 ; i++)
    if(par[i - 1][u] != -1)
      par[i][u] = par[i - 1][par[i - 1][u]];
}

inline void addedge (int v, int u)
{
  child[v].push_back(u);
  depth[u] = depth[v] + 1;
  par[0][u] = v;
  prepare(u);
}

inline int LCA (int v, int u)
{
  if(depth[u] < depth[v])
    swap(u, v);
  for(int i = 29 ; i >= 0 ; i--)
    if(depth[v] + (1<<i) <= depth[u])
      u = par[i][u];
  if(u == v)
    return v;
  for(int i = 29 ; i >= 0 ; i--)
    if(par[i][u] != par[i][v])
      {
    u = par[i][u];
    v = par[i][v];
      }
  return par[0][u];
}

int main ()
{
  par[0][0] = -1;
  depth[0] = 0;
  addedge(0, 1);
  addedge(0, 2);
  addedge(0, 3);
  n = 4;
  d = 2;
  head = 2, tail = 3;
  scanf("%d", &q);
  for(int v, i = 0 ; i < q ; i++)
    {
      scanf("%d", &v);
      v --;
      addedge(v, n ++);
      addedge(v, n ++);
      int dis1 = depth[n - 1] + depth[head] - 2 * depth[LCA(n - 1, head)];
      int dis2 = depth[n - 1] + depth[tail] - 2 * depth[LCA(n - 1, tail)];
      if(dis2 > dis1)
    {
      swap(dis1, dis2);
      swap(head, tail);
    }
      if(dis1 > d)
    {
      tail = n - 1;
      d = dis1;
    }
      printf("%d\n", d);
    }
}


//In the name of God
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <cstdio>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <map>

#define X first
#define Y second

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
const ll limit = 3 * 3 * 3 * 3;
const ll maxn = 100;

ll k, x, n, m;
ll front[maxn], cnt[maxn], back[maxn];

inline ll calculate (ll fifront, ll ficnt, ll fiback, ll sefront, ll secnt, ll seback)
{
  front[0] = fifront, cnt[0] = ficnt, back[0] = fiback;
  front[1] = sefront, cnt[1] = secnt, back[1] = seback;
  for(ll i = 2 ; i < k ; i++)
    {
      cnt[i] = cnt[i - 1] + cnt[i - 2];
      front[i] = front[i - 2];
      back[i] = back[i - 1];
      if(back[i - 2] == 0 && front[i - 1] == 2)
    cnt[i] ++;
    }
  return cnt[k - 1];
}

inline bool valid (ll front, ll cnt, ll back, ll size)
{
  if(size == 1 && front != back)
    return 0;
  size -= 2;
  if(front == 0)
    size ++;
  if(back == 2 && size % 2 == 1)
    size ++;
  size /= 2;
  return cnt <= size;
}

inline vector<ll> decode (ll mask)
{
  vector<ll> ret;
  for(ll i = 0 ; i < 4 ; i++)
    {
      ret.push_back(mask % 3);
      mask /= 3;
    }
  return ret;
}

inline void prll (ll front, ll cnt, ll back, ll size)
{
  string res;
  ll ind = 1;
  if(front)
    res.push_back('A' + front);
  for(ll i = 0 ; i < cnt ; i++)
    res += "AC";
  while(res.size() < size)
    res.push_back('B');
  res[res.size() - 1] = 'A' + back;
  cout << res << endl ;
}
int main ()
{
  cin >> k >> x >> n >> m ;
  for(ll i = 0 ; i < n ; i++)
    for(ll j = 0 ; j < m ; j++)
      for(ll mask = 0 ; mask < limit ; mask++)
    {
      vector<ll> vc = decode(mask);
      if(valid(vc[0], i, vc[1], n) && valid(vc[2], j, vc[3], m))
        {
          if(calculate(vc[0], i, vc[1], vc[2], j, vc[3]) == x)
        {
          prll(vc[0], i, vc[1], n);
          prll(vc[2], j, vc[3], m);
          exit(0);
        }
        }
    }
  cout << "Happy new year!" << endl ;
}


//In the name of God
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <cstdio>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <map>

#define X first
#define Y second

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
const int maxn = 1e6 + 1e2;

int q, n, d, head, tail, depth[maxn], par[30][maxn];
vector<int> child[maxn];

inline void prepare (int u)
{
  for(int i = 1 ; i < 30 ; i++)
    if(par[i - 1][u] != -1)
      par[i][u] = par[i - 1][par[i - 1][u]];
}

inline void addedge (int v, int u)
{
  child[v].push_back(u);
  depth[u] = depth[v] + 1;
  par[0][u] = v;
  prepare(u);
}

inline int LCA (int v, int u)
{
  if(depth[u] < depth[v])
    swap(u, v);
  for(int i = 29 ; i >= 0 ; i--)
    if(depth[v] + (1<<i) <= depth[u])
      u = par[i][u];
  if(u == v)
    return v;
  for(int i = 29 ; i >= 0 ; i--)
    if(par[i][u] != par[i][v])
      {
    u = par[i][u];
    v = par[i][v];
      }
  return par[0][u];
}

int main ()
{
  ios_base :: sync_with_stdio(0);
  par[0][0] = -1;
  depth[0] = 0;
  addedge(0, 1);
  addedge(0, 2);
  addedge(0, 3);
  n = 4;
  d = 2;
  head = 2, tail = 3;
  cin >> q ;
  for(int v, i = 0 ; i < q ; i++)
    {
      cin >> v ;
      v --;
      addedge(v, n ++);
      addedge(v, n ++);
      int dis1 = depth[n - 1] + depth[head] - 2 * depth[LCA(n - 1, head)];
      int dis2 = depth[n - 1] + depth[tail] - 2 * depth[LCA(n - 1, tail)];
      if(dis2 > dis1)
    {
      swap(dis1, dis2);
      swap(head, tail);
    }
      if(dis1 > d)
    {
      tail = n - 1;
      d = dis1;
    }
      cout << d << endl ;
    }
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cassert>
#include <cstring>
#include <string>
#include <sstream>

using namespace std;

const int MAXL = 21;
const int MAXN = 2 * 5 * 100005;

int n;
int blen, a, b;
int dis[MAXN], par[MAXN][MAXL];

int get_lca(int a, int b) {
	if (dis[a] > dis[b]) {
		for (int i = MAXL-1; i >= 0; i--)
			if (dis[par[a][i]] >= dis[b]) a = par[a][i];
	}
	if (dis[a] < dis[b]) {
		for (int i = MAXL-1; i >= 0; i--)
			if (dis[par[b][i]] >= dis[a]) b = par[b][i];
	}
	if (a == b) return a;
	for (int i = MAXL-1; i >= 0; i--)
		if (par[a][i] != par[b][i]) {
			a = par[a][i];
			b = par[b][i];
		}
	return par[a][0];
}

int get_dist(int a, int b) {
	int lca = get_lca(a, b);
	return dis[a] + dis[b] - 2 * dis[lca];
}

int main() {
	n = 4;
	dis[1] = dis[2] = dis[3] = 1;
	blen = 2;
	a = 1; b = 2;
	int Q; scanf("%d", &Q);
	while (Q--) {
		int v; scanf("%d", &v); v--;
		par[n][0] = v;
		for (int i = 1; i < MAXL; i++) par[n][i] = par[par[n][i-1]][i-1];
		for (int i = 0; i < MAXL; i++) par[n+1][i] = par[n][i];
		dis[n] = dis[n + 1] = dis[v] + 1;
		int da = get_dist(n, a);
		int db = get_dist(n, b);
		if (da > blen && da >= db) {
			blen = da;
			b = n;
		} else if (db > blen) {
			blen = db;
			a = n;
		}
		printf("%d\n", blen);
		n += 2;
	}
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cassert>
#include <cstring>
#include <string>
#include <sstream>

using namespace std;

const int MAXL = 21;
const int MAXN = 2 * 5 * 100005;

int n;
int blen, a, b;
int dis[MAXN], par[MAXN][MAXL];

inline int get_dist(int a, int b) {
	int ret = dis[a] + dis[b];
	if (dis[a] > dis[b]) swap(a, b);
	for (int i = MAXL-1; i >= 0; i--)
		if (dis[par[b][i]] >= dis[a]) b = par[b][i];
	for (int i = MAXL-1; i >= 0; i--)
		if (par[a][i] != par[b][i]) {
			a = par[a][i];
			b = par[b][i];
		}
	int lca = par[a][0];
	return ret - 2 * dis[lca];
}

int main() {
	n = 4;
	dis[1] = dis[2] = dis[3] = 1;
	blen = 2;
	a = 1; b = 2;
	int Q; scanf("%d", &Q);
	while (Q--) {
		int v; scanf("%d", &v); v--;
		par[n][0] = v;
		for (int i = 1; i < MAXL; i++) par[n][i] = par[par[n][i-1]][i-1];
		for (int i = 0; i < MAXL; i++) par[n+1][i] = par[n][i];
		dis[n] = dis[n + 1] = dis[v] + 1;
		int da = get_dist(n, a);
		int db = get_dist(n, b);
		if (da > blen && da >= db) {
			blen = da;
			b = n;
		} else if (db > blen) {
			blen = db;
			a = n;
		}
		printf("%d\n", blen);
		n += 2;
	}
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cassert>
#include <cstring>
#include <string>
#include <sstream>

using namespace std;

const int MAXL = 21;
const int MAXN = 2 * 5 * 100005;

int n;
int blen, a, b;
int dis[MAXN], par[MAXN][MAXL];

inline int get_dist(int a, int b) {
	int ret = dis[a] + dis[b];
	if (dis[a] > dis[b]) swap(a, b);
	for (int i = MAXL-1; i >= 0; i--)
		if (dis[par[b][i]] >= dis[a]) b = par[b][i];
	if (a == b) return a;
	for (int i = MAXL-1; i >= 0; i--)
		if (par[a][i] != par[b][i]) {
			a = par[a][i];
			b = par[b][i];
		}
	int lca = par[a][0];
	return ret - 2 * dis[lca];
}

int main() {
	n = 4;
	dis[1] = dis[2] = dis[3] = 1;
	blen = 2;
	a = 1; b = 2;
	int Q; scanf("%d", &Q);
	while (Q--) {
		int v; scanf("%d", &v); v--;
		par[n][0] = v;
		for (int i = 1; i < MAXL; i++) par[n][i] = par[par[n][i-1]][i-1];
		for (int i = 0; i < MAXL; i++) par[n+1][i] = par[n][i];
		dis[n] = dis[n + 1] = dis[v] + 1;
		int da = get_dist(n, a);
		int db = get_dist(n, b);
		if (da > blen && da >= db) {
			blen = da;
			b = n;
		} else if (db > blen) {
			blen = db;
			a = n;
		}
		printf("%d\n", blen);
		n += 2;
	}
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cassert>
#include <cstring>
#include <string>
#include <sstream>

using namespace std;

const int MAXL = 21;
const int MAXN = 2 * 5 * 100005;

int n, a, b, blen;
int dis[MAXN], pr[MAXN][MAXL];

int get_dist(int a, int b) {
	int ret = dis[a] + dis[b];
	if (dis[a] > dis[b]) swap(a,b);
	for (int i = MAXL-1; i >= 0; i--)
		if (dis[pr[b][i]] >= dis[a]) b = pr[b][i];
	for (int i = MAXL-1; i >= 0; i--)
		if (pr[a][i] != pr[b][i]) {
			a = pr[a][i];
			b = pr[b][i];
		}
	return ret - dis[pr[a][0]] * 2;
}

int main() {
	n = 4;
	dis[1] = dis[2] = dis[3] = 1;
	a = 1, b = 2, blen = 2;
	int Q; scanf("%d", &Q);
	while (Q--) {
		int v; scanf("%d", &v); v--;
		pr[n][0] = pr[n+1][0] = v;
		for (int i = 1; i < MAXL; i++) pr[n][i] = pr[n+1][i] = pr[pr[n][i-1]][i-1];
		dis[n] = dis[n+1] = dis[v] + 1;
		int d1 = get_dist(n, a);
		int d2 = get_dist(n, b);
		if (d1 >= d2 && d1 > blen) {
			blen = d1; b = n;
		} else if (d2 > blen) {
			blen = d2; a = n;
		}
		printf("%d\n", blen);
		n += 2;
	}
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cassert>
#include <cstring>
#include <string>
#include <sstream>

using namespace std;

const int MAXL = 21;
const int MAXN = 2 * 5 * 100005;

int n;
int blen, a, b;
int dis[MAXN], par[MAXN][MAXL];

int get_lca(int a, int b) {
  if (dis[a] > dis[b]) swap(a, b);
	for (int i = MAXL-1; i >= 0; i--)
		if (dis[par[b][i]] >= dis[a]) b = par[b][i];
	if (a == b) return a;
	for (int i = MAXL-1; i >= 0; i--)
		if (par[a][i] != par[b][i]) {
			a = par[a][i];
			b = par[b][i];
		}
	return par[a][0];
}

int get_dist(int a, int b) {
	int lca = get_lca(a, b);
	return dis[a] + dis[b] - 2 * dis[lca];
}

int main() {
	n = 4;
	dis[1] = dis[2] = dis[3] = 1;
	blen = 2;
	a = 1; b = 2;
	int Q; scanf("%d", &Q);
	while (Q--) {
		int v; scanf("%d", &v); v--;
		par[n][0] = v;
		for (int i = 1; i < MAXL; i++) par[n][i] = par[par[n][i-1]][i-1];
		for (int i = 0; i < MAXL; i++) par[n+1][i] = par[n][i];
		dis[n] = dis[n + 1] = dis[v] + 1;
		int da = get_dist(n, a);
		int db = get_dist(n, b);
		if (da > blen && da >= db) {
			blen = da;
			b = n;
		} else if (db > blen) {
			blen = db;
			a = n;
		}
		printf("%d\n", blen);
		n += 2;
	}
	return 0;
}


#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <climits>
#include <cassert>

#define FOR(i,n) for(int i=0,_n=n;i<_n;i++)
#define FORD(i,n) for(int i=n;i>=0;i--)
#define FORR(i,s,n) for(int i=s,_n=n;i<_n;i++)
#define FORRD(i,n,s) for(int i=n,_s=s;i>=_s;i--)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define pli pair<ll,int>
#define vi vector<int>
#define fs first
#define sec second

#define maxn 600000
#define LOG 20
using namespace std;
typedef long long ll;

int anc[maxn][20],dep[maxn],n;
vi vtx[maxn];

void build(int x,int y,int lv){
	dep[x] = lv;
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[x][i - 1];
	}
	FOR(i,vtx[x].size())
		if(vtx[x][i] != y)
			build(vtx[x][i],x,lv + 1);
}

void add_lca(int x,int y){
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[x][i - 1];
	}
}
int lca(int u, int v) {
	if (dep[u] < dep[v])
		swap(u, v);
	int up = dep[u] - dep[v];
	for (int i = 0; i < LOG; ++i) {
		if (up >> i & 1)
			u = anc[u][i];
	}
	if (u == v)
		return u;
	for (int i = LOG - 1; i >= 0; --i) {
		if (anc[u][i] != anc[v][i])
			u = anc[u][i], v = anc[v][i];
	}
	return anc[u][0];
}

int v1,v2,dist;
int tv1,tv2,tdist;

void upd_max(int a,int b){
	int ndst = dep[a] + dep[b] - 2 * dep[lca(a,b)];
	if(ndst > tdist){
		tdist = ndst;
		tv1 = a;
		tv2 = b;
	}
}
int main(){
	int q,v;
	scanf("%d",&q);

	vtx[0].pb(1);
	vtx[0].pb(2);
	vtx[0].pb(3);

	memset(anc,-1,sizeof anc);

	build(0,-1,1);
	v1 = 1;
	v2 = 2;
	dist = 2;

	n = 4;
	while(q--){
		scanf("%d",&v);
		v--;

		dep[n] = dep[v] + 1;
		dep[n + 1] = dep[v] + 1;

		add_lca(n,v);
		add_lca(n + 1,v);

		tv1 = v1;
		tv2 = v2;
		tdist = dist;

		upd_max(n,v1);
		upd_max(n,v2);
		upd_max(n + 1,v1);
		upd_max(n + 1,v2);
		upd_max(n,n + 1);
		if(tdist > dist){
			dist = tdist;
			v1 = tv1;
			v2 = tv2;
		}
		printf("%d\n",dist);
		n+=2;
	}
	return 0;
}


#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <climits>
#include <cassert>

#define FOR(i,n) for(int i=0,_n=n;i<_n;i++)
#define FORD(i,n) for(int i=n;i>=0;i--)
#define FORR(i,s,n) for(int i=s,_n=n;i<_n;i++)
#define FORRD(i,n,s) for(int i=n,_s=s;i>=_s;i--)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define pli pair<ll,int>
#define vi vector<int>
#define fs first
#define sec second

#define maxn 600000
#define LOG 20
using namespace std;
typedef long long ll;

int anc[maxn][20],dep[maxn],n;
vi vtx[maxn];

void build(int x,int y,int lv){
	dep[x] = lv;
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[x][i - 1];
	}
	FOR(i,vtx[x].size())
		if(vtx[x][i] != y)
			build(vtx[x][i],x,lv + 1);
}

void add_lca(int x,int y){
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[x][i - 1];
	}
}
int lca(int u, int v) {
	if (dep[u] < dep[v])
		swap(u, v);
	int up = dep[u] - dep[v];
	for (int i = 0; i < LOG; ++i) {
		if (up >> i & 1)
			u = anc[u][i];
	}
	if (u == v)
		return u;
	for (int i = LOG - 1; i >= 0; --i) {
		if (anc[u][i] != anc[v][i])
			u = anc[u][i], v = anc[v][i];
	}
	return anc[u][0];
}

int v1,v2,dist;
void upd_max(int w){
	int d1 = dep[w] + dep[v1] - 2 * dep[lca(v1,w)];
	int d2 = dep[w] + dep[v2] - 2 * dep[lca(v2,w)];

	if(d1 > d2 && d1 > dist){
		v2 = w;
		dist = d1;
	}
	else if(d2 > d1 && d2 > dist){
		v1 = w;
		dist = d2;
	}
}
int main(){
	int q,v;
	scanf("%d",&q);

	vtx[0].pb(1);
	vtx[0].pb(2);
	vtx[0].pb(3);

	memset(anc,-1,sizeof anc);

	build(0,-1,1);
	v1 = 1;
	v2 = 2;
	dist = 2;

	n = 4;
	while(q--){
		scanf("%d",&v);
		v--;

		vtx[v].pb(n);
		vtx[v].pb(n + 1);

		dep[n] = dep[v] + 1;
		dep[n + 1] = dep[v] + 1;

		add_lca(n,v);
		add_lca(n + 1,v);

		upd_max(n);
		upd_max(n + 1);
		printf("%d\n",dist);
		n+=2;
	}
	return 0;
}


#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <climits>
#include <cassert>

#define FOR(i,n) for(int i=0,_n=n;i<_n;i++)
#define FORD(i,n) for(int i=n;i>=0;i--)
#define FORR(i,s,n) for(int i=s,_n=n;i<_n;i++)
#define FORRD(i,n,s) for(int i=n,_s=s;i>=_s;i--)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define pli pair<ll,int>
#define vi vector<int>
#define fs first
#define sec second

#define maxn 600000
#define LOG 21
using namespace std;
typedef long long ll;

int anc[maxn][22],dep[maxn],n;
vi vtx[maxn];

void build(int x,int y,int lv){
	dep[x] = lv;
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[go][i - 1];
	}
	FOR(i,vtx[x].size())
		if(vtx[x][i] != y)
			build(vtx[x][i],x,lv + 1);
}
void add_lca(int x,int y){
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[go][i - 1];
	}
}
int lca(int u, int v) {
	if (dep[u] < dep[v])
		swap(u, v);
	int up = dep[u] - dep[v];
	for (int i = 0; i < LOG; ++i) {
		if (up >> i & 1)
			u = anc[u][i];
	}
	if (u == v)
		return u;
	for (int i = LOG - 1; i >= 0; --i) {
		if (anc[u][i] != anc[v][i])
			u = anc[u][i], v = anc[v][i];
	}
	return anc[u][0];
}

int v1,v2,dist;
int tv1,tv2,tdist;

void upd_max(int a,int b){
	int ndst = dep[a] + dep[b] - 2 * dep[lca(a,b)];
	if(ndst > tdist){
		tdist = ndst;
		tv1 = a;
		tv2 = b;
	}
}
int main(){
	int q,v;
	scanf("%d",&q);

	vtx[0].pb(1);
	vtx[0].pb(2);
	vtx[0].pb(3);

	memset(anc,-1,sizeof anc);

	build(0,-1,1);
	v1 = 1;
	v2 = 2;
	dist = 2;

	n = 4;
	while(q--){
		scanf("%d",&v);
		v--;

		dep[n] = dep[v] + 1;
		dep[n + 1] = dep[v] + 1;

		add_lca(n,v);
		add_lca(n + 1,v);

		tv1 = v1;
		tv2 = v2;
		tdist = dist;

		upd_max(n,v1);
		upd_max(n,v2);
		upd_max(n + 1,v1);
		upd_max(n + 1,v2);
		upd_max(n,n + 1);
		if(tdist > dist){
			dist = tdist;
			v1 = tv1;
			v2 = tv2;
		}
		printf("%d\n",dist);
		n+=2;
	}
	return 0;
}


#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <climits>
#include <cassert>

#define FOR(i,n) for(int i=0,_n=n;i<_n;i++)
#define FORD(i,n) for(int i=n;i>=0;i--)
#define FORR(i,s,n) for(int i=s,_n=n;i<_n;i++)
#define FORRD(i,n,s) for(int i=n,_s=s;i>=_s;i--)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define pli pair<ll,int>
#define vi vector<int>
#define fs first
#define sec second

#define maxn 1000005
#define LOG 21
using namespace std;
typedef long long ll;

int anc[maxn][22],dep[maxn],n;
vi vtx[maxn];

void build(int x,int y,int lv){
	dep[x] = lv;
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[go][i - 1];
	}
	FOR(i,vtx[x].size())
		if(vtx[x][i] != y)
			build(vtx[x][i],x,lv + 1);
}
void add_lca(int x,int y){
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[go][i - 1];
	}
}
int lca(int u, int v) {
	if (dep[u] < dep[v])
		swap(u, v);
	int up = dep[u] - dep[v];
	for (int i = 0; i < LOG; ++i) {
		if (up >> i & 1)
			u = anc[u][i];
	}
	if (u == v)
		return u;
	for (int i = LOG - 1; i >= 0; --i) {
		if (anc[u][i] != anc[v][i])
			u = anc[u][i], v = anc[v][i];
	}
	return anc[u][0];
}

int v1,v2,dist;
int tv1,tv2,tdist;

void upd_max(int a,int b){
	int ndst = dep[a] + dep[b] - 2 * dep[lca(a,b)];
	if(ndst > tdist){
		tdist = ndst;
		tv1 = a;
		tv2 = b;
	}
}
int main(){
	int q,v;
	scanf("%d",&q);

	vtx[0].pb(1);
	vtx[0].pb(2);
	vtx[0].pb(3);

	memset(anc,-1,sizeof anc);

	build(0,-1,1);
	v1 = 1;
	v2 = 2;
	dist = 2;

	n = 4;
	while(q--){
		scanf("%d",&v);
		v--;

		dep[n] = dep[v] + 1;
		dep[n + 1] = dep[v] + 1;

		add_lca(n,v);
		add_lca(n + 1,v);

		tv1 = v1;
		tv2 = v2;
		tdist = dist;

		upd_max(n,v1);
		upd_max(n,v2);
		upd_max(n + 1,v1);
		upd_max(n + 1,v2);
		upd_max(n,n + 1);
		if(tdist > dist){
			dist = tdist;
			v1 = tv1;
			v2 = tv2;
		}
		printf("%d\n",dist);
		n+=2;
	}
	return 0;
}


#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <climits>
#include <cassert>

#define FOR(i,n) for(int i=0,_n=n;i<_n;i++)
#define FORD(i,n) for(int i=n;i>=0;i--)
#define FORR(i,s,n) for(int i=s,_n=n;i<_n;i++)
#define FORRD(i,n,s) for(int i=n,_s=s;i>=_s;i--)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define pli pair<ll,int>
#define vi vector<int>
#define fs first
#define sec second

#define maxn 600000
#define LOG 20
using namespace std;
typedef long long ll;

int anc[maxn][20],dep[maxn],n;
vi vtx[maxn];

void build(int x,int y,int lv){
	dep[x] = lv;
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[x][i - 1];
	}
}

void add_lca(int x,int y){
	anc[x][0] = y;
	for (int i = 1; i < LOG; ++i) {
		int go = anc[x][i - 1];
		anc[x][i] = go == -1 ? go : anc[x][i - 1];
	}
}
int lca(int u, int v) {
	if (dep[u] < dep[v])
		swap(u, v);
	int up = dep[u] - dep[v];
	for (int i = 0; i < LOG; ++i) {
		if (up >> i & 1)
			u = anc[u][i];
	}
	if (u == v)
		return u;
	for (int i = LOG - 1; i >= 0; --i) {
		if (anc[u][i] != anc[v][i])
			u = anc[u][i], v = anc[v][i];
	}
	return anc[u][0];
}

int v1,v2,dist;
void upd_max(int w){
	int d1 = dep[w] + dep[v1] - 2 * dep[lca(v1,w)];
	int d2 = dep[w] + dep[v2] - 2 * dep[lca(v2,w)];

	if(d1 > d2 && d1 > dist){
		v2 = w;
		dist = d1;
	}
	else if(d2 > d1 && d2 > dist){
		v1 = w;
		dist = d2;
	}
}
int main(){
	int q,v;
	scanf("%d",&q);

	vtx[0].pb(1);
	vtx[0].pb(2);
	vtx[0].pb(3);

	memset(anc,-1,sizeof anc);

	v1 = 1;
	v2 = 2;
	dist = 2;

	n = 4;
	while(q--){
		scanf("%d",&v);
		v--;

		vtx[v].pb(n);
		vtx[v].pb(n + 1);

		dep[n] = dep[v] + 1;
		dep[n + 1] = dep[v] + 1;

		add_lca(n,v);
		add_lca(n + 1,v);

		upd_max(n);
		upd_max(n + 1);
		printf("%d\n",dist);
		n+=2;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0},clevel[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];
int idsc[SIZE][21];
int part;
vector<int> Dists[SIZE];
int construct_ctree(int rootnow,int fl=0){             // returns the root
	findsizes(rootnow);
//	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	if(fl==1)clevel[c ] = 0;
	else
	clevel[c] = clevel[part]+1;
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			part = c;
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
		}
	}

	queue<ii > Q;int nowl = clevel[c];
	Q.push(mp(c,0) );
//	idsc[c][nowl] = 0;
//	Dists[c].pb(0);
//	cout<<"for c = "<<c<<endl;
	while(!Q.empty()){
		ii now = Q.front();Q.pop();
		int nxt = now.ff,distf = now.ss;
//		if(idsc[nxt][nowl]!=-1)cout<<"Hey error buddy"<<endl;
		idsc[nxt][nowl] = Dists[c].size();
		Dists[c].pb(distf);
//		cout<<nxt<<' '<<distf<<endl;
		for(int i =0; i< llist[nxt].size(); i++){
			int nxn = llist[nxt][i];
			if(idsc[nxn][nowl]==-1 && clevel[nxn]>nowl){
				Q.push(mp(nxn,distf+1));
			}
		}
	}
//	cout<<endl;
	return c;
}
int givedist(int v,int c, int lvl){
//	cout<<"Betw "<<v << " and "<<c <<" dist is "<<Dists[c][idsc[v][lvl]]<<' '<<lvl<<endl;
	return Dists[c][idsc[v][lvl]];
}

//multiset<int> dists[SIZE];
vector<int> contrib,don;
vii maxdists;
int d,n;
int addv(int v){
	int now =v;
//	multiset<int> ::iterator it;
//	cout<<v<<endl;
	int cnt =0;
	while(cpar[now] != -1){

		int distn = givedist(v,cpar[now],clevel[v]-1-cnt);//= tr.dist(cpar[now],v);
		cnt++;
		if(contrib[now] >= distn){now= cpar[now];continue;}
//		if(contrib[now]!=-1)
//			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
//		dists[cpar[now]].insert(distn);
		if(maxdists[cpar[now]].ff==contrib[now])
			maxdists[cpar[now]].ff = distn;
		else if(maxdists[cpar[now]].ss == contrib[now])
			maxdists[cpar[now]].ss = distn;
		contrib[now] = distn;
		now = cpar[now];
		if(don[now]){
			d = max(d, maxdists[now].ff);
			d = max(d,maxdists[now].ff+maxdists[now].ss);
		}
//		it = (dists[now]).end();it--;
//		if(don[now])if(!dists[now].empty())d = max(d,*it);
//		if(dists[now].size() >=2)
//			d = max(d, *(it--) + *it);
	}

//	cout<<v<<" ended "<<d<<endl;
//	for(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<" ("<<maxdists[i].ff<<','<<maxdists[i].ss<<") ";
//		}
//		cout<<endl;
//	}
}

int main(){
	cin.tie(false);cout.tie(false);
	ios::sync_with_stdio(false);
	int n,n1;
	cin>>n;n1=n;
	for(int i =0; i<2*n+4; i++)for(int j = 0; j< 21;j++)idsc[i][j] = -1;
	for(int i =0; i< 2*n+4; i++)Dists[i].clear();
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		scanf("%d",&a);a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
	don.assign(n,0);
	maxdists.assign(n,mp(-1,-1));
//   tr = LCA(llist,n);
	croot = construct_ctree(0,1);
	cpar[croot] = -1;
	if(n >=600000){
		cout<<"Passes"<<endl;
		return 0;
	}
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		printf("%d\n",d);
//		cout<<d<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0},clevel[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];
int idsc[SIZE][21];
int part;
vector<int> Dists[SIZE];
int construct_ctree(int rootnow,int fl=0){             // returns the root
	findsizes(rootnow);
//	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	if(fl==1)clevel[c ] = 0;
	else
	clevel[c] = clevel[part]+1;
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			part = c;
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
		}
	}

	queue<ii > Q;int nowl = clevel[c];
	Q.push(mp(c,0) );
//	idsc[c][nowl] = 0;
//	Dists[c].pb(0);
//	cout<<"for c = "<<c<<endl;
	while(!Q.empty()){
		ii now = Q.front();Q.pop();
		int nxt = now.ff,distf = now.ss;
//		if(idsc[nxt][nowl]!=-1)cout<<"Hey error buddy"<<endl;
		idsc[nxt][nowl] = Dists[c].size();
		Dists[c].pb(distf);
//		cout<<nxt<<' '<<distf<<endl;
		for(int i =0; i< llist[nxt].size(); i++){
			int nxn = llist[nxt][i];
			if(idsc[nxn][nowl]==-1 && clevel[nxn]>nowl){
				Q.push(mp(nxn,distf+1));
			}
		}
	}
//	cout<<endl;
	return c;
}
int givedist(int v,int c, int lvl){
//	cout<<"Betw "<<v << " and "<<c <<" dist is "<<Dists[c][idsc[v][lvl]]<<' '<<lvl<<endl;
	return Dists[c][idsc[v][lvl]];
}

//multiset<int> dists[SIZE];
vector<int> contrib,don;
vii maxdists;
int d,n;
int addv(int v){
	int now =v;
//	multiset<int> ::iterator it;
//	cout<<v<<endl;
	int cnt =0;
	while(cpar[now] != -1){

		int distn = givedist(v,cpar[now],clevel[v]-1-cnt);//= tr.dist(cpar[now],v);
		cnt++;
		if(contrib[now] >= distn){now= cpar[now];continue;}
//		if(contrib[now]!=-1)
//			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
//		dists[cpar[now]].insert(distn);
		if(maxdists[cpar[now]].ff==contrib[now])
			maxdists[cpar[now]].ff = distn;
		else if(maxdists[cpar[now]].ss == contrib[now])
			maxdists[cpar[now]].ss = distn;
		contrib[now] = distn;
		now = cpar[now];
		if(don[now]){
			d = max(d, maxdists[now].ff);
			d = max(d,maxdists[now].ff+maxdists[now].ss);
		}
//		it = (dists[now]).end();it--;
//		if(don[now])if(!dists[now].empty())d = max(d,*it);
//		if(dists[now].size() >=2)
//			d = max(d, *(it--) + *it);
	}

//	cout<<v<<" ended "<<d<<endl;
//	for(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<" ("<<maxdists[i].ff<<','<<maxdists[i].ss<<") ";
//		}
//		cout<<endl;
//	}
}

int main(){
//	cin.tie(false);cout.tie(false);
//	ios::sync_with_stdio(false);
	int n,n1;
	//cin>>n;
	scanf("%d",&n);n1=n;
	for(int i =0; i<2*n+4; i++)for(int j = 0; j< 21;j++)idsc[i][j] = -1;
	for(int i =0; i< 2*n+4; i++)Dists[i].clear();
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		scanf("%d",&a);a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
	don.assign(n,0);
	maxdists.assign(n,mp(-1,-1));
//   tr = LCA(llist,n);
	croot = construct_ctree(0,1);
	cpar[croot] = -1;
	if(n >=600000){
		cout<<"Passes"<<endl;
		return 0;
	}
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		printf("%d\n",d);
//		cout<<d<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];

int construct_ctree(int rootnow){             // returns the root
	findsizes(rootnow);
	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
			//	cout<<c<<' '<<nxt<<endl;
		}
	}
	return c;
}

class LCA{                                                           // Point update Range Query Std SEg Tree
	vector<int> st,lvl, tour,vis,firs;
	int n,top;
	int parent(int p){return p/2;}
	int left(int p){return p<<1;}
	int right(int p){return (p<<1) +1;}
	int rmq(int p, int L,int R, int i,int j){
		if(R<i || L>j) return -1;
		if(L>i && R<j) return st[p];
		if(L==R) return st[p];
		int p1 = rmq(left(p), L  , (L+R)/2,i, j );
		int p2 = rmq(right(p), (L+R)/2 +1, R, i, j);
		if(p1 == -1)
			return p2;
		if(p2 == -1)
			return p1;
		return lvl[tour[p1]]<lvl[tour[p2]] ? p1: p2;
	}
	void build_st(int p , int L, int R){
		if(L == R) {st[p] = L;return;}
		build_st(left(p), L  , (L+R)/2);
		build_st(right(p), (L+R)/2+1, R);
		int p1 = st[left(p)] , p2 = st[right(p)];
		st[p] = (lvl[tour[p1]]<lvl[tour[p2]] ? p1 : p2 );
	}

	public:
	void dfs(int v,vector<int> (&llist)[SIZE]){
		vis[v] = 1;
		firs[v] = tour.size();
		tour.pb( v);
		for(int i = 0; i< llist[v].size(); i++){
			int nxt = llist[v][i];
			if(!vis[nxt]){
				lvl[nxt] = lvl[v] +1;
				dfs(nxt, llist);
				tour.pb( v);
			}
		}
	}

	LCA(vector<int> (&llist)[SIZE],int n=-1,int root=0){
		if(n==-1) return;
		top =0;
		vis.assign(n,0);
		lvl.assign(n,0);tour.clear();firs.assign(n,0);
		lvl[root] = 0;
		dfs(root,llist);
		st.assign(4*tour.size(),0);
		this->n = tour.size();
		build_st(1,0,this->n-1);
	}
	int dist(int a, int b){
		int lca = tour[rmq(1,0,n-1, min(firs[a],firs[b]), max(firs[a],firs[b]))];
		return lvl[a]+lvl[b] - 2*lvl[lca];
	}
};
LCA tr(llist);
multiset<int> dists[SIZE];
vector<int> contrib,don;
int d,n;
int addv(int v){
	int now =v;
	multiset<int> ::iterator it;
//	cout<<v<<endl;
	while(cpar[now] != -1){

		int distn = tr.dist(cpar[now],v);
		if(contrib[now] >= distn){break;}
		if(contrib[now]!=-1)
			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
		dists[cpar[now]].insert(distn);
		contrib[now] = distn;
		now = cpar[now];

		it = (dists[now]).end();it--;
		if(don[now])if(!dists[now].empty())d = max(d,*it);
		if(dists[now].size() >=2)
			d = max(d, *(it--) + *it);
	}

//cout<<v<<" ended "<<d<<endl;
//or(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<*it<<' ';
//		}
//		cout<<endl;
//	}
}

int main(){
	cin.tie(false);cout.tie(false);
	ios::sync_with_stdio(false);
	int n,n1;
	cin>>n;n1=n;
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		cin>>a;a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
	don.assign(n,0);
   tr = LCA(llist,n);
	croot = construct_ctree(0);
	cpar[croot] = -1;
//	for(int i =0;i< n; i++)cout<<cpar[i]<<' ';cout<<endl;
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
//	cout<<"SERI"<<endl;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		cout<<d<<endl;
	}
	//cout<<croot<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0},clevel[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];

int construct_ctree(int rootnow){             // returns the root
	findsizes(rootnow);
//	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
	//		clevel[nxt] = clevel[c] +1;
			//	cout<<c<<' '<<nxt<<endl;
		}
	}
	return c;
}

class LCA{                                                           // Point update Range Query Std SEg Tree
	vector<int> st,lvl, tour,vis,firs;
	int n,top;
	int parent(int p){return p/2;}
	int left(int p){return p<<1;}
	int right(int p){return (p<<1) +1;}
	int rmq(int p, int L,int R, int i,int j){
		if(R<i || L>j) return -1;
		if(L>i && R<j) return st[p];
		if(L==R) return st[p];
		int p1 = rmq(left(p), L  , (L+R)/2,i, j );
		int p2 = rmq(right(p), (L+R)/2 +1, R, i, j);
		if(p1 == -1)
			return p2;
		if(p2 == -1)
			return p1;
		return lvl[tour[p1]]<lvl[tour[p2]] ? p1: p2;
	}
	void build_st(int p , int L, int R){
		if(L == R) {st[p] = L;return;}
		build_st(left(p), L  , (L+R)/2);
		build_st(right(p), (L+R)/2+1, R);
		int p1 = st[left(p)] , p2 = st[right(p)];
		st[p] = (lvl[tour[p1]]<lvl[tour[p2]] ? p1 : p2 );
	}

	public:
	void dfs(int v,vector<int> (&llist)[SIZE]){
		vis[v] = 1;
		firs[v] = tour.size();
		tour.pb( v);
		for(int i = 0; i< llist[v].size(); i++){
			int nxt = llist[v][i];
			if(!vis[nxt]){
				lvl[nxt] = lvl[v] +1;
				dfs(nxt, llist);
				tour.pb( v);
			}
		}
	}

	LCA(vector<int> (&llist)[SIZE],int n=-1,int root=0){
		if(n==-1) return;
		top =0;
		vis.assign(n,0);
		lvl.assign(n,0);tour.clear();firs.assign(n,0);
		lvl[root] = 0;
		dfs(root,llist);
		st.assign(4*tour.size(),0);
		this->n = tour.size();
		build_st(1,0,this->n-1);
	}
	int dist(int a, int b){
		int lca = tour[rmq(1,0,n-1, min(firs[a],firs[b]), max(firs[a],firs[b]))];
		return lvl[a]+lvl[b] - 2*lvl[lca];
	}
};
LCA tr(llist);
multiset<int> dists[SIZE];
vector<int> contrib,don;
int d,n;
int addv(int v){
	int now =v;
	multiset<int> ::iterator it;
//	cout<<v<<endl;
	while(cpar[now] != -1){

		int distn = tr.dist(cpar[now],v);
		if(contrib[now] >= distn){now= cpar[now];continue;}
		if(contrib[now]!=-1)
			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
		dists[cpar[now]].insert(distn);
		contrib[now] = distn;
		now = cpar[now];

		it = (dists[now]).end();it--;
		if(don[now])if(!dists[now].empty())d = max(d,*it);
		if(dists[now].size() >=2)
			d = max(d, *(it--) + *it);
	}

//cout<<v<<" ended "<<d<<endl;
//or(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<*it<<' ';
//		}
//		cout<<endl;
//	}
}

int main(){
	cin.tie(false);cout.tie(false);
	ios::sync_with_stdio(false);
	int n,n1;
	cin>>n;n1=n;
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		cin>>a;a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
	don.assign(n,0);
   tr = LCA(llist,n);
	croot = construct_ctree(0);
	cpar[croot] = -1;
//	for(int i =0;i< n; i++)cout<<cpar[i]<<' ';cout<<endl;
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
//	cout<<"SERI"<<endl;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		cout<<d<<endl;
	}
	//cout<<croot<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
//#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

int endf=1,ende=2;
int dp[SIZE][21],ht[SIZE];
int par[SIZE],d;

void insert(int v,int p){
	par[v] = p;
	ht[v] = ht[p]+1;
	dp[v][0] = p;
	for(int i = 1; i< 21; i++){
		if(dp[v][i-1]<0)break;
		dp[v][i] = dp[dp[v][i-1]][i-1];
	}
}

int lca(int a, int b){
	int a1=a,b1=b;
	//cout<<ht[a1]<<' '<<ht[b1]<<endl;
	for(int i =20; i>= 0; i--){
		if(ht[a1] - (1<<i) >= ht[b1])a1 = dp[a1][i];
	}
	for(int i =20; i>= 0; i--){
		if(ht[b1] - (1<<i) >= ht[a1])b1 = dp[b1][i];
	}
//	cout<<a1<<' '<<b1<<endl;
	if(a1==b1)return a1;
	for(int i = 20; i>=0; i--){
		if(dp[a1][i] != dp[b1][i]){
			a1 = dp[a1][i];
			b1 = dp[b1][i];
		}
	}
	if(a1!=b1){
		a1 = par[a1];
		b1 = par[b1];
	}
	if(a1!= b1)cout<<"Error"<<endl;
	return a1;
}

int main(){

	for(int i =0 ;i<SIZE; i++){
		for(int j =0; j< 21; j++)dp[i][j] = -1;
	}
	par[0] = -1;
	ht[0] = 0;
	insert(1,0);
	insert(2,0);
	insert(3,0);
	int n;
//	cin>>n;
   scanf("%d",&n);
	for(int i =0; i< n; i++){
		int a,b;
		scanf("%d",&a);
		//cin>>a;
		a--;
	//	cin>>a>>b;a--;b--;
	//	cout<<lca(a,b)<<endl;

		insert(4+2*i,a);insert(5+2*i,a);

		int d1 = ht[4+2*i] + ht[endf]-2*ht[lca(a,endf)] , d2 = ht[4+2*i] + ht[ende] -2*ht[lca(a,ende)];
		if(d1>d && d1>d2)
			ende = 4+2*i;
		else if( d2>d &&d2>=d1)endf = 4+2*i;
		d = max(max(d1,d2), d);
		//cout<<d<<endl;
		printf("%d\n",d);
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0},clevel[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];

int construct_ctree(int rootnow){             // returns the root
	findsizes(rootnow);
//	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
	//		clevel[nxt] = clevel[c] +1;
			//	cout<<c<<' '<<nxt<<endl;
		}
	}
	return c;
}

class LCA{                                                           // Point update Range Query Std SEg Tree
	vector<int> st,lvl, tour,vis,firs;
	int n,top;
	int parent(int p){return p/2;}
	int left(int p){return p<<1;}
	int right(int p){return (p<<1) +1;}
	int rmq(int p, int L,int R, int i,int j){
		if(R<i || L>j) return -1;
		if(L>i && R<j) return st[p];
		if(L==R) return st[p];
		int p1 = rmq(left(p), L  , (L+R)/2,i, j );
		int p2 = rmq(right(p), (L+R)/2 +1, R, i, j);
		if(p1 == -1)
			return p2;
		if(p2 == -1)
			return p1;
		return lvl[tour[p1]]<lvl[tour[p2]] ? p1: p2;
	}
	void build_st(int p , int L, int R){
		if(L == R) {st[p] = L;return;}
		build_st(left(p), L  , (L+R)/2);
		build_st(right(p), (L+R)/2+1, R);
		int p1 = st[left(p)] , p2 = st[right(p)];
		st[p] = (lvl[tour[p1]]<lvl[tour[p2]] ? p1 : p2 );
	}

	public:
	void dfs(int v,vector<int> (&llist)[SIZE]){
		vis[v] = 1;
		firs[v] = tour.size();
		tour.pb( v);
		for(int i = 0; i< llist[v].size(); i++){
			int nxt = llist[v][i];
			if(!vis[nxt]){
				lvl[nxt] = lvl[v] +1;
				dfs(nxt, llist);
				tour.pb( v);
			}
		}
	}

	LCA(vector<int> (&llist)[SIZE],int n=-1,int root=0){
		if(n==-1) return;
		top =0;
		vis.assign(n,0);
		lvl.assign(n,0);tour.clear();firs.assign(n,0);
		lvl[root] = 0;
		dfs(root,llist);
		st.assign(4*tour.size(),0);
		this->n = tour.size();
		build_st(1,0,this->n-1);
	}
	int dist(int a, int b){
		int lca = tour[rmq(1,0,n-1, min(firs[a],firs[b]), max(firs[a],firs[b]))];
		return lvl[a]+lvl[b] - 2*lvl[lca];
	}
};
LCA tr(llist);
multiset<int> dists[SIZE];
vector<int> contrib,don;
int d,n;
int addv(int v){
	int now =v;
	multiset<int> ::iterator it;
//	cout<<v<<endl;
	while(cpar[now] != -1){

		int distn = tr.dist(cpar[now],v);
		if(contrib[now] >= distn){break;}
		if(contrib[now]!=-1)
			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
		dists[cpar[now]].insert(distn);
		contrib[now] = distn;
		now = cpar[now];

		it = (dists[now]).end();it--;
		if(don[now])if(!dists[now].empty())d = max(d,*it);
		if(dists[now].size() >=2)
			d = max(d, *(it--) + *it);
	}

//cout<<v<<" ended "<<d<<endl;
//or(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<*it<<' ';
//		}
//		cout<<endl;
//	}
}

int main(){
	cin.tie(false);cout.tie(false);
	ios::sync_with_stdio(false);
	int n,n1;
	cin>>n;n1=n;
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		cin>>a;a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
	don.assign(n,0);
   tr = LCA(llist,n);
	croot = construct_ctree(0);
	cpar[croot] = -1;
//	for(int i =0;i< n; i++)cout<<cpar[i]<<' ';cout<<endl;
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
//	cout<<"SERI"<<endl;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		cout<<d<<endl;
	}
	//cout<<croot<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
//#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];

int construct_ctree(int rootnow){             // returns the root
	findsizes(rootnow);
	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
			//	cout<<c<<' '<<nxt<<endl;
		}
	}
	return c;
}

class LCA{                                                           // Point update Range Query Std SEg Tree
	vector<int> st,lvl, tour,vis,firs;
	int n,top;
	int parent(int p){return p/2;}
	int left(int p){return p<<1;}
	int right(int p){return (p<<1) +1;}
	int rmq(int p, int L,int R, int i,int j){
		if(R<i || L>j) return -1;
		if(L>i && R<j) return st[p];
		if(L==R) return st[p];
		int p1 = rmq(left(p), L  , (L+R)/2,i, j );
		int p2 = rmq(right(p), (L+R)/2 +1, R, i, j);
		if(p1 == -1)
			return p2;
		if(p2 == -1)
			return p1;
		return lvl[tour[p1]]<lvl[tour[p2]] ? p1: p2;
	}
	void build_st(int p , int L, int R){
		if(L == R) {st[p] = L;return;}
		build_st(left(p), L  , (L+R)/2);
		build_st(right(p), (L+R)/2+1, R);
		int p1 = st[left(p)] , p2 = st[right(p)];
		st[p] = (lvl[tour[p1]]<lvl[tour[p2]] ? p1 : p2 );
	}

	public:
	void dfs(int v,vector<int> (&llist)[SIZE]){
		vis[v] = 1;
		firs[v] = tour.size();
		tour.pb( v);
		for(int i = 0; i< llist[v].size(); i++){
			int nxt = llist[v][i];
			if(!vis[nxt]){
				lvl[nxt] = lvl[v] +1;
				dfs(nxt, llist);
				tour.pb( v);
			}
		}
	}

	LCA(vector<int> (&llist)[SIZE],int n=-1,int root=0){
		if(n==-1) return;
		top =0;
		vis.assign(n,0);
		lvl.assign(n,0);tour.clear();firs.assign(n,0);
		lvl[root] = 0;
		dfs(root,llist);
		st.assign(4*tour.size(),0);
		this->n = tour.size();
		build_st(1,0,this->n-1);
	}
	int dist(int a, int b){
		int lca = tour[rmq(1,0,n-1, min(firs[a],firs[b]), max(firs[a],firs[b]))];
		return lvl[a]+lvl[b] - 2*lvl[lca];
	}
};
LCA tr(llist);
multiset<int> dists[SIZE];
vector<int> contrib;
int d,n;
int addv(int v){
	int now =v;
	multiset<int> ::iterator it;
//	cout<<v<<endl;
	while(cpar[now] != -1){

		int distn = tr.dist(cpar[now],v);
		if(contrib[now] >= distn){now = cpar[now];continue;}
		if(contrib[now]!=-1)
			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
		dists[cpar[now]].insert(distn);
		contrib[now] = distn;
		now = cpar[now];

		it = (dists[now]).end();it--;
		if(!dists[now].empty())d = max(d,*it);
		if(dists[now].size() >=2)
			d = max(d, *(it--) + *it);
	}

//cout<<v<<" ended "<<d<<endl;
//or(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<*it<<' ';
//		}
//		cout<<endl;
//	}
}

int main(){
//	cin.tie(false);cout.tie(false);
	ios::sync_with_stdio(false);
	int n,n1;
	cin>>n;n1=n;
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		cin>>a;a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
   tr = LCA(llist,n);
	croot = construct_ctree(0);
	cpar[croot] = -1;
//	for(int i =0;i< n; i++)cout<<cpar[i]<<' ';cout<<endl;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
//	cout<<"SERI"<<endl;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);
		addv(5+2*i);
		cout<<d<<endl;
	}
	//cout<<croot<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];

int construct_ctree(int rootnow){             // returns the root
	findsizes(rootnow);
	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
			//	cout<<c<<' '<<nxt<<endl;
		}
	}
	return c;
}

class LCA{                                                           // Point update Range Query Std SEg Tree
	vector<int> st,lvl, tour,vis,firs;
	int n,top;
	int parent(int p){return p/2;}
	int left(int p){return p<<1;}
	int right(int p){return (p<<1) +1;}
	int rmq(int p, int L,int R, int i,int j){
		if(R<i || L>j) return -1;
		if(L>i && R<j) return st[p];
		if(L==R) return st[p];
		int p1 = rmq(left(p), L  , (L+R)/2,i, j );
		int p2 = rmq(right(p), (L+R)/2 +1, R, i, j);
		if(p1 == -1)
			return p2;
		if(p2 == -1)
			return p1;
		return lvl[tour[p1]]<lvl[tour[p2]] ? p1: p2;
	}
	void build_st(int p , int L, int R){
		if(L == R) {st[p] = L;return;}
		build_st(left(p), L  , (L+R)/2);
		build_st(right(p), (L+R)/2+1, R);
		int p1 = st[left(p)] , p2 = st[right(p)];
		st[p] = (lvl[tour[p1]]<lvl[tour[p2]] ? p1 : p2 );
	}

	public:
	void dfs(int v,vector<int> (&llist)[SIZE]){
		vis[v] = 1;
		firs[v] = tour.size();
		tour.pb( v);
		for(int i = 0; i< llist[v].size(); i++){
			int nxt = llist[v][i];
			if(!vis[nxt]){
				lvl[nxt] = lvl[v] +1;
				dfs(nxt, llist);
				tour.pb( v);
			}
		}
	}

	LCA(vector<int> (&llist)[SIZE],int n=-1,int root=0){
		if(n==-1) return;
		top =0;
		vis.assign(n,0);
		lvl.assign(n,0);tour.clear();firs.assign(n,0);
		lvl[root] = 0;
		dfs(root,llist);
		st.assign(4*tour.size(),0);
		this->n = tour.size();
		build_st(1,0,this->n-1);
	}
	int dist(int a, int b){
		int lca = tour[rmq(1,0,n-1, min(firs[a],firs[b]), max(firs[a],firs[b]))];
		return lvl[a]+lvl[b] - 2*lvl[lca];
	}
};
LCA tr(llist);
multiset<int> dists[SIZE];
vector<int> contrib,don;
int d,n;
int addv(int v){
	int now =v;
	multiset<int> ::iterator it;
//	cout<<v<<endl;
	while(cpar[now] != -1){

		int distn = tr.dist(cpar[now],v);
		if(contrib[now] >= distn){now = cpar[now];continue;}
		if(contrib[now]!=-1)
			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
		dists[cpar[now]].insert(distn);
		contrib[now] = distn;
		now = cpar[now];

		it = (dists[now]).end();it--;
		if(don[now])if(!dists[now].empty())d = max(d,*it);
		if(dists[now].size() >=2)
			d = max(d, *(it--) + *it);
	}

//cout<<v<<" ended "<<d<<endl;
//or(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<*it<<' ';
//		}
//		cout<<endl;
//	}
}

int main(){
	cin.tie(false);cout.tie(false);
	ios::sync_with_stdio(false);
	int n,n1;
	cin>>n;n1=n;
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		cin>>a;a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
	don.assign(n,0);
   tr = LCA(llist,n);
	croot = construct_ctree(0);
	cpar[croot] = -1;
//	for(int i =0;i< n; i++)cout<<cpar[i]<<' ';cout<<endl;
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
//	cout<<"SERI"<<endl;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		cout<<d<<endl;
	}
	//cout<<croot<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0},clevel[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

//vi clist[SIZE];
int croot,cpar[SIZE];
int idsc[SIZE][21];
int part;
vector<int> Dists[SIZE];
int construct_ctree(int rootnow,int fl=0){             // returns the root
	findsizes(rootnow);
//	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	if(fl==1)clevel[c ] = 0;
	else
	clevel[c] = clevel[part]+1;
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			part = c;
			nxt = construct_ctree(nxt);
//			clist[c].pb(nxt);
//			clist[nxt].pb(c);
			cpar[nxt ] =c;
		}
	}

	queue<ii > Q;int nowl = clevel[c];
	Q.push(mp(c,0) );
//	idsc[c][nowl] = 0;
//	Dists[c].pb(0);
//	cout<<"for c = "<<c<<endl;
	while(!Q.empty()){
		ii now = Q.front();Q.pop();
		int nxt = now.ff,distf = now.ss;
//		if(idsc[nxt][nowl]!=-1)cout<<"Hey error buddy"<<endl;
		idsc[nxt][nowl] = Dists[c].size();
		Dists[c].pb(distf);
//		cout<<nxt<<' '<<distf<<endl;
		for(int i =0; i< llist[nxt].size(); i++){
			int nxn = llist[nxt][i];
			if(idsc[nxn][nowl]==-1 && clevel[nxn]>nowl){
				Q.push(mp(nxn,distf+1));
			}
		}
	}
//	cout<<endl;
	return c;
}
int givedist(int v,int c, int lvl){
//	cout<<"Betw "<<v << " and "<<c <<" dist is "<<Dists[c][idsc[v][lvl]]<<' '<<lvl<<endl;
	return Dists[c][idsc[v][lvl]];
}

//multiset<int> dists[SIZE];
int contrib[SIZE]= {0},don[SIZE]={0};
vii maxdists;
int d,n;
int addv(int v){
	int now =v;
//	multiset<int> ::iterator it;
//	cout<<v<<endl;
	int cnt =0;
	while(cpar[now] != -1){

		int distn = givedist(v,cpar[now],clevel[v]-1-cnt);//= tr.dist(cpar[now],v);
		cnt++;
		if(contrib[now] >= distn){now= cpar[now];continue;}
//		if(contrib[now]!=-1)
//			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
//		dists[cpar[now]].insert(distn);
		if(maxdists[cpar[now]].ff==contrib[now])
			maxdists[cpar[now]].ff = distn;
		else if(maxdists[cpar[now]].ss == contrib[now])
			maxdists[cpar[now]].ss = distn;
		contrib[now] = distn;
		now = cpar[now];
		if(don[now]){
			d = max(d, maxdists[now].ff);
			d = max(d,maxdists[now].ff+maxdists[now].ss);
		}
//		it = (dists[now]).end();it--;
//		if(don[now])if(!dists[now].empty())d = max(d,*it);
//		if(dists[now].size() >=2)
//			d = max(d, *(it--) + *it);
	}

//	cout<<v<<" ended "<<d<<endl;
//	for(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<" ("<<maxdists[i].ff<<','<<maxdists[i].ss<<") ";
//		}
//		cout<<endl;
//	}
}

int main(){
//	cin.tie(false);cout.tie(false);
//	ios::sync_with_stdio(false);
	int n,n1;
	scanf("%d",&n);n1=n;
	for(int i =0; i<2*n+4; i++)for(int j = 0; j< 21;j++)idsc[i][j] = -1;
	for(int i =0; i< 2*n+4; i++){Dists[i].clear();contrib[i] = -1;}
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		scanf("%d",&a);a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
//	contrib.assign(n,-1);
//	don.assign(n,0);
	maxdists.assign(n,mp(-1,-1));
//   tr = LCA(llist,n);
	croot = construct_ctree(0,1);
	cpar[croot] = -1;
	if(n >=600000){
		cout<<"Passes"<<endl;
		return 0;
	}
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		printf("%d\n",d);
//		cout<<d<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
//#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];

int construct_ctree(int rootnow){             // returns the root
	findsizes(rootnow);
	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
			//	cout<<c<<' '<<nxt<<endl;
		}
	}
	return c;
}

class LCA{                                                           // Point update Range Query Std SEg Tree
	vector<int> st,lvl, tour,vis,firs;
	int n,top;
	int parent(int p){return p/2;}
	int left(int p){return p<<1;}
	int right(int p){return (p<<1) +1;}
	int rmq(int p, int L,int R, int i,int j){
		if(R<i || L>j) return -1;
		if(L>i && R<j) return st[p];
		if(L==R) return st[p];
		int p1 = rmq(left(p), L  , (L+R)/2,i, j );
		int p2 = rmq(right(p), (L+R)/2 +1, R, i, j);
		if(p1 == -1)
			return p2;
		if(p2 == -1)
			return p1;
		return lvl[tour[p1]]<lvl[tour[p2]] ? p1: p2;
	}
	void build_st(int p , int L, int R){
		if(L == R) {st[p] = L;return;}
		build_st(left(p), L  , (L+R)/2);
		build_st(right(p), (L+R)/2+1, R);
		int p1 = st[left(p)] , p2 = st[right(p)];
		st[p] = (lvl[tour[p1]]<lvl[tour[p2]] ? p1 : p2 );
	}

	public:
	void dfs(int v,vector<int> (&llist)[SIZE]){
		vis[v] = 1;
		firs[v] = tour.size();
		tour.pb( v);
		for(int i = 0; i< llist[v].size(); i++){
			int nxt = llist[v][i];
			if(!vis[nxt]){
				lvl[nxt] = lvl[v] +1;
				dfs(nxt, llist);
				tour.pb( v);
			}
		}
	}

	LCA(vector<int> (&llist)[SIZE],int n=-1,int root=0){
		if(n==-1) return;
		top =0;
		vis.assign(n,0);
		lvl.assign(n,0);tour.clear();firs.assign(n,0);
		lvl[root] = 0;
		dfs(root,llist);
		st.assign(4*tour.size(),0);
		this->n = tour.size();
		build_st(1,0,this->n-1);
	}
	int dist(int a, int b){
		int lca = tour[rmq(1,0,n-1, min(firs[a],firs[b]), max(firs[a],firs[b]))];
		return lvl[a]+lvl[b] - 2*lvl[lca];
	}
};
LCA tr(llist);
multiset<int> dists[SIZE];
vector<int> contrib,don;
int d,n;
int addv(int v){
	int now =v;
	multiset<int> ::iterator it;
//	cout<<v<<endl;
	while(cpar[now] != -1){

		int distn = tr.dist(cpar[now],v);
		if(contrib[now] >= distn){now = cpar[now];continue;}
		if(contrib[now]!=-1)
			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
		dists[cpar[now]].insert(distn);
		contrib[now] = distn;
		now = cpar[now];

		it = (dists[now]).end();it--;
		if(don[now])if(!dists[now].empty())d = max(d,*it);
		if(dists[now].size() >=2)
			d = max(d, *(it--) + *it);
	}

//cout<<v<<" ended "<<d<<endl;
//or(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<*it<<' ';
//		}
//		cout<<endl;
//	}
}

int main(){
//	cin.tie(false);cout.tie(false);
	ios::sync_with_stdio(false);
	int n,n1;
	cin>>n;n1=n;
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		cin>>a;a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
	don.assign(n,0);
   tr = LCA(llist,n);
	croot = construct_ctree(0);
	cpar[croot] = -1;
//	for(int i =0;i< n; i++)cout<<cpar[i]<<' ';cout<<endl;
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
//	cout<<"SERI"<<endl;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		cout<<d<<endl;
	}
	//cout<<croot<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
//#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

int endf=1,ende=2;
int dp[SIZE][21],ht[SIZE];
int par[SIZE],d;

void insert(int v,int p){
	par[v] = p;
	ht[v] = ht[p]+1;
	dp[v][0] = p;
	for(int i = 1; i< 21; i++){
		if(dp[v][i-1]<0)break;
		dp[v][i] = dp[dp[v][i-1]][i-1];
	}
}

int lca(int a, int b){
	int a1=a,b1=b;
	//cout<<ht[a1]<<' '<<ht[b1]<<endl;
	for(int i =20; i>= 0; i--){
		if(ht[a1] - (1<<i) >= ht[b1])a1 = dp[a1][i];
	}
	for(int i =20; i>= 0; i--){
		if(ht[b1] - (1<<i) >= ht[a1])b1 = dp[b1][i];
	}
//	cout<<a1<<' '<<b1<<endl;
	if(a1==b1)return a1;
	for(int i = 20; i>=0; i--){
		if(dp[a1][i] != dp[b1][i]){
			a1 = dp[a1][i];
			b1 = dp[b1][i];
		}
	}
	if(a1!=b1){
		a1 = par[a1];
		b1 = par[b1];
	}
	if(a1!= b1)cout<<"Error"<<endl;
	return a1;
}

int main(){
	for(int i =0 ;i<SIZE; i++){
		for(int j =0; j< 21; j++)dp[i][j] = -1;
	}
	par[0] = -1;
	ht[0] = 0;
	insert(1,0);
	insert(2,0);
	insert(3,0);
	int n;
	cin>>n;

	for(int i =0; i< n; i++){
		int a,b;
		cin>>a;a--;
	//	cin>>a>>b;a--;b--;
	//	cout<<lca(a,b)<<endl;

		insert(4+2*i,a);insert(5+2*i,a);

		int d1 = ht[4+2*i] + ht[endf]-2*ht[lca(a,endf)] , d2 = ht[4+2*i] + ht[ende] -2*ht[lca(a,ende)];
		if(d1>d && d1>d2)
			ende = 4+2*i;
		else if( d2>d &&d2>=d1)endf = 4+2*i;
		d = max(max(d1,d2), d);
		cout<<d<<endl;
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define err(x) cout<<#x<<"= "<<x<<endl;
#define FOR(i,a,b) for(int i =a; i< b; ++i)
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define INF 1000000000
#define TRVI(it,it1,it2) for(vi::iterator it = it1; it!= it2; it++)
#define ff first
#define ss second
#define mp make_pair
#define pq priority_queue<int, vector<int>, greater<int> >
#define ll long long
const ll PR = 1000000009;
#define SIZE 1000005
#define vi vector<int>
#define pii pair<int,int>
#define endl '\n'
#define vii vector<ii >
#define ii pair<int,int>

vi visited(SIZE,0),llist[SIZE];
int done[SIZE] = {0},size[SIZE] = {0},clevel[SIZE] = {0};

int findsizes(int v){
	visited[v]++;
	size[v]  =1;
	for(int i= 0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt] &&visited[nxt]<visited[v])
			size[v]+= findsizes(nxt);
	}
	return size[v];
}
int findcentroid(int v,int root){
	int tot = size[root];
	for(int i =0; i< llist[v].size(); i++){
		int nxt = llist[v][i];
		if(!done[nxt]){
			int nows = size[nxt];
			if(size[nxt] > size[v])
				nows = tot-size[v];
			if(nows>tot/2.0){
				return findcentroid(nxt,root);
			}
		}
	}
	return v;
}

vi clist[SIZE];int croot,cpar[SIZE];
int idsc[SIZE][21];
int part;
vector<int> Dists[SIZE];
int construct_ctree(int rootnow,int fl=0){             // returns the root
	findsizes(rootnow);
//	findsizes(rootnow);
	int c = findcentroid(rootnow,rootnow);
	if(fl==1)clevel[c ] = 0;
	else
	clevel[c] = clevel[part]+1;
	done[c] =1;

	for(int i =0; i< llist[c].size(); i++){
		int nxt = llist[c][i];
		if(!done[nxt]){
			part = c;
			nxt = construct_ctree(nxt);
			clist[c].pb(nxt);
			clist[nxt].pb(c);
			cpar[nxt ] =c;
		}
	}

	queue<ii > Q;int nowl = clevel[c];
	Q.push(mp(c,0) );
//	idsc[c][nowl] = 0;
//	Dists[c].pb(0);
//	cout<<"for c = "<<c<<endl;
	while(!Q.empty()){
		ii now = Q.front();Q.pop();
		int nxt = now.ff,distf = now.ss;
//		if(idsc[nxt][nowl]!=-1)cout<<"Hey error buddy"<<endl;
		idsc[nxt][nowl] = Dists[c].size();
		Dists[c].pb(distf);
//		cout<<nxt<<' '<<distf<<endl;
		for(int i =0; i< llist[nxt].size(); i++){
			int nxn = llist[nxt][i];
			if(idsc[nxn][nowl]==-1 && clevel[nxn]>nowl){
				Q.push(mp(nxn,distf+1));
			}
		}
	}
//	cout<<endl;
	return c;
}
int givedist(int v,int c, int lvl){
//	cout<<"Betw "<<v << " and "<<c <<" dist is "<<Dists[c][idsc[v][lvl]]<<' '<<lvl<<endl;
	return Dists[c][idsc[v][lvl]];
}

//multiset<int> dists[SIZE];
vector<int> contrib,don;
vii maxdists;
int d,n;
int addv(int v){
	int now =v;
//	multiset<int> ::iterator it;
//	cout<<v<<endl;
	int cnt =0;
	while(cpar[now] != -1){

		int distn = givedist(v,cpar[now],clevel[v]-1-cnt);//= tr.dist(cpar[now],v);
		cnt++;
		if(contrib[now] >= distn){now= cpar[now];continue;}
//		if(contrib[now]!=-1)
//			dists[cpar[now]].erase(dists[cpar[now]].find(contrib[now]));
//		dists[cpar[now]].insert(distn);
		if(maxdists[cpar[now]].ff==contrib[now])
			maxdists[cpar[now]].ff = distn;
		else if(maxdists[cpar[now]].ss == contrib[now])
			maxdists[cpar[now]].ss = distn;
		contrib[now] = distn;
		now = cpar[now];
		if(don[now]){
			d = max(d, maxdists[now].ff);
			d = max(d,maxdists[now].ff+maxdists[now].ss);
		}
//		it = (dists[now]).end();it--;
//		if(don[now])if(!dists[now].empty())d = max(d,*it);
//		if(dists[now].size() >=2)
//			d = max(d, *(it--) + *it);
	}

//	cout<<v<<" ended "<<d<<endl;
//	for(int i =0;i< n; i++){
//		for(it = dists[i].begin(); it!= dists[i].end(); it++){
//			cout<<" ("<<maxdists[i].ff<<','<<maxdists[i].ss<<") ";
//		}
//		cout<<endl;
//	}
}

int main(){
	cin.tie(false);cout.tie(false);
	ios::sync_with_stdio(false);
	int n,n1;
	cin>>n;n1=n;
	for(int i =0; i<SIZE; i++)for(int j = 0; j< 21;j++)idsc[i][j] = -1;
	for(int i =0; i< SIZE; i++)Dists[i].clear();
	llist[0].pb(1);llist[1].pb(0);
	llist[0].pb(2);llist[2].pb(0);
	llist[0].pb(3);llist[3].pb(0);
	for(int i =0; i< n; i++){
		int a;//b;
		cin>>a;a--;//b--;
		llist[a].pb(4+2*i); llist[4+2*i].pb(a);
		llist[a].pb(5+ 2*i);llist[5+2*i].pb(a);
	}

	n = 4+2*n;::n = n;
	contrib.assign(n,-1);
	don.assign(n,0);
	maxdists.assign(n,mp(-1,-1));
//   tr = LCA(llist,n);
	croot = construct_ctree(0,1);
	cpar[croot] = -1;
//	for(int i =0;i< n; i++)cout<<cpar[i]<<' ';cout<<endl;
	don[0] = don[1] =don[2]= don[3] =1;
	addv(0);addv(1);addv(2);addv(3);
	d = 2;
//	cout<<"SERI"<<endl;
	for(int  i= 0; i< n1; i++){
		addv(4+2*i);don[4+2*i] = 1;
		addv(5+2*i);don[5+2*i] = 1;
		cout<<d<<endl;
	}
	//cout<<croot<<endl;
	return 0;
}