stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include <bits/stdc++.h>



using int64 = long long;



const int MAX_N = int(2e5) + 10;



int n;

bool is[MAX_N];

char s[MAX_N];



int main() {

	scanf("%s", s + 1);

	n = strlen(s + 1);

	for (int i = 1; i <= n; ++i) {

		if (s[i] == 'C' && s[i - 1] != 'B') {

			is[i] = true;

		}

		if (s[i] == 'B' && s[i + 1] != 'C') {

			is[i] = true;

		}

	}



	int64 ans = 0LL;

	for (int l = 1, r; l <= n; l = r + 1) {

		while (is[l]) ++l;

		if (l > n) break;

		r = l;

		while (r < n && !is[r + 1]) ++r;

		int cnt = 0;

		int64 del = 0LL;

		for (int i = l; i <= r; ++i) {

			if (s[i] == 'A') ++cnt;

			else if (s[i] == 'B' && s[i + 1] == 'C') {

				++i;

				del += cnt;

			}

		}

		ans += del;

	}



	std::cout << ans << std::endl;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

using namespace std;



char s[200002];

int z[200001];

int main(){

	scanf("%s",s+1);

	int n=strlen(s+1);

	for(int i=1;i<=n;i++)

		if(s[i]=='A')z[++z[0]]=1;

		else if(i<n&&s[i]=='B'&&s[i+1]=='C')

			z[++z[0]]=2,i++;

		else z[++z[0]]=3;

	long long ans=0;

	for(int i=1;i<=z[0];i++){

		if(z[i]==3)continue;

		int j=i;

		while(j<=z[0]&&z[j]!=3)j++;

		int w=0;

		for(int k=i;k<=j;k++)

			if(z[k]==2)ans+=k-i-w,w++;

		i=j;

	}

	printf("%lld\n",ans);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;



typedef long long lint;

typedef long double louble;



template<typename T1,typename T2> inline T1 max(T1 a,T2 b){return a<b?b:a;}

template<typename T1,typename T2> inline T1 min(T1 a,T2 b){return a<b?a:b;}



namespace ae86

{

	const int bufl = 1<<15;

	

	char buf[bufl],*s=buf,*t=buf;

	

	inline int fetch()

	{

		if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}

		return *s++;

	}

	

	inline int ty()

	{

		int a=0,b=1,c=fetch();

		while(!isdigit(c))b^=c=='-',c=fetch();

		while(isdigit(c))a=a*10+c-48,c=fetch();

		return b?a:-a;

	}



	inline int ts(char *s)

	{

		int a=0,c=fetch();

		while(c<=32 && c!=EOF)c=fetch();

		while(c>32 && c!=EOF)s[a++]=c,c=fetch();

		s[a]=0;

		return a;

	}

}

using ae86::ty;

using ae86::ts;



const int _ = 200007;



int n;char s[_];



int main()

{

	n=ts(s+1);



	lint ans=0;int cnta=0;

	for(int i=1;i<=n;)

	{

		if(s[i]=='A')cnta++,i++;

		else if(s[i]=='B' && s[i+1]=='C')ans+=cnta,i+=2;

		else cnta=0,i++;

	}

	printf("%lld\n",ans);



	return 0;

}


// Optimized solution to the same problem (faster):
#include<cstdio>

using namespace std;



const int _ = 200007;



char s[_];



int main()

{

	fread(s,1,_,stdin);

	

	long long ans=0,cnta=0;

	for(int i=0;s[i];i++)

	{

		if(s[i]=='A')cnta++;

		else if(s[i]=='B' && s[i+1]=='C')ans+=cnta,i++;

		else cnta=0;

	}

	printf("%lld\n",ans);



	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<algorithm>

#include<vector>

#include<queue>

#include<list>

#include<set>

#include<string>

using namespace std;

int gcd(int a, int b) {

	int c = a % b;

	while (c != 0) {

		a = b;

		b = c;

		c = a % b;

	}

	return b;

}

struct UnionFind {

	vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2



	UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化

		for (int i = 0; i < N; i++) par[i] = i;

	}



	int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}

		if (par[x] == x) return x;

		return par[x] = root(par[x]);

	}



	void unite(int x, int y) { // xとyの木を併合

		int rx = root(x); //xの根をrx

		int ry = root(y); //yの根をry

		if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま

		par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける

	}



	bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す

		int rx = root(x);

		int ry = root(y);

		return rx == ry;

	}

};

