In a competition, N contestants participate in a knockout tournament with N-1 matches. The tournament may not be fair for all contestants, as the number of matches needed to win may vary. The depth of the tournament is the maximum number of matches needed to win. The goal is to find the minimum possible depth of the tournament. The tournament's structure is defined by predetermined contestants playing against each other. The input consists of N and the results of matches, and the output should be the minimum possible depth of the tournament.

# Buggy version:
import bisect, copy, heapq, math, sys
from collections import *
from functools import lru_cache
from itertools import accumulate, combinations, permutations, product
def input():
    return sys.stdin.readline()[:-1]
def ruiseki(lst):
    return [0]+list(accumulate(lst))
def celi(a,b):
    return -(-a//b)
sys.setrecursionlimit(5000000)
mod=pow(10,9)+7
al=[chr(ord('a') + i) for i in range(26)]
direction=[[1,0],[0,1],[-1,0],[0,-1]]

def main()
    n=int(input())
    a=[int(input()) for i in range(n-1)]
    # print(a)
    dic=defaultdict(list)
    for i in range(n-1):
        p=a[i]
        dic[p].append(i+2)
    # print(dic)

    lst=[-1]*(n+1)

    def solve(m):
        if lst[m]!=-1:
            return lst[m]
        tmp=[]
        for i in dic[m]:
            tmp.append(solve(i))
        tmp.sort(reverse=True)
        rtn=0
        for i in range(len(tmp)):
            rtn=max(rtn,tmp[i]+i+1)
        lst[m]=rtn
        return rtn

    solve(1)
    # print(lst)
    print(max(lst))
main()

# Fixed version:
import bisect, copy, heapq, math, sys
from collections import *
from functools import lru_cache
from itertools import accumulate, combinations, permutations, product
def input():
    return sys.stdin.readline()[:-1]
def ruiseki(lst):
    return [0]+list(accumulate(lst))
def celi(a,b):
    return -(-a//b)
sys.setrecursionlimit(5000000)
mod=pow(10,9)+7
al=[chr(ord('a') + i) for i in range(26)]
direction=[[1,0],[0,1],[-1,0],[0,-1]]

def main():
    n=int(input())
    a=[int(input()) for i in range(n-1)]
    # print(a)
    dic={}
    for i in range(n-1):
        p=a[i]
        if p in dic:
            dic[p].append(i+2)
        else:
            dic[p]=[i+2]


    lst=[-1]*(n+1)

    def solve(m):
        if lst[m]!=-1:
            return lst[m]
        tmp=[]
        if m in dic:

            for i in dic[m]:
                tmp.append(solve(i))
        tmp.sort(reverse=True)
        rtn=0
        for i in range(len(tmp)):
            rtn=max(rtn,tmp[i]+i+1)
        lst[m]=rtn
        return rtn

    solve(1)
    # print(lst)
    print(max(lst))
main()

# Buggy version:
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


n = int(input())
a = [None]*(n-1)
from collections import defaultdict
c = defaultdict(list)
for i in range(n-1):
    num = int(input())
    a[i] = num
    c[num].append(i+2)

def sub(winner):
    l = len(c[winner])
    vs = []
    for p in c[winner]:
        vs.append(sub(p))
    ans = l
    for i,v in enumerate(vs):
        ans = max(l, l-(i)+v)
#     print(winner, ans, l, vs)
    return ans
ans = sub(1)
print(ans)

# Fixed version:
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


n = int(input())
a = [None]*(n-1)
from collections import defaultdict
c = defaultdict(list)
for i in range(n-1):
    num = int(input())
    c[num].append(i+2)

def sub(winner):
    l = len(c[winner])
    vs = []
    for p in c[winner]:
        vs.append(sub(p))
    vs.sort()
    ans = l
    for i,v in enumerate(vs):
        ans = max(ans, l-(i)+v)
#     print(winner, ans, l, vs)
    return ans
ans = sub(1)
print(ans)

# Buggy version:
import sys
sys.setrecursionlimit(10**10)

n = int(input())
dic = {}
for i in range(n+1):
    if i <= 1: continue
    ai = int(input())
    if ai in dic:
        dic[ai].append(i)
    else:
        dic[ai] = [i]

def dfs(nxt):
    lst = []
    if nxt in dic:
        while dic[nxt] != []:
            child = dic[nxt].pop()
            tempmax = dfs(child)
            lst.append(tempmax)
    else:
        return 0
    lst.sort(reverse=True)
    for i in range(len(lst)):
        lst[i] += i+1
    return max(lst)

ans = dfs(1)
print(ans)

# Fixed version:
import sys
sys.setrecursionlimit(10**5)

n = int(input())
dic = {}
for i in range(n+1):
    if i <= 1: continue
    ai = int(input())
    if ai in dic:
        dic[ai].append(i)
    else:
        dic[ai] = [i]

def dfs(nxt):
    lst = []
    if nxt in dic:
        while dic[nxt] != []:
            child = dic[nxt].pop()
            tempmax = dfs(child)
            lst.append(tempmax)
    else:
        return 0
    lst.sort(reverse=True)
    for i in range(len(lst)):
        lst[i] += i+1
    return max(lst)

ans = dfs(1)
print(ans)

# Buggy version:
import sys
input = sys.stdin.readline
N = int(input())
a = [0]
reva = [[] for _ in range(N + 1)]
for _ in range(N - 1): a.append(int(input()))
for i in range(N):
  if a[i] == 0: continue
  reva[a[i]].append(i + 1)
exit(0)
dp = [-1] * (N + 1)
def dfs(x):
  global dp
  if len(reva[x]) == 0:
    dp[x] = 1
    return 1
  t = []
  for i in range(len(reva[x])):
    y = reva[x][i]
    t.append(dfs(y))
  t.sort(reverse = True)
  for i in range(len(reva[x])):
    t[i] += i + 1
  dp[x] = max(t)
  return dp[x]
print(dfs(1) - 1)

# Fixed version:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 6)
N = int(input())
a = [0]
reva = [[] for _ in range(N + 1)]
for _ in range(N - 1): a.append(int(input()))
for i in range(N):
  if a[i] == 0: continue
  reva[a[i]].append(i + 1)
dp = [-1] * (N + 1)
def dfs(x):
  global dp
  if len(reva[x]) == 0:
    dp[x] = 1
    return 1
  t = []
  for y in reva[x]:
    t.append(dfs(y))
  t.sort(reverse = True)
  for i in range(len(t)):
    t[i] += i + 1
  dp[x] = max(t)
  return dp[x]
print(dfs(1) - 1)

# Buggy version:
import sys
sys.setrecursionlimit(10**9)

def dfs(v):
  if len(g[v])==0:
    return 0
  dic={}
  for u in g[v]:
    tmp=dfs(u)
    if tmp not in dic:
      dic[tmp]=1
    else:
      dic[tmp]+=1
  arr=list(dic.keys())
  arr=sorted(arr,reverse=True)
  return max([(i+1)+arr[i] for i in range(len(arr))])

n=int(input())
g=[[] for _ in range(n+1)]
for i in range(n-1):
  v=int(input())
  g[v].append(i+2)
print(dfs(1))

# Fixed version:
import sys
sys.setrecursionlimit(10**9)

def dfs(v):
  if len(g[v])==0:
    return 0
  dic={}
  for u in g[v]:
    tmp=dfs(u)
    if tmp not in dic:
      dic[tmp]=1
    else:
      dic[tmp]+=1
  arr=[]
  for pos in dic.keys():
    arr+=[pos]*dic[pos]
  arr=sorted(arr,reverse=True)
  return max([(i+1)+arr[i] for i in range(len(arr))])

n=int(input())
g=[[] for _ in range(n+1)]
for i in range(n-1):
  v=int(input())
  g[v].append(i+2)
print(dfs(1))