Buggy python submission (verdict: Time Limit Exceeded):
import collections, sys
sys.setrecursionlimit(10**5 + 5)
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

memo = [-1] * (N + 1)


def rec(x):
    if memo[x] == -1:
        if win_lose[x] == set():
            memo[x] = 0
        else:
            memo[x] = max(a + b for a, b in zip(
                sorted(rec(y) for y in win_lose[x])[::-1], range(1, N + 1)))
    return memo[x]


print(rec(1))


Fixed submission:
import collections
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

s1 = [1]
s2 = []
while s1:
    a = s1.pop()
    s2 += [a]
    for b in win_lose[a]:
        s1 += [b]
memo = [0] * (N + 1)
for x in s2[::-1]:
    if win_lose[x] == set():
        memo[x] = 0
    else:
        memo[x] = max(a + b for a, b in zip(
            sorted(memo[y] for y in win_lose[x])[::-1], range(1, N + 1)))
print(memo[1])

Buggy python submission (verdict: Runtime Error):
import collections, sys
sys.setrecursionlimit(10**5 + 5)
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

memo = [-1] * (N + 1)


def rec(x):
    if memo[x] == -1:
        if win_lose[x] == set():
            memo[x] = 0
        else:
            memo[x] = max(a + b for a, b in zip(
                sorted(rec(y) for y in win_lose[x])[::-1], range(1, N + 1)))
    return memo[x]


print(rec(1))


Fixed submission:
import collections
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

s1 = [1]
s2 = []
while s1:
    a = s1.pop()
    s2 += [a]
    for b in win_lose[a]:
        s1 += [b]
memo = [0] * (N + 1)
for x in s2[::-1]:
    if win_lose[x] == set():
        memo[x] = 0
    else:
        memo[x] = max(a + b for a, b in zip(
            sorted(memo[y] for y in win_lose[x])[::-1], range(1, N + 1)))
print(memo[1])

Buggy python submission (verdict: Runtime Error):
import collections, sys
sys.setrecursionlimit(10**5 + 5)
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

memo = [-1] * (N + 1)


def rec(x):
    if memo[x] == -1:
        if win_lose[x] == set():
            memo[x] = 0
        else:
            memo[x] = max(a + b for a, b in zip(
                sorted(rec(y) for y in win_lose[x])[::-1], range(1, N + 1)))
    return memo[x]


print(rec(1))
print(memo)


Fixed submission:
import collections
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

s1 = [1]
s2 = []
while s1:
    a = s1.pop()
    s2 += [a]
    for b in win_lose[a]:
        s1 += [b]
memo = [0] * (N + 1)
for x in s2[::-1]:
    if win_lose[x] == set():
        memo[x] = 0
    else:
        memo[x] = max(a + b for a, b in zip(
            sorted(memo[y] for y in win_lose[x])[::-1], range(1, N + 1)))
print(memo[1])

Buggy python submission (verdict: Runtime Error):
import collections, sys
sys.setrecursionlimit(10**5 + 5)
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

memo = [-1] * (N + 1)


def rec(x):
    if memo[x] == -1:
        if win_lose[x] == set():
            memo[x] = 0
        else:
            memo[x] = max(rec(y) for y in win_lose[x]) + len(win_lose[x])
    return memo[x]


print(
    max(a + b for a, b in zip(
        sorted(rec(x) for x in win_lose[1])[::-1], range(1, N + 1))))


Fixed submission:
import collections
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

s1 = [1]
s2 = []
while s1:
    a = s1.pop()
    s2 += [a]
    for b in win_lose[a]:
        s1 += [b]
memo = [0] * (N + 1)
for x in s2[::-1]:
    if win_lose[x] == set():
        memo[x] = 0
    else:
        memo[x] = max(a + b for a, b in zip(
            sorted(memo[y] for y in win_lose[x])[::-1], range(1, N + 1)))
print(memo[1])

Buggy python submission (verdict: Runtime Error):
import collections
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

memo = [-1] * (N + 1)


def rec(x):
    if memo[x] == -1:
        if win_lose[x] == set():
            memo[x] = 0
        else:
            memo[x] = max(rec(y) for y in win_lose[x]) + len(win_lose[x])
    return memo[x]


for x in win_lose[1]:
    rec(x)
print(1 + max(memo[2:]))


Fixed submission:
import collections
N, *A = [int(_) for _ in open(0).read().split()]
win_lose = {i: set() for i in range(1, N + 1)}
for win, lose in zip(A, range(2, N + 1)):
    win_lose[win].add(lose)

s1 = [1]
s2 = []
while s1:
    a = s1.pop()
    s2 += [a]
    for b in win_lose[a]:
        s1 += [b]
memo = [0] * (N + 1)
for x in s2[::-1]:
    if win_lose[x] == set():
        memo[x] = 0
    else:
        memo[x] = max(a + b for a, b in zip(
            sorted(memo[y] for y in win_lose[x])[::-1], range(1, N + 1)))
print(memo[1])