typedef long long ll;



const ll M = 1000000007;



vector<ll> fac(300001); //n!(mod M)

vector<ll> ifac(300001); //k!^{M-2} (mod M)



ll mpow(ll x, ll n) {

	ll ans = 1;

	while (n != 0) {

		if (n & 1) ans = ans * x % M;

		x = x * x % M;

		n = n >> 1;

	}

	return ans;

}

ll comb(ll a, ll b) {

	if (a == 0 && b == 0)return 1;

	if (a < b || a < 0)return 0;

	ll tmp = ifac[a - b] * ifac[b] % M;

	return tmp * fac[a] % M;

}

// mod. m での a の逆元 a^{-1} を計算する

long long modinv(long long a) {

	long long b = M, u = 1, v = 0;

	while (b) {

		long long t = a / b;

		a -= t * b; swap(a, b);

		u -= t * v; swap(u, v);

	}

	u %= M;

	if (u < 0) u += M;

	return u;

}

int main() {

	ll i, ans=0, count = 0;

	char s[222222];

	cin >> s;

	if (s[0] == 'A')

		count++;

	for (i = 1; s[i] != '\0'; i++) {

		if (s[i] == 'A')

			count++;

		if (s[i] == 'B') {

			if (s[i - 1] != 'A'||s[i+1]!='C')

				count = 0;

		}

		if (s[i] == 'C') {

			if (s[i - 1] == 'B') {

				ans += count;

				s[i] = 'A';

			}

			else

				count = 0;

		}

	}

	cout << ans << endl;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



#define rep(i,n) for(int i=0;i<n;i++)

#define ll long long



int main(){

    string s;

    cin>>s;

    int n=s.size();

    rep(i,n-1){

        if(s[i]=='B'&&s[i+1]=='C') s[i]='K',s[i+1]='D';

    }

    reverse(s.begin(),s.end());

    ll k=0,cnt=0;

    rep(i,n){

        if(s[i]=='K') k++;

        else if(s[i]=='A') cnt+=k;

        else if(s[i]!='D') k=0;

    }

    cout<<cnt<<endl;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <sstream>

#include <vector>



using namespace std;



int main()

{

    string times;

    int x=0;

    int n;

    vector <int> number;

getline(cin,times);

stringstream s(times);

while(s>>n)

    number.push_back(n);



x=(60*(number[2]-number[0])+(number[3]-number[1]))-number[4];



    cout<<x<<endl;





    return 0;

}


// Optimized solution to the same problem (faster):
#include <stdio.h>



int main() {

    int h1, m1, h2, m2, k;

    scanf("%d %d %d %d %d", &h1, &m1, &h2, &m2, &k);

    h1 *= 60;

    h2 *= 60;

    h1 += m1;

    h2 += m2;

    int diff = h2 - h1;

    if (k == h2) {

        printf("0");

        return 0;

    }

    printf("%d", diff - k);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



int main() {

	

	ios::sync_with_stdio(0);

	cin.tie(0), cout.tie(0);

	

	int h1, m1, h2, m2, k; cin >> h1 >> m1 >> h2 >> m2 >> k;

	int a = h1 * 60 + m1, b = h2 * 60 + m2;

	int ans = b - a;

	if (ans < 0) ans += 24 * 60;

	ans -= k;

	cout << ans << "\n";

	

	return 0;

}


// Optimized solution to the same problem (faster):
#include <stdio.h>



int main() {

    int h1, m1, h2, m2, k;

    scanf("%d %d %d %d %d", &h1, &m1, &h2, &m2, &k);

    h1 *= 60;

    h2 *= 60;

    h1 += m1;

    h2 += m2;

    int diff = h2 - h1;

    if (k == h2) {

        printf("0");

        return 0;

    }

    printf("%d", diff - k);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



int main (){

	int h1, m1, h2, m2, k;

	scanf("%d%d%d%d%d", &h1, &m1, &h2, &m2, &k);

	printf("%d\n", (h2 * 60 + m2) - (h1 * 60 + m1) - k);

	return 0;

}


// Optimized solution to the same problem (faster):
#include <stdio.h>







int main()

{

	int H1, H2, M1, M2, k, tH, tM;

	scanf("%d %d %d %d %d", &H1, &M1, &H2, &M2, &k);

	tH = H2 - H1;

	tM = M2 - M1;

	tH = ((tH * 60) + tM) - k ;

	

	printf("%d", tH);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define pb push_back

#define pi (acos(-1))

#define ull  unsigned long long

#define ld long double

///freopen("input.txt","r",stdin);

///freopen("output.txt","w",stdout);

#define M 100000

ll LCM(ll a, ll b)

{

    ll g = __gcd(a,b);

    return (a*b)/g ;

}

string numtostr(ll n)

{

    ostringstream str1 ;

    str1 << n ;

    return str1.str();

}

ll strtonum(string s)

{

    ll x ;

    stringstream str1(s);

    str1 >> x ;

    return x ;

}

int h1,m1,h2,m2,a;

int main(void)

{

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    cout.tie(NULL);

    cin>>h1>>m1>>h2>>m2>>a;

    cout<<h2*60+m2-(h1*60+m1)-a<<'\n';

    return 0;

}


// Optimized solution to the same problem (faster):
#include<stdio.h>



int main(){

	int N;

	int n1;

	int M;

	int m1;

	int k;

	scanf("%d %d %d %d %d",&N ,&n1,&M,&m1,&k );

	int waktu = ((M*60+m1)-(N*60+n1))-k;

	printf ("%d",waktu);

	

	

	

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



int main() {

	ios::sync_with_stdio(0);

	cin.tie(0); cout.tie(0);

	int h1, m1, h2, m2; cin >> h1 >> m1 >> h2 >> m2;

	int k; cin >> k;

	cout << (h2 * 60 + m2 - h1 * 60 - m1 - k) << endl;

	return 0;

}


// Optimized solution to the same problem (faster):
#include<stdio.h>



int main(){

	int N;

	int n1;

	int M;

	int m1;

	int k;

	scanf("%d %d %d %d %d",&N ,&n1,&M,&m1,&k );

	int waktu = ((M*60+m1)-(N*60+n1))-k;

	printf ("%d",waktu);

	

	

	

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

 

using namespace std;

using namespace __gnu_pbds;

 

#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define fbo find_by_order

#define ook order_of_key

 

typedef long long ll;

typedef pair<ll,ll> ii;

typedef vector<int> vi;

typedef long double ld; 

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

typedef set<int>::iterator sit;

typedef map<int,int>::iterator mit;

typedef vector<int>::iterator vit;

 

int par[100001];

vi adj[100001];

int dp[100001];

 

void dfs(int u)

{

	vi vec;

	for(int i = 0; i < adj[u].size(); i++)

	{

		int v = adj[u][i];

		dfs(v);

		vec.pb(dp[v]);

	}

	sort(vec.begin(),vec.end());

	dp[u] = 0;

	for(int i = 0; i < vec.size(); i++)

	{

		int t = vec[i];

		if(dp[u]<t+1) dp[u]=t+1;

		else

		{

			dp[u]++;

		}

	}

	//cerr<<u<<' '<<dp[u]<<'\n';

}

 

int main()

{

	ios_base::sync_with_stdio(0); cin.tie(0);

	int n; cin>>n;

	for(int i = 1; i < n; i++) 

	{

		cin>>par[i];

		par[i]--;

		adj[par[i]].pb(i);

	}

	dfs(0);

	cout<<dp[0]<<'\n';

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<algorithm>

#include<cstring>

using namespace std;

#define MAXN 200002

int n;

struct node

{

	int to,next;

}a[MAXN];

int f[MAXN],b[MAXN],head[MAXN];

bool cmp(int a,int b)

{

	return a>b;

}

void dfs(int u)

{

	int s=0,minn=0;

	for(int i=head[u];~i;i=a[i].next)

		dfs(a[i].to);

	for(int i=head[u];~i;i=a[i].next)

		b[++s]=f[a[i].to];

	if(s==0)return;

	sort(b+1,b+s+1,cmp);

	for(int i=1;i<=s;i++)

		minn=max(minn,i+b[i]);

	f[u]=minn;

}

int main()

{

	memset(head,-1,sizeof(head));

	scanf("%d",&n);

	int x;

	for(int i=2;i<=n;i++)

	{

		scanf("%d",&x);

		a[i]=(node){i,head[x]};

		head[x]=i;

	}

	dfs(1);

	printf("%d",f[1]);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<vector>

#include<algorithm>

#include<functional>

using namespace std;



#define MAXN 100000

int N;

int Height[MAXN+5];

vector<int> G[MAXN+5];



bool cmp(int x,int y){

    return Height[x]>Height[y];

}

void dfs(int u){

    for(int i=0;i<int(G[u].size());i++)

        dfs(G[u][i]);

    sort(G[u].begin(),G[u].end(),cmp);

    for(int i=0;i<int(G[u].size());i++)

        Height[u]=max(Height[u],Height[G[u][i]]+i+1);

}



int main(){

    scanf("%d",&N);

    for(int i=2;i<=N;i++){

        int fa;

        scanf("%d",&fa);

        G[fa].push_back(i);

    }

    dfs(1);

    printf("%d",Height[1]);

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<algorithm>

#include<cstring>

using namespace std;

#define MAXN 200002

int n;

struct node

{

	int to,next;

}a[MAXN];

int f[MAXN],b[MAXN],head[MAXN];

bool cmp(int a,int b)

{

	return a>b;

}

void dfs(int u)

{

	int s=0,minn=0;

	for(int i=head[u];~i;i=a[i].next)

		dfs(a[i].to);

	for(int i=head[u];~i;i=a[i].next)

		b[++s]=f[a[i].to];

	if(s==0)return;

	sort(b+1,b+s+1,cmp);

	for(int i=1;i<=s;i++)

		minn=max(minn,i+b[i]);

	f[u]=minn;

}

int main()

{

	memset(head,-1,sizeof(head));

	scanf("%d",&n);

	int x;

	for(int i=2;i<=n;i++)

	{

		scanf("%d",&x);

		a[i]=(node){i,head[x]};

		head[x]=i;

	}

	dfs(1);

	printf("%d",f[1]);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<map>

#include<algorithm>

#include<vector>

using namespace std;

#define MAXN 100005

int n,t[MAXN];

vector<int> G[MAXN];

void dfs(int u,int f)

{

	map<int,int> cnt;

	for(int i=0;i<G[u].size();i++)

	{

		int v=G[u][i];

		if(v==f) continue;

		dfs(v,u);

		cnt[t[v]]++;

	}

	map<int,int>::iterator it;

	for(it=cnt.begin();it!=cnt.end();it++)

		if(it->second>1)

			cnt[(it->first)+1]+=it->second-1;

	if(it!=cnt.begin())

		it--,t[u]=it->first+1;

}

int main()

{

	scanf("%d",&n);

	for(int i=2;i<=n;i++)

	{

		int x;

		scanf("%d",&x);

		G[i].push_back(x);

		G[x].push_back(i);

	}

	dfs(1,0);

	printf("%d\n",t[1]);

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<algorithm>

#include<cstring>

using namespace std;

#define MAXN 200002

int n;

struct node

{

	int to,next;

}a[MAXN];

int f[MAXN],b[MAXN],head[MAXN];

bool cmp(int a,int b)

{

	return a>b;

}

void dfs(int u)

{

	int s=0,minn=0;

	for(int i=head[u];~i;i=a[i].next)

		dfs(a[i].to);

	for(int i=head[u];~i;i=a[i].next)

		b[++s]=f[a[i].to];

	if(s==0)return;

	sort(b+1,b+s+1,cmp);

	for(int i=1;i<=s;i++)

		minn=max(minn,i+b[i]);

	f[u]=minn;

}

int main()

{

	memset(head,-1,sizeof(head));

	scanf("%d",&n);

	int x;

	for(int i=2;i<=n;i++)

	{

		scanf("%d",&x);

		a[i]=(node){i,head[x]};

		head[x]=i;

	}

	dfs(1);

	printf("%d",f[1]);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <vector>

#include <string>

#include <map>

#include <set>

#include <cassert>

using namespace std;

#define rep(i,a,n) for (int i=a;i<n;i++)

#define per(i,a,n) for (int i=n-1;i>=a;i--)

#define pb push_back

#define mp make_pair

#define all(x) (x).begin(),(x).end()

#define fi first

#define se second

#define SZ(x) ((int)(x).size())

typedef vector<int> VI;

typedef long long ll;

typedef pair<int,int> PII;

const ll mod=1000000007;

ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

// head



const int N=101000;

int n,f[N],dp[N];

VI r[N],s[N];

void dfs(int u) {

	r[u].clear();

	for (auto v:s[u]) {

		dfs(v);

		r[u].pb(dp[v]);

	}

	sort(all(r[u]));

	reverse(all(r[u]));

	rep(i,0,SZ(r[u])) {

		dp[u]=max(dp[u],r[u][i]+i+1);

	}

}

int main() {

	scanf("%d",&n);

	rep(i,2,n+1) {

		scanf("%d",f+i);

		s[f[i]].pb(i);

	}

	dfs(1);

	printf("%d\n",dp[1]);

}


// Optimized solution to the same problem (faster):
#include<iostream>

#include<cstdio>

#include<queue>

#include<vector>

#include<algorithm>

using namespace std;

int n;

int ans;

int par[100010];

int s[100010];

int z[100010];

int h[100010];

vector<int>v[100010];

void solve(int x)

{

	vector<int>t;

	for(int i=0;i<v[x].size();i++)

	{

		solve(v[x][i]);

		t.push_back(h[v[x][i]]);

	}

	sort(t.begin(),t.end());

	int l=t.size();

	for(int i=0;i<l;i++)

	{

		h[x]=max(h[x],t[i]+l-i);

	}

}

int main()

{

	scanf("%d",&n);

	for(int i=1;i<=n;i++)h[i]=1; 

	for(int i=2;i<=n;i++)

	{

		scanf("%d",par+i);

		v[par[i]].push_back(i);

	}

	solve(1);

	printf("%d",h[1]-1);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define Would

#define you

#define please



const int cm = 1 << 17;

char cn[cm], * ci = cn + cm, ct;

inline char getcha() {

	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}

inline int getint() {

	int A = 0;

	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';

	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';

	return A;

}



pair<int, int> E[100001];

int H[100001];

int sagasu(int A) {

	vector<int> kari;

	for (int i = H[A]; i; i = E[i].second) kari.pb(sagasu(E[i].first));

	sort(kari.begin(), kari.end(), greater<int>());

	int ret = 0;

	rep(i, kari.size()) ret = max(ret, i + kari[i] + 1);

	return ret;

}



int main() {

	cin.tie(0);

	ios::sync_with_stdio(false);





	int N = getint();



	for (int i = 2; i <= N; i++) {

		int a = getint();

		E[i] = mp(i, H[a]);

		H[a] = i;

	}



	co(sagasu(1));



	Would you please return 0;

}

// Optimized solution to the same problem (faster):
#pragma GCC optimize ("O3")

//#pragma GCC target ("avx")

//#include<bits/stdc++.h>

#include<cstdio>

#include<algorithm>

#include<functional>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define chmin(x, y) x = min(x, y)

#define chmax(x, y) x = max(x, y)

#define Would

#define you

#define please



const int cm = 1 << 17;

char cn[cm], * ci = cn + cm, ct;

inline char getcha() {

	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}

inline int getint() {

	int A = 0;

	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';

	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';

	return A;

}

pair<int, int> E[100001];

int H[100001];

int n[100001], kari[100001];

int sagasu(int A) {

	if (n[A] == n[A - 1]) return 0;

	if (n[A] == n[A - 1] + 1) {

		return sagasu(E[H[A]].first) + 1;

	}

	int k = n[A - 1];

	for (int i = H[A]; i; i = E[i].second) {

		kari[k++] = sagasu(E[i].first);

	}

	sort(kari + n[A - 1], kari + n[A], greater<int>());

	int ret = 0;

	for (int i = 0; i < n[A] - n[A - 1]; i++) ret = max(ret, kari[n[A - 1] + i] + i);

	return ret + 1;

}



int main() {

	//cin.tie(0);

	//ios::sync_with_stdio(false);





	int N = getint();



	for (int i = 2; i <= N; i++) {

		int a = getint();

		n[a]++;

		E[i] = mp(i, H[a]);

		H[a] = i;

	}

	rep1(i, N) n[i] = n[i - 1] + n[i];



	printf("%d\n", sagasu(1));



	Would you please return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <set>

#include <map>

#include <queue>

#include <ctime>

#include <cmath>

#include <cstdio>

#include <vector>

#include <string>

#include <cctype>

#include <bitset>

#include <cstring>

#include <cstdlib>

#include <utility>

#include <iostream>

#include <algorithm>

#define REP(i,a,b) for(int i=(a);i<=(b);i++)

#define PER(i,a,b) for(int i=(a);i>=(b);i--)

#define RVC(i,S) for(int i=0;i<(S).size();i++)

#define RAL(i,u) for(int i=fr[u];i!=-1;i=e[i].next)

using namespace std;

typedef long long LL;

typedef pair<int,int> pii;

     

template<class T> inline

void read(T& num) {

    bool start=false,neg=false;

    char c;

    num=0;

    while((c=getchar())!=EOF) {

        if(c=='-') start=neg=true;

        else if(c>='0' && c<='9') {

            start=true;

            num=num*10+c-'0';

        } else if(start) break;

    }

    if(neg) num=-num;

}

/*============ Header Template ============*/



struct edge {

    int next,to;

};



const int maxn=(int)(2e5)+5;

int fr[maxn];

int f[maxn];

vector<int> vi[maxn];

edge e[maxn<<1];

int tote=0;



inline void addone(int u,int v) {

    ++tote;

    e[tote].next=fr[u];fr[u]=tote;e[tote].to=v;

}



inline void addedge(int u,int v) {

    addone(u,v);addone(v,u);

}



void dfs(int x,int fa) {

    RAL(i,x) if(e[i].to!=fa) {

        dfs(e[i].to,x);

        vi[x].push_back(f[e[i].to]);

    }

    sort(vi[x].begin(),vi[x].end());

    for(int j=0;j<vi[x].size();j++) f[x]=max(f[x],vi[x][j])+1;

}



int main() {

    int n;

    read(n);

    memset(fr,-1,sizeof(fr));

    REP(i,2,n) {

        int x;

        read(x);

        addedge(x,i);

    }

    dfs(1,0);

    printf("%d\n",f[1]);

    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



const int maxn = (int)(1e5) + 5;

vector<int> nxt[maxn], val[maxn];

int f[maxn];



void dfs(int x) {

	for (int i = 0; i < (int)nxt[x].size(); ++i) {

		dfs(nxt[x][i]); val[x].push_back(f[nxt[x][i]]);

	} f[x] = val[x].size();

	sort(val[x].begin(), val[x].end(), greater<int>()); int now = 0;

	for (int i = 0; i < (int)val[x].size(); ++i) f[x] = max(f[x], val[x][i] + now + 1), ++now;

}



int main() {

	int n;

	scanf("%d", &n);

	for (int i = 2; i <= n; ++i) {

		int x; scanf("%d", &x);

		nxt[x].push_back(i);

	}

	dfs(1);

	return printf("%d\n", f[1]), 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <algorithm>

#include <string>

#include <vector>

#include <math.h>

#define MOD 1000000007

typedef long long ll;

using namespace std;



vector<int> v[100010];

int n;

int h=0;



int dfs(int x){



  int ma=0;

  vector<int> d;

  for(int i=0;i<v[x].size();i++){

    int tmp=dfs(v[x][i]);

    d.push_back(tmp);

  }

  sort(d.begin(),d.end());

  reverse(d.begin(),d.end());

  for(int i=0;i<d.size();i++){

    ma=max(ma,d[i]+i+1);

  }

  //cout<<x<<" "<<ma<<endl;

  return ma;

}



int main(){

  //int n;

  cin>>n;

  //vector<int> v[n+1];



  for(int i=2;i<=n;i++){

    int a;

    cin>>a;

    v[a].push_back(i);

  }



  cout<<dfs(1)<<endl;

  return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <algorithm>

#include <string>

#include <vector>

#include <cmath>

#include <map>

#include <queue>

#include <iomanip>

#include <set>

#include <tuple>

#define mkp make_pair

#define mkt make_tuple

#define rep(i,n) for(int i = 0; i < (n); ++i)

using namespace std;

typedef long long ll;

const ll MOD=1e9+7;



int N;

vector<int> A;



vector<vector<int>> lose;



int dfs(int now){

    int depth=0;

    vector<int> v;

    for(auto nex:lose[now]){

        int val=dfs(nex);

        v.push_back(val);

    }

    sort(v.begin(),v.end());

    reverse(v.begin(),v.end());

    for(int i=0;i<v.size();i++) depth=max(depth,v[i]+i+1);

    return depth;

}



int main(){

  cin>>N;

  A.resize(N+1,0);

  for(int i=2;i<=N;i++) cin>>A[i];



  lose.resize(N+1);

  for(int i=2;i<=N;i++){

      lose[A[i]].push_back(i);

  }



  cout<<dfs(1)<<endl;



  return 0;

}


// Fastest known solution for this problem: