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

Difficulty: EASY
Tags: Tree algorithms

Graph algorithms

Graph traversal

Starter code:

Solutions:
import sys
readline = sys.stdin.buffer.readline

def i1():
	return int(readline())

def nl():
	return [int(s) for s in readline().split()]

def nn(n):
	return [int(readline()) for i in range(n)]

def nlp(x):
	return [int(s) + x for s in readline().split()]

def nll(n):
	return [[int(s) for s in readline().split()] for i in range(n)]

def mll(n):
	return ([int(s) for s in readline().split()] for i in range(n))

def s1():
	return readline().rstrip()

def sn(n):
	return [readline().rstrip() for i in range(n)]

def sm(n):
	return (readline().rstrip() for i in range(n))

def redir(s):
	global readline
	import os
	fn = sys.argv[0] + f'/../in-{s}.txt'
	readline = open(fn).readline if os.path.exists(fn) else readline
redir('a')
n = i1()
parents = [int(s) - 1 for s in sm(n)]
ulevel = [-1] * n
for i in range(n):
	if ulevel[i] > 0:
		continue
	cnt = 1
	p = parents[i]
	while p >= 0 and ulevel[p] < 0:
		cnt += 1
		ulevel[p] = i
		i = p
		p = parents[i]
	if p < 0:
		x = 1
	else:
		x = ulevel[p] + 1
	for _ in range(cnt):
		p = ulevel[i]
		ulevel[i] = x
		x += 1
		i = p
print(max(ulevel))


n = int(input())
gr = []
st = []
for i in range(n + 1):
	gr.append([])
for i in range(n):
	x = int(input())
	if x != -1:
		gr[x].append(i + 1)
	else:
		st.append(i + 1)

def trav(a):
	dis = [-1 for x in range(n + 1)]
	q = []
	q.append(a)
	dis[a] = 0
	while len(q) > 0:
		b = q[0]
		q.pop(0)
		for i in range(len(gr[b])):
			z = gr[b][i]
			if dis[z] == -1:
				q.append(z)
				dis[z] = dis[b] + 1
	dis.sort()
	return dis[len(dis) - 1]
f = []
for i in range(len(st)):
	k = trav(st[i])
	f.append(k)
f.sort(reverse=True)
print(f[0] + 1)


n = int(input())
a = []
for i in range(n):
	a.append(int(input()))
ans = -1
for i in range(n):
	x = a[i]
	s = 1
	while x != -1:
		s += 1
		x = a[x - 1]
	ans = max(ans, s)
print(ans)


import sys

def main1():
	n = int(input())
	dict = {}
	depth = [0] * (n + 1)
	for i in range(1, n + 1):
		readVal = int(input())
		if readVal != -1:
			depth[i] = 1
		if readVal in dict:
			dict[readVal].append(i)
		else:
			l = list()
			l.append(i)
			dict[readVal] = l

	def assignDepth(root):
		if root in dict:
			for child in dict[root]:
				depth[child] += depth[root]
				assignDepth(child)
	for x in dict:
		if x != -1 and depth[x] == 0:
			depth[x] = 1
			assignDepth(x)
	big = 1
	for j in range(1, n + 1):
		if depth[j] > big:
			big = depth[j]
	print(big)
sys.setrecursionlimit(5000)
main1()


import math, sys, re, itertools
(rs, ri, rai) = (input, lambda : int(input()), lambda : list(map(int, input().split())))
n = ri()
g = [0] * n
for i in range(n):
	g[i] = ri() - 1
res = 0
for i in range(n):
	x = i
	t = 1
	while g[x] >= 0:
		p = x
		x = g[x]
		t += 1
	res = max(res, t)
print(res)


n = int(input())
a = []
for i in range(n):
	a.append(int(input()))
s = 0
for i in range(n):
	c = 0
	while i >= 0:
		i = a[i] - 1
		c += 1
	s = max(s, c)
print(s)


import sys
readline = sys.stdin.buffer.readline

def i1():
	return int(readline())

def nl():
	return [int(s) for s in readline().split()]

def nn(n):
	return [int(readline()) for i in range(n)]

def nlp(x):
	return [int(s) + x for s in readline().split()]

def nll(n):
	return [[int(s) for s in readline().split()] for i in range(n)]

def mll(n):
	return ([int(s) for s in readline().split()] for i in range(n))

def s1():
	return readline().rstrip()

def sn(n):
	return [readline().rstrip() for i in range(n)]

def sm(n):
	return (readline().rstrip() for i in range(n))

def redir(s):
	global readline
	import os
	fn = sys.argv[0] + f'/../in-{s}.txt'
	readline = open(fn).readline if os.path.exists(fn) else readline
redir('a')
n = i1()
parents = [int(s) - 1 for s in sm(n)]
ip = sorted(enumerate(parents), key=lambda x: x[1])
ulevel = [-1] * n
for (i, p) in ip:
	if p < 0:
		ulevel[i] = 1
		continue
	stack = []
	while ulevel[i] < 0:
		stack.append(i)
		i = parents[i]
		if i < 0:
			i = stack.pop()
			ulevel[i] = 1
			break
	x = ulevel[i]
	for i in stack[::-1]:
		x += 1
		ulevel[i] = x
print(max(ulevel))


import math as mt
import sys, string
input = sys.stdin.readline
L = lambda : list(map(int, input().split()))
Ls = lambda : list(input().split())
M = lambda : map(int, input().split())
I = lambda : int(input())
from collections import defaultdict

def dfs(n, dx):
	vis[n] = 1
	dis[n] = dx
	for i in adj[n]:
		if vis[i] == 0:
			dfs(i, dx + 1)
n = I()
vis = [0] * (n + 1)
dis = [0] * (n + 1)
l = []
adj = []
for i in range(n + 1):
	adj.append([])
for i in range(n):
	d = I()
	if d == -1:
		l.append(i + 1)
	else:
		adj[d].append(i + 1)
for i in l:
	dfs(i, 1)
print(max(dis))


n = int(input())
f = [0]
for i in range(n):
	a = int(input())
	f.append(a)
max = -1
for i in range(1, n + 1):
	h = 1
	j = f[i]
	while j != -1:
		h = h + 1
		j = f[j]
	if h > max:
		max = h
print(max)


n = int(input())
a = [[] for i in range(n)]
gen = []
for i in range(n):
	k = int(input())
	if k == -1:
		gen.append(i)
	else:
		a[k - 1].append(i)

def is_leaf(root):
	if a[root]:
		return 0
	else:
		return 1

def f(root):
	if is_leaf(root):
		return 1
	else:
		ret = 1
		for v in a[root]:
			ret = max(ret, f(v) + 1)
		return ret
if len(gen) == n:
	print(1)
elif len(gen) == n - 1:
	print(2)
else:
	flag = 0
	tag = 0
	tag = f(flag)
	for i in gen:
		s = f(i)
		if s > tag:
			flag = i
			tag = s
	print(f(flag))


n = int(input())
p = [int(input()) for i in range(n)]
g = 0
for i in range(n):
	c = 0
	while i >= 0:
		i = p[i] - 1
		c += 1
	g = max(g, c)
print(g)


def main():
	from sys import stdin
	from collections import deque
	n = int(input())
	A = list(map(int, stdin.read().strip().split()))

	class g:

		def __init__(self):
			self.depth = -1
			self.child = []
	d = [g() for i in range(n)]
	M = []
	for i in range(n):
		if A[i] == -1:
			M.append(i)
			continue
		d[A[i] - 1].child.append(i)

	def bfs(a):
		q = deque()
		q.append(a)
		a.depth = 0
		while len(q) > 0:
			a = q.popleft()
			for i in a.child:
				if d[i].depth == -1:
					d[i].depth = a.depth + 1
					q.append(d[i])
	for i in M:
		bfs(d[i])
	D = []
	for i in range(n):
		D.append(d[i].depth)
	print(max(D) + 1)
main()


import sys
sys.setrecursionlimit(2500)
W = 0
G = 1
n = int(input())
color = [-1]
adj_list = [[] for i in range(n + 1)]
root = []
for i in range(1, n + 1):
	color.append(0)
	p = int(input())
	if p == -1:
		root.append(i)
	else:
		adj_list[p].append(i)
max_g_num = 0

def dfs(v: int, g_num):
	global max_g_num
	color[v] = G
	if g_num > max_g_num:
		max_g_num = g_num
	for u in adj_list[v]:
		if color[u] == W:
			dfs(u, g_num + 1)
for v in root:
	dfs(v, 1)
print(max_g_num)


import sys
sys.setrecursionlimit(10 ** 6)
n = int(input())
dic = {}

def dfs(i):
	x = 1
	if i in dic:
		m1 = 0
		for j in dic[i]:
			m1 = max(dfs(j), m1)
		x += m1
	return x
for i in range(n):
	x = int(input())
	if x != -1:
		if x not in dic:
			dic[x] = [i + 1]
		else:
			dic[x].append(i + 1)
output = 1
max1 = 1
for i in dic:
	max1 = max(max1, dfs(i))
print(max1)


import collections

class Solution:

	def __init__(self):
		self.maxHeight = 0

	def dfs(self, tree):
		self.tree = tree
		for root in self.tree[0]:
			self.dfsHelper(root, 1)
		return self.maxHeight

	def dfsHelper(self, curr, height):
		if not curr:
			return
		self.maxHeight = max(self.maxHeight, height)
		for child in self.tree[curr]:
			self.dfsHelper(child, height + 1)
		return
sol = Solution()
n = int(input().strip())
tree = collections.defaultdict(list)
for i in range(1, n + 1):
	pI = int(input().strip())
	if pI == -1:
		tree[0].append(i)
	else:
		tree[pI].append(i)
print(sol.dfs(tree))


from collections import deque

def bfs(u):
	global n, al, dist, prev, used
	q = deque()
	q.append(u)
	md = 1
	used[u] = True
	while len(q) > 0:
		v = q.popleft()
		for i in al[v]:
			if not used[i]:
				used[i] = True
				dist[i] = dist[v] + 1
				if dist[i] + 1 > md:
					md = dist[i] + 1
				q.append(i)
	return md
n = int(input())
al = [[] for i in range(n)]
dist = [0] * n
prev = [0] * n
used = [False] * n
p = [-1] * n
for i in range(n):
	x = int(input()) - 1
	if x >= 0:
		p[i] = x
		al[x].append(i)
res = 0
a = []
for i in range(n):
	if p[i] == -1:
		a.append(i)
i = 0
while i < len(a):
	if not used[a[i]]:
		res = max(res, bfs(a[i]))
	else:
		i += 1
print(res)


t = int(input())
lst = [0]
for c in range(t):
	lst.append(int(input()))
par = []
for c in range(1, t + 1):
	count = 0
	k = c
	while lst[k] != -1:
		count += 1
		k = lst[k]
	par.append(count)
print(max(par) + 1)


def dfs(graph, node, visited, height, parent):
	visited[node] = True
	if parent != -1:
		height[node] = height[parent] + 1
	for i in graph[node]:
		if not visited[i]:
			dfs(graph, i, visited, height, node)
v = int(input())
graph = []
for i in range(v + 1):
	graph.append([])
edges = []
for i in range(v):
	edges.append(int(input()))
roots = []
for i in range(len(edges)):
	if edges[i] != -1:
		graph[edges[i]].append(i + 1)
	else:
		roots.append(i + 1)
height = [1] * (v + 1)
visited = [False] * (v + 1)
for i in roots:
	if not visited[i]:
		dfs(graph, i, visited, height, -1)
print(max(height))


p = list()
for _ in range(int(input())):
	p.append(int(input()))
g = 0
for i in range(len(p)):
	c = 0
	while i >= 0:
		i = p[i] - 1
		c += 1
	g = max(g, c)
print(max(g, c))


def deeper(i):
	global l
	if l[i] < 0:
		return 1
	return deeper(l[i]) + 1
n = int(input())
l = [0 for _ in range(n)]
for i in range(n):
	l[i] = int(input()) - 1
ans = 0
for i in range(n):
	t = deeper(i)
	if ans < t:
		ans = t
print(ans)


n = int(input())
graph = {}
roots = []
for i in range(1, n + 1):
	cur = int(input())
	if cur != -1:
		graph[cur] = graph.get(cur, []) + [i]
	else:
		roots.append(i)
ans = 1

def dfs(root, depth=2):
	global ans
	for path in graph[root]:
		if path in set(graph.keys()):
			dfs(path, depth + 1)
		else:
			ans = max(ans, depth)
for root in roots:
	if root in set(graph.keys()):
		dfs(root)
print(ans)


import math
import sys

class Graph:

	def __init__(self, Nodes, is_directed=False):
		self.nodes = Nodes
		self.adj_list = {}
		self.is_directed = is_directed
		for node in self.nodes:
			self.adj_list[node] = []

	def add_edge(self, u, v):
		if v not in self.adj_list[u]:
			if u not in self.adj_list[v]:
				self.adj_list[v].append(u)

	def print_graph(self):
		for node in self.nodes:
			print(node, '->', self.adj_list[node])

	def degree_node(self, node):
		return len(self.adj_list[node])

	def dfsUTIL(self, v, visited):
		val = 0
		visited[v] = True
		for i in self.adj_list[v]:
			if visited[i] == False:
				val = max(val, self.dfsUTIL(i, visited))
		return val + 1

	def dfs(self, v):
		visited = [False] * (max(self.adj_list) + 1)
		depth = 0
		parents = self.dfsUTIL(v, visited)
		return parents
t = int(input())
nodes = [i + 1 for i in range(t)]
graph = Graph(nodes, True)
root = []
for i in range(t):
	a = int(input())
	if a != -1:
		graph.add_edge(i + 1, a)
	else:
		root.append(i + 1)
maxx = -1
for i in root:
	a = graph.dfs(i)
	if a > maxx:
		maxx = a
print(maxx)


n = int(input())
lista = []
niveis = []
niveis = set(niveis)
for i in range(n):
	chefe = int(input())
	lista.append(chefe)
for i in lista:
	cont = 0
	at = i
	while at != -1:
		cont += 1
		at = lista[at - 1]
	niveis.add(cont)
print(len(niveis))


n = int(input())
graph = [[] for _ in range(n)]
isRoot = [True] * n
for i in range(n):
	p = int(input())
	if p != -1:
		graph[p - 1].append(i)
		isRoot[i] = False

def bfs(v):
	(i, maximum) = (0, 1)
	queue = [[v, 1]]
	while i < len(queue):
		(v, maximum) = queue[i]
		for node in graph[v]:
			queue.append([node, maximum + 1])
		i += 1
	return maximum
ans = 0
for i in range(n):
	if isRoot[i]:
		ans = max(ans, bfs(i))
print(ans)


n = int(input())
a = list()
for i in range(n):
	a.append(int(input()))
h = x = 1
for i in range(n):
	if a[i] > 0:
		h = 1
		while a[i] > 0:
			i = a[i] - 1
			h += 1
		if h > x:
			x = h
print(x)


n = int(input())
l = []
for i in range(n):
	l.append(int(input()))
ans = 0
temp = 0
for i in range(n):
	if l[i] != -1:
		a = 1
		temp = l[i]
		while temp != -1:
			temp = l[temp - 1]
			a += 1
		ans = max(a, ans)
if n > 0 and ans == 0:
	print(1)
else:
	print(ans)


import sys

def solver():
	inp = sys.stdin.read()
	mylist = inp.splitlines()
	n = int(mylist[0])
	emp = [int(elem) for elem in mylist[1:]]
	ans = 0
	for i in range(n):
		count = 0
		j = i
		while j >= 0:
			j = emp[j] - 1
			count += 1
		ans = max(count, ans)
	print(ans)

def main():
	solver()
main()


import os
import sys
from math import *
from collections import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def value():
	return map(int, input().split())

def array():
	return [int(i) for i in input().split()]
ind = []

def dfs(adj, s, vis, c):
	global ind
	ind.append(c)
	vis[s] = True
	for i in adj[s]:
		if vis[i] == False:
			dfs(adj, i, vis, c + 1)
adj = defaultdict(list)
n = int(input())
ar = []
for i in range(n):
	a = int(input())
	ar.append(a)
	if a != -1:
		adj[a].append(i + 1)
		adj[i + 1].append(a)
ans = 0
vis = {i: False for i in range(1, n + 1)}
for i in range(1, n + 1):
	if ar[i - 1] == -1 and vis[i] == False:
		dfs(adj, i, vis, 0)
print(max(ind) + 1)


t = int(input())
dic = {}
for tt in range(1, t + 1):
	p = int(input())
	dic[tt] = p

def dfs(v):
	cont = 1
	atual = v
	while dic[atual] != -1:
		cont += 1
		atual = dic[atual]
	return cont
resp = 0
for i in range(1, t + 1):
	resp = max(resp, dfs(i))
print(resp)


n = int(input())
graph = [-1] * (n + 1)
for index in range(1, n + 1):
	parent = int(input())
	graph[index] = parent
maxi = 0
for i in range(1, n + 1):
	cnt = 0
	j = i
	while j != -1:
		j = graph[j]
		cnt += 1
	maxi = max(maxi, cnt)
print(maxi)


from collections import deque
n = int(input())
d = deque(([] for _ in range(n + 1)))
mi = deque()
for i in range(1, n + 1):
	t = int(input())
	if t > 0:
		d[t].append(i)
	else:
		mi.append(i)
ans = 0
while mi:
	mi = [j for i in mi for j in d[i]]
	ans += 1
print(ans)


n = int(input())
tree = {}
for i in range(n):
	m = int(input())
	tree[i + 1] = m
visited = set()
max = 0
for i in range(1, n + 1):
	if i not in visited:
		node = i
		count = 1
		while tree[node] != -1:
			visited.add(node)
			count += 1
			node = tree[node]
		if count > max:
			max = count
print(max)


import sys
sys.setrecursionlimit(4000)
adj = []
vis = []

def dfs(x):
	vis[x] = 1
	res = 0
	for vert in adj[x]:
		if vis[vert] == -1:
			res = max(dfs(vert) + 1, res)
	return res
for i in range(0, 2000):
	adj.append([])
n = int(input())
vet = []
for i in range(0, n):
	a = int(input())
	a -= 1
	vet.append(a)
	if a != -2:
		adj[a].append(i)
	vis.append(-1)
largecomp = 0
for i in range(0, n):
	if vis[i] == -1 and vet[i] == -2:
		largecomp = max(dfs(i) + 1, largecomp)
print(largecomp)


import sys
sys.setrecursionlimit(100000)

def depth(parent, i, array):
	if array[i] != 0:
		return
	if parent[i] == -1:
		array[i] = 1
		return
	if array[parent[i]] == 0:
		depth(parent, parent[i], array)
	array[i] = array[parent[i]] + 1
n = int(input())
parent = []
for i in range(n):
	a = int(input())
	if a == -1:
		parent.append(-1)
	else:
		parent.append(a - 1)
array = [0] * n
for i in range(n):
	depth(parent, i, array)
print(max(array))


import sys
readline = sys.stdin.buffer.readline

def i1():
	return int(readline())

def nl():
	return [int(s) for s in readline().split()]

def nn(n):
	return [int(readline()) for i in range(n)]

def nnp(n, x):
	return [int(readline()) + x for i in range(n)]

def nmp(n, x):
	return (int(readline()) + x for i in range(n))

def nlp(x):
	return [int(s) + x for s in readline().split()]

def nll(n):
	return [[int(s) for s in readline().split()] for i in range(n)]

def mll(n):
	return ([int(s) for s in readline().split()] for i in range(n))

def s1():
	return readline().rstrip()

def sn(n):
	return [readline().rstrip() for i in range(n)]

def sm(n):
	return (readline().rstrip() for i in range(n))

def redir(s):
	global readline
	import os
	fn = sys.argv[0] + f'/../in-{s}.txt'
	readline = open(fn).readline if os.path.exists(fn) else readline
redir('a')
n = i1()
(roots, children) = ([], [[] for i in range(n)])
for (i, p) in enumerate(nmp(n, -1)):
	if p >= 0:
		children[p].append(i)
	else:
		roots.append(i)
maxdepth = 0
while roots:
	maxdepth += 1
	roots = [j for i in roots for j in children[i]]
print(maxdepth)


import math
import sys
from collections import defaultdict
from collections import deque
input = iter(sys.stdin.buffer.read().decode().splitlines()).__next__
ilele = lambda : map(int, input().split())
alele = lambda : list(map(int, input().split()))

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]
INF = 10 ** 18
sys.setrecursionlimit(1000000)
MOD = 1000000000 + 7
import heapq
first = 1
G = defaultdict(list)

def addEdge(a, b):
	G[a].append(b)
	G[b].append(a)

def BFSUtil(queue, vis, level):
	while queue:
		s = queue.popleft()
		for child in G.get(s, []):
			if vis[child] == False:
				queue.append(child)
				level[child] = level[s] + 1
				vis[child] = True

def nodesatlevel(node, N, maxi, A):
	vis = [False for i in range(N + 1)]
	for node in A:
		if vis[node] == False:
			level = {}
			queue = deque()
			level[node] = 0
			queue.append(node)
			vis[node] = True
			BFSUtil(queue, vis, level)
			maxi = max(maxi, max(level.values()))
	return maxi
N = int(input())
maxi = -1
A = []
for i in range(N):
	(u,) = ilele()
	if u == -1:
		A.append(i + 1)
		maxi = 0
	else:
		addEdge(i + 1, u)
x = nodesatlevel(1, N, maxi, A)
print(x + 1)


n = int(input())
c = 1
a = []
for i in range(n):
	a.append(int(input()))
for i in range(n):
	k = 1
	j = i
	while a[j] > -1:
		j = a[j] - 1
		k += 1
	c = max(k, c)
print(c)


class Graph:

	def __init__(self, size):
		self.size = size
		self.adj_list = {}
		for i in range(size):
			self.adj_list[i] = []

	def add_edge(self, src, des):
		self.adj_list[src].append(des)

	def BFS(self, src):
		d2s = [-1 for i in range(self.size)]
		visited = [False for i in range(self.size)]
		d2s[src] = 0
		visited[src] = True
		queue = [src]
		while len(queue) != 0:
			u = queue.pop(0)
			for node in self.adj_list[u]:
				if not visited[node]:
					visited[node] = True
					d2s[node] = d2s[u] + 1
					queue.append(node)
		return d2s

def main():
	n = int(input())
	g = Graph(n)
	roots = []
	bfss = []
	for i in range(n):
		u = int(input())
		if u != -1:
			g.add_edge(u - 1, i)
		else:
			roots.append(i)
	for i in roots:
		bfss.append(max(g.BFS(i)) + 1)
	print(max(bfss))
main()


n = int(input())
m = []
v = []
h = 0
for i in range(n):
	m.append(int(input()))
for i in range(1, n + 1):
	s = 0
	for j in range(n):
		if m[j] == i:
			s += 1
	v.append(s)
for i in range(n):
	if v[i] == 0:
		c = 0
		j = m[i] - 1
		h = max(h, c)
		while j >= 0:
			c += 1
			j = m[j] - 1
			h = max(h, c)
print(h + 1)


n = int(input())
pra = []
for i in range(n):
	pra.append(int(input()) - 1)
gle = []
aj_sc = 1
q = []
for i in range(n):
	if pra[i] == -2:
		q.append(i)
for i in range(n):
	gle.append(1)
while q != []:
	nQ = []
	for i in range(n):
		if pra[i] in q:
			nQ.append(i)
			gle[i] = gle[pra[i]] + 1
	q = nQ
gle.sort()
print(gle[-1])


import sys
sys.setrecursionlimit(2004)
n = int(input())
a = [0]
color = [0] * (n + 1)
d1 = 1
for i in range(n):
	a.append(int(input()))

def get_neibors(v):
	neibors = []
	if a[v] != -1:
		if color[a[v]] == 0:
			neibors.append(a[v])
	for i in range(1, n + 1):
		if a[i] == v and color[i] == 0:
			neibors.append(i)
	return neibors

def dfs(v, d):
	global d1
	if d > d1:
		d1 = d
	color[v] = 1
	for s in get_neibors(v):
		if color[s] == 0:
			dfs(s, d + 1)
for i in range(1, n + 1):
	if color[i] == 0 and a[i] == -1:
		dfs(i, 1)
print(d1)


n = int(input())
a = []
for i in range(n):
	a.append(int(input()))
b = [0 for i in range(n)]
d = 1
while d != 0:
	d = 0
	for i in range(n):
		if a[i] != -1:
			if b[i] != b[a[i] - 1] + 1:
				d += 1
				b[i] = b[a[i] - 1] + 1
print(sorted(b)[-1] + 1)


n = int(input())
m = [[None, []] for i in range(n)]
for i in range(n):
	x = int(input())
	if x == -1:
		pass
	else:
		m[i][0] = x
		m[x - 1][1].append(i + 1)
d = 0
for i in m:
	if i[1] == []:
		bottom = i
		depth = 0
		while bottom[0] != None:
			bottom = m[bottom[0] - 1]
			depth = depth + 1
		if depth > d:
			d = depth
print(d + 1)


def getDistancia(value):
	if value not in dic:
		return 1
	return 1 + getDistancia(dic[value])
n = int(input())
dic = {}
for e in range(n):
	ent = int(input())
	if ent != -1:
		dic[e + 1] = ent
maior = 1
for e in dic:
	aux = getDistancia(e)
	if aux > maior:
		maior = aux
print(maior)


def dfs(v):
	global s, max_
	used[v] = 1
	for u in g[v]:
		if used[u] == 0:
			s += 1
			dfs(u)
	if s > max_:
		max_ = s
	s -= 1
n = int(input())
g = []
max_ = -1
used = [0] * n
k = []
for i in range(n):
	g.append([])
for i in range(n):
	x = int(input())
	if x != -1:
		g[x - 1].append(i)
	else:
		k.append(i)
for x in k:
	s = 1
	dfs(x)
print(max_)


n = int(input())
mat = []
for _ in range(n):
	mat.append(int(input()))
res = 0
for i in range(n):
	groups = 1
	employee = mat[i]
	while employee != -1:
		groups += 1
		employee = mat[employee - 1]
	res = max(res, groups)
print(res)


from math import sqrt, gcd, ceil, floor, log, factorial
from itertools import permutations, combinations
from collections import Counter, defaultdict

def dfs(node, d, visited, res, lev):
	visited[node] = 1
	res[node] = lev
	for i in d[node]:
		if visited[i] == 0:
			dfs(i, d, visited, res, lev + 1)
n = int(input())
res = [0] * (n + 1)
d = defaultdict(list)
visited = [0] * (n + 1)
lev = 0
val = [0] * (n + 1)
for i in range(1, n + 1):
	p = int(input())
	if p == -1:
		val[i] = p
		continue
	d[i].append(p)
	d[p].append(i)
for i in range(1, n + 1):
	if val[i] == -1:
		dfs(i, d, visited, res, lev)
print(len(set(res[1:])))


from collections import defaultdict
import sys
sys.setrecursionlimit(10000)
n = int(input())
tops = []
hier = defaultdict(list)
for i in range(n):
	boss = int(input())
	if boss == -1:
		if not i + 1 in hier:
			hier[i + 1] = []
		tops.append(i + 1)
	else:
		hier[boss].append(i + 1)

def getDepth(hier, elem, deep):
	depths = {}
	children = hier[elem]
	if len(children) == 0:
		return deep + 1
	else:
		return max([getDepth(hier, x, deep + 1) for x in children])
ans = max([getDepth(hier, x, 0) for x in tops])
print(ans)


import sys
import math

def dfs(graph, start):
	c = 0
	while start != -1:
		c += 1
		start = graph[start]
	return c
n = int(input())
d = [-1] * (n + 1)
for i in range(1, n + 1):
	v = int(input())
	if v != -1:
		d[i] = v
vmax = 0
for i in range(1, n + 1):
	k = dfs(d, i)
	if k > vmax:
		vmax = k
print(vmax)


n = int(input())
p = [int(input()) - 1 for _ in range(n)]

def build_reverse_graph(p):
	graph = {i: [] for i in range(len(p))}
	for (i, source) in enumerate(p):
		if source != -2:
			graph[source].append(i)
	return graph

def get_level_of_atonement(bitch):
	(current, level) = (bitch, 1)
	while p[current] != -2:
		(current, level) = (p[current], level + 1)
	return level

def party():
	reverse_graph = build_reverse_graph(p)
	gods = [i for i in range(len(p)) if p[i] == -2]
	bitches = [i for i in reverse_graph if not reverse_graph[i]]
	return max([get_level_of_atonement(bitch) for bitch in bitches])
print(party())


n = int(input())
l = []
for i in range(n):
	l.append(int(input()) - 1)
m = 0
for i in range(n):
	c = 0
	while i != -2:
		c = c + 1
		i = l[i]
	m = max(c, m)
print(m)


n = int(input())
emp = []
max = 1
for _ in range(n):
	p = int(input())
	emp.append(p)
for i in range(n):
	temp = emp[i]
	times = 1
	while temp != -1:
		temp = emp[temp - 1]
		times += 1
		if times > max:
			max = times
print(max)


n = int(input())
graph = {i: set() for i in range(1, n + 1)}
ls = set()
for i in range(1, n + 1):
	m = int(input())
	if m > -1:
		graph[i] = graph[i].union(set([m]))
		graph[m] = graph[m].union(set([i]))
	else:
		ls.add(i)
visited = set()

def dfs(i):
	visited.add(i)
	if len(graph[i] - visited) < 1:
		return 1
	z = 0
	for j in graph[i] - visited:
		z = max(z, 1 + dfs(j))
	return z
x = 0
for i in range(1, n + 1):
	if i in ls:
		x = max(x, dfs(i))
print(x)


from sys import stdin, stdout, setrecursionlimit
import heapq
from math import gcd, ceil, sqrt
from collections import Counter, deque
from bisect import bisect_left, bisect_right
from itertools import combinations, permutations
ii1 = lambda : int(stdin.readline().strip())
is1 = lambda : stdin.readline().strip()
iia = lambda : list(map(int, stdin.readline().strip().split()))
isa = lambda : stdin.readline().strip().split()
setrecursionlimit(100000)
mod = 1000000007
n = ii1()
arr = [ii1() for i in range(n)]
res = 0
for i in range(n):
	cur = 0
	while i >= 0:
		i = arr[i] - 1
		cur += 1
	res = max(res, cur)
print(res)


from sys import *
inp = lambda : stdin.readline()

def main():
	n = int(inp())
	l = []
	for i in range(n):
		l.append(int(inp()) - 1)
	ans = 0
	for i in range(n):
		(temp, j) = (0, i)
		while l[j] != -2:
			j = l[j]
			temp += 1
		ans = max(ans, temp)
	print(ans + 1)
main()


n = int(input())
g = {i + 1: [] for i in range(n)}
root = []
for v in range(n):
	u = int(input())
	if u != -1:
		g[u].append(v + 1)
	else:
		root.append(v + 1)
vis = [0] * (n + 1)

def dfs(u, h=1):
	vis[u] = h
	for v in g[u]:
		if not vis[v]:
			dfs(v, h + 1)
for i in root:
	dfs(i)
print(max(vis))


n = int(input())
employee = []
for i in range(n + 1):
	employee.append([])
q = []
NpL = 0
for i in range(n):
	p = int(input())
	if p != -1:
		employee[p] += [i + 1]
	else:
		q += [i + 1]
		NpL += 1
level = 1
Next = 0
while len(q) > 0:
	for i in range(len(employee[q[0]])):
		q += [employee[q[0]][i]]
		Next += 1
	q.pop(0)
	NpL -= 1
	if NpL == 0:
		NpL = Next
		Next = 0
		level += 1
print(level - 1)


n = int(input())
freedom = []
Imboss = [[] for x in range(n + 1)]
for i in range(n):
	inn = int(input())
	if inn == -1:
		freedom.append(i + 1)
	else:
		Imboss[inn].append(i + 1)
temp = []
group = 0
while len(freedom) != 0:
	group += 1
	for f in freedom:
		temp = temp + Imboss[f]
	freedom = temp[:]
	temp = []
