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?

Input

The first line contains integer n (1 ≤ n ≤ 2000) — the number of employees.

The next n lines contain the integers pi (1 ≤ pi ≤ n or pi = -1). Every pi denotes the immediate manager for the i-th employee. If pi 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 (pi ≠ i). Also, there will be no managerial cycles.

Output

Print a single integer denoting the minimum number of groups that will be formed in the party.

Examples

Input

5
-1
1
2
1
-1


Output

3

Note

For the first example, three groups are sufficient, for example: 

  * Employee 1 
  * Employees 2 and 4 
  * Employees 3 and 5 
import java.util.*;
import java.io.*;


public class Main {
/*

 */
    public static BR in;
    public static LR lin;
    public static PrintWriter out;
    public static PrintWriter fout;
    static {
        try {
            in = new BR();
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out  ) ) );
            fout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("output.txt") ) ) );
        }
        catch (Exception e){
            
        }
    }
    
    public static boolean bg = true;
    public static void main(String[] args) throws Exception {
        s1();
        out.close();
    }

    private static void s1() throws Exception {
        int n1 = in.ni();
        IntL[] al = new IntL[n1];
        for (int i = 0; i < n1; i++){
            al[i] = new IntL();
        }
        for (int i = 0 ; i < n1; i++){
            int k1 = in.ni();
            if (k1 != -1){
                k1--;
                al[k1].add(i);
            }
        }
        
        int[] parentleft = new int[n1];
        for (int i = 0; i < n1; i++){
            for (int e: al[i]){
                parentleft[e]++;
            }
        }
        
        int[] maxheights = new int[n1];
        Arrays.fill(maxheights, Integer.MIN_VALUE);
        
        IntL q1 = new IntL();
        IntL q2 = new IntL();
        for (int i = 0; i < n1; i++){
            if (parentleft[i] == 0){
                q1.add(i);
                maxheights[i] = 1;
            }
        }
        
        for (;;){
            if (q1.size == 0) break;
            for (int e: q1){
                int temp = maxheights[e] + 1;
                for(int f: al[e]){
                    maxheights[f] = max(maxheights[f], temp);
                    parentleft[f]--;
                    if (parentleft[f] == 0){
                        q2.add(f);
                    }
                }
            }
            q1 = q2;
            q2 = new IntL();
        }
        pn(max(maxheights));
    }
    

    private static void pn(Object... o1) {
        for (int i = 0; i < o1.length; i++) {
            if (i != 0) out.print(" ");
            out.print(o1[i]);
        }
        out.println();
    }

    private static void px(Object... o1) {
        String s1 = Arrays.deepToString(o1);
        if (bg)
            System.out.println("bg:   " + s1.substring(1, s1.length() - 1));
    }

    private static int max(int ... l1){
        int fin = Integer.MIN_VALUE;
        for (int e: l1){
            if (e > fin) fin = e;
        }
        return fin;
    }
    
    private static class LR {
    }

    private static class BR {
        BufferedReader k1 = null;
        StringTokenizer k2 = null;

        public BR() {
            k1 = new BufferedReader(new InputStreamReader(System.in));
        }

        public String nx() throws Exception {
            for (;;) {
                if (k2 == null || !k2.hasMoreTokens()) {
                    String temp = k1.readLine();
                    if (temp == null) return null;
                    k2 = new StringTokenizer(temp);
                }
                else
                    break;
            }

            return k2.nextToken();
        }

        public int ni() throws Exception {
            return Integer.parseInt(nx());
        }
    }

    private static class IntL implements Iterable<Integer> {
        public int[] l1 = null;
        public int size = 0;

        public IntL(int initialCapacity) {
            this.l1 = new int[initialCapacity];
        }

        public IntL() {
            this(5);
        }

        public void add(int e) {
            if (size == l1.length) {
                l1 = Arrays.copyOf(l1, ((l1.length * 3) >> 1) + 1);
            }
            l1[size++] = e;
        }

        @Override
        public String toString() {
            StringBuilder fin = new StringBuilder();
            fin.append('{');
            for (int i = 0; i < size; i++) {
                if (i != 0) fin.append(", ");
                fin.append(l1[i]);
            }
            fin.append('}');
            return fin.toString();
        }

        @Override
        public Iterator<Integer> iterator() {
            return new It();
        }

        public class It implements Iterator<Integer> {
            int ptr = 0;

            @Override
            public boolean hasNext() {
                if (ptr < size) return true;
                return false;
            }

            @Override
            public Integer next() {
                int fin = l1[ptr];
                ptr++;
                return fin;
            }

            @Override
            public void remove() {

            }
        }
    }


}
