A company has *n* employees numbered from 1 to *n*. Each employee either has no immediate manager or exactly one immediate manager, who is another employee with a different number. An employee *A* is said to be the superior of another employee *B* if at least one of the following is true:
 -  Employee *A* is the immediate manager of employee *B* -  Employee *B* has an immediate manager employee *C* such that employee *A* is the superior of employee *C*. 
The company will not have a managerial cycle. That is, there will not exist an employee who is the superior of his/her own immediate manager.

Today the company is going to arrange a party. This involves dividing all *n* employees into several groups: every employee must belong to exactly one group. Furthermore, within any single group, there must not be two employees *A* and *B* such that *A* is the superior of *B*.

What is the minimum number of groups that must be formed?
The first line contains integer *n* (1 ≤ *n* ≤ 2000) — the number of employees.

The next *n* lines contain the integers *p*<sub class="lower-index">*i*</sub> (1 ≤ *p*<sub class="lower-index">*i*</sub> ≤ *n* or *p*<sub class="lower-index">*i*</sub> = -1). Every *p*<sub class="lower-index">*i*</sub> denotes the immediate manager for the *i*-th employee. If *p*<sub class="lower-index">*i*</sub> is -1, that means that the *i*-th employee does not have an immediate manager. 

It is guaranteed, that no employee will be the immediate manager of him/herself (*p*<sub class="lower-index">*i*</sub> ≠ *i*). Also, there will be no managerial cycles.
5
-1
1
2
1
-1
3
4
-1
1
2
3
4
12
-1
1
2
3
-1
5
6
7
-1
9
10
11
4
6
-1
-1
2
3
1
1
3
3
-1
1
1
2
1
-1
1
2
2
-1
2
2
-1
-1
1
3
2
-1
1
3
3
-1
-1
-1
1
5
4
5
1
-1
4
3
12
-1
1
1
1
1
1
3
4
3
3
4
7
4
12
-1
-1
1
-1
1
1
5
11
8
6
6
4
5
12
-1
-1
-1
-1
-1
-1
-1
-1
2
-1
-1
-1
2
12
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
12
3
4
2
8
7
1
10
12
5
-1
9
11
12
12
5
6
7
1
-1
9
12
4
8
-1
3
2
11
12
-1
9
11
6
6
-1
6
3
8
6
1
6
6
12
7
8
4
12
7
9
-1
-1
-1
8
6
-1
3
12
-1
10
-1
1
-1
5
9
12
-1
-1
3
-1
2
12
-1
7
9
12
1
7
-1
-1
8
5
4
-1
3
12
11
11
8
9
1
1
2
-1
10
3
-1
8
5
12
-1
8
9
-1
4
2
11
1
-1
6
-1
10
6
12
7
4
4
-1
6
7
9
7
-1
7
4
1
4
12
-1
6
10
6
1
11
5
9
11
5
1
9
4
12
8
6
6
8
6
-1
6
6
8
6
8
8
3
12
3
8
9
12
2
8
11
12
2
9
-1
11
7
7
7
6
-1
-1
4
4
-1
3
77
53
-1
48
-1
51
-1
54
43
70
19
64
31
45
58
6
61
41
56
34
-1
54
-1
66
65
74
16
38
1
2
61
-1
34
-1
-1
7
19
57
13
61
42
-1
34
65
16
31
61
6
5
34
15
-1
13
4
22
74
7
-1
70
38
61
45
53
46
22
-1
65
34
19
43
48
33
58
36
-1
47
24
34
6
5
2
3
4
5
-1
5
from collections import defaultdict, deque, Counter
import sys
import math
from bisect import bisect_left, bisect_right, bisect
from math import sqrt
from math import gcd


class DSU:
    def __init__(self, n):
        self.parent = []
        self.size = []
        # self.rank = []
        for i in range(n + 1):
            self.parent.append(i)
            self.size.append(1)
            # self.rank.append(0)

    def union(self, u, v):
        pu = self.findPar(u)
        pv = self.findPar(v)
        if pu == pv:
            return
        # if the size of pu is lesser than the size of pv then we will add
        # the pu into pv and the size of pv will increase and vice versa.
        if self.size[pu] < self.size[pv]:
            self.parent[pu] = pv
            self.size[pv] += self.size[pu]
        else:
            self.parent[pv] = pu
            self.size[pu] += self.size[pv]

    def unionByRank(self, u, v):
        pu = self.findPar(u)
        pv = self.findPar(v)
        if pu == pv:
            return
        if self.rank[pu] < self.rank[pv]:
            self.parent[pu] = pv
        elif self.rank[pv] < self.rank[pu]:
            self.parent[pv] = pu
        # if rank is equal then the rank will be increase
        else:
            self.parent[pu] = pv
            self.rank[pv] += 1

    def findPar(self, node):
        if self.parent[node] == node:
            return node
        # path compression -> log(n)
        # path compression and size -> O(4* alpha)
        self.parent[node] = self.findPar(self.parent[node])
        return self.parent[node]


class info():
    def __init__(self, _open=0, _close=0, _full=0):
        self.open = _open
        self.close = _close
        self.full = _full