print(group)


n = int(input())
a = []
for i in range(n):
	x = int(input())
	a.append(x)
queue = []
for i in range(n):
	if a[i] == -1:
		queue.append(i + 1)
level = 0
while len(queue) > 0:
	size = len(queue)
	level += 1
	for i in range(size):
		x = queue.pop(0)
		for j in range(n):
			if a[j] == x:
				queue.append(j + 1)
print(level)


n = int(input())
k = [int(input()) for i in range(n)]
r = 0
i = 0
for i in range(n):
	c = 0
	while i >= 0:
		i = k[i] - 1
		c += 1
	r = max(r, c)
print(r)


class node:

	def __init__(self, value):
		self.value = value
		self.depth = 0
n = int(input())
p = []
d = {}
for i in range(n):
	k = int(input())
	if k != -1:
		if k not in d:
			d[k] = [i + 1]
		else:
			d[k].append(i + 1)
	else:
		p.append(i + 1)
visited = [False] * n
l = [node(i) for i in range(1, n + 1)]
dep = 0
ans = 0
for s in p:
	if s in d:
		queue = []
		queue.append(s)
		while queue:
			s = queue.pop(0)
			dep = l[s - 1].depth
			if visited[s - 1] == False:
				visited[s - 1] = True
				l[s - 1].depth = dep + 1
				dep = l[s - 1].depth
			ans = max(ans, dep)
			if s in d:
				for i in d[s]:
					if visited[i - 1] == False:
						queue.append(i)
						visited[i - 1] = True
						l[i - 1].depth = dep + 1
				dep = l[s - 1].depth + 1
			ans = max(ans, dep)
if ans == 0:
	ans += 1
print(ans)


def binary_search(s, a):
	i = 0
	j = len(s) - 1
	while i <= j:
		mid = (i + j) // 2
		if s[mid] == a:
			return True
		elif s[mid] > a:
			j = mid - 1
		else:
			i = mid + 1
	return False
n = int(input())
supervisors = [i for i in range(1, n + 1)]
s = [[] for i in range(n + 1)]

def add(a, empl):
	s[a].append(empl)
	if binary_search(supervisors, empl):
		supervisors.remove(empl)

def find_height(a):
	g = 1
	p = 0
	for i in s[a]:
		p = max(find_height(i), p)
	g += p
	return g
for i in range(1, n + 1):
	a = int(input())
	if a != -1:
		add(a, i)
ans = -10
for i in supervisors:
	ans = max(ans, find_height(i))
print(ans)


import sys
from sys import stdin, stdout
import bisect
import math
sys.setrecursionlimit(10000000)
mod = 10 ** 9 + 7

def st():
	return list(stdin.readline().strip())

def inp():
	return int(stdin.readline())

def li():
	return list(map(int, stdin.readline().split()))

def mp():
	return map(int, stdin.readline().split())

def pr(n):
	stdout.write(str(n) + '\n')

def DFS(dictionary, vertex, visited):
	visited[vertex] = True
	stack = [vertex]
	print(vertex)
	while stack:
		a = stack.pop()
		for i in dictionary[a]:
			if not visited[i]:
				print(i)
				visited[i] = True
				stack.append(i)

def soe(limit):
	l = [1] * (limit + 1)
	l[0] = 0
	l[1] = 0
	prime = []
	for i in range(2, limit + 1):
		if l[i]:
			for j in range(i * i, limit + 1, i):
				l[j] = 0
	for i in range(2, limit + 1):
		if l[i]:
			prime.append(i)
	return prime

def segsoe(low, high):
	limit = int(high ** 0.5) + 1
	prime = soe(limit)
	n = high - low + 1
	l = [0] * (n + 1)
	for i in range(len(prime)):
		lowlimit = low // prime[i] * prime[i]
		if lowlimit < low:
			lowlimit += prime[i]
		if lowlimit == prime[i]:
			lowlimit += prime[i]
		for j in range(lowlimit, high + 1, prime[i]):
			l[j - low] = 1
	for i in range(low, high + 1):
		if not l[i - low]:
			if i != 1:
				print(i)

def gcd(a, b):
	while b:
		a = a % b
		(b, a) = (a, b)
	return a

def power(a, n):
	r = 1
	while n:
		if n & 1:
			r = r * a
		a *= a
		n = n >> 1
	return r

def dfs(node, level, mydict, visited):
	visited[node] = True
	maxi = level
	for child in mydict[node]:
		if not visited[child]:
			maxi = max(maxi, dfs(child, level + 1, mydict, visited))
	return maxi

def solve():
	n = int(input())
	mydict = {i: [] for i in range(1, n + 1)}
	parent = {i: -1 for i in range(1, n + 1)}
	for i in range(n):
		child = int(input())
		if child != -1:
			mydict[child].append(i + 1)
			parent[i + 1] = child
	visited = [False] * (n + 1)
	max_level = 0
	for i in range(1, n + 1):
		if not visited[i] and parent[i] == -1:
			max_level = max(max_level, dfs(i, 0, mydict, visited))
	print(max_level + 1)
for _ in range(1):
	solve()


n = int(input())
tree = [list() for x in range(0, n + 2)]
top = list()

def dfs(p, cnt):
	global tree
	if len(tree[p]) == 0:
		return cnt
	ans = 0
	for i in range(0, len(tree[p])):
		ans = max(ans, dfs(tree[p][i], cnt + 1))
	return ans
for i in range(1, n + 1):
	v = int(input())
	if v != -1:
		tree[v].append(i)
	else:
		top.append(i)
ans = 0
for i in top:
	ans = max(ans, dfs(i, 1))
print(ans)


n = int(input())
workers = [0] * n
for i in range(n):
	workers[i] = int(input()) - 1
maxn = 1
for i in workers:
	local_max = 1
	j = i
	if j != -2:
		while workers[j] != -2:
			local_max += 1
			j = workers[j]
		local_max += 1
	maxn = max(maxn, local_max)
print(maxn)


import math

def dfs(a, start, leght, m):
	if a[start] == []:
		m.append(leght)
		return 0
	else:
		for i in range(len(a[start])):
			dfs(a, a[start][i], leght + 1, m)
	return m
p = int(input())
a = []
for i in range(p):
	a.append([])
for i in range(p):
	n = int(input())
	if n != -1:
		a[n - 1].append(i)
k = []
for i in range(p):
	if a[i] != []:
		f = dfs(a, i, 1, [])
		for i in range(len(f)):
			k.append(f[i])
if k != []:
	print(max(k))
else:
	print(1)


import sys
sys.setrecursionlimit(3000)

def dfs(v):
	for w in adj[v]:
		d[w] = d[v] + 1
		dfs(w)
n = int(input())
adj = [[] for _ in range(n)]
root = []
for w in range(n):
	v = int(input()) - 1
	if v == -2:
		root.append(w)
	else:
		adj[v].append(w)
d = [0 for _ in range(n)]
for r in root:
	d[r] = 1
	dfs(r)
print(max(d))


n = int(input())
p = []
for i in range(n):
	a = int(input())
	p.append(a)
ans = 1
for i in range(n):
	if p[i] != -1:
		j = i
		count = 1
		while p[j] != -1:
			j = p[j] - 1
			count += 1
		ans = max(ans, count)
print(ans)


number_of_employee = int(input())
manager_list = []
for x in range(number_of_employee):
	manager_list.append(int(input()))
group = 1
for manager in manager_list:
	temp = 1
	while manager != -1:
		manager = manager_list[manager - 1]
		temp += 1
	group = max(group, temp)
print(group)


n = int(input())
m = []
for _ in range(n):
	m.append(int(input()) - 1)
mx = 1

def depth(i):
	t = 0
	while i != -2:
		i = m[i]
		t += 1
	return t
for i in range(n):
	mx = max(mx, depth(i))
print(mx)


import sys
from collections import defaultdict
input = sys.stdin.readline

def inp():
	return int(input())

def inlt():
	return list(map(int, input().split()))

def insr():
	s = input()
	return list(s[:len(s) - 1])

def invr():
	return list(map(int, input().split()))

def dfs(node, count):
	_max = 0
	stack = []
	stack.append((node, count))
	while stack:
		s = stack.pop()
		n = s[0]
		c = s[1]
		_max = max(_max, c)
		for nei in hash_map[n]:
			stack.append((nei, c + 1))
	return _max
n = inp()
hash_map = defaultdict(list)
for i in range(1, n + 1):
	hash_map[inp()].append(i)
print(dfs(-1, 0))


n = int(input())
emp = [int(input()) for i in range(n)]
root = 0
for i in range(n):
	node = 0
	while i >= 0:
		i = emp[i] - 1
		node += 1
	root = max(root, node)
print(root)


try:
	import sys
	sys.setrecursionlimit(6666)
	n = int(input())
	graph = [[] for i in range(n + 1)]
	for i in range(1, n + 1):
		p = int(input())
		if p == -1:
			p = 0
		graph[p].append(i)

	def h(i):
		ch = graph[i]
		if not ch:
			return 0
		return max((h(x) for x in ch)) + 1
	print(h(0))
except BaseException as e:
	print(e)


t = int(input())
arr = []
for i in range(t):
	arr.append(int(input()))
r = 0
for i in range(t):
	j = i
	dep = 0
	while j >= 0:
		j = arr[j] - 1
		dep += 1
	r = max(r, dep)
print(r)


number = int(input())
sotrudniki_raz = [-1]
it = 1
it = 1
while it <= number:
	value = int(input())
	sotrudniki_raz.append(value)
	it += 1
it = 1
itog = 0

def antirekursiya2x():
	global number
	global itog
	massiv = []
	it = 1
	while it <= number:
		if sotrudniki_raz[it] == -1:
			massiv.append(it)
			sotrudniki_raz[it] = 0
		it += 1
	itog += 1
	it = 1
	while it <= number:
		if sotrudniki_raz[it] in massiv:
			sotrudniki_raz[it] = -1
		it += 1
while it <= number:
	if sotrudniki_raz[it] != 0:
		antirekursiya2x()
		it = 0
	it += 1
print(itog)


from collections import defaultdict
from collections import deque

class NTree:

	def __init__(self):
		self.hmap = defaultdict(list)

	def add_node(self, parent, node):
		if parent == -1:
			self.hmap[0].append(node)
		else:
			self.hmap[parent].append(node)
n = int(input())
t = NTree()
i = 1
while i <= n:
	t.add_node(int(input()), i)
	i += 1
levels = 0
node = t.hmap[0]
q = deque([node])
level_children = []
while q:
	np = q.popleft()
	level_children = []
	for node in np:
		if node in t.hmap:
			for child in t.hmap[node]:
				level_children.append(child)
	if level_children:
		q.append(level_children)
	levels += 1
print(levels)


import sys
readline = sys.stdin.buffer.readline

def i1():
	return int(readline())

def nl():
	return [int(s) for s in readline().split()]

def nn(n):
	return [int(readline()) for i in range(n)]

def nlp(x):
	return [int(s) + x for s in readline().split()]

def nll(n):
	return [[int(s) for s in readline().split()] for i in range(n)]

def mll(n):
	return ([int(s) for s in readline().split()] for i in range(n))

def s1():
	return readline().rstrip()

def sn(n):
	return [readline().rstrip() for i in range(n)]

def sm(n):
	return (readline().rstrip() for i in range(n))

def redir(s):
	global readline
	import os
	fn = sys.argv[0] + f'/../in-{s}.txt'
	readline = open(fn).readline if os.path.exists(fn) else readline
redir('a')

def dfs(i):
	global ulevel, parents, n
	stack = []
	while ulevel[i] < 0:
		stack.append(i)
		i = parents[i]
		if i < 0:
			i = stack.pop()
			ulevel[i] = 1
			break
	x = ulevel[i]
	for i in stack[::-1]:
		x += 1
		ulevel[i] = x
n = i1()
parents = [int(s) - 1 for s in sm(n)]
ulevel = [-1] * n
try:
	for i in range(n):
		dfs(i)
except Exception as e:
	print(e)
print(max(ulevel))


n = int(input())
arr = [0] * (n + 1)
arr[0] = -1
y = [0]
for i in range(1, n + 1):
	y.append(int(input()))
for i in range(1, n + 1):
	if y[i] == -1:
		arr[i] = 1
	elif y[i] > i:
		x = y[i]
		count = 1
		while x > i:
			x = y[x]
			count += 1
		arr[i] = arr[x] + count
	else:
		arr[i] = arr[y[i]] + 1
print(max(arr))


lines = int(input())
managers = []
for i in range(lines):
	managers.append(int(input()))
topHeight = 1
for i in range(0, len(managers)):
	height = 1
	active = i
	while managers[active] != -1:
		active = managers[active] - 1
		height += 1
		if height > topHeight:
			topHeight = height
print(topHeight)


n = int(input())
h = [0] * n
arr = [int(input()) for _ in range(n)]

def getParent(index):
	if arr[index] == -1:
		return 1
	return getParent(arr[index] - 1) + 1
for i in range(n):
	h[i] = getParent(i)
print(max(h))


number = int(input())
sotrudniki_raz = [-1]
it = 1
it = 1
while it <= number:
	value = int(input())
	sotrudniki_raz.append(value)
	it += 1
it = 1
itog = 0

def antirekursiya2x():
	global number
	global itog
	it = 1
	trig = True
	while it <= number:
		if it == 1:
			itog += 1
		if sotrudniki_raz[it] == -1:
			itr = 1
			while itr <= number:
				if sotrudniki_raz[itr] == it:
					sotrudniki_raz[itr] = -2
					trig = False
				itr += 1
			sotrudniki_raz[it] = 0
		it += 1
	it = 1
	if trig == False:
		itog += 1
	while it <= number:
		if sotrudniki_raz[it] == -2:
			itr = 1
			while itr <= number:
				if sotrudniki_raz[itr] == it:
					sotrudniki_raz[itr] = -1
				itr += 1
			sotrudniki_raz[it] = 0
		it += 1
	it = 1
while it <= number:
	if sotrudniki_raz[it] != 0:
		antirekursiya2x()
		it = 0
	it += 1
print(itog)


def dfs(i, dep):
	if fa[i] == -1:
		return 1
	if dep[i] > 0:
		return dep[i]
	dep[i] = dfs(fa[i], dep) + 1
	return dep[i]
n = int(input())
fa = [0] * (n + 1)
for i in range(1, n + 1):
	fa[i] = int(input())
dep = [0] * (n + 1)
res = max([dfs(i, dep) for i in range(1, n + 1)])
print(res)


n = int(input())
d = dict()
for i in range(1, n + 1):
	d[i] = int(input())
h = [1]
for (key, val) in d.items():
	c = 1
	while val != -1:
		val = d[val]
		c = c + 1
	h.append(c)
hg = max(h)
print(hg)


from collections import Counter
from collections import defaultdict
import math
import random
import heapq as hq
from math import sqrt
import sys
from functools import reduce

def input():
	return sys.stdin.readline().strip()

def iinput():
	return int(input())

def tinput():
	return input().split()

def rinput():
	return map(int, tinput())

def rlinput():
	return list(rinput())
mod = int(1000000000.0) + 7

def factors(n):
	return set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def bfs(g, n):
	depth = 0
	q = [0]
	visited = [False] * (n + 1)
	visited[0] = True
	while len(q) > 0:
		temp_queue = []
		while len(q) > 0:
			node = q.pop()
			for i in g[node]:
				if not visited[i]:
					temp_queue.append(i)
					visited[i] = True
		depth += 1
		q = temp_queue
	return depth - 1
num = iinput()
g = defaultdict(list)
for i in range(num):
	n = iinput()
	if n != -1:
		g[n].append(i + 1)
	else:
		g[0].append(i + 1)
print(bfs(g, num))


class node:

	def __init__(self, data):
		self.data = data
		self.next = None
n = int(input())
tail = [i for i in range(1, n + 1)]
r = 1
arr = [node(j) for j in range(1, n + 1)]
for i in range(1, n + 1):
	pi = int(input())
	if pi != -1:
		arr[i - 1].next = arr[pi - 1]
		if pi in tail:
			tail.remove(pi)
	elif i in tail:
		tail.remove(i)
for i in tail:
	count = 1
	while arr[i - 1].next != None:
		count += 1
		i = arr[i - 1].next.data
	if count > r:
		r = count
print(r)


from collections import deque
n = int(input())
g = [[] for i in range(n)]
for i in range(n):
	finish = int(input()) - 1
	if finish >= 0:
		g[i].append(finish)
visited2 = []

def dfs(start):
	visited.append(start)
	for k in g[start]:
		if k not in visited:
			dfs(k)
	visited2.append(len(visited))
for i in range(n):
	visited = []
	dfs(i)
print(max(visited2))


n = int(input())
direct_manager = [int(input()) for _ in range(n)]
max_depth = 0
for i in range(n):
	current_depth = 0
	while i >= 0:
		i = direct_manager[i] - 1
		current_depth += 1
	max_depth = max(current_depth, max_depth)
print(max_depth)


n = int(input())
G = {}
for i in range(1, n + 1):
	currentBoss = int(input())
	if currentBoss in G:
		G[currentBoss].append(i)
	else:
		G[currentBoss] = [i]

def DFS():
	maxDepth = 0
	Q = list(zip([1] * len(G[-1]), G[-1]))
	while Q:
		(d, current) = Q.pop()
		if current in G:
			for n in G[current]:
				Q.append((d + 1, n))
		else:
			maxDepth = max(d, maxDepth)
	return maxDepth
print(DFS())


def go():
	n = int(input())
	a = [int(input()) for _ in range(n)]
	m = 0
	for i in range(n):
		c = 0
		while i >= 0:
			i = a[i] - 1
			c += 1
		m = max(m, c)
	return m
print(go())


n = int(input())
arr = list()
checked = [0] * n
length = [-1] * n
for i in range(n):
	arr.append(int(input()))
ma = -1
for i in range(1, n + 1):
	cur_elem = arr[i - 1]
	l = 1
	while cur_elem > 0:
		if checked[cur_elem - 1] == 1:
			l += length[cur_elem - 1]
			break
		else:
			cur_elem = arr[cur_elem - 1]
			l += 1
	checked[i - 1] = 1
	length[i - 1] = l
	ma = max(length[i - 1], ma)
print(ma)


from collections import defaultdict
d = defaultdict(list)
n = int(input())
li = []
for i in range(1, n + 1):
	k = int(input())
	if k == -1:
		li.append(i)
	else:
		d[k].append(i)

def bfs(s):
	lev = 0
	vis = []
	q = [s]
	q.append(-1)
	while q:
		s = q[0]
		if s == -1:
			lev += 1
			q.pop(0)
			if q != []:
				q.append(-1)
		elif s not in vis:
			vis.append(s)
			q.pop(0)
			for node in d[s]:
				if node not in vis:
					q.append(node)
		else:
			q.pop(0)
			for node in d[s]:
				if node not in vis:
					q.append(node)
	return lev
res = []
tmp = 0
for i in li:
	if i in d.keys():
		tmp = bfs(i)
		res.append(tmp)
if res == []:
	print(1)
else:
	print(max(res))


from collections import defaultdict as dd

class Graph:

	def __init__(self, n):
		self.graph = dd(list)
		self.n = n
		self.vis = [False] * (n + 1)

	def add_edge(self, u, v):
		self.graph[u].append(v)

	def bfs(self, u):
		q = [u]
		lvl = [0] * (self.n + 1)
		lvl[u] = 1
		while len(q) > 0:
			f = q.pop()
			for i in self.graph[f]:
				if self.vis[i] == False:
					self.vis[i] = True
					q.append(i)
					lvl[i] = lvl[f] + 1
		return max(lvl)
n = int(input())
g = Graph(n)
l = []
for i in range(n):
	x = int(input())
	if x == -1:
		l.append(i + 1)
		continue
	g.add_edge(x, i + 1)
ans = -float('inf')
for i in l:
	k = g.bfs(i)
	if k != 1:
		ans = max(ans, k)
if ans == -float('inf'):
	ans = 1
print(ans)


import sys
sys.setrecursionlimit(10000)
n = int(input())
trc = [int] * n
v = [[] for _ in range(n)]

def add(x, y):
	v[x].append(y)
for i in range(n):
	trc[i] = int(input())
	if trc[i] != -1:
		add(trc[i] - 1, i)
res = 0

def dfs(x, p, lv):
	global res
	res = max(res, lv)
	for y in v[x]:
		if y == p:
			continue
		dfs(y, x, lv + 1)
for i in range(n):
	if trc[i] != -1:
		continue
	dfs(i, -1, 1)
print(res)


t = int(input())
m = 0
arr = [int(input()) for i in range(t)]
for i in range(t):
	c = 0
	j = i
	while j >= 0:
		j = arr[j] - 1
		c += 1
	m = max(m, c)
print(m)


n = int(input())
employees = set(range(n))
managers = {i: int(input()) - 1 for i in range(n)}
counter = 0
while bool(employees):
	employees = set((key for key in managers.keys() if managers[key] in employees))
	counter += 1
print(counter)


graph = [[] for i in range(2001)]
visited = [False] * 2001
root = []
dist = [1] * 2001

def explore(node):
	visited[node] = True
	for i in graph[node]:
		if visited[i] == False:
			dist[i] = dist[node] + 1
			explore(i)

def dfs():
	for i in root:
		if visited[i] == False:
			explore(i)
n = int(input())
for i in range(1, n + 1):
	x = int(input())
	if x != -1:
		graph[x].append(i)
	else:
		root.append(i)
dfs()
print(max(dist))


n = int(input())
l = []
for _ in range(n):
	temp = int(input())
	l.append(temp)
ans = 0
for i in range(n):
	g = 1
	p = l[i]
	while p != -1:
		g += 1
		p = l[p - 1]
	ans = max(ans, g)
print(ans)


def partyy():
	n = eval(input())
	ppl = []
	for i in range(n):
		x = eval(input())
		ppl.append(x)
	grp = 1
	for i in range(n):
		k = i
		count = 1
		while ppl[k] != -1:
			x = ppl[k]
			k = x - 1
			count = count + 1
		if count > grp:
			grp = count
	print(grp)
partyy()


t = 1
while t:
	t -= 1
	ans = 1
	n = int(input())
	v = [True for _ in range(n)]
	p = [-1 for _ in range(n)]
	for i in range(n):
		p[i] = int(input())
	for i in range(n):
		tmp = 1
		ind = i
		while p[ind] != -1:
			ind = p[ind] - 1
			tmp += 1
		ans = max(ans, tmp)
	print(ans)


(inp, mn) = ([int(input()) - 1 for n in range(int(input()))], 0)
for i in range(len(inp)):
	c = 0
	while i != -2:
		c += 1
		i = inp[i]
	mn = max(c, mn)
print(mn)


import sys
sys.setrecursionlimit(10000)
n = int(input())
P = [int(input()) for _ in range(n)]
A = [[] for _ in range(n + 1)]
R = []
for i in range(n):
	if P[i] > 0:
		A[P[i]] += [i + 1]
	else:
		R += [i + 1]

def hauteur(r):
	if A[r] == []:
		return 1
	else:
		return 1 + max([hauteur(i) for i in A[r]])
print(max([hauteur(i) for i in R]))


n = int(input())
inp = []
for getInput in range(n):
	inp.append(int(input()) - 1)

def recurse(currIndex):
	global l
	i = currIndex
	while True:
		if inp[i] == -2:
			return
		else:
			l.append(inp[i])
			i = inp[i]
l = []
m = 0
for i in range(n):
	l.clear()
	recurse(i)
	if len(l) > m:
		m = len(l)
print(m + 1)


from collections import defaultdict as dd

def dfs(graph, root, level):
	global depth
	depth = max(depth, level)
	for child in graph[root]:
		dfs(graph, child, level + 1)
n = int(input())
graph = dd(list)
depth = 0
child_parent = dict()
for i in range(n):
	k = int(input())
	if k != -1:
		graph[i + 1].append(k)
		child_parent[k] = i + 1
for i in range(1, n + 1):
	if i not in child_parent:
		dfs(graph, i, 0)
print(depth + 1)


import sys
sys.setrecursionlimit(10 ** 6)
debug_mode = True if len(sys.argv) > 1 and sys.argv[1] == '-d' else False
if debug_mode:
	import os
	inf = open(os.path.abspath(__file__).replace('.py', '.in'))

	def input():
		return inf.readline()
from collections import defaultdict

def main():
	n = int(input().strip())
	p = [None] * (n + 1)
	for i in range(1, n + 1):
		p[i] = int(input().strip())
	m = -1
	for i in range(1, n + 1):
		v = p[i]
		curr_len = 1
		curr = v
		while curr != -1:
			curr = p[curr]
			curr_len += 1
		m = max(m, curr_len)
	print(m)
main()
if debug_mode:
	inf.close()


n = int(input())
parent = [-1] * n
lvl = [-1] * n
for i in range(n):
	x = int(input())
	if x > 0:
		parent[i] = x - 1
	else:
		lvl[i] = 1
for i in range(n):
	flag = False
	for j in range(n):
		if lvl[j] != -1:
			continue
		if lvl[parent[j]] != -1:
			lvl[j] = lvl[parent[j]] + 1
			flag = True
	if not flag:
		break
print(max(lvl))


import sys
sys.setrecursionlimit(3000)

def op(x):
	if a[x] != -1:
		return 1 + op(a[x])
	else:
		return 1
n = int(input())
a = [0] * (n + 1)
for i in range(1, n + 1):
	a[i] = int(input())
l = 1
for i in range(1, n + 1):
	l = max(l, op(i))
print(l)


from collections import defaultdict

def get_height(mp, curr_node, height):
	if curr_node not in mp:
		return height
	max_height = height
	for child in mp[curr_node]:
		curr_height = get_height(mp, child, height + 1)
		max_height = max(max_height, curr_height)
	return max_height
num_employees = int(input())
manager2subordinate = defaultdict(list)
for i in range(num_employees):
	employee = i + 1
	manager = int(input())
	manager2subordinate[manager].append(employee)
max_height = get_height(manager2subordinate, -1, 0)
print(max_height)


n = int(input())
parent = [-1 for i in range(n)]
depth = [0 for i in range(n)]
for i in range(n):
	parent[i] = max(-1, int(input()) - 1)
depth = 0
for q in range(n):
	curr = 0
	i = q
	while parent[i] != -1:
		curr += 1
		i = parent[i]
	depth = max(depth, curr)
print(depth + 1)


def f(i, d):
	global ans
	if i + 1 not in a:
		ans = max(ans, d)
		return
	for j in range(len(a)):
		if a[j] == i + 1:
			f(j, d + 1)
n = int(input())
a = [int(input()) for x in range(n)]
ans = -100
for i in range(len(a)):
	if a[i] == -1:
		f(i, 1)
print(ans)


n = int(input())
arr = [int(input()) for i in range(n)]
ans = 0
for i in range(n):
	an = 0
	while i >= 0:
		i = arr[i] - 1
		an += 1
	ans = max(ans, an)
print(ans)


def dfs(v):

	def f(v, k):
		if v == -1:
			return k
		return f(p[v - 1], k + 1)
	return f(v, 1)
n = int(input())
p = [int(input()) for _ in range(n)]
print(max(list(map(dfs, p))))


l = []
mx = 1
n = int(input())
for i in range(n):
	l.append(int(input()))
d = {}
i = 0
while i < n:
	temp = 1
	j = i
	while j != l[j] - 1 and l[j] > -1:
		if j in d:
			temp += d[j] - 1
			break
		else:
			temp += 1
			j = l[j] - 1
	if i not in d:
		d[i] = temp
	mx = max(mx, temp)
	i += 1
print(mx)


def max_depth(par_dict):
	m = len(par_dict)
	memo = {}

	def depth(i):
		if i in memo.keys():
			return memo[i]
		elif par_dict[i] == -1:
			memo[i] = 1
			return memo[i]
		else:
			memo[i] = 1 + depth(par_dict[i])
			return memo[i]
	return max([depth(i + 1) for i in range(m)])
n = int(input())
d = {}
for i in range(n):
	d[i + 1] = int(input())
print(max_depth(d))


n = int(input())
el = [[] for i in range(n + 1)]
for i in range(n):
	s = int(input())
	s = max(s, 0)
	el[s].append(i + 1)
vs = [0] * (n + 1)
vl = [0] * (n + 1)
sp = 0
while sp > -1:
	p = vs[sp]
	sp -= 1
	for v in el[p]:
		sp += 1
		vs[sp] = v
		vl[v] = vl[p] + 1
print(max(vl))


n = int(input())
graph = dict()
for i in range(n):
	graph[i + 1] = []
root = []
for i in range(n):
	p = int(input())
	if p == -1:
		root.append(i + 1)
	else:
		graph[p].append(i + 1)

def dfs(vertex, level):
	if not graph[vertex]:
		return level
	maxxx = 0
	for node in graph[vertex]:
		maxxx = max(maxxx, dfs(node, level + 1))
	return maxxx
result = 0
for node in root:
	result = max(result, dfs(node, 1))
print(result)


import sys
sys.setrecursionlimit(2500)
n = int(input())
g = [[] for i in range(n)]
roots = []
for i in range(n):
	v = int(input()) - 1
	if v == -2:
		roots.append(i)
		continue
	g[v].append(i)

def dfs(v):
	depth = 1
	add = 0
	for to in g[v]:
		add = max(add, dfs(to))
	return depth + add
m = 0
for i in roots:
	m = max(m, dfs(i))
print(m, end='\n')


from queue import Queue

def minSet(n, ch, d, q):
	maxm = 1
	while not q.empty():
		u = q._get()
		for v in ch[u]:
			d[v] = d[u] + 1
			q._put(v)
			if maxm < d[v]:
				maxm = d[v]
	return maxm
n = int(input())
ch = []
d = []
q = Queue()
for i in range(0, n + 1):
	ch.append([])
	d.append(0)
for i in range(1, n + 1):
	f = int(input())
	if f == -1:
		d[i] = 1
		q._put(i)
	else:
		ch[f].append(i)
print(minSet(n, ch, d, q))


n = int(input())
m = [[None, []] for i in range(n)]
for i in range(n):
	sup = int(input())
	if sup == -1:
		pass
	else:
		m[i][0] = sup
		m[sup - 1][1].append(i + 1)
d = 0
for t in m:
	if t[1] == []:
		h = 0
		c = t
		while c[0] != None:
			h += 1
			c = m[c[0] - 1]
		if h > d:
			d = h
print(d + 1)


n = int(input())
a = [[i, 1] for i in range(n)]
for i in range(n):
	v = int(input())
	if v > 0:
		a[i][0] = v - 1
		j = i
		while j != a[j][0]:
			(j, l) = a[j]
			a[j][1] = max(a[j][1], l + 1)
print(max((x[1] for x in a)))


emps = int(input())
sup = {}
for i in range(emps):
	sup[i] = int(input()) - 1
visited = [False] * emps
ma = 1
for i in range(emps):
	current = 1
	ele = i
	while sup[ele] != -2:
		ele = sup[ele]
		current += 1
	ma = max(ma, current)
print(ma)


import sys
sys.setrecursionlimit(100000000)
n = int(input())
d = {}
de = [-1 for i in range(n + 1)]
for i in range(1, n + 1):
	d[i] = int(input())

def depth(v):
	if de[v] != -1:
		return de[v]
	if d[v] == -1:
		return 0
	else:
		return 1 + depth(d[v])
ma = -1
for i in d:
	t = depth(i)
	de[i] = t
	if de[i] > ma:
		ma = de[i]
print(ma + 1)


n = int(input())
l = [0] * (n + 5)
for t in range(n):
	l[t] = int(input())
ans = 0
for i in range(n):
	c = 0
	m = l[i]
	while m != -1:
		m = l[m - 1]
		c += 1
	ans = max(c, ans)
print(ans + 1)


n = int(input())
array = []
for _ in range(n):
	array.append(int(input()))
