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 
//Author : Debojyoti Mandal
//Attribute : Some of the methods are copied from GeeksforGeeks Website
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main
{ 
  static  PrintWriter out=new PrintWriter(System.out);
  static  Reader sc=new Reader();
  //static FastReader sc=new FastReader(System.in);
  static int max=0;
  static void DFS(int v, int dis, boolean[] vis,ArrayList<Integer> graph[])
  {
		vis[v] = true;
		max = Math.max(max, dis);
		dis++;
		for(int i = 0; i < graph[v].size(); i++)
		{
			int u = graph[v].get(i);
			if(!vis[u])
				DFS(u, dis, vis,graph);
		}
  }
 public static void main (String[] args) throws java.lang.Exception
   {
	try{
	     // long n=sc.nextLong();
	     // int n=sc.nextInt();
	     // String s=sc.next();
	     // boolean flag=true;
	     // flag(flag);
	     // ArrayList<Long> al=new ArrayList<>();
	     
		  int t=1;
		  while(t-->0)
		    { 
		       int n=sc.nextInt();
		       int a[]=new int[n];
		       for(int i=0;i<n;i++)
		        a[i]=sc.nextInt();
		        
		       ArrayList<Integer> graph[]=new ArrayList[n];
		        for(int i=0;i<n;i++)
                {
                   graph[i]=new ArrayList<Integer>();
                  // graph[i].add(i);
                }
                
		       for(int i=0;i<n;i++)
		         {
		            int ele=a[i];
		            if(ele!=-1)
		              {
		                 ele--;
		                 graph[ele].add(i);
		                 //graph[ele].add(i);
		              }
		         }
		      for(int i=0;i<n;i++)
		       {
		          boolean[] vis = new boolean[n];
		          DFS(i, 1, vis, graph);
		       }
		      out.println(max);
		    }
	     out.flush();
	     out.close();
	   }     
	catch(Exception e)
		 {}
	}
	
	
//Soluntion Ends Here.............................................ereH sdnE noitnuloS

                                       //Template//
   static class graph
  {
        int v;
        ArrayList<Integer> list[];
        graph(int v)
        {
            this.v=v;
            list=new ArrayList[v+1];
            for(int i=1;i<=v;i++)
                list[i]=new ArrayList<Integer>();
        }
        void addEdge(int a, int b)
        {
            this.list[a].add(b);
        }
    }
  static void flag(boolean flag)
    {
       out.println(flag ? "YES" : "NO");
       out.flush();
    }
    
   // Map<Long,Long> map=new HashMap<>();
   // for(int i=0;i<n;i++)
   //  {
   //     if(!map.containsKey(a[i]))
   //       map.put(a[i],1);
   //     else
   //       map.replace(a[i],map.get(a[i])+1);
   //  }
     
   //  Set<Map.Entry<Long,Long>> hmap=map.entrySet();
   //  for(Map.Entry<Long,Long> data : hmap)
   //     {
          
   //     }
 
 static void sort(int[] a) 
   {
		ArrayList<Integer> l=new ArrayList<>();
		for (int i:a) l.add(i);
		Collections.sort(l);
		for (int i=0; i<a.length; i++) a[i]=l.get(i);
	}
static void sort(long[] a) 
   {
		ArrayList<Long> l=new ArrayList<>();
		for (long i:a) l.add(i);
		Collections.sort(l);
		for (int i=0; i<a.length; i++) a[i]=l.get(i);
	}
 static long gcd(long a, long b) 
    { 
        if (a == 0) 
            return b; 
          
        return gcd(b%a, a); 
    } 
    
static void calcsubarray(long a[],long x[], int n, int c) 
 { 
    for (int i=0; i<(1<<n); i++) 
    { 
        long s = 0; 
        for (int j=0; j<n; j++) 
            if ((i & (1<<j))==0)
                s += a[j+c]; 
        x[i] = s; 
    } 
 } 
 
   static class FastReader{
 
        byte[] buf = new byte[2048];
        int index, total;
        InputStream in;
 
        FastReader(InputStream is) {
            in = is;
        }
 
        int scan() throws IOException {
            if (index >= total) {
                index = 0;
                total = in.read(buf);
                if (total <= 0) {
                    return -1;
                }
            }
            return buf[index++];
        }
 
        String next() throws IOException {
            int c;
            for (c = scan(); c <= 32; c = scan());
            StringBuilder sb = new StringBuilder();
            for (; c > 32; c = scan()) {
                sb.append((char) c);
            }
            return sb.toString();
        }
 
        int nextInt() throws IOException {
            int c, val = 0;
            for (c = scan(); c <= 32; c = scan());
            boolean neg = c == '-';
            if (c == '-' || c == '+') {
                c = scan();
            }
            for (; c >= '0' && c <= '9'; c = scan()) {
                val = (val << 3) + (val << 1) + (c & 15);
            }
            return neg ? -val : val;
        }
 
        long nextLong() throws IOException {
            int c;
            long val = 0;
            for (c = scan(); c <= 32; c = scan());
            boolean neg = c == '-';
            if (c == '-' || c == '+') {
                c = scan();
            }
            for (; c >= '0' && c <= '9'; c = scan()) {
                val = (val << 3) + (val << 1) + (c & 15);
            }
            return neg ? -val : val;
        }
    }
   
    static class Reader 
    { 
        final private int BUFFER_SIZE = 1 << 16; 
        private DataInputStream din; 
        private byte[] buffer; 
        private int bufferPointer, bytesRead; 
  
        public Reader() 
        { 
            din = new DataInputStream(System.in); 
            buffer = new byte[BUFFER_SIZE]; 
            bufferPointer = bytesRead = 0; 
        } 
  
        public Reader(String file_name) throws IOException 
        { 
            din = new DataInputStream(new FileInputStream(file_name)); 
            buffer = new byte[BUFFER_SIZE]; 
            bufferPointer = bytesRead = 0; 
        } 
  
        public String readLine() throws IOException 
        { 
            byte[] buf = new byte[64]; // line length 
            int cnt = 0, c; 
            while ((c = read()) != -1) 
            { 
                if (c == '\n') 
                    break; 
                buf[cnt++] = (byte) c; 
            } 
            return new String(buf, 0, cnt); 
        } 
  
        public int nextInt() throws IOException 
        { 
            int ret = 0; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
            do
            { 
                ret = ret * 10 + c - '0'; 
            }  while ((c = read()) >= '0' && c <= '9'); 
  
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        public long nextLong() throws IOException 
        { 
            long ret = 0; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
            do { 
                ret = ret * 10 + c - '0'; 
            } 
            while ((c = read()) >= '0' && c <= '9'); 
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        public double nextDouble() throws IOException 
        { 
            double ret = 0, div = 1; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
  
            do { 
                ret = ret * 10 + c - '0'; 
            } 
            while ((c = read()) >= '0' && c <= '9'); 
  
            if (c == '.') 
            { 
                while ((c = read()) >= '0' && c <= '9') 
                { 
                    ret += (c - '0') / (div *= 10); 
                } 
            } 
  
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        private void fillBuffer() throws IOException 
        { 
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE); 
            if (bytesRead == -1) 
                buffer[0] = -1; 
        } 
  
        private byte read() throws IOException 
        { 
            if (bufferPointer == bytesRead) 
                fillBuffer(); 
            return buffer[bufferPointer++]; 
        } 
  
        public void close() throws IOException 
        { 
            if (din == null) 
                return; 
            din.close(); 
        } 
    } 

}
// Thank You !