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.io.*;
import java.util.*;
import static java.lang.Math.*;

public class Main {
    private static boolean oj = System.getProperty("ONLINE_JUDGE") != null;
    private static Reader in;
    private static PrintWriter out;
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    private static int min(int... a){int min=a[0]; for(int i:a) min=Math.min(min, i); return min;}
    private static int max(int... a){int max=a[0]; for(int i:a) max=Math.max(max, i); return max;}
    private static long min(long... a){long min=a[0]; for(long i:a)min=Math.min(min, i); return min;}
    private static long max(long... a){long max=a[0]; for(long i:a)max=Math.max(max, i); return max;}
    private static String strm(String str, long m) {
        String ans="";
        while(m>0) {
            if(m%2==1) ans=ans.concat(str);
            str=str.concat(str); m>>=1;
        } return ans;
    }
    private static long mod(long a, long mod) {long res = a%mod; return res>=0 ? res : res+mod;}
    private static int mod(int a, int mod) {int res = a%mod; return res>=0 ? res : res+mod;}
    private static long modpow(long x, int n, int mod) {
        long res = 1;
        for (long p = x; n > 0; n >>= 1, p = mod((mod(p, mod)*mod(p, mod)),  mod)) {
            if ((n & 1) != 0) res = mod(mod(res, mod) * mod(p, mod), mod);
        }
        return res;
    }
    private static long gcd(long a, long b) {return b == 0 ? Math.abs(a) : gcd(b, a % b);}
    private static int gcd(int a, int b) {return b == 0 ? Math.abs(a) : gcd(b, a % b);}
    private static long gcd(long... a) {long gcd=a[0]; for(long x:a) gcd=gcd(gcd, x); return gcd;}
    private static int gcd(int... a) {int gcd=a[0]; for(int x:a) gcd=gcd(gcd, x); return gcd;}
    private static long lcm(long a, long b) {return Math.abs(a / gcd(a, b) * b);}
    private static class Pair {
        public int x, y;
        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
        @Override
        public boolean equals(Object obj) {
            if (obj == this) return true;
            if (!(obj instanceof Pair)) return false;
            Pair pair = (Pair)obj;
            return this.x == pair.x && this.y == pair.y;
        }

        @Override
        public int hashCode() {
            return (this.x+" "+this.y).hashCode();
        }
    }
    private static class Triplet {
        public int x, y, z;
        public Triplet(int x, int y, int z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
        @Override
        public boolean equals(Object obj) {
            if (obj == this) return true;
            if (!(obj instanceof Triplet)) return false;
            Triplet triplet = (Triplet)obj;
            return this.x == triplet.x && this.y == triplet.y && this.z == triplet.z;
        }

        @Override
        public int hashCode() {
            return (this.x+" "+this.y+" "+this.z).hashCode();
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    static class Reader {
        private BufferedReader br;
        private StringTokenizer token;
        protected Reader(FileReader obj) {
            br = new BufferedReader(obj, 32768);
            token = null;
        }
        protected Reader() {
            br = new BufferedReader(new InputStreamReader(System.in), 32768);
            token = null;
        }
        protected String next() {
            while(token == null || !token.hasMoreTokens()) {
                try {
                    token = new StringTokenizer(br.readLine());
                } catch (Exception e) {e.printStackTrace();}
            } return token.nextToken();
        }
        protected String nextLine() {
            String str="";
            try {
                str = br.readLine();
            } catch (Exception e) {e.printStackTrace();}
            return str;
        }
        protected int nextInt() {return Integer.parseInt(next());}
        protected long nextLong() {return Long.parseLong(next());}
        protected double nextDouble() {return Double.parseDouble(next());}
        protected long[] nextLongArr(int n) {
            long[] arr = new long[n]; for(int i=0; i<n; i++) arr[i] = nextLong(); return arr;
        }
        protected int[] nextIntArr(int n) {
            int[] arr = new int[n]; for(int i=0; i<n; i++) arr[i] = nextInt(); return arr;
        }
    }
    public static final int mod = 1_000_000_007;
    static int n;
    static ArrayList<ArrayList<Integer>> al;
    static ArrayList<Integer> roots;
    static boolean[] vis;
    static int max_height;
    private static void bfs (int root) {
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(root);
        vis[root] = true;
        HashMap<Integer, Integer> level = new HashMap<>();
        level.put(root, 1);
        while (!queue.isEmpty()) {
            int v = queue.poll();
            for (int w: al.get(v)) {
                if (!vis[w]) {
                    queue.offer(w);
                    level.put(w, level.get(v)+1);
                    max_height = max(max_height, level.get(w));
                    vis[w] = true;
                }
            }
        }
    }
    private static void solve() throws Exception {
        n = in.nextInt();
        al = new ArrayList<>();
        for (int i=0; i<=n; i++) al.add(new ArrayList<>());
        vis = new boolean[n+1];
        roots = new ArrayList<>();
        for (int i=1; i<=n; i++) {
            int parent = in.nextInt();
            if (parent == -1) roots.add(i);
            else al.get(parent).add(i);
        }
        max_height = 1;
        for (int root: roots) bfs(root);
        out.printf("%d\n", max_height);
    }
    private static void run() throws Exception
    {
//        in = new Reader();
//        in = new Reader(new FileReader("input.txt"));
//        out = new PrintWriter(new FileWriter("output.txt"));
        in = oj ? new Reader() : new Reader(new FileReader("C:\\Users\\Suhaib\\Desktop\\input.txt"));
        out = new PrintWriter(System.out);
        long ti = System.currentTimeMillis();
        solve(); out.flush();
        if (!oj) System.out.println("\n"+(System.currentTimeMillis()-ti)+"ms");
    }
    public static void main(String[] args) throws Exception {run();}
}