for i in range(len(array)):
	j = i
	depth = 0
	while j != -2:
		depth += 1
		j = array[j] - 1
	if i == 0:
		maxDepth = depth
	elif maxDepth < depth:
		maxDepth = depth
print(maxDepth)


import sys
sys.setrecursionlimit(2030)

def calc(posi, valor):
	if posi in d:
		v = 0
		for i in d[posi]:
			v = max(v, calc(i, valor + 1))
		return v
	return valor
n = int(input())
d = {}
v = []
for i in range(n):
	manager = int(input()) - 1
	if manager != -2:
		if manager in d:
			d[manager].append(i)
		else:
			d[manager] = [i]
	else:
		v.append(manager)
h = 0
for i in range(n):
	h = max(calc(i, 1), h)
print(h)


import sys

def dfs(now, used, graf, k):
	global long
	k += 1
	if k > long:
		long = k
	used[now - 1] = 1
	for i in graf[now]:
		dfs(i, used, graf, k)
	return
sys.setrecursionlimit(10000)
n = int(input())
graf = {}
for i in range(n):
	a = int(input())
	if a != -1:
		if a in graf:
			graf[a].append(i + 1)
		else:
			graf[a] = [i + 1]
		if i + 1 not in graf:
			graf[i + 1] = []
	elif i + 1 not in graf:
		graf[i + 1] = []
used = [0] * n
long = 1
for i in range(n):
	if used[i] == 0:
		dfs(i + 1, used, graf, 0)
print(long)


def main():
	(n, res) = (int(input()), 0)
	(tail, head) = ([()] * (n + 1), [])
	for i in range(1, n + 1):
		j = int(input())
		if j == -1:
			head.append(i)
		else:
			t = tail[j]
			if t:
				t.append(i)
			else:
				tail[j] = [i]
	while head:
		head = [j for i in head for j in tail[i]]
		res += 1
	print(res)
main()


from collections import defaultdict
n = int(input())
graph = defaultdict(lambda : [])
for employee in range(1, n + 1):
	x = int(input())
	graph[x].append(employee)
children = [-1]
level = 0
while children:
	n_children = []
	for child in children:
		if child in graph:
			n_children += graph[child]
	children = n_children
	level += 1
print(level - 1)


(n, r) = (int(input()), 0)
(p, h) = ([[] for i in range(n + 1)], [])
for i in range(1, n + 1):
	j = int(input())
	if j > 0:
		p[j].append(i)
	else:
		h.append(i)
while h:
	h = [j for i in h for j in p[i]]
	r += 1
print(r)


n = int(input())
e = [int(input()) for _ in range(n)]
result = 0
for i in range(n):
	count = 0
	while i >= 0:
		i = e[i] - 1
		count += 1
	result = max(result, count)
print(result)


n = int(input())
p = [int(input()) - 1 for i in range(n)]
m = 0
for i in range(len(p)):
	c = 0
	while i != -2:
		c += 1
		i = p[i]
	m = max(c, m)
print(m)


import sys
sys.setrecursionlimit(2050)

def dfs(v):
	global marked, g, depth
	marked[v] = True
	current_depth = depth[v]
	for each_child in g[v]:
		if not marked[each_child]:
			depth[each_child] = current_depth + 1
			marked[each_child] = True
			dfs(each_child)
n = int(input())
g = []
marked = []
depth = []
roots = []
for i in range(n):
	g.append([])
	marked.append(False)
	depth.append(-1)
for i in range(n):
	test = int(input())
	if test != -1:
		father = test - 1
		g[father].append(i)
	else:
		roots.append(i)
for each_root in roots:
	depth[each_root] = 0
	dfs(each_root)
print(max(depth) + 1)


import sys
sys.setrecursionlimit(10 ** 9)
n = int(input())
peres = []
for k in range(n):
	x = int(input())
	if x == -1:
		peres.append(x)
	else:
		peres.append(x - 1)
depth = [-1] * n

def deep(x):
	if peres[x] == -1:
		depth[x] = 1
		return 1
	elif depth[x] != -1:
		return depth[x]
	else:
		res = 1 + deep(peres[x])
		depth[x] = res
		return res
for k in range(n):
	deep(k)
print(max(depth))


def find_depth(graph):
	depth_array = []
	for i in graph.items():
		depth = 0
		manager = i[1]
		while manager != -1:
			manager = graph[manager]
			depth += 1
		depth_array.append(depth)
	groups = Counter(depth_array)
	print(len(groups))
from collections import Counter
n = int(input())
manager_graph = {}
for i in range(1, n + 1):
	manager = int(input())
	manager_graph[i] = manager
find_depth(manager_graph)


def main():
	n = int(input())
	e = [int(input()) for i in range(n)]
	r = 0
	for j in e:
		c = 1
		while j > 0:
			j = e[j - 1]
			c += 1
		r = max(c, r)
	print(r)
main()


t = int(input())
arr = [int(input()) for _ in range(t)]
ans = 0
for i in range(t):
	c = 0
	while i >= 0:
		i = arr[i] - 1
		c += 1
	ans = max(ans, c)
print(ans)


import sys
from collections import defaultdict

def stdinWrapper():
	data = '3\n2\n-1\n1\n'
	for line in data.split('\n'):
		yield line
if '--debug' not in sys.argv:

	def stdinWrapper():
		while True:
			yield input()
inputs = stdinWrapper()

def inputWrapper():
	return next(inputs)

def getType(_type):
	return _type(inputWrapper())

def getArray(_type):
	return [_type(x) for x in inputWrapper().split()]
cnt = getType(int)
relations = [x - 1 if x != -1 else x for x in [getType(int) for _ in range(cnt)]]
groups = defaultdict(int)
deepestCount = [0] * cnt
for (i, rel) in enumerate(relations):
	if rel != -1:
		_pos = rel
		deep = 1
		while _pos != -1:
			deepestCount[_pos] = max(deepestCount[_pos], deep)
			_pos = relations[_pos]
			deep += 1
print(len(set(deepestCount)))


n = int(input())
p = []
h = [0] * n
for i in range(n):
	p.append(int(input()) - 1)
for i in range(n):
	teck = i
	while p[teck] != -2:
		nex = p[teck]
		h[nex] = max(h[nex], h[teck] + 1)
		teck = nex
print(max(h) + 1)


N = 2005
g = list(())
n = int(input())
visited = [0 for x in range(N)]
h = [N for x in range(N)]
ans = 0
q = list(())
for i in range(n):
	g.append(list())
for i in range(n):
	p = int(input())
	if p == -1:
		h[i] = 1
		q.append(i)
	else:
		p -= 1
		g[p].append(i)
while len(q) > 0:
	u = q[0]
	q.pop(0)
	for v in g[u]:
		if h[v] > h[u] + 1:
			h[v] = h[u] + 1
			q.append(v)
for i in range(n):
	ans = max(ans, h[i])
print(ans)


from collections import defaultdict
import sys
sys.setrecursionlimit(10 ** 4)
n = int(input())
managers = [int(input()) for _ in range(n)]
depths = [0] * n

def get_depth(emp):
	if depths[emp]:
		return depths[emp]
	if managers[emp] >= 0:
		depths[emp] = get_depth(managers[emp] - 1) + 1
	else:
		depths[emp] = 1
	return depths[emp]
for emp in range(n):
	get_depth(emp)
print(max(depths))


n = int(input())
list = []
for i in range(n):
	list.append(int(input()))
ans = 0
for i in range(n):
	cur = list[i]
	count = 1
	while cur != -1:
		cur = list[cur - 1]
		count += 1
	ans = max(ans, count)
print(ans)


from collections import defaultdict as DD
G = DD(list)

def AE(G, u, v):
	G[u].append(v)
n = int(input())
for i in range(n):
	x = int(input())
	if x != -1:
		AE(G, x, i + 1)
	else:
		AE(G, 0, i + 1)

def BFS(G, s):
	V = [0 for i in range(n + 1)]
	D = [0 for i in range(n + 1)]
	Q = []
	Q.append(s)
	V[s] = 1
	D[s] = 0
	while Q:
		s = Q.pop(0)
		for i in G[s]:
			if V[i] == 0:
				Q.append(i)
				V[i] = 1
				D[i] = D[s] + 1
	return max(D)
print(BFS(G, 0))


n = int(input())
a = [int(input()) for i in range(n)]
ans = 0
for i in range(n):
	ceng = 1
	q = a[i]
	while q != -1:
		ceng += 1
		q = a[q - 1]
	ans = max(ans, ceng)
print(ans)


n = int(input())
e = {}
for i in range(n):
	e[i + 1] = int(input())
m = 0
for i in range(1, n + 1):
	lvl = 0
	if e[i] != -1:
		c = e[i]
		while c != -1:
			lvl += 1
			c = e[c]
	if lvl > m:
		m = lvl
print(m + 1)


from collections import defaultdict, deque
n = int(input())
adj = defaultdict(list)
depth = [0 for _ in range(n + 1)]
for i in range(1, n + 1):
	temp = int(input())
	adj[temp].append(i)

def bfs(src, vis):
	q = deque()
	q.append(src)
	depth[src] = 0
	vis.add(src)
	while q:
		curr = q.popleft()
		for child in adj[curr]:
			if child not in vis:
				depth[child] = depth[curr] + 1
				vis.add(child)
				q.append(child)
vis = set()
bfs(-1, vis)
print(max(depth))


n = int(input())
p = [0] * n
for i in range(0, n):
	p[i] = int(input())
	p[i] -= 1
mx = 0
for i in range(n):
	j = i
	k = 0
	while j != -2:
		j = p[j]
		k += 1
	mx = max(mx, k)
print(mx)


from collections import defaultdict
n = int(input())
parent = []
nodes = defaultdict(lambda : [])
i = 1
while i <= n:
	num = int(input())
	if num == -1:
		parent.append(i)
	else:
		nodes[num].append(i)
	i += 1

def height(root):
	node_queue = [root]
	height = 0
	while True:
		nodecount = len(node_queue)
		if nodecount == 0:
			return height
		else:
			height += 1
		while nodecount > 0:
			first = node_queue.pop(0)
			for x in nodes[first]:
				node_queue.append(x)
			nodecount -= 1
count_list = []
for i in parent:
	count_list.append(height(i))
print(max(count_list))


n = int(input())
m = 1
res = 1
x = [0]
for i in range(n):
	a = int(input())
	x.append(a)
for i in range(1, n + 1):
	m = 1
	q = x[i]
	while q != -1:
		q = x[q]
		m += 1
	res = max(m, res)
print(res)


n = int(input())
p = []
for i in range(n):
	p.append(int(input()))
r = 0
for i in range(n):
	t = 0
	while i >= 0:
		i = p[i] - 1
		t += 1
	r = max(r, t)
print(r)


from sys import setrecursionlimit
setrecursionlimit(1000000)
n = int(input())
used = [0] * n
graph = [[] for x in range(n)]
ans = 0

def dfs(v, deep):
	global ans
	if deep > ans:
		ans = deep
	used[v] = 1
	for nextv in graph[v]:
		if used[nextv] == 1:
			continue
		dfs(nextv, deep + 1)
for i in range(n):
	v = int(input())
	v -= 1
	if v >= 0:
		graph[v].append(i)
	else:
		used[i] = 2
for i in range(n):
	if used[i] == 2:
		dfs(i, 1)
print(ans)


n = int(input())
company = {}
arr = []
for i in range(n):
	a = int(input())
	if a == -1:
		arr.append(i + 1)
	company.update([(i + 1, a)])
arr_final = []
groups = 1
arr_new = []
while len(arr_final) + len(arr) + len(arr_new) < n:
	for i in range(1, n + 1):
		if company[i] in arr:
			arr_new.append(i)
			add = 1
	arr_final.extend(arr)
	arr = arr_new
	arr_new = []
	groups += add
print(groups)


n = int(input())
m = {}
t = []
for i in range(1, n + 1):
	p = int(input())
	if p != -1:
		m[p] = m.get(p, []) + [i]
	else:
		t.append(i)

def height(p):
	deeper = 0
	for e in m.get(p, []):
		d = height(e)
		if deeper < d:
			deeper = d
	return deeper + 1
res = 0
for r in t:
	h = height(r)
	if res < h:
		res = h
print(res)


import sys
from collections import deque

class Graph(object):

	def __init__(self, n):
		self.root = []
		self.adj = {}
		self.make_adj(n)

	def make_adj(self, n):
		for i in range(1, n + 1):
			self.adj[i] = []

	def adj_list(self, u):
		return self.adj[u]

class BFSResult:

	def __init__(self):
		self.level = {}
		self.parent = {}
		self.max_level = None

def bfs(g, s, r):
	r.parent[s] = None
	r.level[s] = 0
	queue = deque()
	queue.append(s)
	while queue:
		u = queue.popleft()
		for n in g.adj_list(u):
			if n not in r.level:
				r.parent[n] = u
				r.level[n] = r.level[u] + 1
				r.max_level = r.level[u] + 1
				queue.append(n)
n = int(input().rstrip())
g = Graph(n)
i = 1
r = BFSResult()
for _ in range(n):
	u = int(input().rstrip())
	if u == -1:
		g.root.append(i)
	else:
		g.adj[u].append(i)
	i += 1
for s in g.root:
	bfs(g, s, r)
max_l = 0
for i in r.level:
	if r.level[i] > max_l:
		max_l = r.level[i]
if max_l == 0:
	print(1)
else:
	print(max_l + 1)


n = int(input())
teams = [()] * (n + 1)
heads = list()
c = 0
for i in range(1, n + 1):
	x = int(input())
	if x == -1:
		heads.append(i)
	elif teams[x]:
		teams[x].append(i)
	else:
		teams[x] = [i]
while heads:
	heads = [j for i in heads for j in teams[i]]
	c += 1
print(c)


n = int(input())
l = [int(input()) for i in range(n)]
m = 0
for i in range(len(l)):
	j = i
	ans = 0
	while l[j] != -1:
		ans += 1
		j = l[j] - 1
	m = max(m, ans)
print(m + 1)


n = int(input())
arr = [0] * n
cont = 1
for i in range(n):
	p = int(input())
	arr[i] = p
for i in range(n):
	if arr[i] != -1:
		arr[i] -= 1
for i in range(n):
	(val1, val2) = (i, 1)
	while arr[val1] != -1:
		val2 += 1
		val1 = arr[val1]
	cont = max(cont, val2)
print(cont)


from collections import defaultdict, deque

def construct_graphs(n, array):
	graph_dict = defaultdict(list)
	level_dict = dict()
	sources = []
	for (idx, superior_num) in enumerate(array):
		if superior_num > 0:
			graph_dict[superior_num - 1].append(idx)
		else:
			sources.append(idx)
	return (sources, graph_dict)

def DFS(sources, graph_dict):
	heights = []
	for source in sources:
		level_dict = dict()
		level_dict[source] = 1
		max_height = 1
		queue = deque()
		queue.append(source)
		while len(queue) != 0:
			node = queue.popleft()
			for employee in graph_dict[node]:
				max_height = level_dict[node] + 1
				level_dict[employee] = max_height
				queue.append(employee)
		heights.append(max_height)
	return max(heights)
n = int(input())
array = []
for __ in range(n):
	array.append(int(input()))
(sources, graph_dict) = construct_graphs(n, array)
print(DFS(sources, graph_dict))


def dfs(graph, start=0):
	n = len(graph)
	dp = [0] * n
	(visited, finished) = ([False] * n, [False] * n)
	stack = [start]
	while stack:
		start = stack[-1]
		if not visited[start]:
			visited[start] = True
			for child in graph[start]:
				if not visited[child]:
					stack.append(child)
		else:
			stack.pop()
			dp[start] += 1
			for child in graph[start]:
				if finished[child]:
					dp[start] += dp[child]
			finished[start] = True
	return (visited, dp)
n = int(input())
arr = [[] for i in range(n)]
for i in range(n):
	x = int(input())
	if x != -1:
		arr[i].append(x - 1)
maxi = 0
for i in range(n):
	maxi = max(maxi, max(dfs(arr, i)[1]))
print(maxi)


(n, k) = (int(input()), 0)
a = [[] for i in range(n + 1)]
r = []
for i in range(1, n + 1):
	g = int(input())
	if g > 0:
		a[g] += [i]
	else:
		r += [i]
while r:
	r = [j for i in r for j in a[i]]
	k += 1
print(k)


import sys
import math
n = int(input())
par = [int(input()) for i in range(n)]
q = []
g = [[] for i in range(n)]
for i in range(n):
	if par[i] == -1:
		q.append((i, 1))
	else:
		g[par[i] - 1].append(i)
l = 0
while l < len(q):
	(a, b) = q[l]
	for i in g[a]:
		q.append((i, b + 1))
	l += 1
print(q[-1][1])


n = int(input())
a = []
for i in range(n):
	a.append(int(input()) - 1)
ans = 0
for i in range(len(a)):
	L = 0
	while i > -2:
		i = a[i]
		L += 1
	ans = max(ans, L)
print(ans)


n = int(input())
children = [[] for _ in range(n + 1)]
for x in range(1, n + 1):
	y = int(input())
	if y == -1:
		children[0].append(x)
	else:
		children[y].append(x)
from collections import deque
Q = deque()
Q.append((0, 0))
maxL = 0
while Q:
	(x, lx) = Q.popleft()
	if lx > maxL:
		maxL = lx
	for y in children[x]:
		Q.append((y, lx + 1))
print(maxL)


l = []
ans = 0
n = int(input())
for i in range(n):
	p = int(input())
	l.append(p - 1)
for j in range(n):
	cnt = 0
	x = l[j]
	while x != -2:
		x = l[x]
		cnt += 1
	ans = max(ans, cnt)
print(ans + 1)


t = int(input())
c = [int(input()) for _ in range(t)]
v = [[] for _ in range(t + 1)]
for i in range(t):
	if c[i] == -1:
		v[0].append(i + 1)
	else:
		v[c[i]].append(i + 1)
s = [(val, 1) for val in v[0]]
m = 0
while s:
	cur = s.pop()
	m = max(cur[1], m)
	for n in v[cur[0]]:
		s.append((n, cur[1] + 1))
print(m)


from math import *
from collections import *
from random import *
from bisect import *
import sys
input = sys.stdin.readline
t = 1

def bfs(deg, vis, cur, pa):
	qu = deque([])
	qu.append([cur, pa])
	while qu:
		x = qu.popleft()
		vis[x[0]] = 1
		dis[x[0]] += dis[x[1]] + 1
		for i in deg[x[0]]:
			if vis[i] == 1:
				continue
			qu.append([i, x[0]])
while t:
	t -= 1
	n = int(input())
	deg = [[] for i in range(n + 1)]
	ance = [[] for i in range(n + 1)]
	for i in range(n):
		x = int(input())
		if x == -1:
			continue
		deg[i + 1].append(x)
		deg[x].append(i + 1)
		ance[i + 1].append(x)
	dis = [0 for i in range(n + 1)]
	vis = [0 for i in range(n + 1)]
	for i in range(1, n + 1):
		if vis[i] == 0:
			pa = i
			while len(ance[pa]) != 0:
				pa = ance[pa][0]
			bfs(deg, vis, pa, 0)
	print(max(dis))


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
sys.setrecursionlimit(int(pow(10, 6)))
mod = int(pow(10, 9) + 7)
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def l():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
t = 1
for _ in range(t):
	n = l()[0]
	A = [l()[0] for i in range(n)]
	maxdepth = 0
	for i in range(n):
		currdepth = 1
		curr = i
		while A[curr] != -1:
			curr = A[curr] - 1
			currdepth += 1
		maxdepth = max(maxdepth, currdepth)
	print(maxdepth)


def Max(D):
	res = 0
	for k in D.keys():
		if len(D[k]) == 0:
			res = max(1, res)
		else:
			res = max(res, 1 + height(D, k))
	return res

def height(D, k):
	if k not in D:
		return 0
	if len(D[k]) == 0:
		return 1
	Max = 0
	for y in D[k]:
		c = 1
		if y in D:
			c += height(D, y)
		Max = max(Max, c)
	return Max
n = int(input())
D = {}
for i in range(1, n + 1):
	x = int(input())
	if x == -1:
		if i not in D:
			D[i] = []
	elif x in D:
		D[x].append(i)
	else:
		D[x] = [i]
print(Max(D))


from collections import defaultdict
n = int(input())
graph = defaultdict(lambda : [])

def findheight(x):
	ans = 0
	for i in graph[x]:
		ans = max(ans, findheight(i))
	return ans + 1
for i in range(n):
	x = int(input())
	if x != -1:
		graph[x].append(i + 1)
key = list(graph.keys())
if key == []:
	print('1')
else:
	ans = 0
	for i in key:
		ans = max(ans, findheight(i))
	print(ans)


n = int(input())
a = [1] * (n + 1)
childs = [[] for i in range(n + 1)]

def update(n):
	for i in childs[n]:
		a[i] = a[n] + 1
		if len(childs[i]) != 0:
			update(i)
for i in range(1, n + 1):
	parent = int(input())
	if parent != -1:
		a[i] = a[parent] + 1
		if len(childs[i]) != 0:
			update(i)
		childs[parent].append(i)
print(max(a))


ans = -1
g = {}
a = int(input())
for i in range(1, a + 1):
	g[i] = []
for i in range(a):
	b = int(input())
	if b != -1:
		g[b].append(i + 1)
for i in range(1, a + 1):
	visited = [False] * (a + 1)
	dist = [10000] * (a + 1)
	v = [i]
	dist[i] = 0
	while v:
		a1 = v.pop()
		if not visited[a1]:
			visited[a1] = True
			for i in g[a1]:
				v += g[a1]
				dist[i] = min(dist[i], dist[a1] + 1)
	quant = max([e for e in dist if e < 10000]) + 1
	ans = max(ans, quant)
print(ans)


n = int(input())
line = list()
for i in range(n):
	line.append(int(input()))
note = list()
for i in range(n):
	num = 1
	idx = line[i] - 1
	while idx >= 0:
		num += 1
		idx = line[idx] - 1
	note.append(num)
print(max(note))


def height(start, tree):
	height = 1
	while tree[start] != -1:
		height += 1
		start = tree[start]
	return height
n = int(input())
managers = {}
for i in range(n):
	managers[i + 1] = int(input())
max_height = 1
for i in range(1, n + 1):
	max_height = max(max_height, height(i, managers))
print(max_height)


n = int(input())
m = [[None, []] for i in range(n)]
l = 0
for i in range(n):
	x = int(input())
	if x == -1:
		pass
	else:
		m[i][0] = x
		m[x - 1][1].append(i + 1)
for t in m:
	if t[1] == []:
		h = 0
		c = t
		while c[0] != None:
			h = h + 1
			c = m[c[0] - 1]
		if h > l:
			l = h
print(l + 1)


n = int(input())
pi = [int(input()) for i in range(n)]
ans = 1
for i in range(n):
	if pi[i] == -1:
		continue
	num = pi[i]
	temp = 1
	while pi[num - 1] != -1:
		temp += 1
		num = pi[num - 1]
	ans = max(ans, temp + 1)
print(ans)


n = int(input())
q = n
p = []
g = 0
while q > 0:
	w = int(input())
	p.append(w)
	q = q - 1
for i in range(len(p)):
	x = 1
	while p[i] != -1:
		x = x + 1
		i = p[i] - 1
	g = max(g, x)
print(g)


n = int(input())
l1 = []
i = 0
while i < n:
	l1.append([int(input())])
	i += 1
i = 0
while i < len(l1):
	targ = l1[i][0]
	while targ != -1:
		l1[i].append(targ)
		l1[targ - 1].append(i + 1)
		targ = l1[targ - 1][0]
	i += 1
i = 0
tables = [[]]
while i < n:
	j = 0
	while j < len(tables):
		ruined = 0
		for x in tables[j]:
			if x in l1[i]:
				ruined = 1
				break
		if ruined:
			j += 1
		else:
			tables[j].append(i + 1)
			break
	if j == len(tables):
		tables.append([i + 1])
	i += 1
print(len(tables))


import sys
import math

def dfs(graph, start):
	stack = [start]
	c = 0
	while stack:
		vertex = stack.pop()
		c += 1
		stack.extend(graph[vertex])
	return c
n = int(input())
d = []
for i in range(n + 1):
	d.append(set())
vmax = 0
for i in range(1, n + 1):
	v = int(input())
	if v != -1:
		d[i].add(v)
for i in range(1, n + 1):
	k = dfs(d, i)
	if k > vmax:
		vmax = k
print(vmax)


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, random, time, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
eps = 1.0 / 10 ** 10
mod = 10 ** 9 + 7
dd = [(-1, 0), (0, 1), (1, 0), (0, -1)]
ddn = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

def I():
	return int(sys.stdin.readline())

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

def main():
	n = I()
	p = [I() for _ in range(n)]
	fm = {}
	fm[-1] = 0

	def f(i):
		if i in fm:
			return fm[i]
		t = f(p[i - 1]) + 1
		fm[i] = t
		return t
	r = 0
	for i in range(1, n + 1):
		t = f(i)
		if r < t:
			r = t
	return r
print(main())


from queue import Queue

class Node:

	def __init__(self, data):
		self.data = data
		self.color = None

	def __repr__(self):
		return str(self.data)

class Graph:

	def __init__(self, size):
		self.size = size
		self.adj_list = {}
		for i in range(size):
			self.adj_list[i] = []
		self.visited = [False for _ in range(self.size)]
		self.d2s = [0 for _ in range(self.size)]

	def add_edge(self, src, des):
		self.adj_list[src].append(des)

	def BFS(self, src):
		d2s = [-1 for i in range(self.size)]
		visited = [False for i in range(self.size)]
		d2s[src] = 0
		visited[src] = True
		queue = [src]
		while len(queue) != 0:
			u = queue.pop(0)
			for node in self.adj_list[u]:
				if not visited[node]:
					visited[node] = True
					d2s[node] = d2s[u] + 1
					queue.append(node)
		return d2s

	def DFS(self, src):
		stack = [src]
		while len(stack) != 0:
			u = stack.pop()
			self.visited[u] = True
			for node in self.adj_list[u]:
				if not self.visited[node]:
					self.visited[node] = True
					self.d2s[node] = self.d2s[u] + 1
					stack.append(node)
					self.DFS(node)
		return self.d2s

def main():
	n = int(input())
	g = Graph(n)
	roots = []
	doeb = []
	for i in range(n):
		u = int(input())
		if u != -1:
			g.add_edge(u - 1, i)
		else:
			roots.append(i)
	for n in roots:
		doeb.append(max(g.DFS(n)) + 1)
	print(max(doeb))
main()


import sys
input = sys.stdin.readline
from math import log2, log, ceil

def swaparr(arr, a, b):
	temp = arr[a]
	arr[a] = arr[b]
	arr[b] = temp

def gcd(a, b):
	if a == 0:
		return b
	return gcd(b % a, a)

def nCr(n, k):
	if k > n - k:
		k = n - k
	res = 1
	for i in range(k):
		res = res * (n - i)
		res = res / (i + 1)
	return res

def upper_bound(a, x, lo=0):
	hi = len(a)
	while lo < hi:
		mid = (lo + hi) // 2
		if a[mid] < x:
			lo = mid + 1
		else:
			hi = mid
	return lo

def primefs(n):
	primes = {}
	while n % 2 == 0:
		primes[2] = primes.get(2, 0) + 1
		n = n // 2
	for i in range(3, int(n ** 0.5) + 2, 2):
		while n % i == 0:
			primes[i] = primes.get(i, 0) + 1
			n = n // i
	if n > 2:
		primes[n] = primes.get(n, 0) + 1
	return primes

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def swap(a, b):
	temp = a
	a = b
	b = temp
	return (a, b)

def find(x, link):
	while x != link[x]:
		x = link[x]
	return x

def union(x, y, link, size):
	x = find(x, link)
	y = find(y, link)
	if size[x] < size[y]:
		(x, y) = swap(x, y)
	if x != y:
		size[x] += size[y]
		link[y] = x

