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 CF87Div1A 
{
	static ArrayList<ArrayList<Integer>> al;
	static ArrayList<ArrayList<Integer>> rev;
	static Set<Integer> visited;
	static int n,max,ans;
	static Stack<Integer> st;
	static ArrayList<ArrayList<Integer>> RevGraph(ArrayList<ArrayList<Integer>> a)
	{
		ArrayList<ArrayList<Integer>> t=new ArrayList<ArrayList<Integer>>();
		for(int i=0;i<a.size();i++)
			t.add(new ArrayList<Integer>());
		for(int i=0;i<a.size();i++)
		{
			for(int j=0;j<a.get(i).size();j++)
				t.get(j).add(i);
		}
		return t;
	}
	static void dfs()
	{
		int i;
		for(i=1;i<=n;i++)
		{
			if(!visited.contains(i))
				DFSUtil(i);
		}
	}
	static void DFSUtil(int k) 
	{
		visited.add(k);
		for(Integer i:al.get(k))
		{
			if(!visited.contains(i))
				DFSUtil(i);
		}
		st.add(k);
	}
	static void DFSRev(int k)
	{
		ans++;
		visited.add(k);
		for(Integer i:al.get(k))
		{
				DFSRev(i);
		}		
	}
	static int SCC()
	{
		int t;
		ans=0;
		max=Integer.MIN_VALUE;
		rev=RevGraph(al);
		dfs();
		visited=new HashSet<>();
		while(!st.empty())
		{
			t=st.pop();
			if(!visited.contains(t))
			{
				ans=0;
				DFSRev(t);
				max=Math.max(ans,max);
			}
		}
		return max;
	}
	public static void main(String args[]) 
	{
		InputReader in = new InputReader(System.in);
		OutputStream outputStream = System.out;
		PrintWriter out = new PrintWriter(outputStream);
		/*------------------------------My Code starts here------------------------------*/
		int i=0;
		n=in.nextInt();
		int[] a=nextIntArray(in, n);
		al=new ArrayList<ArrayList<Integer>>();
		visited=new HashSet<>();
		st=new Stack<Integer>();
		for(i=0;i<=n;i++)
			al.add(new ArrayList<Integer>());
		for(i=0;i<n;i++)
		{
			if(a[i]!=-1)
				al.get(i+1).add(a[i]);
		}
		out.println(SCC());
		out.close();
		/*------------------------------The End------------------------------------------*/
	}

	public static final long l = (int) (1e9 + 7);

	private static int[] nextIntArray(InputReader in, int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = in.nextInt();
		return a;
	}

	private static void show(int[] a) {
		for (int i = 0; i < a.length; i++)
			System.out.print(a[i] + " ");
		System.out.println();
	}

	private static void show2DArray(char[][] a) {
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[0].length; j++)
				System.out.print(a[i][j]);
			System.out.println();
		}
	}

	static class Pair {
		private int first;
		private int second;

		public Pair(int i, int j) {
			this.first = i;
			this.second = j;
		}

		public int getFirst() {
			return first;
		}

		public int getSecond() {
			return second;
		}

		public void setFirst(int k) {
			this.first = k;
		}

		public void setSecond(int k) {
			this.second = k;
		}
	}

	static int modPow(int a, int b, int p) {
		int result = 1;
		a %= p;
		while (b > 0) {
			if ((b & 1) != 0)
				result = (result * a) % p;
			b = b >> 1;
		a = (a * a) % p;
		}
		return result;
	}

	public static void SieveOfEratosthenes(int n) {
		boolean[] prime = new boolean[n + 1];
		Arrays.fill(prime, true);
		prime[1] = false;
		int i, j;
		for (i = 2; i * i <= n; i++) {
			if (prime[i]) {
				for (j = i; j <= n; j += i) {
					if (j != i)
						prime[i] = false;
				}
			}
		}
	}

	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());
		}
	}
}