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.awt.geom.Line2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.StringTokenizer;

public class A implements Runnable {
	static String Y = "YES", N = "NO";
	static long inf = (long) 1e18;
	static int inf2 = Integer.MAX_VALUE / 2;

	public static void main(String[] args) {
		new Thread(null, new A(), "Solver", 1L << 26).start();
	}

	private FastScanner scan;
	private PrintWriter out;

	public A() {
		scan = new FastScanner(System.in);
		out = new PrintWriter(System.out);
	}

	public void run() {
		try {
			solve();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(1 / 0);
		}
	}

	static long ceilDiv(long n, long d) {
		if (n < 0 != d < 0) {
			return (n / d) - (n % d == 0 ? 0 : 1);
		}
		return (n / d) + (n % d == 0 ? 0 : 1);
	}
	void solve() throws IOException {
		int n = scan.nextInt();
		int[] ps = new int[n];
		ArrayList<Integer>[] cs = new ArrayList[n];
		for(int i=0;i<n;i++)
			cs[i] = new ArrayList<Integer>();
		ArrayDeque<Pair> bfs = new ArrayDeque<>();
		for(int i=0;i<n;i++) {
			ps[i] = scan.nextInt()-1;
			if(ps[i] < 0) {
				ps[i] = -1;
				bfs.offer(new Pair(1,i));
			} else
				cs[ps[i]].add(i);
		}
		int ans = 0;
		while(!bfs.isEmpty()) {
			Pair p = bfs.poll();
			ans = Math.max(ans, (int)p.a);
			for(int c : cs[(int)p.b]) {
				bfs.offer(new Pair(p.a+1,c));
			}
		}
		out.println(ans);
		
	}

	static class DisjointSet {
		int[] p;
		int sz;

		public DisjointSet(int size) {
			p = new int[size];
			for (int i = 0; i < size; i++)
				p[i] = i;
			this.sz = size;
		}

		public int root(int x) {
			return x == p[x] ? x : (p[x] = root(p[x]));
		}

		public void union(int a, int b) {
			a = root(a);
			b = root(b);
			if (a != b) {
				p[a] = b;
				sz--;
			}
		}
	}

	void print(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			out.print(arr[i]);
			if (i == arr.length - 1)
				out.println();
			else
				out.print(" ");
		}

	}

	static class Pair implements Comparable<Pair> {
		long a, b;

		public Pair(long a, long b) {
			this.a = a;
			this.b = b;
		}

		@Override
		public int compareTo(Pair o) {
			if (a == o.a)
				return Long.compare(b, o.b);
			return Long.compare(a, o.a);
		}

		@Override
		public String toString() {
			return "(" + a + "," + b + ")";
		}
	}

	static long max(long... ls) {
		long max = ls[0];
		for (long l : ls) {
			if (l > max)
				max = l;
		}
		return max;
	}

	static int max(int... ls) {
		int max = ls[0];
		for (int l : ls) {
			if (l > max)
				max = l;
		}
		return max;
	}

	static double max(double... ls) {
		double max = ls[0];
		for (double l : ls) {
			if (l > max)
				max = l;
		}
		return max;
	}

	static long min(long... ls) {
		long min = ls[0];
		for (long l : ls) {
			if (l < min)
				min = l;
		}
		return min;
	}

	static double min(double... ls) {
		double min = ls[0];
		for (double l : ls) {
			if (l < min)
				min = l;
		}
		return min;
	}

	static int min(int... ls) {
		int min = ls[0];
		for (int l : ls) {
			if (l < min)
				min = l;
		}
		return min;
	}

	static void yes(boolean a) {
		System.out.println(a ? Y : N);
	}

	static long gcd(long a, long b) {
		if (b == 0)
			return a;
		return gcd(b, a % b);
	}

	static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
			st = new StringTokenizer("");
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String next() throws IOException {
			while (!st.hasMoreTokens()) {
				st = new StringTokenizer(br.readLine());
			}
			return st.nextToken();
		}
	}

	class BPM {
		private Dinics d;
		private int leftCount;
		private int rightCount;

		public BPM(int leftCount, int rightCount) {
			this.leftCount = leftCount;
			this.rightCount = rightCount;
			this.d = new Dinics(leftCount + rightCount + 2, 0, leftCount + rightCount + 1);
			for (int i = 1; i <= leftCount; i++) {
				d.addEdge(d.s, i, 1);
			}
			for (int i = leftCount + 1; i <= leftCount + rightCount; i++) {
				d.addEdge(i, d.t, 1);
			}
		}

		public void addMatching(int left, int right) {
			d.addEdge(1 + left, 1 + leftCount + right, 1);
		}

		public int[] getMatchings() {
			this.d.calculateFlow();
			int[] answer = new int[leftCount];
			Arrays.fill(answer, -1);
			for (edge e : this.d.e) {
				if (e.a == d.s || e.b == d.t)
					continue;
				if (e.flow != 1)
					continue;
				answer[e.a - 1] = e.b - (leftCount + 1);
			}
			return answer;
		}
	}

	class Dinics {
		public static final int INF = 1000000000;

		public Dinics(int n, int s, int t) {
			this.n = n;
			this.g = new ArrayList[n];
			this.s = s;
			this.t = t;
			this.q = new int[n];
			this.d = new int[n];
			this.ptr = new int[n];
			this.intd = new int[n];
			for (int i = 0; i < n; i++)
				g[i] = new ArrayList<Integer>();
		}

		int n, s, t;
		int[] intd;
		int[] ptr;
		int[] d;
		int[] q;
		ArrayList<edge> e = new ArrayList<edge>();
		ArrayList<Integer>[] g;

		void addEdge(int a, int b, int cap) {
			edge e1 = new edge(a, b, cap, 0);
			edge e2 = new edge(b, a, 0, 0);
			g[a].add((int) e.size());
			e.add(e1);
			g[b].add((int) e.size());
			e.add(e2);
		}

		boolean bfs() {
			int qh = 0, qt = 0;
			q[qt++] = s;
			Arrays.fill(d, -1);
			d[s] = 0;
			while (qh < qt && d[t] == -1) {
				int v = q[qh++];
				for (int i = 0; i < g[v].size(); ++i) {
					int id = g[v].get(i), to = e.get(id).b;
					if (d[to] == -1 && e.get(id).flow < e.get(id).cap) {
						q[qt++] = to;
						d[to] = d[v] + 1;
					}
				}
			}
			return d[t] != -1;
		}

		int dfs(int v, int flow) {
			if (flow == 0)
				return 0;
			if (v == t)
				return flow;
			for (; ptr[v] < (int) g[v].size(); ++ptr[v]) {
				int id = g[v].get(ptr[v]), to = e.get(id).b;
				if (d[to] != d[v] + 1)
					continue;
				int pushed = dfs(to, Math.min(flow, e.get(id).cap - e.get(id).flow));
				if (pushed != 0) {
					e.get(id).flow += pushed;
					e.get(id ^ 1).flow -= pushed;
					return pushed;
				}
			}
			return 0;
		}

		public int calculateFlow() {
			int flow = 0;
			for (;;) {
				if (!bfs())
					break;
				Arrays.fill(ptr, 0);
				int pushed;
				while ((pushed = dfs(s, INF)) != 0)
					flow += pushed;
			}
			return flow;
		}

	}

	static class edge {
		int a, b, cap, flow;

		public edge(int a, int b, int cap, int flow) {
			this.a = a;
			this.b = b;
			this.cap = cap;
			this.flow = flow;
		}
	}
}