def sieve(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime
MAXN = int(1000000.0 + 5)
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def find_parent(parent, i, cnt):
	cnt += 1
	if parent[i - 1] == i:
		return cnt
	if parent[i - 1] != i:
		find_parent(parent, parent[i - 1], cnt)
from collections import Counter
n = int(input())
p = [int(input()) for i in range(n)]
ans = 0
for i in range(n):
	cnt = 1
	var = p[i]
	while var != -1:
		var = p[var - 1]
		cnt += 1
	ans = max(ans, cnt)
print(ans)


import sys
from collections import defaultdict
sys.setrecursionlimit(5000)
global ans
ans = 0

def read():
	return sys.stdin.readline()

def longestpath(v, c):
	global ans
	visit[v] = True
	c += 1
	if ans <= c:
		ans = c
	for j in range(len(a[v])):
		if visit[a[v][j]] == False:
			longestpath(a[v][j], c)
n = int(read())
a = defaultdict(list)
visit = [False] * n
inp = []
for i in range(n):
	temp = int(read())
	inp.append(temp)
	if temp != -1:
		a[temp - 1].append(i)
for i in range(n):
	if inp[i] == -1:
		longestpath(i, 0)
print(ans)


def fun(arr, i):
	if arr[i] == -1:
		return 1
	else:
		return fun(arr, arr[i] - 1) + 1
n = int(input())
arr = list()
for i in range(n):
	arr.append(int(input()))
max1 = -1
for i in range(n):
	max1 = max(max1, fun(arr, i))
print(max1)


from collections import defaultdict
x = int(input())
dp = [0] * (x + 1)
vis = [1] * (x + 1)

def dfs(x, d):
	vis[x] = 0
	if len(d[x]) > 0:
		for i in d[x]:
			if vis[i]:
				dfs(i, d)
			dp[x] = max(dp[x], 1 + dp[i])
d = defaultdict(list)
for i in range(x):
	a = int(input())
	d[a].append(i + 1)
p = list(d.keys())
p.remove(-1)
for i in p:
	if vis[i]:
		dfs(i, d)
print(max(dp) + 1)


n = int(input())
ls = [0] * n
ans = 1
for i in range(n):
	ls[i] = int(input())
	if ls[i] != -1:
		ls[i] -= 1
for i in range(n):
	j = i
	cnt = 1
	while ls[j] != -1:
		cnt += 1
		j = ls[j]
	ans = max(ans, cnt)
print(ans)


n = int(input())
a = [0]
for i in range(1, n + 1):
	a.append(int(input()))
ans = 0
for i in range(1, n + 1):
	tmp = 0
	item = a[i]
	while item != -1:
		tmp += 1
		item = a[item]
	ans = max(ans, tmp)
print(ans + 1)


graph = {}
bosses = []
for i in range(int(input())):
	bosses.append(int(input()))
	graph[i + 1] = []
i = 0
while i < len(bosses):
	if bosses[i] != -1:
		graph[i + 1].append(bosses[i])
	i += 1
mx = 0
for key in graph.keys():
	dep = 1
	key2 = key
	while len(graph[key2]) > 0:
		dep += 1
		key2 = graph[key2][0]
	mx = max(dep, mx)
print(mx)


class CodeforcesTask115ASolution:

	def __init__(self):
		self.result = ''
		self.n = 0
		self.superior = []

	def read_input(self):
		self.n = int(input())
		for x in range(self.n):
			self.superior.append(int(input()))

	def process_task(self):
		graph = [[[], 1] for x in range(self.n)]
		for x in range(self.n):
			if self.superior[x] > 0:
				graph[self.superior[x] - 1][0].append(x + 1)
		for x in range(self.n):
			if graph[x][1] == 1:
				to_visit = [(y, graph[x][1] + 1) for y in graph[x][0]]
				while to_visit:
					visiting = to_visit.pop(-1)
					graph[visiting[0] - 1][1] = max(graph[visiting[0] - 1][1], visiting[1])
					for nxt in graph[visiting[0] - 1][0]:
						to_visit.append((nxt, visiting[1] + 1))
		levels = [x[1] for x in graph]
		self.result = str(max(levels))

	def get_result(self):
		return self.result
Solution = CodeforcesTask115ASolution()
Solution.read_input()
Solution.process_task()
print(Solution.get_result())


n = int(input())
arr = []
for i in range(n):
	arr.append(int(input()))

def count_lvl(idx):
	if stairs.get(idx, -2) != -2:
		return stairs[idx]
	elif arr[idx] == -1:
		stairs[idx] = 1
	else:
		stairs[idx] = stairs.get(arr[idx] - 1, count_lvl(arr[idx] - 1)) + 1
	return stairs[idx]
if len(arr) == 0:
	print(0)
else:
	stairs = {}
	levels = 1
	for (idx, i) in enumerate(arr):
		if stairs.get(idx, -2) != -2:
			curr_lvl = stairs.get(idx)
		elif i == -1:
			curr_lvl = 1
			stairs[idx] = 1
		else:
			curr_lvl = stairs.get(i - 1, count_lvl(i - 1)) + 1
			stairs[idx] = curr_lvl
		levels = max(levels, curr_lvl)
print(levels)


n = int(input())
a = [int(input()) for i in range(n)]
m = 0
for i in range(n):
	c = 0
	while i != -1:
		i = a[i - 1]
		c += 1
	m = max(c, m)
print(m)


x = int(input())
lis = []
lis.insert(0, -1)
for i in range(x):
	lis.append(int(input()))
c = 0
mx = 0
for i in lis:
	c = 0
	while i != -1:
		c += 1
		i = lis[i]
	mx = max(c, mx)
print(mx + 1)


n = int(input())
m = 1
l = []
for i in range(n):
	l.append(int(input()))
for i in range(n):
	p = 1
	r = l[i]
	while r != -1:
		r = l[r - 1]
		p += 1
	if p > m:
		m = p
print(m)


n = int(input())
mgrs = []
for i in range(n):
	mgrs.append(int(input()) - 1)
queue = []
subs = [[] for i in range(n)]
for i in range(n):
	mgr = mgrs[i]
	if mgr < 0:
		queue.append(i)
	else:
		subs[mgr].append(i)
depths = [1] * n
while len(queue) > 0:
	emp = queue.pop(0)
	for sub in subs[emp]:
		depths[sub] = depths[emp] + 1
		queue.append(sub)
print(max(depths))


n = int(input())
f = [int(input()) for i in range(n)]
g = [[] for i in range(n)]
q = []
for x in range(n):
	if f[x] == -1:
		q.append((x, 1))
	else:
		g[f[x] - 1].append(x)
l = 0
while l < len(q):
	(x, d) = q[l]
	for y in g[x]:
		q.append((y, d + 1))
	l += 1
print(q[-1][1])


import sys
sys.setrecursionlimit(100000)

def find(d, x):
	try:
		cnt = [1] * len(d[x])
		for i in range(len(d[x])):
			cnt[i] += find(d, d[x][i])
		return max(cnt)
	except KeyError:
		return 1
n = int(input())
d = {}
top = []
for i in range(n):
	p = int(input())
	if p == -1:
		top.append(i + 1)
	else:
		try:
			d[p].append(i + 1)
		except KeyError:
			d[p] = [i + 1]
m = [1]
for i in top:
	m.append(find(d, i))
print(max(m))


def BFS_level(vertex):
	s = [(vertex, 1)]
	while s:
		n = s.pop(0)
		for i in range(len(d[n[0]])):
			s.append((d[n[0]][i], n[1] + 1))
		if len(s) == 0 and len(d[n[0]]) == 0:
			return n[1]
n = int(input())
d = {i + 1: [] for i in range(n)}
roots = []
for i in range(1, n + 1):
	a = int(input())
	if a == -1:
		roots.append(i)
	else:
		d[a].append(i)
max_level = 0
for i in roots:
	w = BFS_level(i)
	if w > max_level:
		max_level = w
print(max_level)


n = int(input())
dic = {}
vis = []
count = 0
for i in range(n):
	vis.append(0)
	dic[i + 1] = int(input())
for i in range(n):
	if vis[i] == 1:
		continue
	else:
		g = 1
		src = i + 1
		vis[src - 1] = 1
		while dic[src] != -1:
			src = dic[src]
			vis[src - 1] = 1
			g += 1
		count = max(count, g)
print(count)


import sys
sys.setrecursionlimit(2500)
n = int(input())
adj = [[]] * (n + 1)
for i in range(n + 1):
	adj[i] = []
dep = [0] * (n + 1)
pred = [0] * (n + 1)
for i in range(1, n + 1):
	a = int(input())
	if a == -1:
		dep[i] = 0
	else:
		pred[i] = a
for i in range(1, n + 1):
	j = i
	while pred[j] != 0:
		dep[i] += 1
		j = pred[j]
print(max(dep) + 1)


import sys
sys.setrecursionlimit(3000)
n = int(input())
adj = [[] for _ in range(n)]
out = [None for _ in range(n)]
for i in range(n):
	x = int(input())
	if x != -1:
		x -= 1
		adj[x].append(i)

def dfs(i):
	if out[i] is not None:
		return out[i]
	if len(adj[i]) == 0:
		out[i] = 1
		return out[i]
	o = 1
	for neighbour in adj[i]:
		o = max(o, 1 + dfs(neighbour))
	return o
print(max(map(dfs, range(n))))


n = int(input())
par = [-1 for i in range(2001)]
for i in range(n):
	p = int(input())
	par[i] = p
	if p != -1:
		par[i] -= 1
top = 0
for i in range(2001):
	if par[i] == -1:
		continue
	depth = 0
	j = par[i]
	while j != -1:
		depth += 1
		j = par[j]
	top = max(top, depth)
print(top + 1)


n = int(input())
parent = [0] + [int(input()) for _ in range(n)]
ans = 0
for i in range(1, n + 1):
	x = i
	cur = 0
	while x != -1:
		cur += 1
		x = parent[x]
	ans = max(ans, cur)
print(ans)


n = int(input())
people = {}
k = 0
suma = 1
res = 0
for i in range(n):
	m = int(input())
	people[i + 1] = m
for i in range(n):
	k = i + 1
	while people[k] != -1:
		suma += 1
		k = people[k]
	if res < suma:
		res = suma
	suma = 1
print(res)


import math
import sys
p = [-1] * 5000
n = int(input())
f = -999999999
for i in range(0, n):
	x = int(input())
	p[i + 1] = x
for i in range(1, n + 1):
	y = i
	ans = 1
	while p[y] != -1:
		ans = ans + 1
		y = p[y]
	f = max(f, ans)
print(f)


n = int(input())
a = [-1] * n
for i in range(n):
	p = int(input())
	if p == -1:
		a[i] = -1
	else:
		a[i] = p - 1
maxi = 0
for num in a:
	c = num
	d = 0
	while num != -1:
		num = a[num]
		d += 1
	maxi = max(maxi, d)
print(maxi + 1)


n = int(input())
m = {}
h = 0
for i in range(1, n + 1):
	m[i] = [int(input()), set(), 0]
for i in range(1, n + 1):
	s = set()
	for j in range(1, n + 1):
		if m[j][0] == i:
			s.add(j)
	m[i][1] = s
for i in range(1, n + 1):
	if len(m[i][1]) == 0:
		c = 0
		m[i][2] = c
		j = m[i][0]
		while j > 0:
			c += 1
			m[j][2] = max(c, m[j][2])
			j = m[j][0]
for i in range(1, n + 1):
	h = max(h, m[i][2])
print(h + 1)


import collections

def do():
	n = int(input())
	res = 1
	ind = collections.defaultdict(int)
	graph = collections.defaultdict(list)
	stack = []
	for i in range(1, n + 1):
		m = int(input())
		if m != -1:
			graph[m].append(i)
			ind[i] += 1
	for i in range(1, n + 1):
		if ind[i] == 0:
			stack.append([i, 1])
	while stack:
		(cur, l) = stack.pop()
		res = max(res, l)
		for nei in graph[cur]:
			stack.append([nei, l + 1])
	return res
print(do())


from math import inf
n = int(input())
matrix = {}
for i in range(n):
	br = int(input())
	matrix[i] = br - 1
ans = -1 * inf
for i in range(n):
	cnt = 1
	p = i
	while matrix[p] != -2:
		p = matrix[p]
		cnt += 1
	if cnt > ans:
		ans = cnt
print(ans)


from sys import stdin
input = lambda : stdin.readline().strip()
from math import ceil, sqrt, factorial, gcd

class Node:

	def __init__(self):
		self.status = 0
		self.child = set()

def height(a):
	if len(l[a].child) == 0:
		return 1
	z = []
	for i in l[a].child:
		z.append(height(i))
	return max(z) + 1
n = int(input())
l = {}
m = -100
for i in range(1, n + 1):
	l[i] = Node()
for i in range(1, n + 1):
	x = int(input())
	if x == -1:
		l[i].status = -1
	elif x in l:
		l[x].child.add(i)
q = 0
for i in l:
	if l[i].status == -1:
		m = max(height(i), m)
print(m)


n = int(input())
tab = [0] * n
for i in range(0, n):
	tab[i] = int(input()) - 1
x = 0
q = []
max = 0
state = [-10] * n
for i in range(0, len(tab)):
	depth = 1
	k = i
	while tab[k] != -2:
		if state[k] != -10:
			depth = depth + state[k] - 1
			break
		k = tab[k]
		depth = depth + 1
	state[i] = depth
	if max < depth:
		max = depth
print(str(max))


import sys
sys.setrecursionlimit(10 ** 6)
inf = float('inf')
mod = 1000000007

def get_array():
	return list(map(int, sys.stdin.readline().split()))

def get_ints():
	return map(int, sys.stdin.readline().split())

def input():
	return sys.stdin.readline()
visited = [False] * 2005
dist = [1] * 2005
graph = [[] for i in range(2005)]
root = []

def explore(node):
	visited[node] = True
	for child in graph[node]:
		if visited[child] == False:
			dist[child] = 1 + dist[node]
			explore(child)

def dfs(n):
	for i in root:
		if visited[i] == False:
			explore(i)

def main():
	n = int(input())
	for i in range(1, n + 1):
		x = int(input())
		if x != -1:
			graph[x].append(i)
		else:
			root.append(i)
	dfs(n)
	print(max(dist[1:n + 1]))
main()


import sys
sys.setrecursionlimit(10 ** 6)
n = int(input())
b = [False] * n

def dfs(graph, x, r):
	b[x] = True
	if len(graph[x]) == 1 and x != r:
		return 1
	if len(graph[x]) == 0:
		return 1
	vx = 0
	for i in graph[x]:
		if b[i] == False:
			vx = max(vx, dfs(graph, i, r))
	return vx + 1
graph = {k: [] for k in range(n)}
a = [0 for i in range(n)]
for i in range(n):
	x = int(input()) - 1
	a[i] = x
	if x != -2:
		graph[i].append(x)
		graph[x].append(i)
ans = 0
for i in range(n):
	if a[i] == -2:
		ans = max(ans, dfs(graph, i, i))
print(ans)


import sys
readline = sys.stdin.buffer.readline

def i1():
	return int(readline())

def nl():
	return [int(s) for s in readline().split()]

def nn(n):
	return [int(readline()) for i in range(n)]

def nlp(x):
	return [int(s) + x for s in readline().split()]

def nll(n):
	return [[int(s) for s in readline().split()] for i in range(n)]

def mll(n):
	return ([int(s) for s in readline().split()] for i in range(n))

def s1():
	return readline().rstrip()

def sn(n):
	return [readline().rstrip() for i in range(n)]

def sm(n):
	return (readline().rstrip() for i in range(n))

def redir(s):
	global readline
	import os
	fn = sys.argv[0] + f'/../in-{s}.txt'
	readline = open(fn).readline if os.path.exists(fn) else readline
redir('a')
n = i1()
parents = [int(s) - 1 for s in sm(n)]
maxdepth = 1
for i in range(n):
	depth = 1
	i = parents[i]
	while i >= 0:
		depth += 1
		i = parents[i]
	if depth > maxdepth:
		maxdepth = depth
print(maxdepth)


import sys
import collections
import math
import random

def f1():
	return int(sys.stdin.readline().strip())

def f2():
	return map(int, sys.stdin.readline().strip().split())

def f3():
	return list(map(int, sys.stdin.readline().strip().split()))

def f4():
	return sys.stdin.readline().strip()

def f5():
	return list(map(str, sys.stdin.readline().strip().split()))

def bfs(n, graph):
	maxDepth = 0
	if graph is None or len(graph) == 0:
		return maxDepth
	for j in range(1, n + 1):
		queue = collections.deque([(j, 1)])
		while queue:
			(currentNode, currentLevel) = queue.popleft()
			maxDepth = max(maxDepth, currentLevel)
			if currentNode in graph:
				for node in graph[currentNode]:
					queue.append((node, currentLevel + 1))
	return maxDepth
n = f1()
adjacencyList = collections.defaultdict(list)
for i in range(n):
	p = f1()
	adjacencyList[p].append(i + 1)
print(bfs(n, adjacencyList))


import sys
sys.setrecursionlimit(10 ** 8)

def find(g, i, f):
	m = 0
	for j in g[i]:
		if f[j] == 0:
			m = max(m, find(g, j, f))
			f[j] = 1
	return m + 1
from collections import defaultdict as dc
n = int(input())
g = dc(list)
x = []
for i in range(n):
	p = int(input())
	if p == -1:
		x.append(i + 1)
	else:
		g[p].append(i + 1)
m = 1
f = [0] * (n + 1)
for i in x:
	if f[i] == 0:
		f[i] = 1
		m = max(m, find(g, i, f))
print(m)


n = int(input())
pt = []
a = [[] for i in range(n + 1)]
start = [0] * (n + 1)
incoming = []
for i in range(n):
	x = int(input())
	if x != -1:
		a[x].append(i + 1)
		start[i + 1] = 1
for i in range(1, n + 1):
	if start[i] == 0:
		incoming.append(i)
h = [0] * (n + 1)
vis = [0] * (n + 1)
ans = 0
for i in incoming:
	if vis[i] == 0:
		st = [i]
		vis[i] = 1
		while st:
			p = st.pop(0)
			for j in a[p]:
				if vis[j] == 0:
					vis[j] = 1
					st.append(j)
					h[j] = h[p] + 1
print(max(h) + 1)


def get_depth(sup, i):
	if sup[i] == -1:
		return 0
	else:
		return 1 + get_depth(sup, sup[i])
n = int(input())
sup = [0] * 2001
for i in range(1, n + 1):
	sup[i] = int(input())
C = [0] * 2001
depth = [-1] * 2001
for i in range(1, n + 1):
	depth[i] = get_depth(sup, i)
	C[depth[i]] += 1
groups = 0
for d in range(2001):
	if C[d] > 0:
		groups += 1
print(groups)


from collections import defaultdict

class Main:

	def __init__(self):
		self.x = defaultdict(list)

	def addition(self, a, b):
		self.x[a].append(b)

	def f1(self, start, n, distance, visited):
		q = []
		q.append(start)
		visited[start] = 1
		distance[start] = 1
		while q:
			start = q.pop(0)
			for i in self.x[start]:
				q.append(i)
				visited[i] = 1
				if distance[start] + 1 > distance[i]:
					distance[i] = distance[start] + 1
n = int(input())
g = Main()
for i in range(n):
	u = int(input()) - 1
	if u != -2:
		g.addition(u, i)
distance = [0] * n
visited = [0] * n
for i in range(n):
	if visited[i] == 0:
		g.f1(i, n, distance, visited)
print(max(distance))


class Node(object):

	def __init__(self, parent=None):
		self.parent = parent
n = int(input())
Nodes = []
for i in range(n):
	k = int(input())
	if k == -1:
		new = Node()
		Nodes.append(new)
	else:
		new = Node(k - 1)
		Nodes.append(new)
max_length = 1
for i in range(n):
	length = 1
	temp = Nodes[i]
	while temp.parent != None:
		length += 1
		temp = Nodes[temp.parent]
	max_length = max(max_length, length)
print(max_length)


n = int(input())
l = []
for i in range(n):
	x = int(input())
	l.append(x)
ans = 1
for i in range(n):
	if l[i] != -1:
		k = i
		c = 1
		while l[k] != -1:
			k = l[k] - 1
			c += 1
		ans = max(ans, c)
print(ans)


n = int(input())
l = [int(input()) for i in range(n)]
ans = 0
for i in range(n):
	c = 0
	while i >= 0:
		i = l[i] - 1
		c += 1
	ans = max(ans, c)
print(ans)


n = int(input().strip())
p = [None] * (n + 1)
for i in range(1, n + 1):
	p[i] = int(input().strip())
m = -1
for i in range(1, n + 1):
	v = p[i]
	curr_len = 1
	curr = v
	while curr != -1:
		curr = p[curr]
		curr_len += 1
	m = max(m, curr_len)
print(m)


from sys import stdin

class Node:

	def __init__(self):
		self.val = 1
		self.parent = None
n = int(stdin.readline())
a = [Node() for _ in range(n)]
res = 1
for i in range(n):
	t = int(stdin.readline())
	if t != -1:
		a[i].parent = a[t - 1]
		a[i].val = a[t - 1].val + 1
		res = max(res, a[i].val)
changed = True
while changed:
	changed = False
	for i in range(n):
		if a[i].parent is not None and a[i].val != a[i].parent.val + 1:
			a[i].val = a[i].parent.val + 1
			res = max(res, a[i].val)
			changed = True
print(res)


from collections import deque
n = int(input())
d = deque()
vertexes = []
for i in range(n):
	vertexes.append([])
for i in range(n):
	parent = int(input())
	if parent == -1:
		d.append((i, 1))
	else:
		parent -= 1
		vertexes[parent].append(i)
ans = 0
while d:
	(at, now_h) = d.pop()
	ans = max(ans, now_h)
	for i in vertexes[at]:
		d.append((i, now_h + 1))
print(ans)


n = int(input())
employee = [0]
team = 0
totalTeam = 0
for i in range(0, n):
	employee.append(int(input()))
for i in range(1, n + 1):
	j = i
	tmp = 1
	while employee[j] != -1:
		tmp += 1
		j = employee[j]
	if tmp > team:
		team = tmp
print(team)


from collections import deque
num_emps = int(input())
emp_managers = [int(input()) for x in range(num_emps)]
emp_tree = []
root_nodes = []
for i in range(len(emp_managers)):
	emp_tree.append({'value': i + 1, 'children': []})
for i in range(len(emp_managers)):
	if emp_managers[i] != -1:
		emp_tree[emp_managers[i] - 1]['children'].append(i)
	else:
		root_nodes.append(i)

def depth(root_node):
	depth = 0
	q = deque([root_node])
	child_count = 1
	next_row_count = 0
	while q:
		node = q.popleft()
		child_count -= 1
		q += emp_tree[node]['children']
		next_row_count += len(emp_tree[node]['children'])
		if child_count == 0:
			depth += 1
			child_count = next_row_count
			next_row_count = 0
	return depth
max_depth = max([depth(node) for node in root_nodes])
print(max_depth)


def solution(arr):
	res = 1
	manager = {}
	for (i, managerId) in enumerate(arr):
		employeeId = i + 1
		manager[employeeId] = managerId
	for employeeId in manager:
		chainLength = 1
		while manager[employeeId] != -1:
			chainLength += 1
			employeeId = manager[employeeId]
		res = max(res, chainLength)
	return res
n = int(input())
arr = []
for i in range(n):
	arr.append(int(input()))
print(solution(arr))


def solve(graph):
	n = len(graph)
	heigths = [-1 for x in range(n)]
	for i in range(n):
		if graph[i] == -1:
			heigths[i] = 0
			heigth(graph, heigths, n, i)
	return max(heigths) + 1

def heigth(graph, heigths, n, v):
	for w in range(n):
		if graph[w] == v:
			heigths[w] = heigths[v] + 1
			heigth(graph, heigths, n, w)
n = int(input())
a = [-1 for x in range(n)]
for i in range(n):
	m = int(input())
	if m != -1:
		a[i] = m - 1
print(solve(a))


n = int(input())
employees = [i for i in range(n)]
rank_log = []
ret = 1
for i in range(n):
	rank_log.append(int(input()))
for i in range(n):
	running_max = 1
	cur = rank_log[i]
	while cur != -1:
		cur = rank_log[cur - 1]
		running_max += 1
	ret = max(ret, running_max)
print(ret)


__author__ = 'Utena'
from collections import deque
n = int(input())
manage = [[] for i in range(n + 1)]
root = []
superior = [0] * (n + 1)
temp = deque()
for i in range(1, n + 1):
	s = int(input())
	if s > 0:
		manage[s].append(i)
	else:
		root.append(i)
		superior[i] = 1
for a in root:
	temp.append(a)
while temp != deque([]):
	q = temp.popleft()
	for c in manage[q]:
		temp.append(c)
		superior[c] = superior[q] + 1
print(max(superior))


n = int(input())
vn = list()
for a in range(n):
	vn.append(int(input()))
cmax = 0
for a in vn:
	t = a
	c = 0
	while t != -1:
		c += 1
		t = vn[t - 1]
	cmax = max(cmax, c)
print(cmax + 1)


from collections import defaultdict
ans = 0
used = [False] * 2002
adj = defaultdict(list)
start = [0] * 2002

def dfs(src, d):
	global used, ans
	used[src] = True
	if src in adj:
		for i in adj[src]:
			if not used[i]:
				dfs(i, d + 1)
	ans = max(ans, d)
n = int(input())
for i in range(1, n + 1):
	p = int(input())
	if p == -1:
		start[i] = 1
	else:
		adj[p].append(i)
for i in range(1, n + 1):
	if start[i]:
		dfs(i, 1)
print(ans)


n = int(input())
maior = 0
empregados = [int(input()) for _ in range(n)]
for i in range(len(empregados)):
	atual = empregados[i]
	taman = 1
	while atual != -1:
		atual = empregados[atual - 1]
		taman += 1
	maior = max(maior, taman)
print(maior)


n = int(input())
l = [int(input()) - 1 for i in range(n)]
cc = 0
for i in range(n):
	c = 0
	while i != -2:
		i = l[i]
		c += 1
	cc = max(c, cc)
print(cc)


employee = []
groups = 0
for i in range(int(input())):
	employee.append(int(input()))
for i in range(len(employee)):
	cont = 0
	j = employee[i]
	while j != -1:
		cont += 1
		j = employee[j - 1]
	groups = max(cont, groups)
print(groups + 1)


from queue import Queue

def minimun_groups(graph, ceos):
	depths = [0] * len(graph)
	queue = Queue()
	for ceo in ceos:
		queue.put(ceo)
		while not queue.empty():
			boss = queue.get()
			for employee in graph[boss]:
				depths[employee] = depths[boss] + 1
				queue.put(employee)
	print(len(set(depths)))

def main():
	total_employees = int(input())
	employees = []
	ceos = []
	for i in range(total_employees):
		employees.append(int(input()))
		if employees[i] == -1:
			ceos.append(i)
	graph = [[] for _ in employees]
	for (i, boss) in enumerate(employees):
		if boss != -1:
			graph[boss - 1] += [i]
	minimun_groups(graph, ceos)
main()


from collections import defaultdict
import sys
sys.setrecursionlimit(3000)

def trav(stack, levels, children, level):
	for i in stack:
		levels[i] = level
		trav(children[i], levels, children, level + 1)
N = int(input())
children = defaultdict(list)
levels = [0] * N
for i in range(N):
	par = int(input()) - 1
	children[par].append(i)
trav(children[-2], levels, children, 0)
print(max(levels) + 1)


import sys
sys.setrecursionlimit(10 ** 6)
MOD = 1000000007

def get_array():
	return list(map(int, sys.stdin.readline().split()))

def get_ints():
	return map(int, sys.stdin.readline().split())

def input():
	return sys.stdin.readline()

def print_array(a):
	print(' '.join(map(str, a)))
visited = [False] * 2005
dist = [1] * 2005
graph = [[] for i in range(2005)]
root = []

def explore(node):
	visited[node] = True
	for child in graph[node]:
		if visited[child] == False:
			dist[child] = 1 + dist[node]
			explore(child)

def dfs():
	for i in root:
		if visited[i] == False:
			explore(i)

def main():
	n = int(input())
	for i in range(1, n + 1):
		x = int(input())
		if x != -1:
			graph[x].append(i)
		else:
			root.append(i)
	dfs()
	print(max(dist[1:n + 1]))
main()


def dfs(node, fa, h):
	if h[node] != 0:
		return h[node]
	if fa[node] == -1:
		return 1
	h[node] = dfs(fa[node], fa, h) + 1
	return h[node]

def sol(n, fa):
	res = 1
	h = [0] * (n + 1)
	for i in range(1, n + 1):
		res = max(res, dfs(i, fa, h))
	return res
n = int(input())
fa = [0] * (n + 1)
for i in range(1, n + 1):
	fa[i] = int(input())
print(sol(n, fa))


def main():
	n = int(input())
	(cur, nxt, tail) = (set(), set(), [0])
	for i in range(1, n + 1):
		p = int(input())
		if p == -1:
			nxt.add(i)
			tail.append(0)
		else:
			tail.append(p)
	res = 1
	while any(tail):
		(cur, nxt) = (nxt, cur)
		nxt.clear()
		res += 1
		for (i, item) in enumerate(tail):
			if item in cur:
				nxt.add(i)
				tail[i] = 0
	print(res)
main()


def level(i):
	l = 0
	while i > 0:
		(i, l) = (G[i], l + 1)
	return l
(n, G) = (int(input()), {})
for i in range(1, n + 1):
	G[i] = int(input())
h = {i: level(i) for i in range(1, n + 1)}
print(max(h.values()))


class graph(object):

	def __init__(self, n):
		self.nodes = [i for i in range(1, n + 1)]
		self.sup = {}

	def addsup(self, a, b):
		self.sup[b] = a
n = int(input())
company = graph(n)
for b in range(1, n + 1):
	a = int(input())
	if a == -1:
		pass
	else:
		company.addsup(a, b)
longest = []
for i in company.nodes:
	if i in longest:
		continue
	current = [i]
	while current[-1] in company.sup:
		current.append(company.sup[current[-1]])
	if len(longest) < len(current):
		longest = current
print(len(longest))


nEmployees = int(input())
employees = []

def searchSuperior(indexEmployee, levels):
	global employees
	if employees[indexEmployee - 1] == -1:
		return levels
	return searchSuperior(employees[indexEmployee - 1], levels + 1)
for _ in range(nEmployees):
	employees.append(int(input()))
highest = 0
for i in range(nEmployees):
	aux = searchSuperior(i, 1)
	highest = aux if aux > highest else highest
print(highest)


from collections import deque
n = int(input())
depth = [1] * (n + 1)
result = [[] for i in range(n + 1)]
for i in range(n):
	tem = int(input())
	if tem == -1:
		result[0].append(i + 1)
	else:
		result[tem].append(i + 1)
search = deque(result[0])
while search:
	start = search.popleft()
	for i in result[start]:
		search.append(i)
		depth[i] = depth[start] + 1
group = max(depth)
print(group)


def dfs(x, cnt):
	global m
	if m < cnt:
		m = cnt
	for i in l[x]:
		dfs(i, cnt + 1)
n = int(input())
l = [set() for i in range(n)]
l1 = []
m = 0
for i in range(n):
	a = int(input())
	if a != -1:
		l[a - 1].add(i)
	else:
		l1.append(i)
for i in l1:
	dfs(i, 0)
print(m + 1)


from collections import defaultdict, deque
g = defaultdict(list)
arr = []
n = int(input())
for i in range(n):
	p = int(input())
	if p != -1:
		g[i + 1].append(p)
		g[p].append(i + 1)
	else:
		arr.append(i + 1)
res = 1
for item in arr:
	v = [False] * (n + 1)
	ans = 0
	q = deque()
	q.append([item, 0])
	v[item] = True
	prev = -1
	while len(q) > 0:
		t = q.popleft()
		if prev != t[1]:
			prev = t[1]
			ans = ans + 1
		for child in g[t[0]]:
			if v[child] == False:
				v[child] = True
				q.append([child, prev + 1])
	res = max(res, ans)
print(res)


import sys
sys.setrecursionlimit(2000)

def dfs(i, comp, memo):
	if comp[i] == -1:
		memo[i] = 1
		return memo[i]
	if memo[i]:
		return memo[i]
	else:
		memo[i] = 1 + dfs(comp[i], comp, memo)
		return memo[i]
n = int(input())
comp = [-1] * (n + 1)
for i in range(1, n + 1):
	comp[i] = int(input())
memo = [0] * (n + 1)
res = max([dfs(i, comp, memo) for i in range(1, n + 1)])
print(res)


import sys
sys.setrecursionlimit(10000)

class Node:

	def __init__(self, val, children):
		self.val = val
		self.children = children
n = int(input())
list_of_edges = []
for i in range(n + 1):
	list_of_edges.append([])
for b in range(n):
	a = int(input())
	if a == -1:
		a = 0
	list_of_edges[a].append([a, b + 1])
tree = Node(0, {})

def build(set_of_edges, node, parent, tree_graph):
	for pair in set_of_edges[node]:
		child = pair[1]
		tree_graph.children[child] = Node(child, {})
		build(set_of_edges, child, node, tree_graph.children[child])
	return tree
build(list_of_edges, 0, 0, tree)
largest = 0

def dfs(tree_graph, node, depth):
	ans = 0
	if tree_graph.children == {}:
		ans = max(ans, depth)
	for child in tree_graph.children:
		ans = max(ans, dfs(tree_graph.children[child], child, depth + 1))
	return ans
print(dfs(tree, 0, 1) - 1)


N = int(input())
ls = []
ns = []
for i in range(N):
	ls.append(int(input()) - 1)
	ns.append([])
try:
	for i in range(N):
		if ls[i] < 0:
			continue
		ns[ls[i]].append(i)
except:
	print(0)
try:
	deps = [-1] * N

	def consTree(root, dep):
		stacks = [(root, dep)]
		while stacks:
			(root, dep) = stacks.pop()
			deps[root] = dep
			for i in ns[root]:
				stacks.append((i, dep + 1))
except:
	print(1)
try:
	for i in range(N):
		if ls[i] < 0:
			consTree(i, dep=1)
except:
	print(2)
print(max(deps))


n = int(input())
graph = [[] for i in range(n)]
su = []
inp = [int(input()) for i in range(n)]

def dfs(a, b):
	t = b
	for i in graph[a]:
		b = max(b, dfs(i, t + 1))
	return b
for i in range(n):
	if inp[i] != -1:
		graph[inp[i] - 1].append(i)
	else:
		su.append(i)
ans = 1
for i in su:
	ans = max(ans, dfs(i, 1))
print(ans)


import sys
import threading
from collections import defaultdict
n = int(input())
adj = defaultdict(list)
root = []
for i in range(1, n + 1):
	val = int(input())
	if val == -1:
		root.append(i)
	else:
		adj[val].append(i)
		adj[i].append(val)

def dfs(node, par):
	height = 0
	for i in range(len(adj[node])):
		if adj[node][i] != par:
			height = max(height, dfs(adj[node][i], node))
	return 1 + height

def main():
	ans = -(10 ** 7 + 7)
	for i in range(len(root)):
		h = dfs(root[i], -1)
		ans = max(ans, h)
	print(ans)
sys.setrecursionlimit(10 ** 6)
threading.stack_size(10 ** 8)
t = threading.Thread(target=main)
t.start()
t.join()


import sys
sys.setrecursionlimit(3000)
global depth
depth = 0

def recurs(parent, n):
	global depth
	depth = max(depth, n)
	for x in tree[parent]:
		recurs(x - 1, n + 1)
n = int(input())
tree = []
root = []
for x in range(n):
	tree.append([])
for x in range(n):
	temp = int(input())
	if temp == -1:
		root.append(x + 1)
	else:
		tree[temp - 1].append(x + 1)
for z in root:
	recurs(z - 1, 1)
print(depth)


n = int(input())
d = [-1 for _ in range(n)]
peaple = []
for i in range(n):
	peaple.append(int(input()))
f = 1
while f != 0:
	f = 0
	for (i, p) in enumerate(peaple):
		if p == -1:
			d[i] = 0
		elif d[p - 1] != -1:
			d[i] = 1 + d[p - 1]
		else:
			f = 1
print(max(d) + 1)


n = int(input())
a = {}
for i in range(n):
	t = int(input())
	a[i] = t
b = [1] * n
for i in range(n):
	k = a[i]
	while k != -1:
		b[i] += 1
		k = a[k - 1]
s = max(b)
print(s)


n = int(input())
l = [int(input()) - 1 for i in range(n)]
maxi = 1

def depth(i):
	t = 0
	while i != -2:
		i = l[i]
		t += 1
	return t
for i in range(n):
	maxi = max(maxi, depth(i))
print(maxi)


import sys
sys.setrecursionlimit(100000)

class Graph:

	def __init__(self, n):
		self.n = n
		self.adj = [[] for i in range(n)]

	def add(self, v, u):
		self.adj[v].append(u)
		self.adj[u].append(v)
n = int(input())
g = Graph(n)
root = []
for i in range(n):
	p = int(input())
	if p == -1:
		root.append(i)
		continue
	g.add(i, p - 1)
used = [False for i in range(n)]
dp = [0 for i in range(n)]

def dfs(v, p, depth):
	used[v] = True
	dp[v] = depth
	for u in g.adj[v]:
		if used[u]:
			continue
		dfs(u, v, depth + 1)
for x in root:
	dfs(x, -1, 0)
print(max(dp) + 1)


import sys
sys.setrecursionlimit(10000)

class Edge(object):

	def __init__(self, src, dest):
		self.src = src
		self.dest = dest

	def getSource(self):
		return self.src

	def getDestination(self):
		return self.dest

	def __str__(self):
		return str(self.src) + '->' + str(self.dest)

class Graph(object):

	def __init__(self):
		self.edges = dict()

	def addNode(self, node):
		if node in self.edges:
			return ValueError('Duplicate node')
		else:
			self.edges[node] = []

	def addEdge(self, edge):
		src = edge.getSource()
		dest = edge.getDestination()
		if src not in self.edges:
			return ValueError('Source node absent')
		if dest in self.edges[src]:
			return
		self.edges[src].append(dest)

	def childrenOf(self, node):
		return self.edges[node]

	def hasNode(self, node):
		return node in self.edges

	def __str__(self):
		result = ''
		for src in self.edges:
			for dest in self.edges[src]:
				result = result + str(src) + '->' + str(dest) + '\n'
		return result[:-1]
n = int(input())
graph = Graph()
graph.addNode(-1)
for i in range(1, n + 1):
	if i not in graph.edges:
		graph.addNode(i)
	parent = int(input())
	if parent not in graph.edges:
		graph.addNode(parent)
	graph.addEdge(Edge(parent, i))

def findHeight(graph, rootNode):
	if len(graph.edges[rootNode]) == 0:
		return 1
	else:
		maxSubtreeHeight = 0
		for child in graph.edges[rootNode]:
			h = 1 + findHeight(graph, child)
			maxSubtreeHeight = max(maxSubtreeHeight, h)
		return maxSubtreeHeight
print(findHeight(graph, -1) - 1)


import math, string, itertools, fractions, heapq, collections, re, array, bisect
from itertools import chain, dropwhile, permutations, combinations
from collections import defaultdict, deque

def VI():
	return list(map(int, input().split()))

def main(n, p):
	g = [[] for i in range(n)]
	manager = []
	for (i, v) in enumerate(p):
		if v >= 0:
			g[v].append(i)
		else:
			manager.append(i)
	maxd = 0
	depth = [1] * n
	for m in manager:
		q = deque()
		q.appendleft(m)
		while len(q) != 0:
			v = q.pop()
			for x in g[v]:
				q.appendleft(x)
				depth[x] = depth[v] + 1
	print(max(depth))

def main_input():
	n = VI()[0]
	p = []
	for i in range(n):
		p.append(int(input()) - 1)
	main(n, p)
main_input()


n = int(input())
mapBoss = {}
for i in range(1, n + 1):
	num = int(input())
	mapBoss[i] = num
groups = 0
for key in mapBoss:
	num = key
	count = 0
	while True:
		if mapBoss[num] == -1:
			break
		count += 1
		num = mapBoss[num]
	groups = max(groups, count)
print(groups + 1)


def solve(n, x):
	g = dict()
	i = 0
	for e in x:
		g[i] = e - 1
		i += 1
	d = [None] * n
	for i in range(n):
		cur = i
		cnt = 1
		while g[cur] != -2:
			if d[cur] is not None:
				cnt += d[cur] - 1
				break
			cur = g[cur]
			cnt += 1
		d[i] = cnt
	return max(d)
n = int(input())
x = []
for _ in range(n):
	x.append(int(input()))
print(solve(n, x))


def fastio():
	import sys
	from io import StringIO
	from atexit import register
	global input
	sys.stdin = StringIO(sys.stdin.read())
	input = lambda : sys.stdin.readline().rstrip('\r\n')
	sys.stdout = StringIO()
	register(lambda : sys.__stdout__.write(sys.stdout.getvalue()))
fastio()
import sys
sys.setrecursionlimit(5000)
MOD = 10 ** 9 + 7
I = lambda : list(map(int, input().split()))
(n,) = I()
g = [[] for i in range(n + 1)]
sup = []
for i in range(n):
	(k,) = I()
	if k != -1:
		g[k - 1].append(i)
	else:
		sup.append(i)

def dfs(x, y):
	temp = y
	for i in g[x]:
		y = max(y, dfs(i, temp + 1))
	return y
ans = 1
for i in sup:
	ans = max(ans, dfs(i, 1))
print(ans)


n = int(input())
manager_table = []
for i in range(n):
	manager_table.append(int(input()))
maximum_depth = 1

def count_depth(n):
	depth = 1
	while manager_table[n] > 0:
		n = manager_table[n] - 1
		depth += 1
	return depth
for i in range(n):
	depth = count_depth(i)
	if depth > maximum_depth:
		maximum_depth = depth
print(maximum_depth)


n = int(input())

class Node:

	def __init__(self):
		self.parent = None
nodes = [None]
for i in range(n):
	nodes.append(Node())
for j in range(1, n + 1):
	parent = int(input())
	nodes[j].parent = parent
max_height = -10
visited = set()
for k in range(1, n + 1):
	if k not in visited:
		visited.add(k)
		parent = k
		depth = 0
		while parent != -1:
			parent = nodes[parent].parent
			depth += 1
		max_height = max(max_height, depth)
print(max_height)


n = int(input())
arr = []
ans = 0
for i in range(n):
	arr.append(int(input()))
for i in range(n):
	c = 0
	while i >= 0:
		i = arr[i] - 1
		c += 1
	ans = max(ans, c)
print(ans)


l = []
mx = 1
n = int(input())
for i in range(n):
	l.append(int(input()))
i = 0
while i < n:
	temp = 1
	j = i
	while j != l[j] - 1 and l[j] > -1:
		temp += 1
		j = l[j] - 1
	mx = max(mx, temp)
	i += 1
print(mx)


def bfs(s):
	i = 0
	frontier = [s]
	while frontier:
		next = []
		for u in frontier:
			if u in adj:
				for v in adj[u]:
					next.append(v)
		frontier = next
		i += 1
	return i
n = int(input())
root = []
adj = {}
for i in range(1, n + 1):
	p = int(input())
	if p == -1:
		root.append(i)
	elif p not in adj:
		adj[p] = [i]
	else:
		adj[p].append(i)
m = 0
for i in root:
	m = max(m, bfs(i))
print(m)


def bfs(ind):
	while len(queue) != 0:
		mark[ind] = True
		for i in range(len(b[ind])):
			if not mark[b[ind][i]]:
				queue.append(b[ind][i])
				level[b[ind][i]] = level[ind] + 1
		queue.pop(0)
		if len(queue) != 0:
			ind = queue[0]
n = int(input())
a = []
level = [1] * n
queue = []
mark = [False] * n
for i in range(n):
	a.append(int(input()))
b = []
for i in range(n):
	b.append([])
for i in range(n):
	if a[i] != -1:
		b[a[i] - 1].append(i)
for i in range(n):
	if a[i] == -1:
		level[i] = 1
		queue.append(i)
		bfs(i)
print(max(level))


n = int(input())
u = dict()
Root = list()
for i in range(0, n):
	Father = int(input())
	if Father == -1:
		Root.append(i + 1)
		continue
	if Father not in u:
		u[Father] = list()
	u[Father].append(i + 1)
maxH = 1
for i in Root:
	Q = list()
	Q.append(i)
	H = 1
	Wide = [None] * 100000
	(Wide[0], Wide[1]) = (0, 1)
	while Q:
		t = Q.pop()
		if Wide[H] > 0:
			Wide[H] = Wide[H] - 1
		else:
			while Wide[H] == 0:
				H = H - 1
			Wide[H] = Wide[H] - 1
		if t not in u:
			continue
		H = H + 1
		if H > maxH:
			maxH = int(H)
		Wide[H] = len(u[t])
		Q.extend(u[t])
print(maxH)


import math
import sys

class Graph:

	def __init__(self, Nodes, is_directed=False):
		self.nodes = Nodes
		self.adj_list = {}
		self.is_directed = is_directed
		for node in self.nodes:
			self.adj_list[node] = []

	def add_edge(self, u, v):
		if v not in self.adj_list[u]:
			self.adj_list[u].append(v)
		if self.is_directed == False:
			if u not in self.adj_list[v]:
				self.adj_list[v].append(u)

	def print_graph(self):
		for node in self.nodes:
			print(node, '->', self.adj_list[node])

	def degree_node(self, node):
		return len(self.adj_list[node])

	def dfsUTIL(self, v, visited, parents=[]):
		visited[v] = True
		for i in self.adj_list[v]:
			if visited[i] == False:
				self.dfsUTIL(i, visited, parents)
				parents.append(i)

	def dfs(self, v):
		visited = [False] * (max(self.adj_list) + 1)
		depth = 0
		parents = [v]
		self.dfsUTIL(v, visited, parents)
		return len(parents)

def dict_sort(ans):
	ans = sorted(ans.items(), reverse=True, key=lambda kv: kv[1])

def is_prime(n):
	if n == 1:
		return 0
	for i in range(2, int(math.sqrt(n)) + 1):
		if n % i == 0:
			return False
	return True

def swap(a, b):
	temp = a
	a = b
	b = temp
	return (a, b)

def seive_primes(n):
	flag = [0] * (n + 10)
	flag[1] = flag[0] = 1
	i = 2
	while i * i <= n + 1:
		if flag[i] == 0:
			j = i * i
			while j <= n + 1:
				flag[j] = 1
				j += i
		i += 1
	return flag

def gcd(a, b):
	if b == 0:
		return a
	return gcd(b, a % b)

def lcm(a, b):
	return a * b // gcd(a, b)

def alphabates():
	return 'abcdefghijklmnopqrstuvwxyz'

def binary_search(ls, n, flag):
	low = 0
	hi = n - 1
	while low <= hi:
		mid = (low + hi) // 2
		if ls[mid] == flag:
			return mid
		elif ls[mid] > flag:
			hi = mid - 1
		else:
			low = mid + 1
	return -1

def qdrt(x, a, b, c):
	return a * x * x + b * x + c

def inp():
	ls = list(map(int, input().split()))
	return ls

def mult_inp():
	return map(int, input().split())
t = int(input())
nodes = [i + 1 for i in range(t)]
graph = Graph(nodes, True)
for i in range(t):
	a = int(input())
	if a != -1:
		graph.add_edge(i + 1, a)
maxxx = -1
for i in nodes:
	a = graph.dfs(i)
	if a > maxxx:
		maxxx = a
print(maxxx)


import sys
sys.setrecursionlimit(2100)
n = int(input())
grafo = []
for i in range(n):
	grafo.append([])
raizes = []
for i in range(0, n):
	p = int(input())
	if p == -1:
		raizes.append(i)
	else:
		p = p - 1
		grafo[p].append(i)

def dfs(v, p):
	if not grafo[v]:
		return p
	maior = 0
	for u in grafo[v]:
		maior = max(maior, dfs(u, p + 1))
	return maior
maior_de_todas = 0
for i in raizes:
	maior_de_todas = max(maior_de_todas, dfs(i, 1))
print(maior_de_todas)


a = [int(input()) for i in range(int(input()))]
m = 1
for x in a:
	d = 1
	while x != -1:
		x = a[x - 1]
		d += 1
	m = max(m, d)
print(m)


import sys, itertools, math, collections, random

def ia():
	return [int(i) for i in sys.stdin.readline().strip().split(' ')]

def ii():
	return int(sys.stdin.readline().strip())

def istr():
	return sys.stdin.readline().strip()
n = ii()
A = []
for _ in range(n):
	A.append(ii())
ans = 0
for i in range(n):
	l = 1
	b = A[i]
	while b != -1:
		b = A[b - 1]
		l += 1
	ans = max(l, ans)
print(ans)


p = [int(input()) for _ in range(int(input()))]
r = 0
for i in range(len(p)):
	c = 0
	while i >= 0:
		i = p[i] - 1
		c += 1
	r = max(r, c)
print(r)


n = int(input())
l = [0] * n
count = 1
for i in range(n):
	x = int(input())
	if x != -1:
		l[i] = x - 1
	else:
		l[i] = x
for i in range(n):
	k = i
	j = 1
	while l[k] != -1:
		j += 1
		k = l[k]
	count = max(count, j)
print(count)


def findDepth(p):
	max_count = 1
	for x in range(len(p)):
		count = 0
		while p[x] != -1:
			count += 1
			x = p[x] - 1
		count += 1
		max_count = max(count, max_count)
	return max_count

def main():
	n = int(input())
	p = []
	for x in range(n):
		p.append(int(input()))
	result = findDepth(p)
	print(result)
main()


class Node:

	def __init__(self, index):
		self.manager = None
		self.sup = set()
		self.index = index

	def add_manager(self, manager):
		self.manager = manager

	def get_superiors(self):
		if len(self.sup) == 0:
			if self.manager is None:
				return set()
			self.sup = self.manager.get_superiors()
			self.sup.add(self.manager)
		return self.sup.copy()

	def do_get_superiors(self):
		if len(self.sup) == 0 and self.manager is not None:
			self.get_superiors()

	def in_superior(self, others):
		return len(others & self.sup) > 0

	def is_superior(self, other):
		return other in self.sup

	def __repr__(self):
		return str(self) + ': manager: ' + str(self.manager) + ', sup: {' + ', '.join([str(s) for s in self.sup]) + '}'

	def __str__(self):
		return str(self.index) + 'M'

	def __eq__(self, obj):
		return obj.index == self.index

	def __hash__(self):
		return self.index
ls = [Node(_) for _ in range(int(input()))]
for i in range(len(ls)):
	x = int(input())
	if x != -1:
		ls[i].add_manager(ls[x - 1])
m = 0
for l in ls:
	m = max(m, len(l.get_superiors()))
print(m + 1)


n = int(input())
t = [[] for i in range(n + 1)]
for i in range(1, n + 1):
	a = int(input())
	if a == -1:
		t[0].append(i)
	else:
		t[a].append(i)
ans = 0
r = t[0]
while r:
	r = [i for j in r for i in t[j]]
	ans += 1
print(ans)


n = int(input())
d = [1] * n
p = [-1] * n
for i in range(n):
	p[i] = int(input())
	if p[i] != -1:
		p[i] -= 1
for i in range(n):
	u = i
	while p[u] > -1:
		d[p[u]] = max(d[p[u]], d[u] + 1)
		u = p[u]
print(max(d))


n = int(input())
l = [int(input()) for _ in range(n)]
count = 0
for i in range(n):
	(j, c) = (i, 0)
	while j >= 0:
		j = l[j] - 1
		c += 1
	count = max(count, c)
print(count)


def bfs(adj, s):
	Q = []
	Q.append(s)
	visited[s] = True
	level[s] = -1
	while len(Q) != 0:
		v = Q.pop(0)
		for ww in range(len(adj[v])):
			w = adj[v][ww]
			if visited[w] == False:
				visited[w] = True
				Q.append(w)
				level[w] = level[v] + 1
n = int(input())
adj = [[] for _ in range(n + 1)]
for i in range(1, n + 1):
	u = int(input())
	if u == -1:
		adj[0].append(i)
	else:
		adj[u].append(i)
level = [0] * (n + 1)
visited = [False] * (n + 1)
for i in range(0, n + 1):
	if visited[i] == False:
		bfs(adj, i)
print(max(level) + 1)


n = int(input())
rel = {}
for i in range(1, n + 1):
	x = int(input())
	rel[i] = x
from collections import deque
maxlevel = 0
for i in range(1, n + 1):
	q = deque([i])
	count = 1
	while q:
		nxt = q.popleft()
		sup = rel[nxt]
		if sup != -1:
			q.append(sup)
			count += 1
	maxlevel = max(count, maxlevel)
print(maxlevel)


num_de_empregados = int(input())
gerentes = []
for i in range(num_de_empregados):
	gerente = int(input())
	gerentes.append(gerente)
grupos = 0
for gerente in gerentes:
	aux = 0
	while gerente != -1:
		gerente = gerentes[gerente - 1]
		aux += 1
	grupos = max(aux, grupos)
grupos = grupos + 1
print(grupos)


def nvf(vis):
	for i in range(len(vis)):
		if vis[i] == False:
			return i
	return len(vis)

def dfs(n, p, vis):
	vis[n] = True
	m = []
	for i in p[n]:
		if i == -2:
			return 1
		if vis[i] == False:
			m.append(dfs(i, p, vis))
	return 1 + max(m)
n = int(input())
p = [[-2]] * n
t = []
for i in range(n):
	x = int(input())
	if x == -1:
		t.append(i)
		continue
	elif p[x - 1] == [-2]:
		p[x - 1] = [i]
	else:
		p[x - 1].append(i)
ans = []
vis = [False] * n
for i in t:
	ans.append(dfs(i, p, vis))
print(max(ans))


from collections import deque
n = int(input())
p = list(map(lambda x: int(x) - 1, (input() for i in range(n))))
links_to = [[] for i in range(n)]
for (i, e) in enumerate(p):
	if e >= 0:
		links_to[e].append(i)
lv = [-1] * n
to_visit = deque()
for (i, cp) in enumerate(p):
	if cp == -2:
		to_visit.append(i)
		lv[i] = 0
while len(to_visit) > 0:
	c = to_visit.pop()
	for l in links_to[c]:
		if lv[l] == -1:
			lv[l] = lv[c] + 1
			to_visit.append(l)
print(max(lv) + 1)


n = int(input())
arr = [0]

def search(x):
	a = x
	b = 1
	while arr[a] != -1:
		a = arr[a]
		b += 1
	return b
for i in range(0, n):
	arr.append(int(input()))
ans = 1
for i in range(1, n + 1):
	ans = max(ans, search(i))
print(ans)


n = int(input())
arr = [None for i in range(n)]
for i in range(n):
	arr[i] = int(input())
	if arr[i] != -1:
		arr[i] -= 1
group = 0
for i in range(len(arr)):
	tmp = 0
	j = i
	while arr[j] != -1:
		tmp += 1
		j = arr[j]
	group = max(group, tmp)
print(group + 1)


from collections import defaultdict
from optparse import Values

def dfs(person, num):
	group[person] = max(group[person], num)
	for m in manager_of[person]:
		dfs(m, num + 1)
num_people = int(input())
manager_of = defaultdict(list)
group = defaultdict(int)
for i in range(1, num_people + 1):
	sub = int(input())
	if sub == -1:
		continue
	manager_of[sub].append(i)
for i in range(1, num_people + 1):
	if group[i] == 0:
		dfs(i, 0)
print(max(group.values()) + 1)


from sys import stdin, stdout
import math, sys, heapq
from itertools import permutations, combinations
from collections import defaultdict, deque, OrderedDict
from os import path
import random
import bisect as bi

def yes():
	print('YES')

def no():
	print('NO')
if path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')

	def I():
		return int(input())

	def In():
		return map(int, input().split())
else:

	def I():
		return int(stdin.readline())

	def In():
		return map(int, stdin.readline().split())

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gt(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return -1

def dfs(d, n, roots):
	visited = [False] * (n + 1)
	parent = [0] * (n + 1)
	ans = 1
	for x in roots:
		q = deque([x])
		parent[x] = 1
		while q:
			temp = q.popleft()
			for child in d[temp]:
				if visited[child] == False:
					q.appendleft(child)
					parent[child] = parent[temp] + 1
					ans = max(ans, parent[child])
			visited[temp] = True
	print(ans)

def main():
	try:
		n = I()
		roots = []
		d = defaultdict(list)
		for x in range(n):
			q = I()
			if q == -1:
				roots.append(x + 1)
			else:
				d[q].append(x + 1)
		dfs(d, n, roots)
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(1):
	main()


l = []
l.append(0)
for _ in range(int(input())):
	l.append(int(input()))
val = 0
for i in range(1, len(l)):
	x = l[i]
	count = 0
	while x > 0:
		x = l[x]
		count += 1
	val = max(count, val)
print(val + 1)


n = int(input())
A = [0]
depth = [0] * (n + 1)
for i in range(n):
	A.append(int(input()))
	if A[i + 1] == -1:
		depth[i + 1] = 1
mx = 0
for i in range(1, n + 1):
	if depth[i] == 0:
		j = i
		c = 0
		while depth[j] == 0:
			j = A[j]
			c += 1
		depth[i] = depth[j] + c
	mx = max(mx, depth[i])
print(mx)


import sys
input = sys.stdin.readline
n = int(input())
d = {}
m = 0
bez = {}
for i in range(n):
	q = int(input())
	if q == -1:
		d[i + 1] = 1
		m = max(d[i + 1], m)
	elif q in d:
		d[i + 1] = d[q] + 1
		m = max(d[i + 1], m)
	else:
		bez[i + 1] = q
k = 1
while len(list(bez.keys())) > 0:
	bez1 = {}
	for i in bez:
		if bez[i] in d:
			d[i] = d[bez[i]] + 1
			m = max(d[i], m)
		else:
			bez1[i] = bez[i]
	bez = bez1
	k += 1
print(m)


n = int(input())
a = [0]
for i in range(n):
	a.append(int(input()))
r = 0
c = 0
for i in range(1, n + 1):
	c = i
	cc = 1
	while a[c] != -1:
		c = a[c]
		cc = cc + 1
	if r < cc:
		r = cc
print(r)


from collections import defaultdict

class Graph:

	def __init__(self, n):
		self.nodes = n
		self.graph = defaultdict(list)
		self.visited = [0] * self.nodes

	def add_edge(self, x, y):
		self.graph[x].append(y)

	def max_length(self):
		ret = 0
		for i in range(self.nodes):
			if self.visited[i] == 0:
				ret = max(ret, self.dfs(i))
		return ret

	def dfs(self, u):
		for v in self.graph[u]:
			if self.visited[v] == 0:
				self.dfs(v)
			self.visited[u] = max(self.visited[u], self.visited[v])
		self.visited[u] += 1
		return self.visited[u]
n = int(input())
graph = Graph(n)
for i in range(n):
	p_i = int(input())
	if not p_i == -1:
		graph.add_edge(p_i - 1, i)
print(graph.max_length())


n = int(input())
arr = [int(input()) for _ in range(n)]
ans = 0
for i in range(n):
	this = 0
	while i >= 0:
		i = arr[i] - 1
		this += 1
	ans = max(ans, this)
print(ans)


n = int(input())
a = [0]
for i in range(n):
	a.append(int(input()))
b = [0] * (n + 1)
c = True
while c:
	c = False
	for i in range(1, n + 1):
		if a[i] < 0:
			b[i] = 1
		elif b[a[i]] > 0:
			b[i] = b[a[i]] + 1
		else:
			c = True
s = 0
for i in range(1, n + 1):
	if b[i] > s:
		s = b[i]
print(s)


n = int(input())
user_input = []
for i in range(n):
	user_input.append(int(input()))
temp = [1] * n
for i in range(n):
	k = user_input[i]
	while k != -1:
		temp[i] = temp[i] + 1
		k = user_input[k - 1]
print(max(temp))


t = int(input())
parent = [-1 for i in range(t)]
for i in range(t):
	temp = int(input())
	if temp == -1:
		parent[i] = temp
	else:
		parent[i] = temp - 1
min = 0
for j in range(t):
	ans = 1
	k = j
	while parent[k] != -1:
		ans += 1
		k = parent[k]
	if ans > min:
		min = ans
print(min)


t = int(input())
l = [0]
for i in range(1, t + 1):
	n = int(input())
	l.append(n)

def dfs(g):
	depth = [1] * (t + 1)
	ans = 0
	for a in range(1, t + 1):
		b = 0
		while a != -1:
			b += 1
			a = g[a]
		ans = max(ans, b)
	print(ans)
dfs(l)


n = int(input())
d = {}
max = 0
for i in range(1, n + 1):
	d[i] = int(input())
for i in range(1, n + 1):
	j = i
	c = 1
	while d[j] != -1:
		j = d[j]
		c += 1
	if c > max:
		max = c
print(max)


n = int(input())
a = [int(input()) for i in range(n)]
ans = 0
for i in range(n):
	g = 1
	p = a[i]
	while p != -1:
		g += 1
		p = a[p - 1]
	ans = max(g, ans)
print(ans)


import sys
sys.setrecursionlimit(20000)
n = int(input())
root = set()
parent = dict()
child = dict()
for i in range(1, n + 1):
	a = int(input())
	if a == -1:
		root.add(i)
	else:
		parent[i] = a
		if a in child:
			child[a].add(i)
		else:
			child[a] = set()
			child[a].add(i)
weight_max = 0

def lol(j, c, we):
	if j not in c:
		return we
	else:
		s = list()
		for y in c[j]:
			s.append(lol(y, c, we + 1))
		return max(s)
test = list()
for i in root:
	test.append(lol(i, child, 1))
print(max(test))


def GetParentHt(hts, kid, parents):
	return hts[parents[kid - 1] - 1] + 1

def GetHts(roots, graph, parents):
	hts = [-1] * len(graph)
	for root in roots:
		hts[root - 1] = 0
		ht = 0
		stack = [root]
		while stack:
			curr = stack.pop()
			for kid in graph[curr - 1]:
				hts[kid - 1] = GetParentHt(hts, kid, parents)
				stack.append(kid)
	return hts

def Party(hts):
	hts.sort()
	curr = hts[0]
	if hts:
		groups = 1
	else:
		groups = 0
	for i in hts:
		if i != curr:
			curr = i
			groups += 1
	return groups

def main():
	n = int(input())
	graph = {}
	for i in range(n):
		graph[i] = []
	roots = []
	parents = [0] * n
	for i in range(n):
		p = int(input())
		if p == -1:
			roots.append(i + 1)
			parents[i] = -1
		else:
			graph[p - 1].append(i + 1)
			parents[i] = p
	hts = GetHts(roots, graph, parents)
	print(Party(hts))
main()


def heigth(v):
	for w in range(n):
		if _graph[w] == v:
			heigths[w] = heigths[v] + 1
			heigth(w)
n = int(input())
graph = [-1 for x in range(n)]
heigths = [-1 for x in range(n)]
for i in range(n):
	p = int(input())
	if p == -1:
		heigths[i] = 0
		continue
	graph[i] = p - 1
_graph = [-1 for x in range(n + 1)]
for i in range(n):
	if graph[i] == -1:
		_graph[i] = n
	else:
		_graph[i] = graph[i]
heigths = [-1 for x in range(n + 1)]
heigths[n] = 0
heigth(n)
print(max(heigths))


from collections import deque
import sys

def levels(start):
	count = 0
	flag = 0
	l = [start, -1]
	l = deque(l)
	while l.count(-1) != len(l):
		element = l.popleft()
		if element == -1:
			count += 1
			l.append(-1)
		else:
			for i in parent[element]:
				l.append(i)
	return count + 1
input = sys.stdin.readline
n = int(input())
parent = [[] for i in range(n)]
root = []
for i in range(n):
	p = int(input())
	if p != -1:
		parent[p - 1].append(i)
	else:
		root.append(i)
m = 0
for i in root:
	temp = levels(i)
	if m < temp:
		m = temp
print(m)


(n, p) = (int(input()), [])
for i in range(n):
	p.append(int(input()) - 1)
MAX = 0
for i in range(n):
	x = 0
	while i != -2:
		i = p[i]
		x += 1
	MAX = max(x, MAX)
print(MAX)


import sys
sys.setrecursionlimit(10 ** 5)

def dfs(graph, roots):
	maxV = 0
	for root in roots:
		p = recur(graph, root, 1)
		if p > maxV:
			maxV = p
	return maxV

def recur(graph, r, lvl):
	if r in graph:
		maxLvl = 0
		for i in graph[r]:
			pLvl = recur(graph, i, lvl + 1)
			if pLvl > maxLvl:
				maxLvl = pLvl
		return maxLvl
	else:
		return lvl
n = int(input())
roots = []
graph = {}
for k in range(n):
	element = int(input())
	if element == -1:
		roots.append(k + 1)
	else:
		try:
			graph[element].append(k + 1)
		except:
			graph[element] = [k + 1]
print(dfs(graph, roots))


def geti(dic, i, cont):
	boole = False
	for e in dic[i]:
		if e in dic:
			boole = True
			geti(dic, e, cont + 1)
	if not boole:
		biu.append(cont)
n = int(input())
lista = []
valores = []
dicgeral = {}
for e in range(n):
	ent = int(input())
	valores.append(ent)
	if ent == -1:
		dicgeral[e + 1] = []
		lista.append(e + 1)
for i in range(n):
	if valores[i] != -1:
		if valores[i] in dicgeral:
			dicgeral[valores[i]].append(i + 1)
		else:
			dicgeral[valores[i]] = [i + 1]
maior = 0
for e in lista:
	biu = []
	if len(dicgeral[e]):
		geti(dicgeral, e, 1)
		if max(biu) > maior:
			maior = max(biu)
maior += 1
print(maior)


from collections import deque
MAX = 0
n = int(input())
k = {-1: {}}
for i in range(1, n + 1):
	k[i] = {}
for i in range(1, n + 1):
	em = int(input())
	k[em][i] = None
i = 0
w = n
q = deque()
q.append([-1, 0])
while i <= w:
	s = q.popleft()
	if len(k[s[0]].keys()) != 0:
		for m in k[s[0]].keys():
			q.append([m, s[1] + 1])
	else:
		MAX = s[1]
	i += 1
print(MAX)


t = int(input())
a = []
for i in range(t):
	a.append(int(input()))
largest = 1
for i in range(t):
	if a[i] != -1:
		x = a[i]
		counter = 1
		while x != -1:
			x = a[x - 1]
			counter += 1
		if counter > largest:
			largest = counter
print(largest)


n = int(input())
li = [int(input()) for i in range(n)]
high = 0
for i in range(n):
	q = li[i]
	c = 1
	while q != -1:
		q = li[q - 1]
		c = c + 1
	if high < c:
		high = c
print(high)


n = int(input())
s = []
for a in range(n):
	s.append([a + 1, int(input())])
root = [-1]
leaves = []
m = 0
while True:
	for i in root:
		for pair in s:
			if pair[1] == i:
				leaves.append(pair[0])
	if leaves == []:
		break
	else:
		root = leaves
		leaves = []
		m += 1
print(m)


def helper(employer, cur, dp):
	s = []
	while dp[cur] is None and employer[cur] > -1:
		s.append(cur)
		cur = employer[cur]
	if employer[cur] == -1:
		dp[cur] = 1
	top = dp[cur]
	while s:
		cur = s.pop()
		dp[cur] = top + 1
		top += 1

def ans():
	employer = []
	while True:
		try:
			employer.append(int(input()))
		except EOFError:
			break
	if len(employer) == 0:
		return [0]
	n = employer[0]
	dp = [None] * (n + 1)
	dp[0] = 0
	s = []
	for i in range(1, n + 1):
		if dp[i] is None:
			helper(employer, i, dp)
	return dp
print(max(ans()))


n = int(input())
l = [-10]
for i in range(n):
	r = int(input())
	l.append(r)
ma = 0
for i in range(1, n + 1):
	p = 0
	while l[i] != -1:
		p += 1
		i = l[i]
	ma = max(p, ma)
print(ma + 1)


def getDistancia(dic, i, cont):
	boole = False
	for e in dic[i]:
		if e in dic:
			boole = True
			getDistancia(dic, e, cont + 1)
	if not boole:
		tamanhosArvores.append(cont)
n = int(input())
dicgeral = {}
raizes = []
valores = []
for e in range(n):
	p = int(input())
	valores.append(p)
	if p == -1:
		dicgeral[e + 1] = []
		raizes.append(e + 1)
for i in range(n):
	if valores[i] != -1:
		if valores[i] in dicgeral:
			dicgeral[valores[i]].append(i + 1)
		else:
			dicgeral[valores[i]] = [i + 1]
maior = 0
tamanhosArvores = []
for e in raizes:
	if len(dicgeral[e]):
		getDistancia(dicgeral, e, 1)
		if max(tamanhosArvores) > maior:
			maior = max(tamanhosArvores)
maior += 1
print(maior)


n = int(input())
r = []
m = 0
for _ in [0] * n:
	r.append(int(input()))
for i in range(n):
	a = i
	l = 0
	while r[a] != -1:
		a = r[a] - 1
		l += 1
	m = max(m, l)
print(m + 1)


n = int(input())
parent = [n] * n
edge = []
depth = [0] * n
ans = 0
stor = []
for i in range(n):
	edge.append([])
for i in range(n):
	parent[i] = int(input())
	parent[i] = parent[i] - 1
	if parent[i] == -2:
		parent[i] = n
	else:
		edge[parent[i]].append(i)
for i in range(n):
	if parent[i] != n:
		continue
	stor = [i]
	while stor:
		u = stor[-1]
		stor = stor[:-1]
		for v in edge[u]:
			depth[v] = depth[u] + 1
			stor.append(v)
for i in range(n):
	ans = max(ans, depth[i])
print(ans + 1)


n = int(input())
l = []
for i in range(n):
	l.append(int(input()))
c = 0
for i in l:
	g = 0
	while i >= 0:
		g += 1
		i = l[i - 1]
	c = max(g, c)
print(c + 1)


a = {}
c = {}
n = int(input())
for i in range(1, n + 1):
	b = int(input())
	a[i] = b
dep = 0
for i in range(1, n + 1):
	k = 1
	r = i
	while a[r] != -1:
		r = a[r]
		if r in c:
			k += c[r]
			break
		else:
			k += 1
	c[i] = k
	dep = max(k, dep)
print(dep)


class Tree:

	def __init__(self, rootObj):
		self.key = rootObj
		self.children = []

	def newChild(self, newNode):
		self.children.append(newNode)

	def getChildren(self):
		return self.children

	def setRootVal(self, obj):
		self.key = obj

	def getRootVal(self):
		return self.key
t = int(input())
nodes = [Tree(i) for i in range(t)]
noManager = []
for i in range(t):
	val = int(input())
	if val == -1:
		noManager.append(i)
	else:
		nodes[val - 1].newChild(nodes[i])

def maxDepth(root):
	if root is None:
		return 0
	q = []
	q.append(root)
	height = 0
	while True:
		nodeCount = len(q)
		if nodeCount == 0:
			return height
		height += 1
		while nodeCount > 0:
			node = q[0]
			q.pop(0)
			for child in node.getChildren():
				q.append(child)
			nodeCount -= 1
print(max([maxDepth(nodes[i]) for i in noManager]))


from sys import setrecursionlimit
setrecursionlimit(30000)
maxl = -1

def dfs(v, lvl):
	used[v] = True
	global maxl
	if lvl > maxl:
		maxl = lvl
	for u in ch[v]:
		dfs(u, lvl + 1)
n = int(input())
used = [False] * n
p = [int(input()) - 1 for i in range(n)]
ch = [[] for i in range(n)]
for i in range(n):
	if p[i] != -2:
		ch[p[i]].append(i)
for i in range(n):
	if p[i] == -2:
		dfs(i, 1)
print(maxl)


import os
import sys
from io import BytesIO, IOBase
adj = [[] for _ in range(2002)]

def dfs(u):
	ans = 0
	for i in range(len(adj[u])):
		ans = max(ans, dfs(adj[u][i]))
	return ans + 1

def main():
	n = int(input())
	for i in range(1, n + 1):
		v = int(input())
		if v == -1:
			adj[0].append(i)
		else:
			adj[v].append(i)
	print(dfs(0) - 1)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import sys
intin = lambda : map(int, input().split())
Ain = lambda : list(map(int, input().split()))
mod = 1000000007
sys.setrecursionlimit(100000)
n = int(input())
roots = []
v = [[] for i in range(300000)]
d = [0] * 300000
for i in range(1, n + 1):
	a = int(input())
	if a == -1:
		roots.append(i)
		continue
	v[a].append(i)
	v[i].append(a)
vis = [False] * 300000

def dfs(node):
	vis[node] = True
	for i in range(len(v[node])):
		son = v[node][i]
		if vis[son]:
			continue
		d[son] = d[node] + 1
		dfs(son)
for root in roots:
	d[root] = 0
	dfs(root)
ans = 0
for i in range(n + 1):
	ans = max(ans, d[i])
print(ans + 1)


mod = 10 ** 9 + 7
ii = lambda : int(input())
si = lambda : input()
dgl = lambda : list(map(int, input()))
f = lambda : map(int, input().split())
il = lambda : list(map(int, input().split()))
ls = lambda : list(input())
n = ii()
l = [ii() - 1 for _ in range(n)]
mx = 0
for i in range(n):
	c = 1
	j = l[i]
	while j != -2:
		c += 1
		j = l[j]
	mx = max(mx, c)
print(mx)


t = int(input())
g = []
maior = 0

def busca(g, pos, cont):
	if pos == 0:
		return cont
	return busca(g, g[pos], cont + 1)
for i in range(t + 1):
	g.append([])
for i in range(t):
	x = int(input())
	if x != -1:
		g[i + 1] = x
	else:
		g[i + 1] = 0
for i in range(t):
	res = busca(g, i + 1, 0)
	if maior < res:
		maior = res
print(maior)


(d, l) = ({}, [])
for i in range(int(input())):
	p = int(input())
	if p == -1:
		d[i + 1] = 0
	elif p in d.keys():
		d[i + 1] = -1 + d[p]
	else:
		l.append([i + 1, p])
while len(l) > 0:
	for i in l:
		if i[1] in d.keys():
			d[i[0]] = -1 + d[i[1]]
			l.remove(i)
o = d.values()
print(max(o) - min(o) + 1)


n = int(input())
l = list()
a = list()
c = list()
for i in range(0, n):
	l.append(int(input()))
	b = [0] * n
	a.append(b)
for i in range(0, n):
	if l[i] != -1:
		a[l[i] - 1][i] = 1

def bfs(b, node, k):
	count = 1
	visited = [0] * k
	dist = [1] * k
	queue = [node]
	visited[node] = 1
	node = queue.pop(0)
	t = 0
	while True:
		for x in range(0, k):
			if b[node][x] == 1 and visited[x] == 0:
				queue.append(x)
				visited[x] = 1
				value = dist[node] + 1
				if value > dist[x]:
					dist[x] = value
		if len(queue) == 0:
			break
		else:
			node = queue.pop(0)
	return max(dist)
for i in range(0, n):
	if l[i] == -1:
		m = bfs(a, i, n)
		c.append(m)
print(max(c))


from collections import deque
n = int(input())
graph = [[] for i in range(n)]
for i in range(n):
	x = int(input())
	if x != -1:
		graph[i].append(x - 1)
ans = 0
for i in range(n):
	stack = deque()
	stack.append(i)
	while stack:
		if len(stack) > ans:
			ans = len(stack)
		if len(graph[stack[-1]]) == 0:
			break
		else:
			stack.append(graph[stack[-1]][0])
print(ans)


import queue

class nod:
	state = 0
	emp = []
	depth = 0

	def __init__(self, state, lis, depth):
		self.state = state
		self.emp = lis
		self.depth = depth

def bfs(G, source):
	Q = queue.Queue()
	level = [10000] * 10000
	Q.put(source)
	level[source] = 0
	maxx = 0
	while Q.empty() == False:
		u = Q.get()
		if u in G:
			for edge in G[u]:
				if level[edge] == 10000:
					level[edge] = level[u] + 1
					maxx = max(level[edge], maxx)
					Q.put(edge)
	return maxx + 1
hm = int(input())
sources = []
diction = {}
maxx = 1
for i in range(1, hm + 1):
	boss = int(input())
	if boss == -1:
		sources.append(i)
		pass
	elif boss not in diction:
		diction[boss] = []
		diction[boss].append(i)
	else:
		diction[boss].append(i)
maximum = 0
for head in sources:
	maximum = max(maximum, bfs(diction, head))
print(maximum)


class node:

	def __init__(self, data):
		self.data = data
		self.next = None
n = int(input())
tail = [True for i in range(1, n + 1)]
r = 1
arr = [node(j) for j in range(1, n + 1)]
for i in range(1, n + 1):
	pi = int(input())
	if pi != -1:
		arr[i - 1].next = arr[pi - 1]
		tail[pi - 1] = False
	else:
		tail[i - 1] = False
for i in range(len(tail)):
	if tail[i]:
		count = 1
		while arr[i].next != None:
			count += 1
			i = arr[i].next.data - 1
		if count > r:
			r = count
print(r)


from __future__ import division, print_function
import os
import sys
from io import BytesIO, IOBase
from sys import stdin, stdout
import math, sys, heapq
from itertools import permutations, combinations
from collections import defaultdict, deque, OrderedDict
from os import path
import random
import bisect as bi

def dfs(d, n, roots):
	visited = [False] * (n + 1)
	parent = [0] * (n + 1)
	ans = 1
	for x in roots:
		q = deque([x])
		parent[x] = 1
		while q:
			temp = q.popleft()
			for child in d[temp]:
				if visited[child] == False:
					q.appendleft(child)
					parent[child] = parent[temp] + 1
					ans = max(ans, parent[child])
			visited[temp] = True
	print(ans)

def main():
	try:
		n = int(input())
		roots = []
		d = defaultdict(list)
		for x in range(n):
			q = int(input())
			if q == -1:
				roots.append(x + 1)
			else:
				d[q].append(x + 1)
		dfs(d, n, roots)
	except:
		pass
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import sys
sys.setrecursionlimit(5000)
n = int(input())
an = 0
p = [i for i in range(n)]

def find(y):
	global cnt
	cnt += 1
	if y == p[y]:
		return y
	return find(p[y])
for _ in range(n):
	k = int(input())
	if k != -1:
		p[_] = k - 1
for i in range(n):
	cnt = 0
	find(i)
	an = max(an, cnt)
print(an)


n = int(input())
p = [0] * n
nex = [[] for i in range(n)]
status = []
output = 1
for i in range(n):
	p[i] = int(input())
	if p[i] != -1:
		nex[p[i] - 1].append(i + 1)
	else:
		status.append((i + 1, 0, 1))
while len(status):
	(position, previous, rank) = status.pop()
	if rank > output:
		output = rank
	if len(nex[position - 1]):
		for i in nex[position - 1]:
			status.append((i, position, rank + 1))
print(output)


size = int(input())
lis = [-1] * size
for y in range(size):
	lis[y] = int(input()) - 1
r = [0] * size
for x in range(size):
	c = x
	while lis[c] > -1:
		r[x] += 1
		c = lis[c]
print(max(r) + 1)


a = int(input())
man = [0]
ans = 0
for i in range(a):
	man.append(int(input()))
for i in range(1, a + 1):
	j = i
	mark = 1
	while man[j] != -1:
		mark += 1
		j = man[j]
	if mark > ans:
		ans = mark
print(ans)


from collections import *

class Graph:

	def __init__(self, n):
		self.n = n
		self.count = [0] * self.n
		self.g = defaultdict(list)
		self.visited = [False] * self.n

	def add_edge(self, u, v):
		self.g[v].append(u)

	def dfs(self, at, i):
		if not self.visited[at]:
			self.count[i] += 1
		for j in self.g[at]:
			self.dfs(j, i + 1)

	def show(self):
		for i in range(self.n):
			print(i, self.g[i])
n = int(input())
graph = Graph(n + 1)
for i in range(1, n + 1):
	j = int(input())
	if j == -1:
		graph.add_edge(i, 0)
	else:
		graph.add_edge(i, j)
graph.dfs(0, 0)
res = 0
for i in graph.count:
	if i == 0:
		break
	res += 1
print(res - 1)


import sys
sys.setrecursionlimit(10 ** 5)

def res():

	def re(x, v, y):
		v[y] = True
		t = 0
		for j in x[y]:
			t = max(t, 1 + re(x, v, j))
		return t
	n = int(input())
	x = {}
	v = {}
	for i in range(1, n + 1):
		x[i] = []
		v[i] = False
	for i in range(1, n + 1):
		t = int(input())
		if t == -1:
			continue
		else:
			x[t].append(i)
	k = 0
	for i in x:
		if v[i] == False and x != []:
			k = max(k, re(x, v, i))
	print(k + 1)
res()


from sys import stdin, stdout
import sys
cin = stdin.readline
cout = stdout.write
mp = lambda : list(map(int, cin().split()))
sys.setrecursionlimit(10 ** 9)

def getLevel(y):
	if level[y]:
		return level[y]
	elif not l[y]:
		return 1
	else:
		level[y] = getLevel(l[y]) + 1
		return level[y]
(n,) = mp()
l = [0] * (n + 1)
for i in range(1, n + 1):
	(x,) = mp()
	if x == -1:
		continue
	else:
		l[i] = x
level = [0] * (n + 1)
for i in range(1, n + 1):
	if not l[i]:
		level[i] = 1
	elif not level[i]:
		level[i] = getLevel(l[i]) + 1
cout(str(max(level)))


import math
import collections
import bisect
import heapq
import time
import random
import itertools
import sys
N = int(input())
A = [0] * (N + 1)
for i in range(1, N + 1):
	p = int(input())
	A[i] = p
ans = 0
for i in range(1, N + 1):
	l = 1
	u = A[i]
	while u > 0:
		u = A[u]
		l += 1
	ans = max(ans, l)
print(ans)


import sys
sys.setrecursionlimit(3000)
n = int(input())
inp = []
for getInput in range(n):
	inp.append(int(input()) - 1)

def recurse(currIndex):
	global l
	if inp[currIndex] == -2:
		return
	else:
		l.add(inp[currIndex])
		recurse(inp[currIndex])
l = set()
m = 0
for i in range(n):
	l.clear()
	recurse(i)
	if len(l) > m:
		m = len(l)
print(m + 1)


n = int(input())
superierList = []
for i in range(n):
	superierList.append(int(input()))
orderList = [1] * n
leafList = [0] * n
for i in range(n):
	thisSup = superierList[i]
	thisOrder = orderList[i]
	if thisSup != -1:
		if thisOrder == 1:
			leafList[i] = 1
			orderList[thisSup - 1] = 2
			leafList[thisSup - 1] = 0
for i in range(len(leafList)):
	if leafList[i] == 1:
		thisSup = superierList[i]
		thisOrder = orderList[i]
		while thisSup != -1:
			updateOrder = thisOrder + 1
			if updateOrder < orderList[thisSup - 1]:
				thisSup = -1
			else:
				orderList[thisSup - 1] = updateOrder
				thisSup = superierList[thisSup - 1]
				thisOrder = updateOrder
print(max(orderList))


from sys import stdin, stdout
parent = []
total = int(stdin.readline())
for employee in range(total):
	a = int(stdin.readline())
	if a != -1:
		parent.append(a - 1)
	else:
		parent.append(a)
res = 0
depth = [-1 for i in range(total)]
for i in range(total):
	p = i
	current = 1
	while parent[p] != -1:
		if depth[p] != -1:
			current += depth[p] - 1
			break
		current += 1
		p = parent[p]
	if depth[i] == -1:
		depth[i] = current
	res = max(res, current)
print(res)


n = int(input())
p = []
ans = 1
for i in range(n):
	a = int(input())
	p.append(a)
for a in p:
	if a == -1:
		continue
	level = 1
	while a != -1:
		a = p[a - 1]
		level += 1
		ans = max(level, ans)
print(ans)


def party(n, managers):

	def DFS(p):
		if p in memo:
			return memo[p]
		elif managers[p] < 0:
			memo[p] = 1
			return 1
		else:
			res = 1 + DFS(managers[p])
			memo[p] = res
			return res
	memo = {}
	longest = 0
	for p in range(n):
		val = 1
		while managers[p] >= 0:
			val += 1
			p = managers[p]
		longest = max(longest, val)
	return longest
n = int(input())
managers = []
for i in range(n):
	manager = int(input()) - 1
	managers.append(manager)
res = party(n, managers)
print(res)


from collections import defaultdict
import sys
sys.setrecursionlimit(3000)

class Tree:

	def __init__(self, data):
		self.tree = defaultdict(list)
		for (node, parent) in enumerate(data, start=1):
			self.tree[parent].append(node)

	def get_depth(self):
		return self.DFS(-1)

	def DFS(self, node, depth=0):
		m = 0
		for child in self.tree[node]:
			m = max(m, self.DFS(child, depth + 1))
		return max(m, depth)
n = int(input())
p = [int(input()) for _ in range(n)]
t = Tree(p)
print(t.get_depth())


from sys import stdin, stdout

def dfs(sup):
	global emp
	if emp[sup] == []:
		return 1
	else:
		maxdepth = 0
		for newsup in emp[sup]:
			maxdepth = max(maxdepth, dfs(newsup))
		return 1 + maxdepth
n = int(stdin.readline())
emp = [[] for _ in range(n)]
sups = []
for i in range(n):
	x = int(stdin.readline())
	if not x == -1:
		emp[x - 1].append(i)
	else:
		sups.append(i)
maxdepth = 0
for sup in sups:
	maxdepth = max(maxdepth, dfs(sup))
stdout.write('{}'.format(maxdepth))


from collections import defaultdict
subordinates = defaultdict(lambda : [])
n = int(input())
for i in range(1, n + 1):
	manager = int(input())
	subordinates[manager].append(i)
next_group = [-1]
groups = -1
while next_group:
	groups += 1
	(todo, next_group) = (next_group, [])
	for employee in todo:
		next_group.extend(subordinates[employee])
print(groups)


import sys
from collections import deque
num_of_soldier = int(sys.stdin.readline())
visited_flag = [-1] * (num_of_soldier + 1)
graph = [0] * (num_of_soldier + 1)
for i in range(num_of_soldier):
	graph[i + 1] = int(sys.stdin.readline())

def dfs(start_node):
	stack = deque()
	visited_node = []
	num = 0
	stack.append(start_node)
	visited_node.append(start_node)
	while stack:
		node = stack.pop()
		if visited_flag[node] != -1:
			num += visited_flag[node]
			break
		if graph[node] == -1:
			visited_flag[node] = 0
			break
		num += 1
		stack.append(graph[node])
		visited_node.append(graph[node])
	for i in visited_node:
		visited_flag[i] = num
		num -= 1
for i in range(num_of_soldier):
	if visited_flag[i + 1] == -1:
		dfs(i + 1)
print(max(visited_flag) + 1)


n = int(input())
l = []
for j in range(n):
	l.append(int(input()))
g = 0
for i in range(n):
	ans = 0
	while i >= 0:
		i = l[i] - 1
		ans += 1
	g = max(g, ans)
print(g)


n = int(input())
ds = dict()
for i in range(1, n + 1):
	d = int(input())
	if d in ds:
		ds[d].append(i)
	else:
		ds[d] = [i]
pls = [(x, 1) for x in ds[-1]]
m = 0
while pls:
	c = pls.pop(0)
	m = max(m, c[1])
	if c[0] in ds:
		pls += [(x, c[1] + 1) for x in ds[c[0]]]
print(m)


n = int(input())
t = []
for i in range(n + 1):
	t.append(0)
for i in range(1, n + 1):
	t[i] = int(input())
maxx = 0
for i in range(1, n + 1):
	sum = 0
	while i != -1:
		i = t[i]
		sum += 1
	maxx = max(maxx, sum)
print(maxx)


import collections

def num_levels(graph, s, visited):
	visited[s] = True
	q = [s]
	res = 1
	while True:
		q_tmp = []
		for v in q:
			for u in graph[v]:
				if not visited[u]:
					q_tmp.append(u)
		if not q_tmp:
			break
		q = q_tmp
		res += 1
	return res

def max_num_levels(graph, roots, n):
	visited = [False] * n
	max_levels = 1
	for root in roots:
		num_levels_root = num_levels(graph, root, visited)
		if num_levels_root > max_levels:
			max_levels = num_levels_root
	return max_levels
n = int(input())
roots = []
graph = [[] for _ in range(n)]
for child in range(n):
	parent = int(input())
	if parent == -1:
		roots.append(child)
	else:
		graph[parent - 1].append(child)
print(max_num_levels(graph, roots, n))


from sys import stdin
from collections import deque

def solve(tc):
	n = int(stdin.readline().strip())
	q = deque()
	adj = [[] for i in range(n)]
	for i in range(n):
		par = int(stdin.readline().strip())
		if par < 0:
			q.append([i, 1])
		else:
			par -= 1
			adj[par].append(i)
	maxdeg = 0
	while len(q) > 0:
		t = q.popleft()
		maxdeg = max(maxdeg, t[1])
		for child in adj[t[0]]:
			q.append([child, t[1] + 1])
	print(maxdeg)
tcs = 1
for tc in range(tcs):
	solve(tc)


n = int(input())
managers = [-1] * n
for i in range(n):
	manager = int(input())
	if manager != -1:
		managers[i] = manager - 1
tree = {}
for i in range(n):
	tree[i] = []
for (i, m) in enumerate(managers):
	if m != -1:
		tree[m].append(i)

def largestChain(v):
	if not tree[v]:
		return 1
	ans = 0
	for u in tree[v]:
		ans = max(ans, largestChain(u) + 1)
	return ans
ans = 0
for i in range(n):
	if managers[i] == -1:
		ans = max(ans, largestChain(i))
print(ans)


from collections import defaultdict
graph = defaultdict(list)

def addEdge(u, v):
	graph[u].append(v)
n = int(input())
arr = []
for i in range(n):
	arr.append(int(input()))
for i in range(n):
	if arr[i] != -1:
		addEdge(i + 1, arr[i])

def DFSUtil(v, visited, stack):
	visited.append(v)
	stack.append(v)
	for node in graph[v]:
		if node not in visited:
			DFSUtil(node, visited, stack)
	return stack
cc = []
for i in range(1, n + 1):
	visited = []
	if i in graph:
		stack = []
		if i not in visited:
			cc.append(DFSUtil(i, visited, stack))
cc.sort(reverse=True, key=lambda arr: len(arr))
if cc == []:
	print(1)
else:
	print(len(cc[0]))


from sys import stdin, stdout
n = int(stdin.readline())
from collections import defaultdict
adj = defaultdict(list)
start = []
for i in range(1, n + 1):
	x = int(stdin.readline())
	if x == -1:
		start.append(i)
		continue
	adj[i].append(x)
	adj[x].append(i)
q = []
for x in start:
	q.append(x)
vis = set()
group = 0
while len(q):
	size = len(q)
	for i in range(size):
		front = q.pop(0)
		vis.add(front)
		for node in adj[front]:
			if node not in vis:
				q.append(node)
	group += 1
stdout.write('{}\n'.format(group))


def findDepth(a, i):
	depth = 1
	nextLevel = a[i][:]
	while len(nextLevel) > 0:
		depth += 1
		children = nextLevel[:]
		nextLevel = []
		for child in children:
			nextLevel += a[child]
	return depth
n = int(input())
a = []
for i in range(n):
	a.append([])
roots = []
for i in range(n):
	x = int(input())
	if x > 0:
		a[x - 1].append(i)
	else:
		roots.append(i)
print(max([findDepth(a, i) for i in roots]))


n = int(input())
arr = [int(input()) for i in range(n)]
graph = {i: set() for i in range(1, n + 1)}
for i in range(n):
	if arr[i] != -1:
		graph[arr[i]] = graph[arr[i]].union(set([i + 1]))
visited = set()
maxLen = 0
temp = 0

def dfs(visited, graph, node):
	global maxLen, temp
	if node in visited:
		temp -= 1
	elif node not in visited:
		visited.add(node)
		if len(graph[node]) == 0:
			maxLen = max(maxLen, temp)
		else:
			for neighbor in graph[node]:
				temp += 1
				dfs(visited, graph, neighbor)
	temp -= 1
for i in range(n):
	temp = 0
	visited.clear()
	dfs(visited, graph, i + 1)
print(maxLen + 1)


n = int(input())
data = [int(input()) for _ in range(n)]
root = 0
for i in range(n):
	depth = 0
	while i >= 0:
		i = data[i] - 1
		depth += 1
	root = max(root, depth)
print(root)


n = int(input())
graph = dict(zip([i for i in range(1, n + 1)], [[] for i in range(n)]))
parent = []
for i in range(n):
	p = int(input())
	parent.append(p)
	if p != -1:
		graph[p].append(i + 1)
from collections import deque

def bfs(u):
	q = deque()
	q.append(u)
	count = 0
	while len(q) > 0:
		size = len(q)
		for v in list(q):
			for neighbor in graph[v]:
				q.append(neighbor)
		count += 1
		for _ in range(size):
			q.popleft()
	return count
ans = 0
for i in range(n):
	if parent[i] == -1:
		ans = max(ans, bfs(i + 1))
print(ans)


def solve(superiors):
	if not superiors:
		print(0)
	n = len(superiors)
	max_depth = 0
	for i in range(n):
		depth = 0
		while i >= 0:
			i = superiors[i] - 1
			depth += 1
		max_depth = max(max_depth, depth)
	print(max_depth)
n = int(input())
solve([int(input()) for _ in range(n)])


n = int(input())
ver = []
for _ in range(n):
	ver.append(int(input()))
d = 0
for i in range(n):
	c = 0
	while i >= 0:
		i = ver[i] - 1
		c += 1
	d = max(d, c)
print(d)


n = int(input())
aux = [0]
h = 0
for i in range(n):
	entrada = int(input())
	aux.append(entrada)
for e in range(1, n + 1):
	cont = 0
	while aux[e] != -1:
		cont += 1
		e = aux[e]
	h = max(cont, h)
print(h + 1)


from collections import deque
children = [[] for _ in range(int(input()) + 1)]
for i in range(len(children) - 1):
	p = int(input())
	if p == -1:
		p = 0
	children[p].append(i + 1)
q = deque()
q.extend(((1, c) for c in children[0]))
result = -1
while q:
	(depth, index) = q.popleft()
	result = max(result, depth)
	q.extend(((depth + 1, c) for c in children[index]))
print(result)


n = int(input())
p = []
l = []
for i in range(n):
	w = int(input())
	p.append(w)
dd = {i + 1: p[i] for i in range(n)}
d = {}
for i in range(1, n + 1):
	d[i] = [i]
	x = i
	while True:
		if dd[x] != -1:
			d[i].append(dd[x])
			x = dd[x]
		else:
			l.append(len(d[i]))
			break
print(max(l))


def searchd(i):
	c = 1
	while i != -1:
		c += 1
		i = p[i]
	return c
n = int(input())
p = [-1 for i in range(n)]
for i in range(n):
	t = int(input())
	if t != -1:
		t -= 1
	p[i] = t
ans = 0
for i in range(n):
	d = searchd(p[i])
	if d > ans:
		ans = d
print(ans)


def answer2(n, bosses_ary, steps_ary):
	for i in range(1, n + 1, 1):
		steps_ary[i] = steps_func(i, bosses_ary, steps_ary)
	return max(steps_ary)

def steps_func(index, b_ary, s_ary):
	if b_ary[index] == -1:
		return 1
	elif s_ary[b_ary[index]] > 0:
		return s_ary[b_ary[index]] + 1
	else:
		return steps_func(b_ary[index], b_ary, s_ary) + 1

def main():
	n = int(input())
	bosses_ary = [0] * (n + 1)
	steps_ary = [0] * (n + 1)
	for j in range(1, n + 1):
		bosses_ary[j] = int(input())
	print(answer2(n, bosses_ary, steps_ary))
main()


def f(i, d):
	global ans
	if b[i]:
		for x in b[i]:
			f(x, d + 1)
	else:
		ans = max(ans, d)
n = int(input())
a = [int(input()) for x in range(n)]
b = [[] for x in range(n)]
for i in range(n):
	if a[i] != -1:
		b[a[i] - 1].append(i)
ans = -100
for i in range(len(a)):
	if a[i] == -1:
		f(i, 1)
print(ans)


def dfs(x, count):
	global f, ans
	f[x] = True
	if len(sons[x]) == 0:
		ans = max(ans, count)
	for j in sons[x]:
		dfs(j, count + 1)
n = int(input())
root = []
sons = [[] for i in range(n + 1)]
for i in range(1, n + 1):
	x = int(input())
	if x == -1:
		root.append(i)
	else:
		sons[x].append(i)
f = [False] * (n + 1)
ans = 0
for i in root:
	dfs(i, 1)
print(ans)


import sys
sys.setrecursionlimit(1000000)
n = int(input())
graph = dict()
for i in range(n):
	graph[i] = []
for i in range(n):
	x = int(input()) - 1
	if x != -2:
		graph[x].append(i)
depths = []

def dfs(i, d):
	if len(graph[i]) == 0:
		depths.append(d)
	else:
		for _ in graph[i]:
			dfs(_, d + 1)
for i in range(n):
	dfs(i, 1)
print(max(depths))


maxint = int(100000.0)
ad = [[] for i in range(maxint)]

def dfs(n):
	res = 0
	for i in range(len(ad[n])):
		res = max(res, dfs(ad[n][i]))
	return res + 1
n = int(input())
for i in range(1, n + 1):
	x = int(input())
	if x == -1:
		ad[0].append(i)
	else:
		ad[x].append(i)
print(dfs(0) - 1)


n = int(input())
a = []
for i in range(n):
	a.append(int(input()))
ans = 0
for i in range(n):
	count = 1
	j = a[i]
	while j != -1:
		count += 1
		j = a[j - 1]
	if count > ans:
		ans = count
print(ans)


class node:

	def __init__(self, n, l):
		self.num = n
		self.link = l
n = int(input())
l = []
adj = [[]]
for i in range(n):
	l.append(int(input()))
	adj.append([])
w = []
for i in range(n):
	if l[i] == -1:
		w.append(i + 1)
	else:
		adj[l[i]].append(i + 1)
m = -1
for i in range(len(w)):
	k = [w[i]]
	c = 0
	while k != []:
		p = len(k)
		for j in range(p):
			k = k + adj[k[0]]
			k = k[1:]
		c += 1
	m = max(m, c)
print(m)


def search(parent):
	ans = 0
	for i in range(1, n + 1):
		cnt = 1
		while parent[i] != -1:
			i = parent[i]
			cnt += 1
		ans = max(ans, cnt)
	return ans
n = int(input())
parent = [-1 for i in range(2005)]
for i in range(1, n + 1):
	parent[i] = int(input())
print(search(parent))


n = int(input())
array = []
for i in range(n):
	a = int(input())
	array.append(a)
ans = 0
for i in range(n):
	index = i
	temp = 0
	while array[index] != -1:
		temp += 1
		index = array[index] - 1
	if temp > ans:
		ans = temp
print(ans + 1)


class hierarchy:
	lookup = dict()

	def __init__(self, num, manager_num, manager=None):
		self.manager = manager
		self.manager_num = manager_num
		self.num = num

	def get_level(self):
		if self.manager == None:
			return 0
		else:
			count = 0
			superior = self.manager
			while superior != None:
				count += 1
				superior = superior.manager
			return count
employee_num = int(input())
employees = []
for x in range(employee_num):
	manager_num = int(input())
	emp_obj = hierarchy(x, manager_num)
	employees.append(emp_obj)
	hierarchy.lookup[x + 1] = emp_obj
for emp in employees:
	emp.manager = hierarchy.lookup.get(emp.manager_num)
levels = set([emp.get_level() for emp in employees])
print(len(levels))


n = int(input())
a = [-2]
k = 0
for i in range(1, n + 1):
	a.append(int(input()))
ind = []
while True:
	for i in range(len(a)):
		if a[i] == -1:
			a[i] = -2
			ind.append(i)
	if ind == []:
		break
	k += 1
	for i in range(len(ind)):
		nach = ind[i]
		for j in range(len(a)):
			if a[j] == nach:
				a[j] = -1
	ind = []
print(k)


def search_depth(employee_mapping, number):
	if number not in employee_mapping:
		return 1
	max_depth = 0
	for employee in employee_mapping[number]:
		depth = search_depth(employee_mapping, employee)
		if depth > max_depth:
			max_depth = depth
	return max_depth + 1

def func():
	employee_mapping = {}
	n = int(input())
	for i in range(n):
		manager_number = int(input())
		if manager_number not in employee_mapping:
			employee_mapping[manager_number] = []
		employee_mapping[manager_number].append(i + 1)
	depth = search_depth(employee_mapping, -1)
	print(depth - 1)
func()


def __dfs(node, visited, graph, c):
	temp = c
	if visited[node]:
		return c
	visited[node] = True
	for i in graph.get(node, []):
		c = max(c, __dfs(i, visited, graph, temp + 1))
	return c

def dfsAll(n, graph):
	c = 1
	visited = [False] * n
	for ii in graph:
		if visited[ii] == False:
			tt = __dfs(ii, visited, graph, 1)
			c = max(c, tt)
	print(c)
t = int(input())
graph = {}
tempg = []
for x in range(t):
	temp = int(input())
	tempg.append((x, temp))
tempg.sort(key=lambda x: x[-1])
for x in tempg:
	if x[1] != -1:
		if graph.get(x[1] - 1) == None:
			graph[x[1] - 1] = []
		graph[x[1] - 1].append(x[0])
	elif x[1] == -1:
		if graph.get(x[0]) == None:
			graph[x[0]] = []
for i in range(t):
	if graph.get(i) == None:
		graph[i] = []
dfsAll(t, graph)


from collections import defaultdict as dc

class Graph:

	def __init__(self):
		self.color = dc(int)
		self.parent = dc(int)
		self.adjlist = dc(list)
		self.d = dc(int)
		self.m = 0
		self.a = []

	def addedge(self, a, b, co):
		self.color[a] = 'white'
		self.color[b] = 'white'
		self.adjlist[a].append(b)

	def printlist(self):
		print(self.m)

	def bfs(self, i):
		self.color[i] = 'gray'
		self.d[i] = 0
		self.a.append(i)
		while len(self.a) > 0:
			p = self.a.pop(0)
			for i in self.adjlist[p]:
				if self.color[i] == 'white':
					self.color[i] = 'gray'
					self.parent[p] = i
					self.d[i] = self.d[p] + 1
					self.m = max(self.d[i], self.m)
					self.a.append(i)
			self.color[p] = 'black'
n = int(input())
g = Graph()
b = []
for i in range(n):
	a = int(input())
	g.addedge(a, i + 1, 0)
	if a == -1:
		b.append(i + 1)
g.bfs(-1)
g.printlist()


n = int(input())
list = 2000 * [-3]
for i in range(n):
	k = int(input())
	list[i] = k - 1
max = 0
for i in range(n):
	c = 0
	k = i
	while k >= 0:
		k = list[k]
		c += 1
	if c > max:
		max = c
print(max)


q = int(input())
r = [[] for _ in range(q)]
e = []
t = []
for i in range(q):
	w = int(input())
	r[i].append(w)
	e.append(w)
for i in range(q):
	while r[i][-1] != -1:
		r[i].append(e[r[i][-1] - 1])
	t.append(len(r[i]))
print(max(t))


import sys
n = int(input())
g = [0] * n
for i in range(n):
	a = int(input())
	g[i] = a - 1
lens = [0] * n
sys.setrecursionlimit(3000)

def dfs(start, temp):
	lens[temp] += 1
	if g[start] != -2:
		dfs(g[start], temp)
for i in range(n):
	dfs(i, i)
print(max(lens))


import sys

def dfs(used, graf, now, m):
	used[now] = 1
	global ma
	n = m
	for i in graf[now]:
		if used[i] != 1:
			m += 1
			if m > ma:
				ma = m
			dfs(used, graf, i, m)
		m = n
sys.setrecursionlimit(10 ** 5)
n = int(input())
ma = 0
p = []
graf = [[] for i in range(n + 1)]
used = [0 for i in range(n + 1)]
used[0] = 1
for i in range(1, n + 1):
	k = int(input())
	if k != -1:
		graf[k].append(i)
	else:
		p.append(i)
for i in range(len(p)):
	dfs(used, graf, p[i], 1)
if ma == 0:
	print(1)
else:
	print(ma)


import sys
sys.setrecursionlimit(10000)
n = int(input())
children = [[] for _ in range(n)]
parents = [-1] * n
for node in range(n):
	parent = int(input())
	if parent != -1:
		parents[node] = parent - 1
		children[parent - 1].append(node)

def dfs(node, children, depth):
	if not children[node]:
		return depth
	return max((dfs(child, children, depth + 1) for child in children[node]))
print(max((dfs(root, children, 1) for root in range(n) if parents[root] == -1)))


from sys import setrecursionlimit
setrecursionlimit(3001)

def get_depth(root, dic, depth=0):
	if root in dic.keys():
		max_depth = depth
		for new_root in dic[root]:
			new_depth = get_depth(new_root, dic, depth + 1)
			if new_depth > max_depth:
				max_depth = new_depth
		return max_depth
	else:
		return depth
n = int(input())
dic = dict()
roots = []
for i in range(n):
	k = int(input())
	if k == -1:
		roots.append(i + 1)
	elif k in dic.keys():
		dic[k].append(i + 1)
	else:
		dic[k] = [i + 1]
max_depth = 0
for root in roots:
	depth = get_depth(root, dic)
	if depth > max_depth:
		max_depth = depth
print(max_depth + 1)


from sys import stdin, setrecursionlimit, stdout
from collections import deque
from math import sqrt, floor, ceil, log, log2, log10, pi, gcd, sin, cos, asin
from heapq import heapify, heappop, heappush, heapreplace, heappushpop

def ii():
	return int(stdin.readline())

def fi():
	return float(stdin.readline())

def mi():
	return map(int, stdin.readline().split())

def fmi():
	return map(float, stdin.readline().split())

def li():
	return list(mi())

def si():
	return stdin.readline().rstrip()

def lsi():
	return list(si())
test_case = 1
while test_case:
	test_case -= 1
	n = ii()
	a = [[] for _ in range(n + 1)]
	root = []
	val = [0] * (n + 1)
	for i in range(n):
		x = ii()
		if x == -1:
			root.append(i + 1)
		else:
			a[x].append(i + 1)
	v = [1] * (n + 1)
	for i in root:
		q = deque([i])
		v[i] = 0
		while q:
			x = q.popleft()
			for j in a[x]:
				if v[j]:
					v[j] = 0
					q.append(j)
					val[j] = val[x] + 1
	print(len(set(val)))


n = int(input())
L = []
c = 1
for i in range(n):
	a = int(input())
	if a != -1:
		a -= 1
	L += [a]
for i in range(n):
	c0 = 1
	e = i
	while L[e] > -1:
		c0 += 1
		e = L[e]
	c = max(c, c0)
print(c)


import sys
sys.setrecursionlimit(1000000)

def dfs(x):
	if len(child[x]) == 0:
		H[x] = 1
	else:
		mx = 0
		for y in child[x]:
			dfs(y)
			mx = max(mx, H[y] + 1)
		H[x] = mx
n = int(input())
child = [[] for _ in range(n)]
pa = [-1 for _ in range(n)]
root = []
for i in range(n):
	x = int(input())
	if x == -1:
		root.append(i)
		continue
	pa[i] = x - 1
	child[x - 1].append(i)
H = [0 for _ in range(n)]
group = 0
for r in root:
	dfs(r)
	group = max(group, H[r])
print(group)


class node:

	def __init__(self, data):
		self._data = data
		self._children = []

	def add(self, node):
		self._children.append(node)

	def is_leaf(self):
		return len(self._children) == 0

	def height(self):
		if self.is_leaf():
			return 0
		else:
			return 1 + max((c.height() for c in self._children))
import sys
sys.setrecursionlimit(1000000)
n = int(input())
tree = []
tree.append(node(0))
boolean = 1
for i in range(n):
	tree.append(node(i + 1))
for i in range(n):
	s = int(input())
	if s > 0:
		tree[s].add(tree[i + 1])
	else:
		tree[0].add(tree[i + 1])
print(tree[0].height())


import sys
import threading
from collections import defaultdict
n = int(input())
adj = defaultdict(list)
for i in range(n):
	adj[int(input())].append(i + 1)

def fun(root, par, adj):
	ans = 0
	for ch in adj.get(root, []):
		if ch != par:
			ans = max(ans, fun(ch, root, adj))
	return 1 + ans

def main():
	ans = -1
	for i in adj[-1]:
		ans = max(ans, fun(i, -1, adj))
	print(ans)
sys.setrecursionlimit(10 ** 6)
threading.stack_size(10 ** 8)
t = threading.Thread(target=main)
t.start()
t.join()


from copy import copy as cp
rt = []
a = {}
for i in range(int(input())):
	t = int(input())
	if t == -1:
		rt += [i + 1]
	if t in a:
		a[t] += [i + 1]
	else:
		a[t] = [i + 1]
x = rt
y = []
k = 1
while True:
	for i in x:
		try:
			y += a[i]
		except:
			pass
	if y != []:
		k += 1
		x = cp(y)
		y = []
	else:
		break
print(k)


n = int(input())
parent = []
for i in range(n):
	parent.append(int(input()) - 1)
res = float('-inf')
for i in range(n):
	depth = 0
	while i != -2:
		depth += 1
		i = parent[i]
	res = max(res, depth)
print(res)


def sol1():
	n = int(input())
	A = []
	ans = 0
	for i in range(n):
		A.append(int(input()) - 1)
	for i in range(n):
		j = i
		k = 0
		while A[j] >= 0:
			j = A[j]
			k += 1
		if k > ans:
			ans = k
	print(ans + 1)

def sol():
	n = int(input())
	A = []
	for i in range(n):
		A.append(int(input()) - 1)
	dp = [1] * n
	for i in range(n):
		if A[i] == -2:
			dp[i] = 1
		else:
			dp[i] = dp[A[i]] + 1
		print(dp)
	print(max(dp))
sol1()


from collections import deque

def inc_level_sons(emp):
	queue = deque()
	queue.append(emp)
	while queue:
		emp = queue.popleft()
		for e in emps[emp]:
			emps_level[e] = emps_level[emp] + 1
			queue.append(e)
n = int(input())
emps = [[] for i in range(2005)]
emps_level = [1] * 2005
for i in range(n):
	e = int(input())
	if e != -1:
		emps[e].append(i + 1)
		emps_level[i + 1] = emps_level[e] + 1
		inc_level_sons(i + 1)
print(str(max(emps_level)))


n1 = n = int(input())
arr = []
while n1:
	n1 -= 1
	arr.append(int(input()))
for i in range(n):
	number = arr[i]
	if number == -1:
		continue
	arr[i] = arr[i] - 1
startingindices = []
for i in range(n):
	if i not in arr:
		startingindices.append(i)
maxi = 1
for index in startingindices:
	if arr[index] == -1:
		continue
	count = 1
	nxt = arr[index]
	while nxt != -1:
		count += 1
		nxt = arr[nxt]
	maxi = max(count, maxi)
print(maxi)


import atexit
import io
import sys
from collections import deque
sys.setrecursionlimit(123456)
_I_B = sys.stdin.read().splitlines()
input = iter(_I_B).__next__
_O_B = io.StringIO()
sys.stdout = _O_B

@atexit.register
def write():
	sys.__stdout__.write(_O_B.getvalue())
md = 0

def depth(root, mrt, d):
	global md
	d += 1
	md = max(md, d)
	for i in mrt[root]:
		depth(i, mrt, d)

def main():
	global md
	mrt = dict()
	roots = []
	for _ in range(int(input())):
		m = int(input())
		try:
			mrt[_ + 1]
		except KeyError:
			mrt[_ + 1] = []
		if m == -1:
			roots.append(_ + 1)
		else:
			try:
				mrt[m].append(_ + 1)
			except KeyError:
				mrt[m] = [_ + 1]
	levels = 0
	for root in roots:
		md = 0
		depth(root, mrt, 0)
		levels = max(levels, md)
	print(levels)
main()


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
n = int(input())
p = [int(input()) for i in range(n)]
g = 0
for i in range(n):
	c = 0
	while i >= 0:
		i = p[i] - 1
		c += 1
	g = max(g, c)
print(g)


from functools import reduce
from operator import *
from math import *
from sys import *
from string import *
setrecursionlimit(10 ** 7)
RI = lambda : list(map(int, input().split()))
RS = lambda : input().rstrip().split()
n = RI()[0]
root = -1
nodes = {i: [] for i in range(n + 1)}

def getHeight(root):
	if nodes[root] == []:
		return 1
	return max((getHeight(r) for r in nodes[root])) + 1
for i in range(1, n + 1):
	p = RI()[0]
	if p == -1:
		p = 0
	nodes[p].append(i)
print(getHeight(0) - 1)


def tree_input(m):
	l = {i: [] for i in range(1, m + 1)}
	for i in range(1, m + 1):
		b = int(input())
		l[i].append(b)
	return l
n = int(input())
l = tree_input(n)
c = 0

def dfs(x):
	v = {i: False for i in l}
	q = [x]
	c = 1
	while len(q) != 0:
		temp = q[0]
		q.pop(0)
		for i in l[temp]:
			if i == -1:
				break
			if v[i]:
				continue
			v[i] = True
			c += 1
			q.append(i)
	return c
out = 0
for i in l:
	out = max(out, dfs(i))
print(out)


(z, zz) = (input, lambda : list(map(int, z().split())))
zzz = lambda : [int(i) for i in stdin.readline().split()]
(szz, graph, mod, szzz) = (lambda : sorted(zz()), {}, 10 ** 9 + 7, lambda : sorted(zzz()))
from string import *
from collections import *
from queue import *
from sys import *
from collections import *
from math import *
from heapq import *
from itertools import *
from bisect import *
from collections import Counter as cc
from math import factorial as f
from bisect import bisect as bs
from bisect import bisect_left as bsl
from itertools import accumulate as ac

def lcd(xnum1, xnum2):
	return xnum1 * xnum2 // gcd(xnum1, xnum2)

def prime(x):
	p = ceil(x ** 0.5) + 1
	for i in range(2, p):
		if x % i == 0 and x != 2 or x == 0:
			return 0
	return 1

def dfs(u, visit, graph):
	visit[u] = True
	for i in graph[u]:
		if not visit[i]:
			dfs(i, visit, graph)
n = int(z())
p = [int(z()) for _ in range(n)]
g = 0
for i in range(n):
	c = 0
	while i >= 0:
		i = p[i] - 1
		c += 1
	g = max(g, c)
print(g)


n = int(input())
lst = [int(input()) for i in range(n)]
count = 0
for i in range(n):
	flg = 0
	while i >= 0:
		i = lst[i] - 1
		flg += 1
	count = max(count, flg)
print(count)


def dfs(v):
	global counter
	global maxi
	counter = 1
	i = v
	while len(a[i]) != 0:
		i = a[i][0]
		counter += 1
	maxi = max(counter, maxi)
maxi = -1
n = int(input())
a = []
b = []
for i in range(n):
	c = []
	d = []
	a.append(c)
	b.append(d)
for i in range(n):
	x = int(input())
	if x != -1:
		x -= 1
		a[i].append(x)
		b[x].append(i)
for i in range(n):
	dfs(i)
print(maxi)


import sys
sys.setrecursionlimit(3000)
N = int(input())
d = {}
for i in range(N):
	a = int(input())
	if a == -1:
		continue
	if a not in d:
		d[a] = [i + 1]
	else:
		d[a].append(i + 1)
color = [0 for i in range(N + 1)]

def rec(i, cl):
	color[i] = cl
	if i in d:
		for a in d[i]:
			rec(a, cl + 1)
for i in range(1, N + 1):
	if color[i] == 0:
		rec(i, 1)
ans = max(color)
print(ans)


import sys
sys.setrecursionlimit(10000)

def max_depth(dictionary, parent, depth=0):
	children = [key for key in dictionary.keys() if dictionary[key] == parent]
	if len(children) == 0:
		return depth
	else:
		depth += 1
		children_depth = [max_depth(dictionary, child, depth=depth) for child in children]
		return max(children_depth)
hierarchy = {}
n = int(input())
for i in range(n):
	employee = int(input())
	hierarchy[i] = employee - 1
trees_depth = [max_depth(hierarchy, key) for key in hierarchy.keys() if hierarchy[key] == -2]
print(max(trees_depth) + 1)


n = int(input())
stack = []
matrix = [[0] * n for i in range(n)]
for i in range(n):
	x = int(input())
	if x == -1:
		stack.append([i, 1])
	else:
		matrix[x - 1][i] = 1
k = 0
while stack:
	cur = stack.pop(0)
	if k < cur[1]:
		k = cur[1]
	for i in range(n):
		if matrix[cur[0]][i]:
			stack.append([i, cur[1] + 1])
print(k)


def get_height(tree, i):
	stack = []
	while tree[i][1] is None:
		stack.append(i)
		i = tree[i][0]
	while stack:
		i = stack.pop()
		tree[i][1] = tree[tree[i][0]][1] + 1
	return tree[i][1]
n = int(input())
tree = [[None, None, []] for _ in range(n)]
for i in range(n):
	tree[i][0] = int(input()) - 1
	if tree[i][0] == -2:
		tree[i][1] = 1
max_height = 0
for i in range(n):
	max_height = max(max_height, get_height(tree, i))
print(max_height)


from collections import defaultdict
n = int(input())
graph = {}
graph = defaultdict(lambda : -1, graph)
for i in range(1, n + 1):
	ele = int(input())
	graph[i] = ele
depth = 0
for i in range(1, n + 1):
	count = 0
	ele = i
	while ele != -1:
		count += 1
		ele = graph[ele]
	depth = max(count, depth)
print(depth)


import sys
sys.setrecursionlimit(2050)
n = int(input())
d = {}
ll = []
mx = 0
roots = []
for i in range(1, n + 1):
	d[i] = set()
for i in range(1, n + 1):
	m = int(input())
	if m == -1:
		roots.append(i)
	else:
		d[m].add(i)
level = [-1] * (n + 1)
lvl = 1
dep = 0
ans = -1

def dfs(s):
	global visited, n, dep, ans, K
	dep += 1
	if dep > ans:
		ans = dep
	visited[s] = 1
	for i in d[s]:
		if visited[i] == 0:
			dfs(i)
	dep -= 1
for K in roots:
	dep = 0
	visited = [0] * (n + 1)
	dfs(K)
	for j in range(1, n + 1):
		if visited[j] == 0:
			if dep >= ans:
				ans = dep
			dfs(j)
		break
print(ans)


import sys
sys.setrecursionlimit(4000)
n = int(input())
a = []
for i in range(n):
	a.append(int(input()) - 1)
d = [0] * n

def spam(e, c):
	global a
	c += 1
	if e == -2:
		return c
	elif d[e] != 0:
		return c + d[e]
	else:
		return spam(a[e], c)
for e in range(n):
	d[e] = spam(a[e], 0)
print(max(d))


n = int(input())
a = [0]
for i in range(n):
	a.append(int(input()))
mem = [False] * (n + 1)
mx = 0
for i in range(1, n + 1):
	if not mem[i]:
		count = 1
		j = i
		while a[j] != -1:
			count += 1
			mem[j] = True
			j = a[j]
		mx = max(mx, count)
print(mx)


n = int(input())
a = [int(input()) for _ in range(n)]
r = 0
for i in range(n):
	c = 0
	while i >= 0:
		i = a[i] - 1
		c += 1
	r = max(r, c)
print(r)


from collections import deque
n = int(input())
r = (n + 1) * [1]
s = [[] for i in range(0, n + 1)]
for i in range(1, n + 1):
	p = int(input())
	if p == -1:
		s[0].append(i)
	else:
		s[p].append(i)
q = deque(s[0])
while q:
	p = q.popleft()
	for i in s[p]:
		q.append(i)
		r[i] = r[p] + 1
print(max(r))


from collections import defaultdict

class Graph:

	def __init__(self):
		self.graph = defaultdict(list)

	def addEdge(self, u, v):
		self.graph[u].append(v)

	def dfs(self, visited, v, num, group):
		visited[v] = True
		group[v] = num
		for i in self.graph[v]:
			if visited[i] == False:
				self.dfs(visited, i, num + 1, group)

	def DFSUtil(self, root, V):
		visited = [False] * (V + 1)
		group = [-1] * (V + 1)
		num = 1
		for i in range(1, V + 1):
			if root[i] == True:
				self.dfs(visited, i, num, group)
		return max(group)
n = int(input())
root = [True] * (n + 1)
g = Graph()
for i in range(1, n + 1):
	k = int(input())
	if k != -1:
		g.addEdge(k, i)
		root[i] = False
print(g.DFSUtil(root, n))


import collections
n = int(input())
l = []
g = []
for i in range(n):
	l.append(-1)
	g.append([])
for i in range(n):
	p = int(input())
	l[i] = max(p - 1, -1)
	if p != -1:
		g[p - 1].append(i)
q1 = collections.deque([])
q2 = collections.deque([])
count = 1
for i in range(len(l)):
	if l[i] == -1:
		q1.append(i)
flip = 0
while len(q1) != 0 or len(q2) != 0:
	if flip == 0:
		if len(q1) == 0:
			break
		else:
			for i in g[q1[0]]:
				q2.append(i)
			q1.popleft()
		if len(q1) == 0 and len(q2) != 0:
			flip = 1
			count += 1
	else:
		if len(q2) == 0:
			break
		else:
			for i in g[q2[0]]:
				q1.append(i)
			q2.popleft()
		if len(q2) == 0 and len(q1) != 0:
			flip = 0
			count += 1
print(count)


def find(i):
	t = 0
	while par[i] != 0:
		i = par[i]
		t += 1
	return t
n = int(input())
t = 0
par = [0 for i in range(n + 1)]
d = {}
for _ in range(1, n + 1):
	x = int(input())
	if x != -1:
		par[_] = x
	else:
		par[_] = 0
ans = 0
for i in range(1, n + 1):
	r = find(i)
	t = 0
	ans = max(r, ans)
print(ans + 1)


n = int(input())
mx = 1
a = [[] for i in range(n)]
for i in range(n):
	x = int(input())
	a[i].append(x - 1)
for i in range(n):
	s = i
	cnt = 0
	if len(a[i]) == 0:
		continue
	while True:
		cnt += 1
		if a[s][0] == -2:
			break
		else:
			s = a[s][0]
	mx = max(mx, cnt)
print(mx)


import os.path
from math import gcd, floor, ceil
from collections import *
import sys
mod = 1000000007
INF = float('inf')

def st():
	return list(sys.stdin.readline().strip())

def li():
	return list(map(int, sys.stdin.readline().split()))

def lis():
	return list(map(str, sys.stdin.readline().split()))

def mp():
	return map(int, sys.stdin.readline().split())

def inp():
	return int(input())

def pr(n):
	return sys.stdout.write(str(n) + '\n')

def prl(n):
	return sys.stdout.write(str(n) + ' ')
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
mod = 1000000007
INF = float('inf')
Y = 'YES'
N = 'NO'

def bfs(g, i):
	q = [i]
	grp = 0
	while len(q):
		n = len(q)
		while n:
			cur = q.pop(0)
			for nbr in g[cur]:
				q.append(nbr)
			n -= 1
		grp += 1
	return grp

def solve():
	n = inp()
	g = [[] for _ in range(n + 1)]
	for i in range(n):
		s = inp()
		if s == -1:
			continue
		g[s].append(i + 1)
	grps = float('-inf')
	for i in range(1, n + 1):
		grps = max(grps, bfs(g, i))
	print(grps)
for test in range(1):
	solve()


n = int(input())
d = [0] * n
for i in range(n):
	v = int(input())
	if v != -1:
		v -= 1
	d[i] = v
max_w = 0
for i in range(n):
	weight = 1
	cur = i
	while d[cur] != -1:
		weight += 1
		cur = d[cur]
	if weight > max_w:
		max_w = weight
print(max_w)


import math
from collections import deque

def findDepth(val, dic):
	q = deque()
	d = deque()
	c = val
	q.append(c)
	d.append(1)
	dp = []
	while len(q) > 0:
		c = q[0]
		dHere = d[0]
		dp.append(dHere)
		q.popleft()
		d.popleft()
		for (k, v) in dic.items():
			if v == c:
				q.append(k)
				d.append(dHere + 1)
	return max(dp)
n = int(input())
dic1 = {}
for i in range(n):
	p2 = int(input())
	p1 = i + 1
	dic1[p1] = p2
	if p2 == -1:
		dic1[p1] = 'ROOT'
	if p2 not in dic1 and p2 != -1:
		dic1[p2] = 'ROOT'
depth = []
for (key, value) in dic1.items():
	if value == 'ROOT':
		depth.append(findDepth(key, dic1))
print(max(depth))


import sys
import math
import string
N = int(sys.stdin.readline())
a = [0]
for x in range(1, N + 1):
	a.append(int(sys.stdin.readline()))
res = 0
for x in range(1, N + 1):
	count = 0
	superior = a[x]
	while superior >= 0:
		superior = a[superior]
		count += 1
	res = count if count > res else res
print(res + 1)


import sys
input = sys.stdin.readline

def dfs(start, cnt):
	if armylist[start] == []:
		return cnt
	for pre in armylist[start]:
		return dfs(pre, cnt + 1)
n = int(input())
armylist = [[] for _ in range(n + 1)]
for start in range(1, n + 1):
	pre = int(input())
	if pre == -1:
		continue
	armylist[start].append(pre)
maxcnt = 0
for i in range(1, n + 1):
	maxcnt = max(maxcnt, dfs(i, 1))
print(maxcnt)


I0 = lambda : map(int, input().split())
I1 = lambda : int(input())
I2 = lambda : list(map(int, input().split()))
from collections import defaultdict

def Tree_Height(f, tree):
	l = len(g[f])
	if l == 0:
		return 1
	M = -1
	for i in g[f]:
		M = max(M, Tree_Height(i, tree) + 1)
	return M
g = defaultdict(list)
root = list()
n = I1()
M = -float('inf')
for i in range(n):
	p = I1()
	if p == -1:
		root.append(i + 1)
	else:
		g[p].append(i + 1)
for father in root:
	M = max(M, Tree_Height(father, g))
print(M)


import sys
sys.setrecursionlimit(1000000)
n = int(input())
graph = [[] for i in range(n)]
for i in range(n):
	pi = int(input())
	if pi != -1:
		graph[pi - 1].append(i)
res = 0
dist = [-1] * n

def dfs(u):
	if dist[u] != -1:
		return dist[u]
	res = 1
	for v in graph[u]:
		res = max(res, dfs(v) + 1)
	dist[u] = res
	return res
for i in range(n):
	res = max(res, dfs(i))
print(res)


n = int(input())
arr = [[0 for _ in range(n)] for _ in range(n)]
roots = []
for i in range(n):
	x = int(input())
	if x == -1:
		arr[i][i] = -1
		roots.append(i)
	else:
		arr[i][x - 1] = 1
longest = -1
for x in roots:
	v = [False] * n
	stack = []
	l = 0
	stack.append(x)
	while True:
		count = len(stack)
		if count == 0:
			break
		l += 1
		while count > 0:
			e = stack.pop(0)
			v[e] = True
			for i in range(n):
				if arr[i][e] == 1 and (not v[i]):
					stack.append(i)
			count -= 1
	if l > longest:
		longest = l
print(longest)


from queue import Queue

def heightByBfs(src, graph):
	q = Queue()
	q.put(src - 1)
	currLevel = 1
	nxtLevel = 0
	level = 0
	while not q.empty():
		curr = q.get()
		currLevel -= 1
		for child in graph[curr]:
			q.put(child - 1)
			nxtLevel += 1
		if currLevel == 0:
			level += 1
			currLevel = nxtLevel
			nxtLevel = 0
	return level

def solve():
	sources = []
	n = int(input())
	graph = [[] for _ in range(n)]
	for i in range(n):
		src = int(input())
		yeah = False
		if src == -1:
			sources.append(i + 1)
		else:
			graph[src - 1].append(i + 1)
	if yeah:
		print('What is the damn BUG!!!!!!')
	res = 0
	for src in sources:
		res = max(res, heightByBfs(src, graph))
	print(res)
	return
solve()


import math
import atexit
import io
import sys
_OUTPUT_BUFFER = io.StringIO()
sys.stdout = _OUTPUT_BUFFER

@atexit.register
def write():
	sys.__stdout__.write(_OUTPUT_BUFFER.getvalue())

def array_to_string(a):
	s = ''
	for i in a:
		s += str(i)
	return s

def gcd(a, b):
	if a == 0:
		return b
	return gcd(b % a, a)

def lcm(a, b):
	return a * b / gcd(a, b)
n = int(input())
d = dict()
depth = dict()
temp = []
for i in range(n):
	inp = int(input())
	if inp != -1:
		if depth.get(inp):
			depth[i + 1] = depth[inp] + 1
		else:
			temp.append((inp, i + 1))
	else:
		depth[i + 1] = 1
while len(temp) > 0:
	for i in temp:
		if depth.get(i[0]):
			depth[i[1]] = depth[i[0]] + 1
			temp.remove((i[0], i[1]))
print(max(depth.values()))


n = int(input())
p = [int(input()) for i in range(n)]
ans = 0
c = 0
for i in range(0, n):
	c = 0
	x = i
	while x >= 0:
		c += 1
		x = p[x] - 1
	ans = max(ans, c)
print(ans)


def countit(index, x):
	count = 1
	while x[index] != -1:
		index = x[index] - 1
		count += 1
	return count
n = int(input())
x = []
for i in range(n):
	x.append(int(input()))
count = 0
total = -1
for i in range(len(x)):
	count = countit(i, x)
	if count > total:
		total = count
print(total)


n = int(input())
arr = [int(input()) - 1 for i in range(n)]
levels = []
for i in range(n):
	level = 0
	current = arr[i]
	while current != -2:
		current = arr[current]
		level += 1
	levels.append(level)
print(max(levels) + 1)


import sys

def party(n, managers):

	def DFS(p):
		if p in memo:
			return memo[p]
		elif managers[p] < 0:
			memo[p] = 1
			return 1
		else:
			res = 1 + DFS(managers[p])
			memo[p] = res
			return res
	memo = {}
	longest = 0
	for p in range(n):
		longest = max(longest, DFS(p))
	return longest
sys.setrecursionlimit(3000)
n = int(input())
managers = []
for i in range(n):
	manager = int(input()) - 1
	managers.append(manager)
res = party(n, managers)
print(res)


from collections import *

class graph:

	def __init__(self, gdict=None):
		if gdict is None:
			gdict = defaultdict(list)
		(self.gdict, self.edges) = (gdict, [])

	def get_vertices(self):
		return list(self.gdict.keys())

	def add_edge(self, node1, node2):
		self.gdict[node1].append(node2)
		self.edges.append([node1, node2])

	def bfs_util(self, i):
		(queue, self.visit[i], level) = (deque([[i, 1]]), 1, 1)
		while queue:
			(s, level) = queue.popleft()
			for i in self.gdict[s]:
				if self.visit[i] == 0:
					queue.append([i, level + 1])
					self.visit[i] = 1
		return level

	def bfs(self):
		(self.visit, self.cnt) = (defaultdict(int), 0)
		for i in pars:
			if self.visit[i] == 0:
				self.cnt = max(self.bfs_util(i), self.cnt)
		return self.cnt
(n, g, pars) = (int(input()), graph(), [])
for i in range(1, n + 1):
	x = int(input())
	if x == -1:
		pars.append(i)
	else:
		g.add_edge(x, i)
print(g.bfs())


n = int(input())
a = [0] + [int(input()) for i in range(n)]
m = 1
for i in range(1, n + 1):
	l = 1
	p = a[i]
	while p != -1:
		l += 1
		p = a[p]
	m = max(l, m)
print(m)


mod = 1000000007
ii = lambda : int(input())
si = lambda : input()
dgl = lambda : list(map(int, input()))
f = lambda : map(int, input().split())
il = lambda : list(map(int, input().split()))
ls = lambda : list(input())
n = ii()
nodes = [ii() - 1 for i in range(n)]
mx = 1
for i in range(n):
	x = nodes[i]
	c = 1
	while x != -2:
		c += 1
		x = nodes[x]
	mx = max(mx, c)
print(mx)


from collections import deque, Counter
import array
from itertools import combinations, permutations
from math import sqrt
import unittest

def read_int():
	return int(input().strip())

def read_int_array():
	return [int(i) for i in input().strip().split(' ')]
n = read_int()
P = [int(input().strip()) for _ in range(n)]
H = [0] * n
max_h = 0
for i in range(n):
	v = P[i]
	h = 1
	while v != -1 and H[v - 1] < h:
		H[v - 1] = h
		v = P[v - 1]
		h += 1
	h -= 1
	if h > max_h:
		max_h = h
print(max_h + 1)


def dfs(vertice):
	pilha = [vertice]
	maiorDistancia = 1
	distancias = {vertice: 1}
	while len(pilha) > 0:
		vertice = pilha.pop()
		if adjacencias.get(vertice) != None:
			for v in adjacencias[vertice]:
				if distancias.get(v) == None:
					distancias[v] = distancias[vertice] + 1
					maiorDistancia = max(maiorDistancia, distancias[v])
					pilha.append(v)
	return maiorDistancia
n = int(input())
adjacencias = {}
numGrupos = 0
i = 1
while i <= n:
	vertice = int(input())
	if adjacencias.get(vertice) == None:
		adjacencias[vertice] = []
	adjacencias[vertice].append(i)
	i += 1
for vertice in adjacencias[-1]:
	numGrupos = max(dfs(vertice), numGrupos)
print(numGrupos)


def dfs(node):
	level = 0
	for i in adj[node]:
		level = max(level, dfs(i))
	return level + 1
n = int(input())
adj = [[] for x in range(n)]
for x in range(n):
	i = int(input())
	if i != -1:
		adj[i - 1].append(x)
ans = max([dfs(x) for x in range(n)])
print(ans)


m = 0
x = int(input())
l = [int(input()) for i in range(x)]
for i in range(x):
	c = 0
	while i >= 0:
		i = l[i] - 1
		c += 1
	m = max(c, m)
print(m)


import sys
from math import sqrt, floor, factorial
from collections import deque, Counter
inp = sys.stdin.readline
read = lambda : list(map(int, inp().strip().split()))

def solve():
	(n, k) = (int(input()), 0)
	(p, r) = ([[] for i in range(n + 1)], [])
	for i in range(1, n + 1):
		j = int(input())
		if j > 0:
			p[j].append(i)
		else:
			r.append(i)
	while r:
		r = [j for i in r for j in p[i]]
		k += 1
	print(k)
solve()


from collections import defaultdict
MaxList = []

class Graph:

	def __init__(self):
		self.graph = defaultdict(list)

	def addEdge(self, fr, to):
		self.graph[fr].append(to)
		self.graph[to].append(fr)

	def BFS(self, root, Visited):
		queue = []
		queue.append(root)
		Visited[root - 1] = True
		count = 0
		while queue:
			InnerQueue = queue.copy()
			while InnerQueue:
				InnerQueue.pop(0)
				current = queue.pop(0)
				for i in self.graph[current]:
					if Visited[i - 1] == False:
						queue.append(i)
						Visited[i - 1] = True
			count += 1
		MaxList.append(count)
N = int(input())
G = Graph()
Visited = [False] * N
List = []
for i in range(N):
	temp = int(input())
	if temp != -1:
		G.graph[temp].append(i + 1)
	else:
		List.append(i + 1)
for i in List:
	G.BFS(i, Visited)
print(max(MaxList))


H = 1

def dfs(g, vis, x, h):
	global H
	if vis[x - 1] != 1:
		vis[x - 1] = 1
	if len(g[x - 1]) == 0:
		H = max(H, h)
	else:
		for i in range(len(g[x - 1])):
			dfs(g, vis, g[x - 1][i], h + 1)
n = int(input())
vis = [0 for i in range(n)]
g = [[] for i in range(n)]
q = []
for i in range(n):
	r = int(input())
	if r != -1:
		g[r - 1].append(i + 1)
	else:
		q.append(i + 1)
for i in range(len(q)):
	dfs(g, vis, q[i], 1)
print(H)


n = int(input())
a = []
for i in range(n):
	a.append(int(input()))
maxsum = 0
for i in range(n):
	if a[i] != -1:
		sum = 1
		j = a[i] - 1
		while a[j] != -1:
			sum += 1
			j = a[j] - 1
		if maxsum < sum:
			maxsum = sum
print(maxsum + 1)


def maxdepth(tree, start):
	queue = [(start, 0)]
	curr = 0
	while curr < len(queue):
		for i in tree[queue[curr][0]]:
			queue.append((i, queue[curr][1] + 1))
		curr += 1
	depths = [queue[i][1] for i in range(len(queue))]
	return max(depths)
n = int(input())
tree = {i: [] for i in range(n)}
roots = []
for i in range(n):
	parent = int(input()) - 1
	if parent != -2:
		tree[parent].append(i)
	else:
		roots.append(i)
ans = 0
for i in roots:
	s = maxdepth(tree, i)
	if s > ans:
		ans = s
print(ans + 1)


from sys import stdin, stdout

def main():
	data = []
	count = 0
	n = int(stdin.readline())
	for i in range(0, n + 1):
		data.append(0)
	for i in range(1, n + 1):
		data[i] = int(stdin.readline())
	for i in range(1, n + 1):
		currentCounter = 0
		currentData = data[i]
		while currentData != -1:
			currentData = data[currentData]
			currentCounter = currentCounter + 1
		if count < currentCounter:
			count = currentCounter
	count = count + 1
	stdout.write(str(count))
main()


n = int(input())
data = [int(input()) for _ in range(n)]
grup = 0
for i in range(n):
	tmp = 0
	while i >= 0:
		i = data[i] - 1
		tmp += 1
	if grup <= tmp:
		grup = tmp
print(grup)


class Node:

	def __init__(self, val):
		self.val = val
		self.depth = 0
		self.visited = False
		self.neighbors = []

def dfs(node):
	stack = []
	stack.append(node)
	while len(stack):
		root = stack.pop(-1)
		if not root.visited:
			groups[root.depth] += 1
			root.visited = True
		for neighbor in root.neighbors:
			if not neighbor.visited:
				neighbor.depth = root.depth + 1
				stack.append(neighbor)
n = int(input())
groups = [0] * 2001
nodes = [None]
for i in range(1, n + 1):
	nodes.append(Node(i))
roots = []
for i in range(n):
	x = int(input())
	if x == -1:
		roots.append(nodes[i + 1])
		continue
	nodes[x].neighbors.append(nodes[i + 1])
for node in roots:
	if len(node.neighbors):
		dfs(node)
count = 0
for group in groups:
	if group:
		count += 1
if count == 0:
	print(1)
else:
	print(count)


n = int(input())
ans = 0
mem = []
for i in range(n):
	mem.append(int(input()))
for i in range(n):
	count = 0
	x = mem[i]
	while x != -1:
		x = mem[x - 1]
		count += 1
	ans = max(ans, count)
print(ans + 1)


a = int(input())
record = []
for i in range(a):
	tmp = int(input())
	record.append(tmp)
maxx = 0
for item in record:
	child = 0
	while True:
		if item == -1:
			maxx = max(child, maxx)
			child = 0
			break
		item = record[item - 1]
		child += 1
print(maxx + 1)


n = int(input())
employee = []
cnt = [0 for i in range(n)]
x = []
for i in range(n):
	m = int(input())
	employee.append(m)
for i in range(n):
	if employee[i] == -1:
		cnt[i] = 1
		x.append(1)
	elif cnt[i] == 0:
		cnt[i] = 1
		nCount = 1
		a = employee[i]
		while True:
			if employee[a - 1] != -1:
				cnt[a - 1] = 1
				nCount += 1
				a = employee[a - 1]
			else:
				nCount += 1
				x.append(nCount)
				break
	else:
		pass
print(max(x))


n = int(input())
p = []
tree = {i: set() for i in range(n + 1)}
for j in range(n):
	x = int(input())
	p.append(x)
	if p[j] != -1:
		tree[p[j]] = tree[p[j]].union(set([j + 1]))
mx = 0
temp = 0
visited = set()

def dfs(visited, tree, node):
	global mx, temp
	if node not in visited:
		visited.add(node)
		if len(tree[node]) == 0:
			mx = max(mx, temp)
		else:
			for neighbour in tree[node]:
				temp += 1
				dfs(visited, tree, neighbour)
	temp -= 1
for k in range(n):
	temp = 0
	visited.clear()
	dfs(visited, tree, k + 1)
print(mx + 1)


import sys
sys.setrecursionlimit(10 ** 6)
n = int(input())
child = {i: [] for i in range(1, n + 1)}
for i in range(1, n + 1):
	a = int(input())
	if a != -1:
		child[a].append(i)

def dfs(v, lvl, par=0):
	lvl[v] = lvl[par] + 1
	for i in child[v]:
		dfs(i, lvl, v)
maxi = -1
for i in range(1, n + 1):
	lvl = [0 for i in range(0, n + 1)]
	dfs(i, lvl)
	maxi = max(maxi, max(lvl))
print(maxi)


n = int(input())
m = [[None, []] for i in range(n)]
for i in range(n):
	sup = int(input())
	if sup == -1:
		pass
	else:
		m[i][0] = sup
		m[sup - 1][1].append(i + 1)
d = 0
for t in m:
	if t[1] == []:
		depth = 0
		cur = t
		while cur[0] != None:
			depth += 1
			cur = m[cur[0] - 1]
		if depth > d:
			d = depth
print(d + 1)


import math
from collections import *
import sys
from functools import reduce

def get_ints():
	return map(int, input().strip().split())

def get_list():
	return list(get_ints())

def getlistofstring():
	return list(input().strip().split())

def printxsp(*args):
	return print(*args, end='')

def printsp(*args):
	return print(*args, end=' ')
UGLYMOD = int(1000000000.0) + 7
SEXYMOD = 998244353
MAXN = int(100000.0)
N = int(input())
manager = defaultdict(list)
queue = deque()
depth = [0] * (N + 1)
for sub in range(1, N + 1):
	man = int(input())
	if man == -1:
		queue.append([sub, 1])
		depth[sub] = 1
	else:
		manager[man].append(sub)
while len(queue):
	this = queue.popleft()
	man = this[0]
	dep = this[1] + 1
	for sub in manager[man]:
		if depth[sub] != dep:
			queue.append([sub, dep])
			depth[sub] = dep
print(max(depth))


import pdb
import sys

def solver():
	inp = sys.stdin.read()
	mylist = inp.splitlines()
	n = int(mylist[0])
	emp = [int(elem) for elem in mylist[1:]]
	r = 0
	for i in range(n):
		c = 0
		while i >= 0:
			i = emp[i] - 1
			c += 1
		r = max(c, r)
	print(r)

def main():
	solver()
main()


def solve(tree):
	levels = 0
	childs = []
	childs.append(tree[0])
	while len(childs) > 0:
		levels += 1
		new_childs = []
		for i in childs[0]:
			new_childs += tree[i]
		if len(new_childs) > 0:
			childs.append(new_childs)
		childs.pop(0)
	return levels
n = int(input())
node_list = []
for i in range(n + 1):
	node_list.append([])
for i in range(n):
	parent_pos = int(input())
	parent_pos = parent_pos + 1 if parent_pos < 0 else parent_pos
	node_list[parent_pos].append(i + 1)
print(solve(node_list))


from collections import defaultdict
from sys import setrecursionlimit
setrecursionlimit(2000000)
mx = -1

def dfs(x, level):
	global mx
	mx = max(mx, level)
	for i in range(len(dic[x])):
		dfs(dic[x][i], level + 1)
n = int(input())
dic = defaultdict(list)
for i in range(1, n + 1):
	x = int(input())
	if x != -1:
		dic[x].append(i)
	else:
		dic[0].append(i)
for i in range(len(dic[0])):
	dfs(dic[0][i], 1)
print(mx)


n = int(input())
a = [-1] * n
for i in range(n):
	manager = int(input()) - 1
	a[i] = manager
d = [0] * n
for cEmployee in range(n):
	depth = 0
	employee = cEmployee
	while a[employee] != -2:
		employee = a[employee]
		depth += 1
	d[cEmployee] = depth
print(max(d) + 1)


n = int(input())
a = {}
c = [[] for i in range(n + 1)]
for i in range(1, n + 1):
	t = int(input())
	a[i] = t
	c[i].append(t)
	if t == -1:
		c[0].append(i)
	else:
		c[t].append(i)
d = []
for i in range(1, n + 1):
	if len(c[i]) == 1:
		d.append(i)
b = 1
s = 0
for i in d:
	k = a[i]
	while k != -1:
		b += 1
		k = a[k]
	if b > s:
		s = b
	b = 1
print(s)


n = int(input())
boss = []
super_b = []
for i in range(n):
	boss.append([])
for i in range(n):
	b = int(input())
	if b != -1:
		boss[b - 1].append(i)
	else:
		super_b.append(i)
num = 0
for i in super_b:
	pres_boss = i
	level = 1
	queue = [pres_boss]
	marked = [0] * n
	marked[pres_boss] = 1
	while queue:
		pres_boss = queue[0]
		new = []
		for j in boss[pres_boss]:
			if marked[j] != 1:
				new.append(j)
				marked[j] = marked[pres_boss] + 1
		if new:
			queue.extend(new)
		queue.pop(0)
		level = max(marked)
	if level > num:
		num = level
print(num)


n = int(input())
graph = [[] for i in range(n)]
for i in range(n):
	x = int(input())
	if x != -1:
		graph[i].append(x - 1)
ans = 0
for i in range(n):
	stack = []
	stack.append(i)
	while stack:
		if len(stack) > ans:
			ans = len(stack)
		if len(graph[stack[-1]]) == 0:
			break
		else:
			stack.append(graph[stack[-1]][0])
print(ans)


def solve(p, parents, lvl):
	if lvl[p] != -1:
		return lvl[p]
	if parents[p] == -1:
		lvl[p] = 1
	else:
		lvl[p] = solve(parents[p], parents, lvl) + 1
	return lvl[p]
n = int(input())
parent = [-1] * n
for i in range(n):
	x = int(input())
	if x > 0:
		parent[i] = x - 1
lvl = [-1] * n
for i in range(n):
	solve(i, parent, lvl)
print(max(lvl))


import sys
sys.setrecursionlimit(2100)

def inc_level_sons(emp):
	for e in emps[emp]:
		emps_level[e] = emps_level[emp] + 1
		inc_level_sons(e)
n = int(input())
emps = [[] for i in range(2005)]
emps_level = [1] * 2005
for i in range(n):
	e = int(input())
	if e != -1:
		emps[e].append(i + 1)
		emps_level[i + 1] = emps_level[e] + 1
		inc_level_sons(i + 1)
print(str(max(emps_level)))


import sys
from collections import defaultdict
from time import time

class Node:

	def __init__(self, i, children=None):
		self.i = i
		self.children = children if children else []

	def __repr__(self):
		return '{}'.format(self.i)

def find_max_level(root):
	stack = [(root, 1)]
	max_level = -1
	while stack:
		(node, lvl) = stack.pop()
		max_level = max(lvl, max_level)
		for child in node.children:
			stack.append((child, lvl + 1))
	return max_level

def main():
	data = sys.stdin.read()
	lines = data.split('\n')
	n_employees = int(lines[0])
	j = 1
	nodes = [Node(i) for i in range(1, n_employees + 1)]
	trees = []
	for i in range(1, n_employees + 1):
		mgr = int(lines[i])
		if mgr == -1:
			trees.append(nodes[i - 1])
		else:
			nodes[mgr - 1].children.append(nodes[i - 1])
	print(max((find_max_level(root) for root in trees)))
main()


import sys
sys.setrecursionlimit(4000)

def up_tree(i, depth=1):
	if depth < depths[i]:
		return 0
	else:
		depths[i] = depth
		if managers[i] == -2:
			return depth
		else:
			return up_tree(managers[i], depth + 1)
n = int(input())
managers = [-1] * n
depths = [0] * n
for i in range(n):
	managers[i] = int(input()) - 1
mm = 0
for i in range(n):
	mm = max(mm, up_tree(i))
print(mm)


t = int(input())
l = []
for _ in range(t):
	a = int(input())
	l.append(a)
r = 1
for i in range(t):
	c = 1
	q = l[i] - 1
	while q != -2:
		c += 1
		q = l[q] - 1
	r = max(r, c)
print(r)


n = int(input())
p = [int(input()) for _ in range(n)]
p.insert(0, -99)
result = -1
for i in range(1, n + 1):
	count = 0
	while i != -1:
		i = p[i]
		count += 1
		result = max(result, count)
print(result)


import sys
import pdb

def get_input_file():
	f = open('demo115.txt', 'r')
	var = f.read()
	return var

def solver():
	inp = sys.stdin.read()
	mylist = inp.splitlines()
	n = int(mylist[0])
	emp = [int(elem) for elem in mylist[1:]]
	ans = 0
	for i in range(n):
		count = 0
		j = i
		while j >= 0:
			j = emp[j] - 1
			count += 1
		ans = max(count, ans)
	print(ans)

def main():
	solver()
main()


import sys
sys.setrecursionlimit(2500)

class graph:
	m = None
	d = {}

	def __init__(self, n):
		self.m = [0 for _ in range(n + 1)]

	def add_edge(self, a, b):
		self.m[a] = b

	def get_depth(self, a):
		if a == -1:
			return 0
		if a not in self.d:
			self.d[a] = 1 + self.get_depth(self.m[a])
		return self.d[a]
n = int(input())
g = graph(n)
for p in range(n):
	g.add_edge(p + 1, int(input()))
t = 0
for i in range(1, n + 1):
	t = max(t, g.get_depth(i))
print(t)


import sys
from collections import deque
fast_reader = sys.stdin.readline
fast_writer = sys.stdout.write

def input():
	return fast_reader().strip()

def print(*argv):
	fast_writer(' '.join((str(i) for i in argv)))
	fast_writer('\n')

def bfs(i, d):
	q = deque([i])
	visited = set()
	c = 0
	while len(q) != 0:
		t = q.popleft()
		if t in visited:
			continue
		else:
			c += 1
			if t in d:
				q.append(d[t])
	return c
for _ in range(1):
	n = int(input())
	d = {}
	for i in range(n):
		p = int(input())
		if p == -1:
			continue
		d[i] = p - 1
	m = 0
	for i in range(n):
		m = max(m, bfs(i, d))
	print(m)


n = int(input())
depths = [0] * (n + 1)
m = 1
data = []
rec = []
for i in range(n):
	data.append(int(input()))
for i in range(n):
	if data[i] == -1:
		depths[i + 1] = 1
	else:
		rec.append([i, data[i]])
while len(rec) > 0:
	t = []
	for i in rec:
		t0 = depths[i[1]]
		if t0 == m:
			depths[i[0] + 1] = t0 + 1
		else:
			t.append(i)
	m += 1
	rec = t
print(m)


from collections import defaultdict

def parse_input():
	n = int(input())
	p = [-1 for i in range(n + 1)]
	for i in range(1, n + 1):
		pi = int(input())
		p[i] = pi
	return (n, p)

def main():
	(num_employees, parent) = parse_input()
	ans = 0
	for i in range(1, num_employees + 1):
		cur = i
		d = 0
		while cur != -1:
			d += 1
			cur = parent[cur]
		ans = max(ans, d)
	print(ans)
main()


from collections import defaultdict
from sys import stdin
root_nodes = []
graph = defaultdict(list)

def parse_input():
	employees = int(stdin.readline())
	for employee in range(1, employees + 1):
		boss = int(stdin.readline())
		if boss == -1:
			root_nodes.append(employee)
		else:
			graph[boss].append(employee)

def count_groups():
	current_group = root_nodes
	groups = 0
	while current_group:
		next_group = []
		for employee in current_group:
			next_group.extend(graph[employee])
		current_group = next_group
		groups += 1
	print(groups)
parse_input()
count_groups()


p = []
n = int(input())
for _ in range(n):
	p.append(int(input()))
r = 0
for i in range(n):
	c = 0
	j = i
	while j >= 0:
		j = p[j] - 1
		c += 1
	r = max(r, c)
print(r)


numof_employess = int(input())
adjacency_list = {}
visited = [False for i in range(numof_employess + 1)]
is_root = [False for i in range(numof_employess + 1)]
for employee in range(1, numof_employess + 1):
	adjacency_list[employee] = []
for i in range(numof_employess):
	manager = int(input())
	if manager != -1:
		adjacency_list[manager].append(i + 1)
	else:
		is_root[i + 1] = True

def get_max_depth_of_tree(start, visited):
	stack = [start]
	max_depth = 0
	while stack != []:
		V = stack[0]
		max_depth = max(len(stack), max_depth)
		advancing = False
		for neig in adjacency_list.get(V):
			if not visited[neig]:
				stack.insert(0, neig)
				visited[neig] = True
				advancing = True
				break
		if not advancing:
			del stack[0]
	return max_depth
global_max_depth = 0
for employee in range(1, numof_employess + 1):
	if is_root[employee]:
		global_max_depth = max(get_max_depth_of_tree(employee, visited), global_max_depth)
print(global_max_depth)


N = 2000 + 5
n = int(input())
d = []
step = []
vis = []

def findt(u):
	lent = 1
	vis[u] = 1
	while d[u] != -1:
		u = d[u]
		if vis[u] == 1:
			return lent + step[u]
		lent += 1
	return lent
for i in range(0, n + 1):
	d.append(-1)
	vis.append(0)
	step.append(0)
for i in range(1, n + 1):
	v = int(input())
	d[i] = v
maxlen = 0
for i in range(1, n + 1):
	if vis[i] == 0:
		step[i] = findt(i)
	maxlen = max(maxlen, step[i])
print(maxlen)


def sol(employees):
	maxDepth = 0
	for i in range(len(employees)):
		currDepth = 1
		tmp = i
		while employees[tmp] != -1:
			currDepth += 1
			tmp = employees[tmp] - 1
		maxDepth = max(maxDepth, currDepth)
	return maxDepth
n = int(input())
rs = []
for i in range(n):
	rs.append(int(input()))
print(sol(rs))


n = int(input())
max = 1
a = []
for _ in range(n):
	a.append(int(input()))
a.insert(0, None)
for i in range(1, n + 1):
	sum = 1
	q = a[i]
	while q != -1:
		q = a[q]
		sum += 1
	if sum > max:
		max = sum
print(max)


from collections import defaultdict

def main():
	num_employees = int(input())
	parent = defaultdict(int)
	for i in range(1, num_employees + 1):
		parent[i] = int(input())
	max_depth = -1
	for i in range(1, num_employees + 1):
		child = i
		nodes = 1
		while parent[child] != -1:
			child = parent[child]
			nodes += 1
		max_depth = max(nodes, max_depth)
	print(max_depth)
main()


r = lambda : int(input()) - 1
n = r() + 1
o = [r() for x in range(n)]
m = 0
for i in range(n):
	c = 0
	while i != -2:
		c += 1
		i = o[i]
	m = max(m, c)
print(m)


employees = int(input())
array = []
for i in range(employees):
	x = int(input())
	array.append(x)
counter = 0
for i in range(employees):
	pathLen = 0
	buffer = array[i]
	j = i
	while buffer > 0 and j < employees:
		pathLen += 1
		buffer = array[array[j] - 1]
		j = array[j] - 1
	counter = max(counter, pathLen)
print(counter + 1)


n = int(input())
employees = dict()
for i in range(1, n + 1):
	employees[i] = int(input())
max_depth = 0
for key in employees:
	temp = key
	count = 0
	while employees[temp] != -1:
		count += 1
		temp = employees[temp]
	max_depth = max(max_depth, count)
print(max_depth + 1)


n = int(input())
superierList = []
for i in range(n):
	superierList.append(int(input()))
orderList = [1] * n
for i in range(n):
	thisSup = superierList[i]
	thisOrder = orderList[i]
	while thisSup != -1:
		updateOrder = thisOrder + 1
		if updateOrder < orderList[thisSup - 1]:
			thisSup = -1
		else:
			orderList[thisSup - 1] = updateOrder
			thisSup = superierList[thisSup - 1]
			thisOrder = updateOrder
print(max(orderList))


def height(node):
	ans = 1
	for viz in l_adj[node]:
		aux = 1
		if not visited[viz - 1]:
			aux += height(viz)
		ans = max(ans, aux)
	return ans
n = int(input())
flag = []
l_adj = {}
for j in range(1, n + 1):
	l_adj[j] = []
for i in range(1, n + 1):
	sup = int(input())
	if sup == -1:
		flag.append(i)
		continue
	l_adj[sup].append(i)
max_height = 0
visited = [False] * n
for node in flag:
	max_height = max(max_height, height(node))
print(max_height)


inp = int(input())
(l, k, u, pp, s) = ([], [], [], [], [])
(total, maximum) = (0, 0)
for num in range(inp):
	l.append(int(input()))
for num in range(inp):
	if l[num] == -1:
		k.append(num + 1)
for kk in k:
	p = [kk]
	while len(p) >= 1:
		for num in range(inp):
			if l[num] in p:
				u.append(num + 1)
				s.append(l[num])
		s = set(s)
		if len(s) != 0:
			total += 1
		p = u
		u = []
		s = []
	if total > maximum:
		maximum = total
	total = 0
print(maximum + 1)


N = int(input())
l = []
for i in range(N):
	l.append(int(input()))
ans = 0
for i in range(N):
	deep = 1
	x = l[i]
	while x != -1:
		x = l[x - 1]
		deep += 1
	ans = max(deep, ans)
print(ans)


n = int(input())
g = {}
r = []
for i in range(1, n + 1):
	p = int(input())
	if p != -1:
		g[p] = g.get(p, []) + [i]
	else:
		r.append(i)

def height(p):
	deeper = 0
	for i in g.get(p, []):
		d = height(i)
		if deeper < d:
			deeper = d
	return deeper + 1
result = 0
for j in r:
	h = height(j)
	if result < h:
		result = h
print(result)


n = int(input())
rtnd = []
l = n
d = {}
lvl = {}

def dfs(nd, rt):
	lvl[nd] = lvl[rt] + 1
	if nd not in d.keys():
		return
	for i in d[nd]:
		if i != rt:
			dfs(i, nd)
	return
while n > 0:
	j = l - n + 1
	i = int(input())
	if i == -1:
		rtnd.append(j)
	else:
		if j not in d.keys():
			d[j] = []
		if i not in d.keys():
			d[i] = []
		d[j].append(i)
		d[i].append(j)
	n -= 1
lvl[0] = 0
for i in rtnd:
	dfs(i, 0)
print(max(lvl.values()))


n = int(input())
employee = ['a']
for t in range(n):
	x = int(input())
	employee.append(x)
count = 0
b = [-1]
while len(b) != 0:
	l = len(employee)
	ind = []
	c = []
	for i in range(1, l):
		for b_ in b:
			if employee[i] == b_:
				employee[i] = 'a'
				c.append(i)
				break
	b = c
	count = count + 1
print(count - 1)


n = int(input())
import sys
sys.setrecursionlimit(10000)
p = [int] * n
to = [[] for i in range(n)]

def add(x, y):
	to[x].append(y)
for i in range(n):
	p[i] = int(input())
	if p[i] == -1:
		continue
	add(p[i] - 1, i)
ans = 0

def dfs(v, P, depth):
	global ans
	ans = max(ans, depth)
	for u in to[v]:
		if u == P:
			continue
		dfs(u, v, depth + 1)
for i in range(n):
	if p[i] != -1:
		continue
	dfs(i, -1, 1)
print(ans)


def dfs(i, tree, h):
	if h[i] != -1:
		return h[i]
	res = 1
	for c in tree[i]:
		res = max(res, dfs(c, tree, h) + 1)
	h[i] = res
	return res

def sol(n, tree):
	res = 1
	h = [-1] * (n + 1)
	for i in range(1, n + 1):
		res = max(res, dfs(i, tree, h))
	return res
n = int(input())
tree = [[] for i in range(n + 1)]
for i in range(1, n + 1):
	fa = int(input())
	if fa != -1:
		tree[fa].append(i)
print(sol(n, tree))


n = int(input())
p = [int(input()) for i in range(n)]
r = 0
r = int(r)
for i in range(n):
	count = 0
	while i >= 0:
		i = p[i] - 1
		count += 1
	r = max(r, count)
print(r)


class Graph:

	def __init__(self, v):
		self.v = v
		self.graph = [[0 for col in range(v)] for row in range(v)]
		self.visited = [False for _ in range(v)]
DEBUG = False

def getDepth(g, src):
	q = [src]
	depth = 0
	cnt = 1
	while q:
		val = q.pop(0)
		if DEBUG:
			print('==>' + str(val))
		cnt -= 1
		g.visited[val] = True
		for i in range(g.v):
			if g.graph[val][i] == 1:
				if g.visited[i] == False:
					q.append(i)
		if cnt == 0:
			depth += 1
			cnt = len(q)
	return depth

def solve():
	v = int(input())
	g = Graph(v)
	root = []
	for i in range(v):
		parent = int(input())
		if parent == -1:
			root.append(i)
			continue
		g.graph[parent - 1][i] = 1
	max = -1
	if DEBUG:
		print(g.graph)
	for i in range(len(root)):
		temp = getDepth(g, root[i])
		if DEBUG:
			print('======')
		if temp > max:
			max = temp
	print(str(max))
solve()


class Node(object):

	def __init__(self, val):
		self.val = val
		self.connections = []

def dfs_visit(node, visited, l):
	visited[node.val - 1] = True
	l += 1
	for c in node.connections:
		l = dfs_visit(c, visited, l)
	return l

def dfs(nodearr, n):
	visited = [False] * n
	maxl = 0
	for i in range(n):
		if visited[i] == False:
			newmax = dfs_visit(nodearr[i], visited, 0)
			if newmax > maxl:
				maxl = newmax
	return maxl
n = int(input())
nodearr = []
for i in range(n):
	nodearr.append(Node(i + 1))
for i in range(n):
	x = int(input())
	if x != -1:
		nodearr[i].connections.append(nodearr[x - 1])
print(dfs(nodearr, n))


a = int(input())
st = []
k = []
for x in range(a):
	s = int(input())
	if s != -1:
		st.append([s - 1, x])
	k.append(s)
graf = [[] for i in range(a + 1)]
mo = 0
mor = 0
for x in range(len(st)):
	graf[st[x][0]].append(st[x][1])

def melysegi(x):
	global mo, mor, graf
	mo = mo + 1
	if mo > mor:
		mor = mo
	for y in range(len(graf[x])):
		melysegi(graf[x][y])
	mo = mo - 1
for x in range(a):
	if k[x] == -1:
		melysegi(x)
		mo = 0
print(mor)