class SGTree():
    """docstring for SGTree"""

    def __init__(self, n):
        self.seg = [0 for _ in range(4 * n)]

    def build(self, ind, low, high, arr):
        if low == high:
            self.seg[ind] = arr[low]
            return
        mid = (low + high) // 2
        self.build(2 * ind + 1, low, mid, arr)
        self.build(2 * ind + 2, mid + 1, high, arr)
        self.seg[ind] = min(self.seg[2 * ind + 1], self.seg[2 * ind + 2])

    def query(self, ind, low, high, l, r):
        # no overlap
        # high low  l r   or  l r   high low
        if r < low or l > high:
            return sys.maxsize
        # complete overlap
        # low l r high
        if low <= l and r >= high:
            return self.seg[ind]

        # partial overlap
        mid = (low + high) >> 1
        left = self.query(2 * ind + 1, 0, mid, l, r)
        right = self.query(2 * ind + 2, mid + 1, high, l, r)
        return min(left, right)

    def update(self, ind, low, high, i, val):
        if low == high:
            self.seg = val
            return
        mid = (low + high) >> 1
        if i <= mid:
            self.update(2 * ind + 1, low, mid, i, val)
        else:
            self.update(2 * ind + 1, mid + 1, high, i, val)
        self.seg[ind] = min(self.seg[2 * ind + 1], self.seg[2 * ind + 2])


def isPalindrome(s):
    i = 0
    j = len(s) - 1
    while i < j:
        if s[i] != s[j]:
            return False
        i += 1
        j -= 1
    return True


def IntList():
    lis = input().split()
    lis = list(map(int, lis))
    return lis


def StrList():
    s = input()
    lis = [val for val in s]
    # print(lis)
    return lis


def FloatList():
    lis = input().split()
    lis = list(map(float, lis))
    return lis


def searchRange(nums, target):
    res = []
    ans1 = -1
    ans2 = -1

    def bs(nums, key):
        start = 0
        end = len(nums) - 1
        ans = -1
        while start <= end:
            mid = start + (end - start) // 2
            if nums[mid] == key:
                ans = mid
                end = mid - 1
            elif nums[mid] > key:
                end = mid - 1
            else:
                start = mid + 1
        return ans

    def bs1(nums, key):
        start = 0
        end = len(nums) - 1
        ans = -1
        while start <= end:
            mid = start + (end - start) // 2
            if nums[mid] == key:
                ans = mid
                start = mid + 1
            elif nums[mid] > key:
                end = mid - 1
            else:
                start = mid + 1
        return ans

    ans1 = bs(nums, target)
    ans2 = bs1(nums, target)
    res.append(ans1)
    res.append(ans2)
    return res


def SieveOfEratosthenes(n, isPrime):
    isPrime[0] = isPrime[1] = False
    for i in range(2, n + 1):
        isPrime[i] = True

    p = 2
    while p * p <= n:
        if isPrime[p] == True:
            i = p * p
            while (i <= n):
                isPrime[i] = False
                i += p
        p += 1


def findPrimePair(n):
    isPrime = [0] * (n + 1)
    SieveOfEratosthenes(n, isPrime)
    for i in range(0, n):

        if (isPrime[i] and isPrime[n - i]):
            print(i, (n - i))
            return


def query(ind, low, high, l, r, seg):
    # no overlap
    # high low  l r   or  l r   high low
    if r < low or l > high:
        return info()
    # complete overlap
    # low l r high
    if low <= l and r >= high:
        return self.seg[ind]

    # partial overlap
    mid = (low + high) >> 1
    left = self.query(2 * ind + 1, 0, mid, l, r, seg)
    right = self.query(2 * ind + 2, mid + 1, high, l, r, seg)
    return merge(left, right)


def merge(left, right):
    ans = info()

    ans.full = left.full + right.full + min(left.open, right.close)
    ans.open = left.open + right.open + min(left.open, right.close)
    ans.close = left.close + right.close + min(left.open, right.close)
    return ans


def build(ind, low, high, s, seg):
    # print("HEllo")
    if low == high:
        seg[ind] = info(s[low] == "(", s[low] == ")", 0)
        return
    mid = (low + high) // 2
    build(2 * ind + 1, low, mid, s, seg)
    build(2 * ind + 2, mid + 1, high, s, seg)
    seg[ind] = merge(seg[2 * ind + 1], seg[2 * ind + 2])


def solve(i, j, lis, cnt):
    if i >= j:
        return cnt[0]
    if lis[i] == lis[j]:
        return solve(i + 1, j - 1, lis, cnt)
    temp = lis[i + 1:j]
    temp2 = lis[i:j - 1]
    return min(solve(i + 1, j, lis, cnt[0] + 1), solve(i, j - 1, temp2, cnt[0] + 1))


def gridGame():
    n, m = map(int, input().split())
    mx = ['0' for _ in range(m)]
    lis = []
    for i in range(n):
        temp = StrList()
        for i in range(m):
            mx[i] = max(mx[i], temp[i])
        lis.append(temp)
    cnt = 0
    for i in range(n):
        for j in range(m):
            if lis[i][j] == mx[j]:
                cnt += 1
                break
    print(cnt)


def retT(a, b):
    if len(a) == len(b):
        return "="
    elif len(a) < len(b):
        return '<'
    return ">"


def retF(a, b):
    if len(a) == len(b):
        return "="
    elif len(a) > len(b):
        return '<'
    return "<"


def solveByPrateek():
    n = int(input())
    graph = defaultdict(list)
    for i in range(n):
        node = int(input())
        graph[node].append(i+1)
    visited = [False for _ in range(n + 1)]

    def dfs(node, depth):
        mx = depth
        for emp in graph[node]:
            if not visited[emp]:
                visited[emp] = True
                mx = max(mx,dfs(emp, depth + 1))
        return mx
    # print(graph)
    mxx = 1
    mxx = dfs(-1,0)
    # for i in range(1, n + 1):
    #     if not visited[i]:
    #         mxx = max(mxx, dfs(i, 1))
    print(mxx)


solveByPrateek()
