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 {
		static boolean[] visited;
		static ArrayList<ArrayList<Integer>> arr= new ArrayList<ArrayList<Integer>>();
		public static long mod= (long) (1e9 +7);
		public static void main(String args[]){
			InputReader s= new InputReader(System.in);
			OutputStream outputStream= System.out;
			PrintWriter out= new PrintWriter(outputStream);
			int n= s.nextInt();
			for(int i=0;i<=n;i++)
				arr.add(new ArrayList<Integer>());
			int source[]= new int[n+1];
			int j=0;
			for(int i=1;i<=n;i++){
				int x= s.nextInt();
				if(x!=-1){
					arr.get(i).add(x);
					arr.get(x).add(i);
				}
				else {
					source[j]= i;
					j++;
				}
			}
			int depth=0;
			for(int i=0;i<j;i++){
				visited= new boolean[n+1];
				int x= dfs(source[i]);
				if(x>depth){
					depth=x;	
				}
			}
			out.println(depth);
			out.close();
		}
		static int dfs(int curr){
			visited[curr]= true;
			int maxDepth= 0;
			for(int i=0;i<arr.get(curr).size();i++){
				if(!visited[arr.get(curr).get(i)]){
					//System.out.println("ds");
					maxDepth= Math.max(maxDepth, dfs(arr.get(curr).get(i)));
				}
			}
			return maxDepth+1;
		}
		static class InputReader {
	
		    public BufferedReader reader;
		    public StringTokenizer tokenizer;
	 
		    public InputReader(InputStream inputstream) {
		      reader = new BufferedReader(new InputStreamReader(inputstream));
		      tokenizer = null;
		    }
		    
		    public String nextLine(){
		    	String fullLine=null;
		    	while (tokenizer == null || !tokenizer.hasMoreTokens()) {
		            try {
		              fullLine=reader.readLine();
		            } catch (IOException e) {
		              throw new RuntimeException(e);
		            }
		            return fullLine;
		          }
		          return fullLine;
		    }
			public String next() {
		      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
		        try {
		          tokenizer = new StringTokenizer(reader.readLine());
		        } catch (IOException e) {
		          throw new RuntimeException(e);
		        }
		      }
		      return tokenizer.nextToken();
		    }
			public long nextLong() {
			      return Long.parseLong(next());
			    }
		    public int nextInt() {
		      return Integer.parseInt(next());
		    }
		  }
		static class Pair implements Comparable<Pair>
		{
			long f,s;
			Pair(long ii, long cc)
			{
				f=ii;
				s=cc;
			}
			
			public int compareTo(Pair o) 
			{
				return Long.compare(this.f, o.f);
			}
			
		}
		public static int gcd(int number1, int number2) {  
			if(number2 == 0){
				return number1;
			} 
			return gcd(number2, number1%number2); 
		}
		public static int combinations(int n,int r){
			if(n==r) return 1;
			if(r==1) return n;
			if(r==0) return 1;
			return combinations(n-1,r)+ combinations(n-1,r-1);
		}
		public static long binomialCoeff(int n, int k)
		{
		    long C[][]= new long[n+1][k+1];
		    int i, j;
		 
		    // Caculate value of Binomial Coefficient in bottom up manner
		    for (i = 0; i <= n; i++)
		    {
		        for (j = 0; j <= Math.min(i, k); j++)
		        {
		            // Base Cases
		            if (j == 0 || j == i)
		                C[i][j] = 1;
		 
		            // Calculate value using previosly stored values
		            else
		                C[i][j] = C[i-1][j-1] + C[i-1][j];
		        }
		    }
		 
		    return C[n][k];
		}
		public static int expo(int a, int b){
		    if (b==1)
		        return a;
		    if (b==2)
		        return a*a;
	
		    if (b%2==0){
		            return expo(expo(a,b/2),2);
		    }
		    else{
		        return a*expo(expo(a,(b-1)/2),2);
		    }
		}
		
		public static void sieve(int N){
			int arr[]= new int[N+1];
			for(int i=2;i<Math.sqrt(N);i++){
				if(arr[i]==0){
					for(int j= i*i;j<= N;j= j+i){
						arr[j]=1;
					}
				}
			}
			// All the i for which arr[i]==0 are prime numbers.
		}
	}
	
