One day Polycarp published a funny picture in a social network making a poll about the color of his handle. Many of his friends started reposting Polycarp's joke to their news feed. Some of them reposted the reposts and so on.

These events are given as a sequence of strings "name1 reposted name2", where name1 is the name of the person who reposted the joke, and name2 is the name of the person from whose news feed the joke was reposted. It is guaranteed that for each string "name1 reposted name2" user "name1" didn't have the joke in his feed yet, and "name2" already had it in his feed by the moment of repost. Polycarp was registered as "Polycarp" and initially the joke was only in his feed.

Polycarp measures the popularity of the joke as the length of the largest repost chain. Print the popularity of Polycarp's joke.


-----Input-----

The first line of the input contains integer n (1 ≤ n ≤ 200) — the number of reposts. Next follow the reposts in the order they were made. Each of them is written on a single line and looks as "name1 reposted name2". All the names in the input consist of lowercase or uppercase English letters and/or digits and have lengths from 2 to 24 characters, inclusive.

We know that the user names are case-insensitive, that is, two names that only differ in the letter case correspond to the same social network user.


-----Output-----

Print a single integer — the maximum length of a repost chain.


-----Examples-----
Input
5
tourist reposted Polycarp
Petr reposted Tourist
WJMZBMR reposted Petr
sdya reposted wjmzbmr
vepifanov reposted sdya

Output
6

Input
6
Mike reposted Polycarp
Max reposted Polycarp
EveryOne reposted Polycarp
111 reposted Polycarp
VkCup reposted Polycarp
Codeforces reposted Polycarp

Output
2

Input
1
SoMeStRaNgEgUe reposted PoLyCaRp

Output
2

Source: codeforces | Difficulty: EASY
Tags: Tree algorithms

Graph algorithms

Graph traversal

Dynamic programming


Solutions:
n = int(input())
reposts = {}
for i in range(n):
	s = input().split()
	(name1, name2) = (s[0].lower(), s[2].lower())
	if name2 == 'polycarp':
		reposts[name1] = 2
	else:
		reposts[name1] = reposts[name2] + 1
print(max(reposts.values()))


n = int(input())
reposts = {}
for _ in range(n):
	(a, _, b) = [x.lower() for x in input().split()]
	reposts.setdefault(b, []).append(a)
dist = {}

def dfs(at, val=1):
	dist[at] = val
	if at in reposts:
		for go in reposts[at]:
			dfs(go, val + 1)
dfs('polycarp')
print(max(dist.values()))


import copy
a = []
b = {}
w = 0
for o in range(int(input())):
	t = [i.lower() for i in input().split()]
	try:
		a[b[t[2]]] += [t[0]]
	except:
		b[t[2]] = w
		a += [[t[0]]]
		w += 1
c = [1] * len(a)
x = ['polycarp']
y = []
j = 1
while True:
	for i in x:
		try:
			y += a[b[i]]
		except:
			pass
	if y == []:
		break
	else:
		j += 1
		x = copy.copy(y)
		y = []
print(j)


n = int(input())
d = dict()
d['polycarp'] = 1
s = 'polycarp'
max_ = -1
for i in range(n):
	a = list(map(str, input().split()))
	b = ''
	for j in range(len(a[0])):
		if ord(a[0][j]) >= 65 and ord(a[0][j]) <= 90:
			b = b + chr(ord(a[0][j]) + 32)
		else:
			b = b + a[0][j]
	a[0] = b
	b = ''
	for j in range(len(a[2])):
		if ord(a[2][j]) >= 65 and ord(a[2][j]) <= 90:
			b = b + chr(ord(a[2][j]) + 32)
		else:
			b = b + a[2][j]
	a[2] = b
	d[a[0]] = 1
	d[a[0]] = d[a[0]] + d[a[2]]
	s = a[0]
	if d[a[0]] > max_:
		max_ = d[a[0]]
print(max_)


from collections import defaultdict

def dfstraverse(g, dist, arg, visit):
	for i in g[arg]:
		if visit[i] == -1:
			visit[i] = 1
			dist[i] = dist[arg] + 1
			dfstraverse(g, dist, i, visit)
g = defaultdict(list)
visit = defaultdict()
n = int(input())
for _ in range(n):
	(u, v) = input().split(' reposted ')
	u = u.lower()
	v = v.lower()
	g[u].append(v)
	g[v].append(u)
	visit[u] = -1
	visit[v] = -1
dist = defaultdict()
dist['polycarp'] = 1
visit['polycarp'] = 1
dfstraverse(g, dist, 'polycarp', visit)
print(max(dist.values()))


n = int(input())
tree = {'polycarp': []}
for _ in range(n):
	(name1, r, name2) = input().split(' ')
	tree[name2.lower()] = tree.get(name2.lower(), []) + [name1.lower()]
ans = 1

def dfs(root, depth=1):
	global ans
	for vertex in tree[root]:
		if vertex in tree.keys():
			dfs(vertex, depth + 1)
		else:
			ans = max(ans, depth + 1)
dfs('polycarp')
print(ans)


n = int(input())
ans = {'polycarp': 1}
for i in range(n):
	(repost, _, reposted) = input().lower().split()
	ans[repost] = ans[reposted] + 1
print(max(ans.values()))


from functools import reduce
from operator import *
from math import *
from sys import *
from string import *
from collections import *
setrecursionlimit(10 ** 7)
dX = [-1, 1, 0, 0, -1, 1, -1, 1]
dY = [0, 0, -1, 1, 1, -1, -1, 1]
RI = lambda : list(map(int, input().split()))
RS = lambda : input().rstrip().split()
n = RI()[0]
di = {'polycarp': 1}
l = 1
adj = {1: []}

def height(node):
	if len(adj[node]) == 0:
		return 1
	return 1 + max((height(i) for i in adj[node]))
for i in range(n):
	(a, b, c) = RS()
	a = a.lower()
	c = c.lower()
	if a not in di:
		l += 1
		di[a] = l
	if di[a] not in adj:
		adj[di[a]] = []
	adj[di[c]].append(di[a])
print(height(1))


reposts = dict()
reposts['polycarp'] = 1
max = 1
for i in range(int(input())):
	repost = input().lower().split(' ')
	reposts[repost[0]] = reposts[repost[2]] + 1
	if reposts[repost[0]] > max:
		max = reposts[repost[0]]
print(max)


n = int(input())
lst = [input().lower().split() for i in range(n)]
d = dict()
d['polycarp'] = 1
mx = 1
for i in lst:
	d[i[0]] = d[i[2]] + 1
	mx = max(mx, d[i[0]])
print(mx)


import collections
n = int(input())
graph = collections.defaultdict(list)
for i in range(n):
	(x, y) = input().split('reposted')
	x = x.lower().strip()
	y = y.lower().strip()
	graph[y].append(x)
que = [('polycarp', 1)]
seen = set()
ans = 0
while que:
	(node, depth) = que.pop(0)
	ans = max(ans, depth)
	for i in graph[node]:
		if i not in seen:
			seen.add(i)
			que.append((i, depth + 1))
print(ans)


def fun(d, s):
	l = 1
	a = 0
	try:
		for j in d[s]:
			a = max(a, fun(d, j))
	except KeyError:
		k = 1
	return l + a
n = int(input())
d = {}
for i in range(n):
	l = list(map(str, input().split()))
	a = l[0].lower()
	b = l[2].lower()
	try:
		d[b].append(a)
	except KeyError:
		d[b] = [a]
ma = 0
for i in d:
	ma = max(ma, fun(d, i))
print(ma)


n = int(input())
A = dict()
A['polycarp'] = 1
for i in range(n):
	(a, rep, b) = input().split()
	a = a.lower()
	b = b.lower()
	A[a] = A[b] + 1
mx = 1
for i in A:
	mx = max(mx, A[i])
print(mx)


n = int(input())
dic = {'polycarp': 1}
for i in range(n):
	(a, b) = input().lower().split(' reposted ')
	dic[a] = dic[b] + 1
print(max(dic.values()))


n = int(input())
reposted_list = {'polycarp': 1}
for i in range(n):
	(reposter, r, author) = input().split(' ')
	(reposter, author) = (reposter.lower(), author.lower())
	reposted_list[reposter] = reposted_list[author] + 1
print(reposted_list[max(reposted_list, key=reposted_list.get)])


n = int(input())

def DFS(node, name):
	if node.name == name:
		return node
	for child in node.childs:
		n = DFS(child, name)
		if n != None:
			return n
	return None

class Node:

	def __init__(self, name):
		self.name = name
		self.childs = []

class Tree:

	def __init__(self, root):
		self.root = root

	def add(self, name, to):
		node = DFS(self.root, to)
		node.childs.append(Node(name))

	def max_depth(self, node):
		m = 1
		for child in node.childs:
			n = 1 + self.max_depth(child)
			if n > m:
				m = n
		return m
tree = Tree(Node('polycarp'))
for i in range(n):
	inp = input().lower().split()
	tree.add(inp[0], inp[2])
print(tree.max_depth(tree.root))


lenth = 0

def dfs(Author, depth):
	global u
	global lenth
	s = ''
	if Author not in u:
		if depth > lenth:
			lenth = depth
		return
	for s in u[Author]:
		dfs(s, depth + 1)
n = int(input())
i = 1
u = dict()
for i in range(0, n):
	(Reposter, Author) = input().split(' reposted ')
	Reposter = Reposter.lower()
	Author = Author.lower()
	if Author not in u:
		u[Author] = list()
	u[Author].append(Reposter)
dfs('polycarp', 1)
print(lenth)


import copy

def dnf(arr, nickname):
	max_val = 1
	max_local = 0
	for k in range(len(arr)):
		if arr[k][1] == nickname:
			new_nickname = arr[k][0]
			arr1 = copy.copy(arr)
			arr1.pop(k)
			max_local = max(dnf(arr1, new_nickname), int(max_local))
	return max_val + max_local
n = int(input())
reposts = []
for i in range(n):
	reposts.append(input().lower().split(sep=' reposted '))
print(dnf(reposts, 'polycarp'))


import sys

def DFS(vertex):
	for apex in graf[vertex]:
		count_reposts[apex] = count_reposts[vertex] + 1
		if apex in graf:
			DFS(apex)
	return False
num_reposts = int(sys.stdin.readline())
graf = {}
for i in range(num_reposts):
	string = sys.stdin.readline()
	(apex, reposted, vertex) = tuple(map(lambda x: x.lower(), string.split()))
	if vertex in graf:
		graf[vertex] += [apex]
	else:
		graf[vertex] = [apex]
count_reposts = {'polycarp': 1}
DFS('polycarp')
print(max(count_reposts.values()), end='')


def main():
	N = int(input())
	users = {}
	users['polycarp'] = 1
	for x in range(N):
		msg = input().split()
		(user1, user2) = (msg[0].lower(), msg[2].lower())
		users[user1] = users[user2] + 1
	print(max(users.values()))
main()


re_dict = {}
max = 0
n = int(input())
i = 0
while i < n:
	str1 = input()
	str1.strip()
	str1 = str1.split(' reposted ')
	a = str1[1].strip().lower()
	b = str1[0].strip().lower()
	if a not in re_dict:
		re_dict[a] = 1
	num = re_dict[a] + 1
	re_dict[b] = num
	if num > max:
		max = num
	i = i + 1
print(max)


from collections import deque
n = int(input())
m = {}
adj = []
for i in range(202):
	adj.append([])
j = 1
for i in range(n):
	arr = input().split()
	u = arr[2].lower()
	if not u in m.keys():
		m[u] = j
		j += 1
	v = arr[0].lower()
	if not v in m.keys():
		m[v] = j
		j += 1
	adj[m[u]].append(m[v])
ans = 0
for i in range(1, 202):
	visited = [0] * 203
	q = deque()
	distance = [-1] * 203
	q.append(i)
	distance[i] = 1
	visited[i] = 1
	while len(q) != 0:
		a = q[0]
		q.popleft()
		for k in adj[a]:
			if not visited[k]:
				visited[k] = 1
				distance[k] = distance[a] + 1
				q.append(k)
	maxa = max(distance)
	ans = max(ans, maxa)
print(ans)


import random
import math
from collections import defaultdict
import itertools
from sys import stdin, stdout
import operator

def main():
	z = ''
	d = defaultdict()
	d['polycarp'] = [0, None]
	for _ in range(int(stdin.readline())):
		s = input().lower()
		m = s.split(' ')
		d[m[0]] = [0, m[2]]
		if d[m[2]][0] == 0:
			p = d[m[0]]
			while p[1] != None:
				if d[p[1]][0] > p[0]:
					break
				d[p[1]][0] += 1
				p = d[p[1]]
	print(d['polycarp'][0] + 1)
main()


n = int(input())
d = {}
for i in range(n):
	(c, b, a) = input().split()
	a = a.lower()
	c = c.lower()
	if a not in d.keys():
		d[a] = []
	d[a].append(c)
c = 1
q = ['polycarp', None]
while len(q):
	p = q.pop(0)
	if p:
		if p in d.keys():
			for i in d[p]:
				q.append(i)
	elif len(q):
		if q[0] == None:
			break
		c += 1
		q.append(None)
print(c)


n = int(input())
d = {}
dis = {}
arr = {}

def bfs(a, dist):
	cnt = 1
	dis[a] = dist
	arr[a] = 1
	queue = []
	queue.append(a)
	while len(queue):
		s = queue.pop(0)
		for i in d[s]:
			if arr[i] == 0:
				queue.append(i)
				dis[i] = dis[s] + 1
				arr[i] = 1
				cnt = max(cnt, dis[i])
	return cnt
for i in range(n):
	(a, b, c) = map(str, input().split())
	dis[a.lower()] = dis[c.lower()] = arr[a.lower()] = arr[c.lower()] = 0
	if c.lower() in d:
		d[c.lower()].append(a.lower())
	else:
		d[c.lower()] = [a.lower()]
	if a.lower() not in d:
		d[a.lower()] = []
x = bfs('polycarp', 1)
print(x)


N = input()
N = int(N)
res = 0
graph = [['polycarp']]
for i in range(N):
	data = input().split(' ')
	reposter = data[0].lower()
	reposted = data[2].lower()
	length = len(graph)
	for i in range(length):
		if reposted in graph[i]:
			if i < length - 1:
				graph[i + 1].append(reposter)
			else:
				graph.append([reposter])
print(len(graph))


def Explore(name):
	visited[name] = True
	for (key, val) in list_adjacency.items():
		for i in range(len(val)):
			if val[i] == name:
				deep[names.index(name)] = deep[names.index(key)] + 1
	if name in list_adjacency.keys():
		visited[name] = True
		for i in range(len(list_adjacency[name])):
			if visited[list_adjacency[name][i]] == False:
				visited[list_adjacency[name][i]] = True
				if list_adjacency[name][i] in list_adjacency.keys():
					Explore(list_adjacency[name][i])
	else:
		for (key, val) in list_adjacency.items():
			for i in range(len(val)):
				if val[i] == name:
					deep[names.index(name)] = deep[names.index(key)] + 1
global list_adjacency
global visited
global names
global deep
K = int(input())
names = []
list_adjacency = dict()
list_adjacency['polycarp'] = []
for i in range(K):
	(who, whose) = input().split(' reposted ')
	whose = whose.lower()
	who = who.lower()
	if whose in list_adjacency:
		list_adjacency[whose].append(who)
	else:
		list_adjacency[whose] = [who]
	if whose not in names:
		names.append(whose)
	if who not in names:
		names.append(who)
N = len(names)
visited = dict()
visited['polycarp'] = False
for elem in names:
	visited[elem] = False
deep = [0] * N
deep[names.index('polycarp')] = 1
for i in names:
	if visited[i] == False:
		Explore(i)
print(max(deep) + 1)


n = int(input())
test = {}
test['polycarp'] = int(1)
for i in range(n):
	test1 = input().split(' ')
	name = test1[0].lower()
	repost = test1[2].lower()
	test[name] = int(test[repost]) + 1
max = -1
for i in test:
	if test[i] > max:
		max = test[i]
print(max)


d = {}
(d['polycarp'], h) = (1, 1)
n = int(input())
for i in range(0, n):
	(a, b, c) = input().lower().split()
	d[a] = d[c] + 1
print(max(d.values()))


n = int(input())
mp = {'polycarp': 1}
ans = 1
for _ in range(n):
	(name1, _, name2) = input().lower().split()
	h = mp[name2] + 1
	ans = max(h, ans)
	mp[name1] = h
print(ans)


a = int(input())
m = 1
w = {}
w['polycarp'] = 1
for i in range(a):
	(r, s, t) = input().lower().split()
	w[r] = w[t] + 1
	m = max(m, w[r])
print(m)


n = int(input())
level = 1
d = {'polycarp': 0}
c = 1
arr = []
for i in range(n):
	inp = input().lower().split()
	arr.append(inp)
	if inp[0] not in d:
		d[inp[0]] = c
		c += 1
	if inp[2] not in d:
		d[inp[2]] = c
		c += 1
adj = []
vis = []
for i in range(n + 1):
	adj.append([])
	vis.append(False)
for i in range(n):
	q = arr[i]
	a = d[q[0]]
	b = d[q[2]]
	adj[b].append(a)

def dfs(s, v):
	global level
	if level < v:
		level = v
	vis[s] = True
	for i3 in range(len(adj[s])):
		child = adj[s][i3]
		if vis[child] == False:
			dfs(child, v + 1)
dfs(0, level)
print(level)


def solve(dic, s):
	if dic.get(s) == None:
		return 1
	ans = 0
	for i in dic[s]:
		ans = max(ans, solve(dic, i))
	return ans + 1
dic = {'polycarp': []}
for _ in range(int(input())):
	s = [x.lower() for x in input().split(' reposted ')]
	if dic.get(s[1]) == None:
		dic[s[1]] = [s[0]]
	else:
		dic[s[1]].append(s[0])
print(solve(dic, 'polycarp'))


s = {'polycarp': 1}
for i in range(int(input())):
	(n1, n2) = map(lambda x: x.lower(), input().split(' reposted '))
	s[n1] = s[n2] + 1
print(max(s.values()))


(n, q, w, l) = (int(input()), [], [], [['polycarp']])
for i in range(n):
	a = list(input().split())
	q += [a[0].lower()]
	w += [a[2].lower()]
for i in range(n):
	for j in range(len(l)):
		if l[j][-1] == w[i]:
			l += [list(l[j])]
			l[j] += [q[i]]
print(max((len(i) for i in l)))


n = int(input())
t = input().split()
t[0] = t[0].lower()
t[2] = t[2].lower()
m = [[t[0], t[2], 2]]
for i in range(1, n):
	t = input().split()
	t[0] = t[0].lower()
	t[2] = t[2].lower()
	m.append([t[0], t[2], 2])
	for k in range(len(m)):
		if m[i][1] == m[k][0]:
			m[i][2] = m[k][2] + 1
u = []
for i in range(len(m)):
	u.append(m[i][2])
a = max(u)
print(a)


import sys

def add_user(d, u):
	if u in d:
		return d[u]
	else:
		d[u] = len(d)
		return d[u]
n = int(input())
who = [[] for i in range(n + 1)]
users = {}
answer_id = -1
for i in range(n):
	str = input()
	parts = str.split(' ')
	name_one = parts[0].lower()
	name_two = parts[2].lower()
	user_one = add_user(users, name_one)
	user_two = add_user(users, name_two)
	who[user_two].append(user_one)
	if name_two == 'polycarp':
		answer_id = user_two

def dfs(u):
	res = 1
	for v in who[u]:
		res = max(res, dfs(v) + 1)
	return res
print(dfs(answer_id))


class Tree:

	def __init__(self, value, children=[]):
		self.value = value
		self.children = list(children)

	def is_leaf(self):
		return not self.children

	def add_child_tree(self, child):
		self.children.append(Tree(child))

	def depth(self):
		if self.is_leaf():
			return 1
		else:
			d_list = list()
			for ch in self.children:
				d_list.append(1 + ch.depth())
			return max(d_list)

def addCorrectChild(reposter, op, curr):
	if curr.value == op:
		curr.add_child_tree(reposter)
	else:
		for child in curr.children:
			addCorrectChild(reposter, op, child)
num = int(input())
lit_list = [input().lower().split(' reposted ') for _ in range(num)]
tree = Tree('polycarp')
for i in range(num):
	reposter = lit_list[i][0]
	op = lit_list[i][1]
	addCorrectChild(reposter, op, tree)
print(tree.depth())


from queue import Queue
n = int(input())
lines = []
users = set()
table = {}
used = []
for i in range(n):
	line = input().lower()
	lines.append(line)
	users.add(line.split(' ')[0])
	users.add(line.split(' ')[2])
for (index, user) in enumerate(users):
	table[user] = index
graph = [[] for i in range(len(table))]
used = [False for i in range(len(table))]
distances = [0 for i in range(len(table))]
for line in lines:
	user1 = table[line.split(' ')[0]]
	user2 = table[line.split(' ')[2]]
	graph[user1].append(user2)
	graph[user2].append(user1)
queue = Queue()
polycarp = table['polycarp']
used[polycarp] = True
queue.put(polycarp)
while not queue.empty():
	vertex = queue.get()
	for i in graph[vertex]:
		if not used[i]:
			queue.put(i)
			used[i] = True
			distances[i] = distances[vertex] + 1
print(max(distances) + 1)


from sys import stdin, stdout
n = int(stdin.readline().rstrip())
tree = {}
for k in range(n):
	line = stdin.readline().rstrip()
	(name1, name2) = line.split(' reposted ')
	(name1, name2) = (name1.lower(), name2.lower())
	if name2 not in tree:
		tree[name2] = []
	tree[name2].append(name1)
popularity = {'polycarp': 1}
champion = 'polycarp'
queue = ['polycarp']
while queue:
	(name, queue) = (queue[0], queue[1:])
	if name not in tree:
		continue
	for reposter in tree[name]:
		popularity[reposter] = 1 + popularity[name]
		if popularity[reposter] > popularity[champion]:
			champion = reposter
		queue.append(reposter)
print(popularity[champion])


import sys
infile = sys.stdin
outfile = sys.stdout

def main():
	n = int(infile.readline())
	graf = dict()
	graf['polycarp'] = 1
	answer = 1
	for i in range(n):
		(reposter, buff, poster) = [st.lower() for st in infile.readline().split()]
		graf[reposter] = graf[poster] + 1
		answer = max(answer, graf[reposter])
	outfile.write(str(answer))
main()


import sys
from collections import defaultdict
max_depth = 0

def dfs(vertex, vertices, depth):
	global max_depth
	neighbours = vertices[vertex]
	if not neighbours:
		if max_depth < depth:
			max_depth = depth
		return
	depth += 1
	for neighbour in neighbours:
		dfs(neighbour, vertices, depth)

def main():
	global max_depth
	vertices = defaultdict(list)
	reader = (tuple(line.split()) for line in sys.stdin)
	next(reader)
	for (neighbor, _, vertex) in reader:
		neighbor = neighbor.lower()
		vertex = vertex.lower()
		vertices[vertex].append(neighbor)
	root = 'polycarp'
	dfs(root, vertices, depth=1)
	print(max_depth)
main()


n = int(input())
data = dict()
small = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
big = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
data['polycarp'] = 1
for i in range(n):
	(name11, rep, name22) = input().split()
	(name1, name2) = ('', '')
	for i in range(len(name11)):
		if name11[i] in big:
			name1 += small[big.index(name11[i])]
		else:
			name1 += name11[i]
	for i in range(len(name22)):
		if name22[i] in big:
			name2 += small[big.index(name22[i])]
		else:
			name2 += name22[i]
	data[name1] = data[name2] + 1
help = list(data)
ans = 0
for elem in help:
	ans = max(ans, data[elem])
print(ans)


import sys
__author__ = 'zumzoom'
n = int(sys.stdin.readline())
edges = sys.stdin.readlines()
d = dict()
d['polycarp'] = 1
for edge in edges[:n]:
	a = edge.lower().split()
	d[a[0]] = d[a[2]] + 1
print(max(d.values()))


n = int(input())
name = ['polycarp']
edges = [1]
for i in range(n):
	(child, x, parent) = input().lower().split(' ')
	idx = name.index(parent)
	name.append(child)
	edges.append(edges[idx] + 1)
print(max(edges))


from collections import defaultdict
d = defaultdict(list)
res = 1
for _ in range(int(input())):
	li = list(input().split())
	d[li[-1].upper()].append(li[0].upper())

def bfs(s):
	res = 0
	vis = []
	q = [s]
	q.append(-1)
	while q:
		s = q[0]
		if s == -1:
			res += 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 res
k = bfs('POLYCARP')
print(k)


deep = dict()
n = int(input())
adj_dict = dict()
for i in range(n):
	line = [s.lower() for s in input().split()]
	name1 = line[0]
	name2 = line[2]
	if name2 not in list(adj_dict.keys()):
		adj_dict[name2] = list()
		adj_dict[name2].append(name1)
	else:
		adj_dict[name2].append(name1)
	deep[name1] = 0
	deep[name2] = 0
queue = list()
queue.append('polycarp')
while queue:
	current = queue[0]
	queue = queue[1:]
	if current not in adj_dict:
		continue
	for nei in adj_dict[current]:
		deep[nei] = deep[current] + 1
		queue.append(nei)
print(max(deep.values()) + 1)


n = int(input())
k = {'polycarp': 1}
for i in range(n):
	s = input().lower().split()
	k[s[0]] = k[s[2]] + 1
ans = 0
for i in k:
	if ans < k[i]:
		ans = k[i]
print(ans)


def lower(a):
	if 'A' <= a <= 'Z':
		return chr(ord(a) + 32)
	else:
		return a

def ToLower(a):
	a = list(a)
	for i in range(len(a)):
		a[i] = lower(a[i])
	return ''.join(a)

def main():
	n = int(input())
	people = ['polycarp']
	res = [1] * (n + 1)
	for i in range(1, n + 1):
		(a, b, c) = map(ToLower, input().split())
		res[i] = res[people.index(c)] + 1
		people.append(a)
	print(max(res))
main()


n = int(input())
name = []
rep = []
name.append('polycarp')
rep.append(1)
for i in range(n):
	inp = [str(s) for s in input().split()]
	if inp[2][len(inp[2]) - 1] == '\n':
		inp[2] = inp[2][:-1]
	name.append(inp[0].lower())
	for j in range(len(name)):
		if name[j] == inp[2].lower():
			rep.append(rep[j] + 1)
			break
print(max(rep))


def dfs(u):
	b[u] = True
	val = 0
	for i in graph[u]:
		if b[i] == False:
			val = max(val, dfs(i))
	return val + 1
n = int(input())
graph = {}
for i in range(n):
	x = input().lower().split()
	if x[2] in graph.keys():
		graph[x[2]].append(x[0])
	else:
		graph[x[2]] = [x[0]]
	if x[0] in graph.keys():
		graph[x[0]].append(x[2])
	else:
		graph[x[0]] = [x[2]]
y = len(graph.keys())
b = {i: False for i in graph.keys()}
print(dfs('polycarp'))


def dfs(curpost):
	global adjlist, visited
	visited.add(curpost)
	count = 0
	if curpost in adjlist:
		for post in adjlist[curpost]:
			if post not in visited:
				val = dfs(post)
				if val > count:
					count = val
	return count + 1
n = int(input())
adjlist = {}
visited = set()
for i in range(n):
	line = input().split()
	if line[2].lower() not in adjlist:
		adjlist[line[2].lower()] = [line[0].lower()]
	else:
		adjlist[line[2].lower()].append(line[0].lower())
ans = dfs('polycarp')
print(ans)


def add_vertex(graph, v):
	if v not in graph:
		graph[v] = []

def add_edge(graph, v1, v2):
	graph[v1].append(v2)
su = 0
m = 0

def dfs(visited, graph, node):
	global su, m
	if node not in visited:
		visited.add(node)
		su += 1
		m = max(su, m)
		for neighbour in graph[node]:
			dfs(visited, graph, neighbour)
			su -= 1
graph = {}
incidence = {}
n = int(input())
for j in range(1, n + 1):
	s = list(map(str, input().split(' reposted ')))
	add_vertex(graph, s[0].lower())
	add_vertex(graph, s[1].lower())
	add_edge(graph, s[1].lower(), s[0].lower())
visited = set()
dfs(visited, graph, 'polycarp')
print(m)


n = int(input())
mp = {}
for s in range(n):
	str = [x.upper() for x in input().split()]
	if mp.get(str[-1]) != None:
		mp[str[-1]].append(str[0])
	else:
		mp[str[-1]] = [str[0]]

def dfs(v, p=-1):
	mx = 0
	if mp.get(v) == None:
		return 0
	for i in mp[v]:
		if p != i:
			mx = max(mx, dfs(i, v) + 1)
	return mx
print(dfs('Polycarp'.upper()) + 1)


def reposty(lst):
	(d, result) = ({'polycarp': 1}, 0)
	for elem in lst:
		(name1, name2) = (elem[0].lower(), elem[2].lower())
		d[name1] = d[name2] + 1
	for (key, v) in d.items():
		result = max(result, v)
	return result
n = int(input())
a = list()
for i in range(n):
	(s, t, z) = [i for i in input().split()]
	a.append([s, t, z])
print(reposty(a))


from collections import defaultdict, deque
n = int(input())
graph = defaultdict(list)
for i in range(n):
	(u, v) = input().split(' reposted ')
	(u, v) = (u.lower(), v.lower())
	graph[u].append(v)
	graph[v].append(u)
vis = set()
dist = dict()
q = deque()
dist['polycarp'] = 1
q.append('polycarp')
while q:
	u = q.popleft()
	vis.add(u)
	for v in graph[u]:
		if v not in vis:
			dist[v] = 1 + dist[u]
			q.append(v)
			vis.add(v)
print(max(dist.values()))


n = int(input())
a = {'polycarp': 1}
for i in range(n):
	l = input().split()
	a[l[0].lower()] = a[l[2].lower()] + 1
print(max(a.values()))


n = int(input())
d = {'polycarp': 1}
for i in range(n):
	s = input().lower().split()
	d[s[0]] = d[s[2]] + 1
print(max(d.values()))


def repost():
	max_chain = {'polycarp': 1}
	num = int(input())
	for i in range(num):
		reps = input().split()
		max_chain[reps[0].lower()] = max_chain[reps[2].lower()] + 1
	return max(max_chain.values())
print(repost())


from sys import stdin
import re
guys = {'polycarp': 1}
res = 1
stdin.readline()
for line in stdin:
	try:
		(to, _, fr) = map(lambda s: s.strip().lower(), line.lstrip().split(' ', 2))
	except:
		continue
	guys[to] = max(guys[fr] + 1, guys.get(to, 0))
	res = max(guys[to], res)
print(res)


n = int(input())
after = {}
position = {}
repost = []
unused = [True] * n
for i in range(n):
	l = [str(j).lower() for j in input().split()]
	after[l[0]] = l[2]
	position[l[0]] = i
	repost.append(l[0])
maximum = 1
for i in range(n):
	if unused[i]:
		t = repost[i]
		times = 1
		while True:
			try:
				after[t]
			except:
				break
			t = after[t]
			times += 1
			try:
				position[t]
			except:
				break
			k = position[t]
			unused[k] = False
		maximum = max(maximum, times)
print(maximum)


def dfs(adj, node, vis):
	vis.add(node)
	for n in adj[node]:
		if n not in vis:
			return 1 + dfs(adj, n, vis)
	return 0
from sys import stdin, stdout
n = int(stdin.readline())
s = []
for i in range(n):
	x = list(stdin.readline().split())
	for j in range(3):
		x[j] = x[j].lower()
	s.append(x)
d = {}
l = 1
for i in range(len(s)):
	(n1, n2) = (s[i][0], s[i][2])
	if n1 not in d:
		d[n1] = l
		l += 1
	if n2 not in d:
		d[n2] = l
		l += 1
from collections import defaultdict
adj = defaultdict(list)
for i in range(len(s)):
	(x, y) = (d[s[i][0]], d[s[i][2]])
	adj[x].append(y)
ans = 0
for i in range(1, l + 1):
	vis = set()
	c = dfs(adj, i, vis)
	ans = max(ans, c + 1)
stdout.write('{}\n'.format(ans))


n = int(input())
dep = {}
dep['polycarp'] = 1
ans = 1
for i in range(n):
	(user, _, fruser) = input().split()
	d = dep[user.lower()] = dep[fruser.lower()] + 1
	ans = max(ans, d)
print(ans)


def ds(level, name):
	global Adj
	global k
	j = 0
	ch = 0
	ans = level
	for i in [row[name] for row in Adj]:
		if i == 1:
			ans = max(ans, ds(level + 1, j))
			ch += 1
		j += 1
	if ch == 0:
		return level
	else:
		return ans
n = int(input())
names = list(['polycarp'])
A = [['00'] for i in range(n)]
for i in range(n):
	s = input().split(' ')
	if s[0] not in names:
		names.append(s[0].lower())
	A[i] = [s[0].lower(), s[2].lower()]
k = len(names)
Adj = [[0 for i in range(k)] for j in range(k)]
for i in range(n):
	Adj[names.index(A[i][0])][names.index(A[i][1])] = 1
print(ds(1, 0))


arg = int(input())
list2 = [[] for a in range(0, 36100)]
for a in range(0, arg):
	list1 = input().strip().split()
	list1[0] = list1[0].lower()
	list1[2] = list1[2].lower()
	flag3 = 0
	for a in list2:
		if list1[2] in a:
			flag3 = 1
			list2[list2.index(a) * 2 % 36073].append(list1[0])
	if flag3 == 0:
		counter = 1
		while True:
			if list2[counter] == []:
				list2[counter].append(list1[2])
				list2[counter * 2 % 36073].append(list1[0])
				break
			counter += 1
if ['polycarp'] in list2:
	print(len(list2) - list2.count([]))
else:
	print(1)


n = int(input())
a = [input() for _ in range(n)]
a = {i.split()[0].lower(): i.split()[2].lower() for i in a}

def solve(k) -> int:
	if k not in a.keys():
		return 1
	return solve(a[k]) + 1
print(max([solve(i) for i in a.keys()]))


from sys import stdin
n = int(stdin.readline())
cnt = {'POLYCARP': 1}
ans = 1
for i in range(n):
	(name1, _, name2) = map(lambda s: s.strip().upper(), stdin.readline().split())
	cnt[name1] = cnt[name2] + 1
	ans = max(ans, cnt[name1])
print(ans)


import sys
from collections import defaultdict
n = int(sys.stdin.readline())
R = {'polycarp': 1}
for i in range(n):
	(a, b) = map(str.lower, sys.stdin.readline().strip().split(' reposted '))
	R[a] = R[b] + 1
sys.stdout.write(str(max(R.values())))


import sys
n = int(input())
names = ['POLYCARP']
to = [[]]

def find_v(name):
	ind = -1
	for i in range(len(names)):
		if names[i] == name:
			ind = i
	return ind

def dfs(v):
	if len(to[v]) == 0:
		return 1
	sol = 0
	for i in range(len(to[v])):
		sol = max(sol, dfs(to[v][i]))
	return sol + 1
for i in range(n):
	s = input()
	w = s.split()
	w[0] = w[0].upper()
	w[2] = w[2].upper()
	v = find_v(w[2])
	v_to = find_v(w[0])
	if v_to == -1:
		names.append(w[0])
		to.append([])
		v_to = len(names) - 1
	to[v].append(v_to)
res = dfs(0)
print(res)


n = int(input())
t = {}
for i in range(n):
	s = input().split()
	fr = s[2].upper()
	to = s[0].upper()
	if fr in t:
		t[fr].append(to)
	else:
		t[fr] = [to]

def dfs(v):
	if v in t:
		mx = 0
		for i in t[v]:
			mx = max(mx, dfs(i) + 1)
		return mx
	return 0
print(dfs('POLYCARP') + 1)


n = int(input())
graph = {'polycarp': 1}
max = 1
for i in range(n):
	line = input().split()
	a = line[0].lower()
	b = line[2].lower()
	graph[a] = graph[b] + 1
	if max < graph[a]:
		max = graph[a]
print(max)


import sys
import math
import collections
from pprint import pprint as pp
mod = 1000000007

def vector(size, val=0):
	vec = [val for i in range(size)]
	return vec

def matrix(rowNum, colNum, val=0):
	mat = []
	for i in range(rowNum):
		collumn = [val for j in range(colNum)]
		mat.append(collumn)
	return mat
n = int(input())
a = []
for i in range(n):
	s = list(input().split())
	s[0] = s[0].lower()
	s[2] = s[2].lower()
	a.append(s)
d = {}
d['polycarp'] = 1
ans = 1
for i in a:
	name1 = i[0]
	name2 = i[2]
	if name1 not in d:
		d[name1] = d[name2] + 1
	else:
		d[name1] = max(d[name1], d[name2] + 1)
	ans = max(ans, d[name1])
print(ans)


n = int(input())
a = [list(input().split(sep=' reposted ')) for i in range(n)]
s = {'polycarp': 1}
for (i, k) in a:
	if k.lower() in s.keys():
		s[i.lower()] = s[k.lower()] + 1
print(max(s.values()))


import collections, itertools, functools, math

def solve():
	n = int(input())
	graph = dict()
	for _ in range(n):
		(dst, _, src) = input().lower().split()
		if src not in graph:
			graph[src] = set()
		graph[src].add(dst)

	def treeHeight(node):
		if node not in graph:
			return 1
		return 1 + max((treeHeight(n) for n in graph[node]))
	return treeHeight('polycarp')
print(solve())


n = int(input())
mp = dict()
mp['polycarp'] = 1
top = 2
adj = []
visited = [0] * (n + 2)
for i in range(n + 2):
	adj.append([])
for i in range(n):
	strings = list(map(str, input().split()))
	mp[strings[0].lower()] = top
	adj[top].append(mp[strings[2].lower()])
	adj[mp[strings[2].lower()]].append(top)
	top += 1
m = 0

def dfs(x, length):
	visited.append(x)
	for i in adj[x]:
		if i not in visited:
			dfs(i, length + 1)
	global m
	m = max(m, length)
dfs(1, 1)
print(m)


from collections import Counter
import heapq
from collections import Counter
n = int(input())
d = {}
d['polycarp'] = 1
for i in range(n):
	s = input().lower().split(' ')
	d[s[0]] = d[s[2]] + 1
print(max(d.values()))


n = int(input())
a = []
temp = dict()
temp['polycarp'] = 1
for i in range(n):
	x = input().lower()
	(n1, c, n2) = x.split()
	if n2 == 'polycarp':
		temp.update({n1: 1})
	else:
		temp.update({n1: temp[n2] + 1})
print(max(temp.values()) + 1)


n = int(input())
users = [['polycarp']]
p = 0
for x in range(n):
	string = input()
	(a, b) = map(lambda x: x.lower(), string.split(' reposted '))
	q = 0
	while not b in users[q]:
		q += 1
	if q == p:
		users.append([a])
		p += 1
	else:
		users[q + 1].append(a)
print(p + 1)


leaf = {}
n = int(input())
for i in range(n):
	s = input().split()
	a = s[0].lower()
	b = s[2].lower()
	try:
		leaf[b].append(a)
	except:
		leaf[b] = []
		leaf[b].append(a)
q = []
st = []
q.append('polycarp')
m = 0
while len(q) > 0:
	t = q.pop()
	while len(st) > 0 and t not in leaf[st[-1]]:
		st.pop()
	st.append(t)
	try:
		tt = leaf[t]
		for i in tt:
			q.append(i)
	except:
		if len(st) > m:
			m = len(st)
		st.pop()
print(m)


from collections import defaultdict, deque
posts = defaultdict(list)
n = int(input())
for _ in range(n):
	line = input().split()
	posts[line[2].lower()].append(line[0].lower())
longest_chain = 0
queue = deque()
queue.appendleft(['polycarp', 1])
while len(queue):
	current = queue.pop()
	for post in posts[current[0]]:
		new_list = [post, current[1] + 1]
		queue.appendleft(new_list)
		longest_chain = max(longest_chain, new_list[1])
print(longest_chain)


from sys import stdin, stdout
from math import gcd, sqrt, factorial, inf
from collections import deque, defaultdict
input = stdin.readline
R = lambda : map(int, input().split())
I = lambda : int(input())
S = lambda : input().rstrip('\n')
L = lambda : list(R())
P = lambda x: stdout.write(x)
lcm = lambda x, y: x * y // gcd(x, y)
hg = lambda x, y: (y + x - 1) // x * x
pw = lambda x: 0 if x == 1 else 1 + pw(x // 2)
chk = lambda x: chk(x // 2) if not x % 2 else True if x == 1 else False
sm = lambda x: (x ** 2 + x) // 2
N = 10 ** 9 + 7

def solve(p):
	if p not in d:
		return 1
	else:
		m = -inf
		for i in d[p]:
			m = max(m, solve(i))
		return m + 1
d = {}
for i in range(I()):
	x = S().split()
	a = x[0].lower()
	b = x[-1].lower()
	if b not in d:
		d[b] = [a]
	else:
		d[b] += (a,)
print(solve('polycarp'))


from math import *
ci = 1
d = {'polycarp': 0}
n = int(input())
g = {}
for i in range(n + 1):
	g[i] = []
for i in range(n):
	(a, _, b) = [i.lower() for i in input().split()]
	if a not in d:
		d[a] = ci
		ci += 1
	g[d[b]].append(d[a])
de = [1]

def dfs(v, t):
	de[0] = max(de[0], t)
	for u in g[v]:
		dfs(u, t + 1)
dfs(0, 1)
print(de[0])


def dfs(graph, lvl, s, ver):
	ver.remove(s)
	ans = lvl
	if s in graph:
		for j in graph[s]:
			if j in ver:
				ans = max(ans, dfs(graph, lvl + 1, j, ver))
	return ans

def Lower(s):
	return s.lower()
n = int(input())
graph = {}
ver = set()
for i in range(n):
	(a, b) = map(Lower, input().split(' reposted '))
	ver.add(a)
	ver.add(b)
	if b in graph:
		graph[b].append(a)
	else:
		graph[b] = [a]
ans = dfs(graph, 1, 'polycarp', ver)
print(ans)


def Solve(graph, parents, hts):
	name = 'polycarp'
	stack = [name]
	while stack:
		curr = stack.pop()
		if curr in parents.keys():
			hts[curr] = hts[parents[curr]] + 1
		else:
			hts[curr] = 0
		if curr in graph.keys():
			for kid in graph[curr]:
				stack.append(kid)
	hts1 = []
	for i in hts:
		hts1.append(hts[i])
	return max(hts1) + 1

def main():
	n = int(input())
	graph = {}
	parents = {}
	hts = {}
	for i in range(n):
		names = list(map(str, input().split()))
		name1 = names[0]
		name2 = names[2]
		name1 = name1.lower()
		name2 = name2.lower()
		parents[name1] = name2
		hts[name1] = -1
		hts[name1] = -1
		if name2 not in graph.keys():
			graph[name2] = [name1]
		else:
			graph[name2].append(name1)
	print(Solve(graph, parents, hts))
main()


from collections import defaultdict, deque
n = int(input())
graph = defaultdict(list)
visited = set()
longest = defaultdict(int)
persons = set()
for _ in range(n):
	(x, _, y) = input().strip().split()
	graph[y.lower()].append(x.lower())
	persons.update([x.lower(), y.lower()])

def dfs(start):
	stack = deque([(start, 1)])
	res = 1
	while len(stack):
		(node, count) = stack.pop()
		res = max(res, count)
		visited.add(node)
		for neb in graph[node]:
			if neb in visited:
				res = max(res, count + longest[neb])
			else:
				stack.appendleft((neb, count + 1))
	longest[start] = res
	return res
res = 1
for p in persons:
	if p not in visited:
		res = max(res, dfs(p))
print(res)


import math
from collections import deque, defaultdict
from sys import stdin, stdout
input = stdin.readline
listin = lambda : list(map(int, input().split()))
mapin = lambda : map(int, input().split())
n = int(input())
d = defaultdict(int)
d['polycarp'] = 1
ans = 1
for i in range(n):
	(name1, rep, name2) = input().split()
	name1 = name1.lower()
	name2 = name2.lower()
	d[name1] = d[name2] + 1
	ans = max(ans, d[name1])
print(ans)


n = int(input())
tree = {}
for i in range(n):
	(name1, _, name2) = input().split()
	name1 = name1.lower()
	name2 = name2.lower()
	if i == 0:
		start = name2
	if name2 in tree:
		tree[name2].append(name1)
	else:
		tree[name2] = []
		tree[name2].append(name1)
	if name1 not in tree:
		tree[name1] = []

def dfs(s_v, gr):
	explored = []
	l = 0
	queue = []
	k = []
	k.append(0)
	k.append(s_v)
	queue.append(k)
	while queue:
		k = queue.pop()
		n = k.pop()
		m = k.pop()
		if n not in explored:
			explored.append(n)
			m += 1
			l = max(l, m)
			for i in gr[n]:
				if not gr[i] in explored:
					k = []
					k.append(m)
					k.append(i)
					queue.append(k)
	return l
print(dfs(start, tree))


n = int(input())
from collections import defaultdict
d = defaultdict(int)
d['polycarp'] = 1
ans = 0
for i in range(n):
	(a, b, c) = input().split(' ')
	a = a.lower()
	c = c.lower()
	d[a] = max(d[a], d[c] + 1)
	ans = max(ans, d[a])
print(ans)


n = int(input())
p = {'polycarp': 1}
c = 0
for i in range(n):
	l = [x.lower() for x in input().split()]
	p[l[0]] = p[l[2]] + 1
print(max(p.values()))


n = int(input())
names = dict()
names['polycarp'] = 1
max = 1
for i in range(n):
	data = input().strip().split(' ')
	first = data[0].lower()
	last = data[2].lower()
	names[first] = names[last] + 1
	if names[first] > max:
		max = names[first]
print(max)


from collections import defaultdict

def dfs(arg):
	for i in g[arg]:
		dist[i] = dist[arg] + 1
		dfs(i)
n = int(input())
g = defaultdict(list)
dist = defaultdict(int)
for _ in range(n):
	s = input().lower().split(' reposted ')
	g[s[1]].append(s[0])
	dist[s[0]] = 1
	dist[s[1]] = 1
dfs('polycarp')
print(max(dist.values()))


from collections import *
import bisect
import heapq

def ri():
	return int(input())

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

def bfs():
	visited = [False] * (n + 1)
	distances = [1] * (n + 1)
	start = 0
	visited[start] = True
	to_visit = deque()
	to_visit.append(start)
	while to_visit:
		node = to_visit.popleft()
		for neighbor in graph[node]:
			if not visited[neighbor]:
				visited[neighbor] = True
				to_visit.append(neighbor)
				distances[neighbor] = distances[node] + 1
	return max(distances)
n = ri()
graph = [[] for _ in range(n + 1)]
names = dict()
count = 0
for i in range(n):
	(b, _, a) = input().split()
	a = a.lower()
	b = b.lower()
	if a not in names:
		names[a] = count
		count += 1
	if b not in names:
		names[b] = count
		count += 1
	graph[names[a]].append(names[b])
	graph[names[b]].append(names[a])
longuest = bfs()
print(longuest)


n = int(input())
level = {'polycarp': 0}
parent = {'polycarp': None}
frontier = ['polycarp']
edge = {'polycarp': []}
for i in range(n):
	word = input()
	word = word.lower()
	idx1 = word.find(' ')
	name1 = word[:idx1]
	idx2 = len(name1) + 10
	name2 = word[idx2:]
	if name1 not in edge:
		edge[name1] = []
	edge[name2].append(name1)
i = 1
while frontier:
	next = []
	for u in frontier:
		for v in edge[u]:
			if not v in level:
				level[v] = i
				parent[v] = u
				next.append(v)
	i += 1
	frontier = next
maxi = 0
for u in level:
	maxi = max(maxi, level[u] + 1)
print(maxi)


def main():
	n = int(input())
	cur = []
	for _ in range(n):
		a = input().split()
		a[0] = a[0].lower()
		a[2] = a[2].lower()
		cur.append((a[0], a[2]))
	d = {'polycarp': 1}
	to_do = []
	while cur:
		for (i, j) in cur:
			if j in d:
				d[i] = d[j] + 1
			else:
				to_do.append((i, j))
		cur = to_do
		to_do = []
	ans = max(d.values())
	print(ans)
main()


def dps(list, start, count):
	count1 = 0
	k = count
	for i in range(len(list[start])):
		if list[start][i] == 1:
			count = count + 1
			count = dps(list, i, count)
		if count > count1:
			count1 = count
		count = k
	return count1
n = int(input(''))
a = []
b = []
for i in range(n):
	s = str(input(''))
	s = s.lower()
	a.append(s.split(' '))
	if s.split(' ')[0] not in b:
		b.append(s.split(' ')[0])
	if s.split(' ')[2] not in b:
		b.append(s.split(' ')[2])
r = len(b)
matrix = []
for i in range(r):
	u = [0] * r
	matrix.append(u)
for i in range(len(b)):
	for j in range(len(a)):
		if b[i] == a[j][0]:
			for k in range(len(b)):
				if b[k] == a[j][2]:
					matrix[k][i] = 1
				else:
					matrix[k][i] = 0
k = -1
if len(b) == 2:
	print(2)
else:
	for i in range(len(b)):
		if b[i] == 'polycarp':
			print(dps(matrix, i, 0) + 1)
			break


n = int(input())
graph = {'POLYCARP': []}
for i in range(n):
	s = input()
	s1 = s[:s.find(' ')].upper()
	s2 = s[s.rfind(' ') + 1:].upper()
	if s2 not in graph.keys():
		graph[s2] = [s1]
	else:
		graph[s2] += [s1]
max = 1

def next(x, l):
	global max
	if x in graph.keys():
		for item in graph[x]:
			next(item, l + 1)
	elif l > max:
		max = l
next('POLYCARP', 1)
print(max)


def lc(s):
	ss = ''
	for i in s:
		if ord(i) < 97:
			ss += chr(ord(i) + 32)
		else:
			ss += i
	return ss
n = int(input())
dic = {'polycarp': 1}
for i in range(n):
	s = input().split()
	s1 = lc(s[0])
	s2 = lc(s[2])
	if not s2 in dic:
		dic[s2] = 0
	dic[s1] = dic[s2] + 1
print(max(dic.values()))


reposted = {'polycarp': 1}
n = int(input())
for i in range(n):
	names = input().lower().split(' reposted ')
	reposted[names[0]] = reposted[names[1]] + 1
print(reposted[max(reposted, key=reposted.get)])


def main():
	n = int(input())
	lens = {'polycarp': 1}
	ans = 1
	for i in range(n):
		linos = input().split()
		x = linos[0].lower()
		y = linos[2].lower()
		if y in lens:
			z = lens[x] if x in lens else 0
			lens[x] = max(z, lens[y] + 1)
	for (x, y) in lens.items():
		ans = max(ans, y)
	print(ans)
main()


from collections import defaultdict
n = int(input())
g = defaultdict(list)
startingPoint = None
dp = defaultdict(str)
g[''] = ''
maxi = [0]

def dfs(ele, par):
	dp[ele] = 1
	zero = 0
	for e in g[ele]:
		if e == par:
			continue
		dfs(e, ele)
		zero = max(zero, dp[e])
	dp[ele] += zero
	maxi[0] = max(maxi[0], dp[ele])
for i in range(n):
	repost = list(input().split())
	repost[0] = repost[0].lower()
	repost[-1] = repost[-1].lower()
	g[repost[0]].append(repost[-1])
	g[repost[-1]].append(repost[0])
	if i == 0:
		startingPoint = repost[-1]
dfs(startingPoint, '')
print(maxi[0])


n = int(input())
mp = {}
for i in range(n):
	(x, y, z) = map(str, input().split())
	x = x.lower()
	z = z.lower()
	mp[x] = z
ans = 1
for i in mp:
	x = i
	c = 1
	while mp.get(x):
		c = c + 1
		x = mp[x]
	ans = max(ans, c)
print(ans)


n = int(input())
repost = {}
for i in range(n):
	repost[tuple(input().lower().split(' reposted '))] = 0
subrep = []
for i in repost:
	subrep.append(i)
	if i[1] == 'polycarp':
		repost[i] = 2
	else:
		a = []
		for j in subrep:
			if j[0] == i[1]:
				a.append(repost[j])
		repost[i] = max(a) + 1
print(max(repost.values()))


from collections import defaultdict, deque
G = defaultdict(set)
for _ in range(int(input())):
	(V, _, U) = input().lower().split()
	G[U].add(V)
seen = {'polycarp'}
queue = deque([('polycarp', 1)])
while queue:
	(U, x) = queue.popleft()
	for V in G[U]:
		if V not in seen:
			queue.append((V, x + 1))
			seen.add(V)
print(x)


def read_int():
	return int(input().split()[0])

def walk_tree(cur, parent, depth, maxDepth):
	depth += 1
	if depth > maxDepth:
		maxDepth = depth
	for child in rs[cur]:
		if child != parent:
			result = walk_tree(child, cur, depth, maxDepth)
			if result > maxDepth:
				maxDepth = result
	return maxDepth
rs = {}
nReposts = read_int()
readRoot = True
rootPoster = None
for i in range(0, nReposts):
	words = input().split()
	words[0] = words[0].lower()
	words[2] = words[2].lower()
	if readRoot:
		readRoot = False
		rootPoster = words[2]
	if not words[0] in rs:
		rs[words[0]] = []
	if not words[2] in rs:
		rs[words[2]] = []
	rs[words[0]].append(words[2])
	rs[words[2]].append(words[0])
maxDepth = walk_tree(rootPoster, rootPoster, 0, 0)
print(maxDepth)


def du(s):
	ans = 0
	for n in s.keys():
		temp = 0
		x = n
		while True:
			temp += 1
			nxt = d[x]
			if nxt in d.keys():
				x = nxt
			else:
				break
		ans = max(ans, temp)
	return ans + 1
d = {}
for _ in range(int(input())):
	s = input().split(' ')
	d[s[0].lower()] = s[2].lower()
print(du(d))


v = int(input())
ver = 1
ref = {'polycarp': 1}
graph = []
for i in range(v + 2):
	graph.append([])
for i in range(v):
	(child, _, parent) = input().split()
	child = str.lower(child)
	parent = str.lower(parent)
	ver += 1
	ref[child] = ver
	p = ref[parent]
	c = ref[child]
	graph[p].append(c)

def dfs(graph, node, visited, height):
	visited[node] = True
	for i in graph[node]:
		if not visited[i]:
			dfs(graph, i, visited, height)
			height[node] = max(height[node], height[i] + 1)
height = [1] * (len(graph) + 1)
dfs(graph, 1, [False] * (len(graph) + 1), height)
print(height[1])


n = int(input())
mp = {'polycarp': 1}
gx = {}
count = 2
for i in range(0, n):
	s = input()
	s = s.split(' ')
	s.remove('reposted')
	s[0] = s[0].lower()
	s[1] = s[1].lower()
	v = mp[s[1]]
	if s[0] in mp:
		u = mp[s[0]]
	else:
		u = count
		count += 1
		mp[s[0]] = u
		if u in gx:
			gx[u].append(v)
		else:
			gx[u] = [v]
		if v in gx:
			gx[v].append(u)
		else:
			gx[v] = [u]
vis = {}
for i in range(0, 555):
	vis[i] = False
result = [0]

def dfs(node, till):
	vis[node] = True
	result[0] = max(result[0], till)
	for x in gx[node]:
		if vis[x] == False:
			dfs(x, till + 1)
dfs(1, 1)
print(result[0])


def dfs(s):
	k = 0
	for adj in l[s]:
		k = max(dfs(adj), k)
	return k + 1
n = int(input())
l = [[]]
for _ in range(n):
	l.append([])
d = {}
d['polycarp'] = 0
j = 1
for i in range(n):
	s = input().lower().split()
	ind = d[s[2]]
	if s[0] in d.keys():
		l[ind].append(d[s[0]])
	else:
		d[s[0]] = j
		j += 1
		l[ind].append(d[s[0]])
print(dfs(0))


n = int(input())
d = {'polycarp': 1}
for _ in range(n):
	(a, b, c) = input().lower().split()
	d[a] = d[c] + 1
print(max(d.values()))


def dfs(record, key_vertex):
	if key_vertex not in record.keys():
		return 1
	val = 1
	for neighbour in record[key_vertex]:
		val = max(1 + dfs(record, neighbour), val)
	return val
n = int(input())
record = {}
start = ''
cond = True
for i in range(n):
	s = input()
	li = s.split(' ')
	key = li[2].lower()
	if cond:
		start = key
		cond = False
	val = li[0].lower()
	if key in record.keys():
		record[key].append(val)
	else:
		record[key] = [val]
print(dfs(record, start))


def main():
	n = int(input())
	from collections import defaultdict
	e = defaultdict(list)
	for _ in range(n):
		(dst, _, src) = input().split(' ')
		e[src.lower()].append(dst.lower())
	ans = 0
	dq = ['Polycarp'.lower()]
	visit = set(dq)
	while dq:
		ans += 1
		new_dq = []
		for node in dq:
			for neibor in e[node]:
				if neibor not in visit:
					visit.add(neibor)
					new_dq.append(neibor)
		dq = new_dq
	print(ans)
main()


n = int(input())
arr = list(([False] * (n + 1) for i in range(n + 1)))
slov = {}
slov['polycarp'] = 0
q = 1
for i in range(n):
	a = input().lower().split()
	slov[a[0]] = q
	arr[slov[a[2]]][q] = True
	q += 1

def obh(i):
	global arr, n
	ma = 0
	for t in range(n + 1):
		if arr[i][t]:
			arr[i][t] = False
			q = obh(t)
			if q + 1 > ma:
				ma = q + 1
	return ma
print(obh(0) + 1)


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 = {}
for i in range(n):
	m = input().split()
	try:
		d[m[2].lower()].append(m[0].lower())
	except KeyError:
		d[m[2].lower()] = [m[0].lower()]
print(find(d, 'polycarp'))


def bfs(g, s):
	l = 0
	a = []
	a.append(s)
	a.append('-1')
	vis = []
	vis.append(s)
	while len(a) != 0:
		s = a[0]
		a = a[1:]
		if len(a) != 0 and s == '-1':
			l += 1
			a.append('-1')
		if s != '-1':
			for i in g[s]:
				if i not in vis and i in g:
					a.append(i)
					vis.append(i)
	return l + 2

def dfs(g, s):
	res = 0
	for i in g:
		res = max(res, bfs(g, i))
	return res
g = {}
n = int(input())
for i in range(n):
	s = list(map(str, input().split(' ')))
	if s[2].lower() not in g:
		g[s[2].lower()] = []
	g[s[2].lower()].append(s[0].lower())
print(dfs(g, 'polycarp'))


n = int(input())
l = {}
for i in range(n):
	(name1, name2) = input().lower().split(' reposted ')
	if name2 not in l:
		l[name2] = 1
	l[name1] = l[name2] + 1
print(max(l.values()))


dic = {'polycarp': 1}
for i in range(int(input())):
	l = [x.lower() for x in input().split(' ')]
	dic[l[0]] = dic[l[2]] + 1
print(max(dic.values()))


n = int(input())
graph = {'polycarp': []}
for i in range(n):
	information = input().split(' ')
	friend = information[0]
	friend = friend.lower()
	person = information[2]
	person = person.lower()
	graph[friend] = []
	graph[person].append(friend)

def dfs(g, src, cnt=0):
	ans = cnt
	for frend in g[src]:
		temp = dfs(g, frend, cnt + 1)
		if temp > ans:
			ans = temp
	return ans
print(dfs(graph, 'polycarp') + 1)


from collections import deque
n = int(input())
d = {}
for i in range(n):
	(v, _, u) = map(str.lower, input().split())
	d.setdefault(u, []).append(v)
q = deque(['polycarp'])
dis = {}
dis['polycarp'] = 1
while q:
	name = q.popleft()
	try:
		for to in d[name]:
			if to not in dis:
				q.append(to)
				dis[to] = dis[name] + 1
	except KeyError:
		pass
print(max(dis.values()))


n = int(input())
run_dict = {'polycarp': 1}
for i in range(n):
	s = input().split('reposted')
	sec = s[1].lower().strip()
	fir = s[0].lower().strip()
	run_dict[fir] = run_dict[sec] + 1
print(max(run_dict.values()))


__author__ = 'Utena'
n = int(input())
reposts = dict()
for i in range(n):
	s = input().split()
	reposts[s[0].lower()] = s[2].lower()
prev = ['polycarp']
t = 1
while True:
	next = []
	for a in reposts.keys():
		if reposts[a] in prev:
			next.append(a)
	if next == []:
		break
	else:
		t += 1
		prev = next
print(t)


def main():
	n = int(input())
	d = {'polycarp': 1}
	for i in range(n):
		s = str(input()).split()
		d.update({s[0].lower(): d.get(s[2].lower()) + 1})
	print(max(d.values()))
main()


class Node:

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

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

def findMax(nodes, curr, count):
	if len(curr.children) == 0:
		return count
	else:
		currCount = count
		for child in curr.children:
			currCount = max(currCount, findMax(nodes, child, count + 1))
		return currCount

def main():
	nodes = dict()
	nodes['polycarp'] = Node('polycarp')
	t = int(input().strip())
	while t:
		st = input().strip().split(' ')
		user1 = st[0].lower()
		user2 = st[2].lower()
		nodes[user1] = Node(user1)
		nodes[user2].add(nodes[user1])
		t -= 1
	print(findMax(nodes, nodes['polycarp'], 1))
main()


n = int(input())
g = {}
m = 2
for i in range(n):
	k = input().split()
	a1 = k[0].lower()
	a2 = k[2].lower()
	num = 1
	if i == 0:
		g[a2] = num
		g[a1] = num + 1
	else:
		num = g[a2] + 1
		g[a1] = num
		if num > m:
			m = num
print(m)


from collections import defaultdict
t = int(input())
d = defaultdict(list)
l = []

def DFS(visited, x, c, d):
	z = c
	visited[x] = True
	for j in d[x]:
		if visited[j] == False:
			z = max(z, DFS(visited, j, c + 1, d))
	return z
visited = {}
for i in range(t):
	s = input().split(' ')
	l.append(s[0].lower())
	l.append(s[2].lower())
	visited[l[-1]] = False
	visited[l[-2]] = False
	d[l[-1]].append(l[-2])
z = 1
for i in visited:
	c = 1
	if visited[i] == False:
		z = max(z, DFS(visited, i, c, d))
print(z)


n = int(input())
a = dict()
a['polycarp'] = 1
for i in range(n):
	s = input().split()
	s[0] = s[0].lower()
	s[2] = s[2].lower()
	a[s[0]] = a[s[2]] + 1
max = 0
maxi = 'polycarp'
for i in a:
	if a[i] > max:
		maxi = i
		max = a[i]
print(max)


class Node:

	def __init__(self):
		self.dic = {'polycarp': []}

	def addNode(self, addto, newNode):
		self.dic[addto].append(newNode)
		self.dic[newNode] = []

	def maxHight(self, root):
		maxi = 0
		if len(self.dic[root]) == 0:
			return 1
		else:
			for i in range(len(self.dic[root])):
				maxi = max(maxi, 1 + self.maxHight(self.dic[root][i]))
			return maxi
n = int(input())
s = [None] * n
for i in range(n):
	str = input()
	s[i] = str.casefold()
root = Node()
for i in range(len(s)):
	addto = s[i].split()[-1]
	newNode = s[i].split()[0]
	root.addNode(addto.casefold(), newNode.casefold())
print(root.maxHight('polycarp'.casefold()))


PeopleN = int(input())
nameD = {}
for k in range(0, PeopleN):
	nameL = input().split()
	if k == 0:
		nameD[nameL[2].upper()] = 1
	nameD[nameL[0].upper()] = nameD[nameL[2].upper()] + 1
theN = list(nameD.values())
theN.sort()
print(theN.pop())


from typing import List

def solve(n: int, repost_chain: List[List[str]]) -> int:
	graph = {'polycarp': 1}
	max_height = 0
	for repost in repost_chain:
		(reposter, op) = (repost[0], repost[-1])
		height = graph[op.lower()] + 1
		graph[reposter.lower()] = height
		max_height = max(height, max_height)
	return max_height
n = int(input())
repost_chain = [input().split() for _ in range(n)]
print(solve(n, repost_chain))


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()
rootNode = 'polycarp'
graph.addNode(rootNode)
for i in range(n):
	inp = input().lower().split()
	if inp[0] not in graph.edges:
		graph.addNode(inp[0])
	parent = inp[2]
	if parent not in graph.edges:
		graph.addNode(parent)
	graph.addEdge(Edge(parent, inp[0]))

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, rootNode))


m = {}
m['polycarp'] = 1
for _ in range(int(input())):
	s = input().split()
	m[s[0].lower()] = m[s[2].lower()] + 1
print(max(m.values()))


import math

def findDepth(val, dic, d0):
	dSet = []
	for (k, v) in dic.items():
		if v == val:
			dSet.append(findDepth(k, dic, d0 + 1))
	if len(dSet) == 0:
		return d0
	else:
		return max(dSet)
n = int(input())
dic1 = {}
for i in range(n):
	line = input().split(' ')
	p2 = line[2].lower()
	p1 = line[0].lower()
	dic1[p1] = p2
	if p2 not in dic1:
		dic1[p2] = 'ROOT'
depth = []
for (key, value) in dic1.items():
	if value == 'ROOT':
		depth.append(findDepth(key, dic1, 1))
print(max(depth))


mas = {}
mas['polycarp'] = 1
n = int(input())
(i, res) = (0, 1)
for i in range(n):
	(name1, a, name2) = [j.lower() for j in input().split()]
	e = mas[name2] + 1
	mas[name1] = e
	if e > res:
		res = e
print(res)


def DFS(node, chain):
	visited[node] = True
	global ans
	ans = max(ans, chain)
	if not node in adjList:
		return
	for adjNode in adjList[node]:
		if not adjNode in visited:
			DFS(adjNode, chain + 1)
N = int(input())
adjList = {}
for i in range(N):
	command = input().split()
	first = command[0]
	second = command[2]
	first = first.lower()
	second = second.lower()
	if not second in adjList:
		adjList[second] = []
	adjList[second].append(first)
visited = {}
ans = 0
DFS('polycarp', 0)
print(ans + 1)


import sys, re, math
from collections import deque, defaultdict, Counter, OrderedDict
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from queue import Queue
from heapq import heappush, heappop, heapify, nlargest, nsmallest

def STR():
	return list(input())

def INT():
	return int(input())

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

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

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

def sortListWithIndex(listOfTuples, idx):
	return sorted(listOfTuples, key=lambda x: x[idx])

def sortDictWithVal(passedDic):
	temp = sorted(passedDic.items(), key=lambda kv: (kv[1], kv[0]))[::-1]
	toret = {}
	for tup in temp:
		toret[tup[0]] = tup[1]
	return toret

def sortDictWithKey(passedDic):
	return dict(OrderedDict(sorted(passedDic.items())))
INF = float('inf')
mod = 10 ** 9 + 7

def bfs(graph):
	used = defaultdict(bool)
	used['polycarp'] = True
	q = deque([('polycarp', 1)])
	while len(q) > 0:
		popped = q.popleft()
		v = popped[0]
		dis = popped[1]
		if len(graph[v]) == 1 and v != 'polycarp':
			lengths.append(dis)
		for w in graph[v]:
			if not used[w]:
				used[w] = True
				q.append((w, dis + 1))
n = INT()
graph = defaultdict(set)
for _ in range(n):
	(s1, s2, s3) = input().split(' ')
	s1 = s1.lower()
	s3 = s3.lower()
	graph[s1].add(s3)
	graph[s3].add(s1)
lengths = [1]
bfs(graph)
print(max(lengths))


sa = []
a = int(input())
for i in range(a):
	x = list(map(str, input().split(' reposted ')))
	sa.append([x[0].lower(), x[1].lower()])
l = {'polycarp': 1}
d = {}
for i in sa:
	d[i[0]] = i[1]
for i in sa:
	if i[0] not in l:
		l[i[0]] = l[i[1]] + 1
print(max([l[t] for t in l]))


inf = 201
size = 0

def addName(name):
	global size
	size += 1
	d[name] = size
n = int(input())
a = [[inf for j in range(n + 1)] for i in range(n + 1)]
d = {'polycarp': 0}
for i in range(n):
	(c, b) = input().lower().split(' reposted ')
	if c not in d.keys():
		addName(c)
	if b not in d.keys():
		addName(b)
	a[d[b]][d[c]] = 1
dist = [inf for i in range(n + 1)]
dist[0] = 0
q = [0]
for v in q:
	for i in range(n + 1):
		if a[v][i] == 1 and dist[i] > dist[v] + 1:
			q.append(i)
			dist[i] = dist[v] + 1
ans = 1
for i in dist:
	if i != inf and i > ans:
		ans = i
print(ans + 1)


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')
n = int(input())
d = {}
for i in range(n):
	(name1, dsd, name2) = input().split()
	name1 = name1.lower()
	name2 = name2.lower()
	d[name1] = name2
p = list(d.keys())
ans = 0
for i in p:
	q = deque()
	q.append(i)
	visited = set()
	while len(q) != 0:
		t = q.popleft()
		if t in visited:
			continue
		else:
			visited.add(t)
			if t in d:
				q.append(d[t])
	ans = max(ans, len(visited))
print(ans)


n = int(input())
k = []
for i in range(n):
	t = input().split(' ')
	k.append([t[0].lower(), t[2].lower()])
d = [['polycarp']]
for i in k:
	for j in range(len(d)):
		if i[1] in d[j]:
			if j == len(d) - 1:
				d.append([i[0]])
			else:
				d[j + 1].append(i[0])
			break
print(len(d))


import os, sys
from io import IOBase, BytesIO
py2 = round(0.5)
if py2:
	from future_builtins import ascii, filter, hex, map, oct, zip
	range = xrange
BUFSIZE = 8192

class FastIO(BytesIO):
	newlines = 0

	def __init__(self, file):
		self._file = file
		self._fd = file.fileno()
		self.writable = 'x' in file.mode or 'w' in file.mode
		self.write = super(FastIO, self).write if self.writable else None

	def _fill(self):
		s = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
		self.seek((self.tell(), self.seek(0, 2), super(FastIO, self).write(s))[0])
		return s

	def read(self):
		while self._fill():
			pass
		return super(FastIO, self).read()

	def readline(self):
		while self.newlines == 0:
			s = self._fill()
			self.newlines = s.count(b'\n') + (not s)
		self.newlines -= 1
		return super(FastIO, self).readline()

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		if py2:
			self.write = self.buffer.write
			self.read = self.buffer.read
			self.readline = self.buffer.readline
		else:
			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')
import sys

class ostream:

	def __lshift__(self, a):
		sys.stdout.write(str(a))
		return self
cout = ostream()
endl = '\n'
from collections import defaultdict

def lower(S):
	L = list(S)
	Sf = str()
	diff = ord('z') - ord('Z')
	for l in L:
		if ord('A') <= ord(l) <= ord('Z'):
			l = chr(ord(l) + diff)
		Sf = Sf + l
	return Sf
n = int(input())
maxi = 0
D = defaultdict(lambda : 1)
for k in range(n):
	L = list(map(lower, input().split()))
	D[L[0]] = D[L[-1]] + 1
	maxi = max(maxi, D[L[0]])
print(maxi)


dd = {'polycarp': 1}
for _ in range(int(input())):
	(a, b, c) = input().lower().split()
	dd[a] = dd[c] + 1
print(max(dd.values()))


n = int(input())
posts = []
for i in range(n):
	posts.append(input())
if n == 0:
	print(1)
else:
	num = {}
	post0 = posts[0].split(' ')
	num[post0[2].lower()] = 1
	num[post0[0].lower()] = 2
	for i in range(1, n, 1):
		post = posts[i].split(' ')
		num[post[0].lower()] = num[post[2].lower()] + 1
	print(max(num.values()))


n = int(input())
d = {}
d['POLYCARP'] = 1
for i in range(n):
	a = [*map(str.upper, input().split())]
	d[a[0]] = d[a[2]] + 1
print(max(d.values()))


from queue import Queue
g = dict()
for _ in range(int(input())):
	(v, _, u) = map(lambda x: x.lower(), input().split())
	if u not in g:
		g[u] = list()
	g[u].append(v)
q = Queue()
q.put(('polycarp', 1))
r = 0
while not q.empty():
	(u, w) = q.get()
	r = max(r, w)
	for v in g.get(u, []):
		q.put((v, w + 1))
print(r)


m = 0
d = {'polycarp': 1}
for _ in range(int(input())):
	(a, b, c) = input().lower().split()
	d[a] = d[c] + 1
	m = max(d[a], m)
print(m)


n = int(input())
pc = {}
pc['polycarp'] = -1
for i in range(n):
	(b, _, a) = input().split()
	pc[b.lower()] = a.lower()
maxdp = 0
for person in list(pc.keys()):
	depth = 0
	key = person[:]
	while True:
		depth += 1
		key = pc[key]
		if key not in pc:
			break
	if depth > maxdp:
		maxdp = depth
print(maxdp)


import sys
sys.setrecursionlimit(2500)
n = int(input())
g = {}
for i in range(n):
	rep = input().lower().split(' reposted ')
	if rep[0] not in g:
		g[rep[0]] = []
	if rep[1] in g:
		g[rep[1]].append(rep[0])
	else:
		g[rep[1]] = [rep[0]]

def dfs(v):
	add = 0
	for i in g[v]:
		add = max(add, dfs(i))
	return add + 1
print(dfs('polycar' + 'p'))


n = int(input())
mp = {'polycarp': 1}
mx = 1
for i in range(n):
	(d, r, s) = input().split()
	mp[d.lower()] = mp[s.lower()] + 1
	mx = max(mx, mp[d.lower()])
print(mx)


n = int(input())
a = {'polycarp': -1}
for i in range(n):
	b = input().lower().split()
	a[b[0]] = b[2]
ans = 0
for i in a:
	t = 0
	s = i
	while s != -1:
		t += 1
		s = a[s]
	if t > ans:
		ans = t
print(ans)


n = int(input())
m = {}
l = []
c = 0
for i in range(n):
	s = input().split(' ')
	if m.get(s[2].lower(), None) is None:
		l.append(1)
		m[s[2].lower()] = c
		c += 1
	if m.get(s[0].lower(), None) is None:
		l.append(l[m[s[2].lower()]] + 1)
		m[s[0].lower()] = c
		c += 1
	else:
		l[m[s[0].lower()]] += 1
t = 0
for item in l:
	t = max(item, t)
print(t)


match = {}
maxLen = 1
n = int(input())
for _ in range(n):
	l = input().split()
	(source, dest) = (l[2].lower(), l[0].lower())
	try:
		match[source].append(dest)
	except:
		match[source] = [dest]
	if dest not in match:
		match[dest] = []

def dfs(current, length):
	global maxLen
	if len(match[current]) > 0:
		for next in match[current]:
			dfs(next, length + 1)
	elif length > maxLen:
		maxLen = length
dfs('polycarp', 1)
print(maxLen)


n = int(input())
dic = {'polycarp': 1}
for i in range(n):
	(a, b, c) = map(str, input().lower().split())
	dic[a] = dic[c] + 1
print(max(dic.values()))


n = int(input())
cnt = {'polycarp': 1}
for i in range(n):
	arr = input().split()
	name1 = arr[0].lower()
	name2 = arr[2].lower()
	cnt[name1] = cnt[name2] + 1
print(max(cnt.values()))


from collections import defaultdict, deque

def find_popularity(hmap):
	q = deque(['polycarp'])
	traverse = []
	level = 0
	while q:
		traverse.append([])
		for i in range(len(q)):
			node = q.popleft()
			traverse[level].append(node)
			for nei in hmap[node]:
				q.append(nei)
		level += 1
	print(len(traverse))
n = int(input())
hmap = defaultdict(list)
while n > 0:
	(a, b, c) = input().split()
	hmap[c.lower()].append(a.lower())
	n -= 1
find_popularity(hmap)


n = int(input())
adj = {'polycarp': []}

def dfs(node):
	if node not in adj:
		return 1
	cnt = 0
	for x in adj[node]:
		cnt = max(dfs(x), cnt)
	return cnt + 1
while n:
	INPUT = input().split()
	(u, v) = (INPUT[0].lower(), INPUT[2].lower())
	if v in adj:
		adj[v].append(u)
	else:
		adj[v] = [u]
	n -= 1
print(dfs('polycarp'))


n = int(input())
M = dict()
M['policarp'] = 1
for i in range(n):
	(a, rep, b) = input().split()
	a = str.lower(a)
	b = str.lower(b)
	try:
		M[a] = M[b] + 1
	except Exception:
		M[a] = 2
mx = 0
for (i, k) in M.items():
	if k > mx:
		mx = k
print(mx)


class AcyclicGraph:

	def __init__(self):
		self.v = {}
		self.root = None

	def add(self, key, value):
		if key in self.v:
			self.v[key].append(value)
		else:
			self.v[key] = [value]
		if self.root is None:
			self.root = key

	def get_path_lens(self):
		len = {}

		def max_len(name, depth):
			len[name] = depth
			if name in self.v:
				for v in self.v[name]:
					max_len(v, depth + 1)
		max_len(self.root, 0)
		return len
g = AcyclicGraph()
n = int(input())
for i in range(n):
	(name1, _, name2) = input().lower().split()
	g.add(name2, name1)
print(max(g.get_path_lens().values()) + 1)


n = int(input())
a = []
d = {}
for i in range(n):
	(x, y) = input().split(' reposted ')
	x = x.lower()
	y = y.lower()
	a.append([x, y])
	d[x] = 0
	d[y] = 0
d['polycarp'] = 1
for i in range(n):
	d[a[i][0]] += d[a[i][1]] + 1
print(max(d.values()))


from collections import defaultdict, deque
import sys
num_reposts = int(sys.stdin.readline().strip())
reposted_by = defaultdict(list)
for repost in range(num_reposts):
	(name1, _, name2) = sys.stdin.readline().split()
	reposted_by[name2.lower()].append(name1.lower())
queue = deque([('polycarp', 1)])
visited = set()
max_popularity = 1
while queue:
	(poster, distance) = queue.popleft()
	max_popularity = max(distance, max_popularity)
	for reposter in reposted_by[poster]:
		if reposter in visited:
			continue
		queue.append((reposter, distance + 1))
print(max_popularity)


d = {'polycarp': 1}
for i in range(int(input())):
	(j, k, l) = input().lower().split()
	d[j] = d[l] + 1
print(max(d.values()))


n = int(input())
b = ''
r = {}
r['polycarp'] = 1
for i in range(n):
	b = input().lower().split()
	r[b[0]] = r.get(b[0], 1) + r[b[2]]
print(max(r.values()))


import os
import sys
from io import BytesIO, IOBase
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 map(int, input().split())

def main():
	try:
		n = inp()
		ans = 1
		chain = {}
		chain['polycarp'] = 1
		for i in range(n):
			(a, b, c) = input().split()
			(a, b, c) = (a.lower(), b.lower(), c.lower())
			e = chain[c] + 1
			if e > ans:
				ans = e
			chain[a] = e
		print(ans)
	except Exception as e:
		print(e)
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()


n = int(input())
a = {}
a['POLYCARP'] = 1
m = 1
for i in range(n):
	(k1, do, k2) = [i.upper() for i in input().split()]
	r = a[k2] + 1
	a[k1] = r
	if r > m:
		m = r
print(m)


def find_repost_rank(user_name):
	n = int(input())
	repost_dict = {}
	i = 0
	while i < n:
		r = input()
		repost_dict[r.split()[0].lower()] = r.split()[2].lower()
		i += 1
	return find_max(repost_dict, user_name)

def find_max(repost_dict, user_name):
	max_rank = 2
	for k in repost_dict.keys():
		n = k
		current_rank = 2
		while repost_dict[n].lower() != user_name.lower():
			n = repost_dict[n]
			current_rank += 1
		if current_rank > max_rank:
			max_rank = current_rank
	return max_rank
print(find_repost_rank('Polycarp'))


Dic = {}
Dic['POLYCARP'] = 1
m = 1
n = int(input())
for i in range(n):
	(name1, do, name2) = [i.upper() for i in input().split()]
	t = Dic[name2] + 1
	Dic[name1] = t
	if t > m:
		m = t
print(m)


n = int(input())
res = {'polycarp': 1}
m = 1
for i in range(n):
	s = input().split()
	res[s[0].lower()] = res[s[2].lower()] + 1
	m = max(m, res[s[0].lower()])
print(m)


n = int(input())
m = {}
ans = 0
for i in range(n):
	s = input().split()
	s1 = s[0].lower()
	s2 = s[2].lower()
	if i == 0:
		m[s2] = 1
	m[s1] = m[s2] + 1
	if m[s1] > ans:
		ans = m[s1]
print(ans)


class Node:
	__slots__ = ('name', 'children')

	def __init__(self, name, children):
		self.name = name
		self.children = children

def longest_chain(root):
	if root is None:
		return 0
	length = 1
	for c in root.children:
		length = max(length, 1 + longest_chain(c))
	return length
nodes = {}
n = int(input())
for _ in range(n):
	activity = input().split()
	name_1 = activity[0].lower()
	name_2 = activity[2].lower()
	if name_1 not in nodes:
		nodes[name_1] = Node(name_1, [])
	node_1 = nodes[name_1]
	if name_2 not in nodes:
		nodes[name_2] = Node(name_2, [])
	node_2 = nodes[name_2]
	node_2.children.append(node_1)
polycarp = nodes['polycarp']
print(longest_chain(polycarp))


dic = {}
n = int(input())
dic['POLYCARP'] = 1
m = 1
for _ in range(n):
	(first, __, second) = input().split()
	(first, second) = (first.upper(), second.upper())
	value = dic[second] + 1
	dic[first] = value
	m = max(m, value)
print(m)


n = int(input())
chain = {'polycarp': 1}
max_chain = 1
for i in range(n):
	s = input().lower().split()
	(who, from_whom) = (s[0], s[2])
	chain[who] = chain[from_whom] + 1
	max_chain = max(max_chain, chain[who])
print(max_chain)


maxC = 1
people = {'POLYCARP': 1}
strRepost = []
n = int(input())
for i in range(n):
	nameAr = []
	strRepost.append(input())
	nameAr = strRepost[i].upper().split(' ')
	people[nameAr[0]] = people[nameAr[2]] + 1
	if people[nameAr[0]] > maxC:
		maxC = people[nameAr[0]]
print(maxC)


n = int(input())
d = {'polycarp': 1}
for _ in range(n):
	a = input().lower().split()
	d[a[0]] = d[a[2]] + 1
print(max(d.values()))


n = int(input())
depth = dict()
depth['polycarp'] = 1
ans = 1
for i in range(n):
	(a, _, b) = input().split()
	d = depth[a.lower()] = depth[b.lower()] + 1
	ans = max(d, ans)
print(ans)


s = {}
for i in range(int(input())):
	(u, k, v) = input().lower().split()
	s[v] = s.get(v, []) + [u]

def f(x):
	return max((f(y) for y in s[x])) + 1 if x in s else 1
print(f('polycarp'))


n = int(input())
depth = dict()
depth['polycarp'] = 1
ans = 1
for i in range(n):
	a = input().split()
	d = depth[a[0].lower()] = depth[a[2].lower()] + 1
	ans = max(d, ans)
print(ans)


n = int(input())
dct = {'polycarp': 1}
m = 1
for i in range(n):
	ins = input().split(' ')
	child = ins[0].lower()
	depth = dct[ins[2].lower()] + 1
	if depth > m:
		m = depth
	ndct = {child: depth}
	dct.update(ndct)
print(str(m))


from collections import defaultdict

def dfs(node):
	depth = 0
	for child in graph[node]:
		depth = max(depth, dfs(child))
	return depth + 1
graph = defaultdict(list)
for _ in range(int(input())):
	(child, tmp, ancestor) = input().split()
	graph[ancestor.lower()].append(child.lower())
print(dfs('polycarp'))


def length(arr, nowman):
	l = 1
	if nowman != 'polycarp':
		l += length(arr, arr[nowman])
	return l
rarr = {}
for i in range(int(input())):
	r = input().lower().split()
	rarr[r[0]] = r[2]
maxl = 1
for (key, value) in rarr.items():
	l = length(rarr, rarr[key]) + 1
	if maxl < l:
		maxl = l
print(maxl)


n = int(input())
vd = {}
for i in range(n):
	(vf, _, vt) = input().lower().split()
	if vt not in vd:
		vd[vt] = []
	vd[vt].append(vf)
vs = ['polycarp'] * (n + 1)
sp = 0
vl = {'polycarp': 1}
while sp > -1:
	p = vs[sp]
	sp -= 1
	if p not in vd:
		continue
	for v in vd[p]:
		sp += 1
		vs[sp] = v
		vl[v] = vl[p] + 1
print(max(vl.values()))


n = int(input())
im = [input().split() for i in range(n)]
arr = [['polycarp']]
for i in range(n):
	s = [j.lower() for j in im[i]]
	s.pop(1)
	for j in range(len(arr)):
		if s[1] in arr[j]:
			if j < len(arr) - 1:
				arr[j + 1].append(s[0])
			else:
				arr.append([s[0]])
			break
print(len(arr))


n = int(input())
mx = 2
l = ''
sum = 2
x = []
for i in range(n):
	x.append(input().split())
for i in range(n - 1, -1, -1):
	a = x[i][0].lower()
	b = x[i][2].lower()
	sum = 2
	for k in range(i - 1, -1, -1):
		if b == x[k][0].lower():
			sum += 1
			b = x[k][2].lower()
			a = x[k][0].lower()
		else:
			continue
	mx = max(sum, mx)
mx = max(sum, mx)
print(mx)


def rec(x):
	if x not in d:
		return 1
	count = 0
	for i in d[x]:
		count = max(rec(i) + 1, count)
	return count
n = int(input())
names = []
pr = []
d = dict()
for i in range(n):
	(n1, _, n2) = input().split()
	n1 = n1.lower()
	n2 = n2.lower()
	if n1 not in names:
		names.append(n1)
	if n2 not in names:
		names.append(n2)
	if n2 not in d:
		d[n2] = [n1]
	else:
		d[n2].append(n1)
c = 0
print(rec('polycarp'))


def dfs(k):
	sum = 1
	if ans[k] != 0:
		return ans[k]
	for v in edge[k]:
		sum += dfs(v)
	ans[k] = sum
	return ans[k]
n = int(input())
s = [str()] * n
t = [['' for col in range(2)] for row in range(n)]
d = {}
index = 0
edge = [[] for row in range(n * 2)]
ans = [0] * (2 * n)
for i in range(n):
	s[i] = input()
	s[i] = s[i].lower()
	t[i][0] = s[i].split(' ')[0]
	t[i][1] = s[i].split(' ')[2]
	if t[i][0] not in d.keys():
		d[t[i][0]] = index
		index += 1
	if t[i][1] not in d.keys():
		d[t[i][1]] = index
		index += 1
	edge[int(d[t[i][0]])].append(int(d[t[i][1]]))
maxn = 0
for i in range(index):
	if ans[i] == 0:
		maxn = max(maxn, dfs(i))
print(maxn)


__author__ = 'ruckus'

def haveLast(Chains, Name):
	for i in range(len(Chains)):
		if Chains[i][len(Chains[i]) - 1] == Name:
			return i
	return -1
RepostNum = int(input())
Reposts = []
for i in range(RepostNum):
	Reposts.append(input().split())
	Reposts[i][0] = Reposts[i][0].upper()
	Reposts[i][2] = Reposts[i][2].upper()
MaxRepostLen = 1
Chains = []
for i in range(RepostNum):
	if Reposts[i][2] == 'Polycarp'.upper():
		Chains.append(['Polycarp'.upper(), Reposts[i][0]])
	else:
		num = haveLast(Chains, Reposts[i][2])
		if num >= 0:
			Chains[num].append(Reposts[i][0])
		else:
			for j in range(len(Chains)):
				if Reposts[i][2] in Chains[j]:
					Chains.append(Chains[j][:Chains[j].index(Reposts[i][2]) + 1])
					Chains[len(Chains) - 1].append(Reposts[i][0])
for Chain in Chains:
	if len(Chain) > MaxRepostLen:
		MaxRepostLen = len(Chain)
print(MaxRepostLen)


c = {'polycarp': 1}
for i in range(int(input())):
	r = input().split()
	c[r[0].lower()] = c[r[2].lower()] + 1
print(max(c.values()))


from collections import defaultdict
n = int(input())
id = 0
user_dict = dict()
adj_list = defaultdict(list)
for i in range(n):
	(ua, ub) = input().split(' ')[0::2]
	ua = ua.lower()
	ub = ub.lower()
	if ua not in user_dict:
		user_dict[ua] = id
		a = id
		id += 1
	else:
		a = user_dict[ua]
	if ub.lower() not in user_dict:
		user_dict[ub] = id
		b = id
		id += 1
	else:
		b = user_dict[ub]
	adj_list[b].append(a)
visited = set()
ans = 0

def dfs(i, depth):
	global ans
	visited.add(i)
	flag = False
	for k in adj_list[i]:
		if k not in visited:
			dfs(k, depth + 1)
			flag = True
	if not flag:
		ans = max(ans, depth)
dfs(user_dict['polycarp'], 1)
print(ans)


n = int(input())
name = 'polycarp'
link = {'polycarp': 1}
ans = 1
h = 0
sd = []
for i in range(n):
	m = input().split()
	m.remove('reposted')
	for j in m:
		sd.append(j.lower())
	if h == n * 2 - 1:
		break
	link[sd[h]] = link[sd[h + 1]] + 1
	ans = max(ans, link[sd[h]])
	h += 2
print(ans)


n = int(input())
a = {}
a['polycarp'] = 1
for i in range(n):
	(f, m, l) = input().lower().split()
	a[f] = a[l] + 1
print(max(a.values()))


height = 0

def find_height(dct, name, h):
	global height
	vis[name] = True
	for el in dct[name]:
		if el in dct:
			if not vis[el]:
				height = max(height, h + 1)
				find_height(dct, el, h + 1)
		else:
			height = max(height, h + 1)
n = int(input())
dct = {}
for i in range(n):
	s = input().split()
	name1 = s[0].lower()
	name2 = s[2].lower()
	if name2 in dct:
		dct[name2] += [name1]
	else:
		dct[name2] = [name1]
vis = dict(((name, False) for name in dct.keys()))
find_height(dct, 'polycarp', 0)
print(height + 1)


def reg(s):
	s1 = ''
	for i in s:
		if ord(i) >= ord('A') and ord(i) <= ord('Z'):
			s1 += chr(ord(i) - ord('A') + ord('a'))
		else:
			s1 += i
	return s1
s = set()
a = int(input())
d = dict()
t = 0
repeat = []
for i in range(a):
	(x, y, z) = map(str, input().split())
	if reg(x) not in d:
		d[reg(x)] = t
		t += 1
	if reg(z) not in d:
		d[reg(z)] = t
		t += 1
	s.add(reg(x))
	s.add(reg(z))
	repeat.append((d[reg(x)], d[reg(z)]))
l = [[] for i in range(len(s) + 1)]
for i in repeat:
	l[i[0]].append(i[1])
	l[i[1]].append(i[0])
n = len(s)
f = [-1] * (n + 1)
q = [0] * (n + 1)
f[d['polycarp']] = 0
q[0] = d['polycarp']
h = 0
t = 1
while h < t:
	i = q[h]
	h += 1
	for j in l[i]:
		if f[j] == -1:
			f[j] = f[i] + 1
			q[t] = j
			t += 1
print(max(f) + 1)


ans = 1
d = {'polycarp': 1}
for i in range(int(input())):
	l = input().lower().split()
	d[l[0]] = d[l[2]] + 1
	ans = max(d[l[0]], ans)
print(ans)


n = int(input())
di = {'polycarp': 1}
ma = 1
for i in range(n):
	(x, y, z) = input().split()
	x = x.lower()
	z = z.lower()
	di[x] = di[z] + 1
	ma = max(ma, di[x])
print(ma)


n = int(input())
(reposters, maxDeep) = ({'polycarp': 1}, 1)
for i in range(n):
	(a, b, c) = map(str, input().lower().split())
	maxDeep = max(maxDeep, reposters[c] + 1)
	reposters[a] = reposters[c] + 1
print(maxDeep)


a = input('')
listQ = [('polycarp', 1)]
for i in range(int(a)):
	stri = input('')
	stri = stri.split()
	for n in listQ:
		if n[0] == stri[2].lower():
			listQ.append((stri[0].lower(), n[1] + 1))
Max = 1
for i in listQ:
	if i[1] > Max:
		Max = i[1]
print(Max)


n = int(input())
D = {'polycarp': 1}
for i in range(n):
	(s1, temp, s2) = input().lower().split(' ')
	D[s1] = 1 + D[s2]
print(max(D.values()))


d = {'polycarp': []}
for _ in range(int(input())):
	s = input().lower().split()
	(name1, name2) = (s[0], s[2])
	d[name2].append(name1)
	d[name1] = []
stack = ['polycarp']
visited = {'polycarp'}
level = {'polycarp': 1}
while stack:
	a = stack.pop()
	for i in d[a]:
		if i not in visited:
			visited.add(i)
			stack.append(i)
			level[i] = level[a] + 1
print(max(list(level.values())))


def name_to_index(input_list, name):
	for i in range(len(input_list)):
		if input_list[i][0].lower() == name.lower():
			return i
	return None
n = int(input())
reposts = []
for i in range(n):
	reposts.append(input().split(' reposted '))
chain_reposts = [[reposts[i][0].lower(), 0] for i in range(n)]
chain_reposts.append(['polycarp', 1])
max_length = 1
for i in range(n):
	chain_reposts[name_to_index(chain_reposts, reposts[i][0])][1] = chain_reposts[name_to_index(chain_reposts, reposts[i][1])][1] + 1
	if chain_reposts[name_to_index(chain_reposts, reposts[i][0])][1] > max_length:
		max_length = chain_reposts[name_to_index(chain_reposts, reposts[i][0])][1]
print(max_length)


n = int(input())
repo = [['Polycarp'.upper(), 1]]
for i in range(n):
	s = input().split(' ')
	(reposter, feed) = (s[0].upper(), s[2].upper())
	for pair in repo:
		if feed == pair[0]:
			repo.append([reposter, pair[1] + 1])
			break
maxdepth = 1
for i in repo:
	if i[1] >= maxdepth:
		maxdepth = i[1]
print(maxdepth)


from sys import stdin, stdout
n = int(stdin.readline())
names = ['polycarp']
reps = [1]
for _ in range(n):
	(cur, dummy, prev) = stdin.readline().split()
	prev = prev.lower()
	cur = cur.lower()
	ind = names.index(prev)
	names.append(cur)
	reps.append(reps[ind] + 1)
stdout.write(str(max(reps)))


n = int(input())
di = {'POLYCARP': None}
for i in range(n):
	st = input().upper()
	split = st.split()
	di[split[0]] = split[2]
r = 0
for i in di:
	q = di[i]
	c = 1
	while q != None:
		q = di[q]
		c = c + 1
	r = max(r, c)
print(r)


n = int(input())
e = {}
for _ in range(n):
	r = input().split()
	r1 = r[2].lower()
	r0 = r[0].lower()
	if r1 in e:
		e[r1].append(r0)
	else:
		e[r1] = [r0]

def h(n):
	if n not in e:
		return 0
	x = []
	for c in e[n]:
		x.append(h(c))
	return 1 + max(x)
r = 'polycarp'
print(h(r) + 1)


n = int(input())
generation = {}
generation['polycarp'] = 1
maxGeneration = 1
for _ in range(n):
	(new, _, old) = [ele.lower() for ele in input().split(' ')]
	generation[new] = generation[old] + 1
	maxGeneration = max(generation[new], maxGeneration)
print(maxGeneration)


n = int(input())
pairs = []
idx = dict()
count = 0
for _ in range(n):
	(a, b, c) = map(lambda x: x.lower(), input().split())
	if a not in idx:
		idx[a] = count
		count += 1
	if c not in idx:
		idx[c] = count
		count += 1
	pairs.append((a, c))
elems = len(idx)
parent = [i for i in range(elems)]
for tup in pairs:
	parent[idx[tup[0]]] = idx[tup[1]]
maxChain = 0
for i in range(elems):
	cur = i
	chain = 1
	while parent[cur] != cur:
		cur = parent[cur]
		chain += 1
	maxChain = max(chain, maxChain)
print(maxChain)


from collections import Counter
import math
import sys
import os
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 listt():
	return [int(i) for i in input().split()]

def gcd(a, b):
	return math.gcd(a, b)

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

def factors(n):
	step = 2 if n % 2 else 1
	return set(reduce(list.__add__, ([i, n // i] for i in range(1, int(math.sqrt(n)) + 1, step) if n % i == 0)))

def comb(n, k):
	factn = math.factorial(n)
	factk = math.factorial(k)
	fact = math.factorial(n - k)
	ans = factn // (factk * fact)
	return ans

def is_prime(n):
	if n <= 1:
		return False
	if n == 2:
		return True
	if n > 2 and n % 2 == 0:
		return False
	max_div = math.floor(math.sqrt(n))
	for i in range(3, 1 + max_div, 2):
		if n % i == 0:
			return False
	return True

def maxpower(n, x):
	B_max = int(math.log(n, x)) + 1
	return B_max

def binaryToDecimal(n):
	return int(n, 2)

def f(y):
	if y in d:
		return d[y]
	if y == 1:
		d[y] = 1
		return d[y]
	elif y % 2 == 0:
		d[y] = min(f(y // 2) + 1, abs(y - n))
		return d[y]
	else:
		d[y] = min(f(y + 1) + 1, f(y - 1) + 1, abs(y - n))
		return d[y]
n = int(input())
cnt = {'polycarp': 1}
for i in range(n):
	arr = input().split()
	name1 = arr[0].lower()
	name2 = arr[2].lower()
	cnt[name1] = cnt[name2] + 1
print(max(cnt.values()))


def height(g, start, f):
	m = 0
	for i in g[start]:
		if f[i] == 0:
			f[i] = 1
			m = max(m, height(g, i, f))
	return m + 1
from collections import defaultdict as dc
n = int(input())
g = dc(list)
f = dc(int)
for i in range(n):
	s = input().lower().split(' ')
	s = list(s)
	g[s[-1]].append(s[0])
	f[s[0]] = 0
	f[s[-1]] = 0
h = 0
start = 'polycarp'
f[start] = 1
print(height(g, start, f))


n = int(input())
code = {}
m = 0
for i in range(n):
	s = input().lower().split()
	if s[2] not in code.keys():
		code[s[2]] = 0
	code[s[0]] = code[s[2]] + 1
	if m < code[s[0]]:
		m = code[s[0]]
print(m + 1)


from sys import stdin
input = stdin.readline
import math
import sys
from collections import defaultdict
sys.setrecursionlimit(10 ** 4)

def dfs(graph, visted, node):
	visited[node] = True
	l = 1
	for i in graph[node]:
		if i not in visited:
			l = max(l, 1 + dfs(graph, visted, i))
	return l
n = int(input().strip())
graph = defaultdict(list)
for _ in range(n):
	(first, t, second) = list(input().split())
	first = first.lower()
	second = second.lower()
	graph[first].append(second)
	graph[second].append(first)
visited = dict()
print(dfs(graph, visited, 'polycarp'))


from collections import defaultdict
from collections import Counter

class Graph:

	def __init__(self, V):
		self.V = V
		self.graph = defaultdict(list)

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

	def bfslevel(self, s):
		visited = Counter()
		q = []
		q.append(s)
		level = Counter()
		level[s] = 0
		visited[s] = True
		while q:
			s = q.pop(0)
			for i in self.graph[s]:
				if visited[i] == False:
					q.append(i)
					visited[i] = True
					level[i] = level[s] + 1
					final = max(level[i], level[s])
		print(final + 1)
n = int(input())
g = Graph(n)
flag = 0
l = []
for i in range(n):
	l = list(input().split(' '))
	g.addEdge(l[2].lower(), l[0].lower())
g.bfslevel('polycarp')


def toTheBottom(name, lvl=0):
	if name in data:
		lvl += 1
		lvl_list = []
		for i in data[name]:
			lvl_list.append(toTheBottom(i, lvl))
		lvl = max(lvl_list)
	return lvl
n = int(input())
data = {}
for i in range(n):
	(getter, host) = input().lower().split(' reposted ')
	if host in data:
		data[host].append(getter)
	else:
		data[host] = [getter]
q = toTheBottom('polycarp') + 1
print(q)


from collections import defaultdict
n = int(input())
ans = 2
k = defaultdict(int)
k.update({'polycarp': 1})
for i in range(n):
	l = {}
	l = input().split()
	l[0] = l[0].lower()
	l[2] = l[2].lower()
	k.update({l[0]: k[l[2]] + 1})
	if k[l[0]] > ans:
		ans = k[l[0]]
print(ans)


n = int(input())
i = 0
c = {}
c['polycarp'] = 1
while i < n:
	a = input()
	b = a.split()
	c[b[0].lower()] = c[b[2].lower()] + 1
	i += 1
max_ = 2
for i in c.keys():
	if c[i] > max_:
		max_ = c[i]
print(max_)


d = {'polycarp': 1}
N = int(input())
for i in range(N):
	(who, _, whom) = input().lower().strip().split()
	d[who] = d[whom] + 1
print(max(d.values()))


n = int(input())

def dfs(vertex, len):
	length[vertex] = len
	if vertex in graph.keys():
		for i in graph[vertex]:
			if length[i] == 0:
				dfs(i, len + 1)
graph = {}
length = {}
for i in range(n):
	(a, b, c) = map(str, input().split())
	a = a.lower()
	c = c.lower()
	length[a] = 0
	length[c] = 0
	if c not in graph.keys():
		graph[c] = [a]
	else:
		graph[c].append(a)
dfs('polycarp', 1)
mx = -1
for i in length.keys():
	mx = max(mx, length[i])
print(mx)


from operator import itemgetter
users = {'polycarp': 1}
try:
	n = int(input())
	for _ in range(n):
		(user1, user2) = input().lower().split(' reposted ')
		users[user1] = users[user2] + 1
	a = sorted(users.items(), key=itemgetter(1), reverse=True)[0][1]
	print(a)
except:
	print('0')


leng = int(input())
names = ['POLYCARP', 1]
others = []
max = 1
for i in range(leng):
	(x, y) = map(str, input().split(' reposted '))
	others.append(x.upper())
	others.append(y.upper())
for i in range(0, leng * 2, 2):
	if others[i + 1] in names:
		num = names[names.index(others[i + 1]) + 1] + 1
		names.append(others[i])
		names.append(num)
		if num > max:
			max = num
		continue
print(max)


n = int(input())
from collections import defaultdict
father = defaultdict(lambda : None)
heights = defaultdict(lambda : None)

def lk(s):
	return s.lower()
for _ in range(n):
	words = input().split()
	father[lk(words[0])] = lk(words[2])
maxHeight = 0

def height(word):
	if not father[lk(word)]:
		return 1
	elif heights[lk(word)]:
		return heights[lk(word)]
	else:
		heights[lk(word)] = height(father[lk(word)]) + 1
		return heights[lk(word)]
for word in list(father):
	if maxHeight < height(word):
		maxHeight = height(word)
print(maxHeight)


n = int(input())
dictionary = {'polycarp': 1}
mass = []
for i in range(n):
	(whoname, whomname) = input().split(' reposted ')
	whomname = whomname.lower()
	dictionary[whoname.lower()] = dictionary[whomname] + 1
	mass.append(dictionary[whomname] + 1)
print(max(mass))


n = int(input())
result = list()
result.append(['polycarp'])
for i in range(n):
	length = len(result)
	s = input().split()
	s0 = s[0].lower()
	s2 = s[2].lower()
	for i in range(length - 1):
		if s2 in result[i] and s0 not in result[i + 1]:
			result[i + 1].append(s0)
	if s2 in result[length - 1]:
		result.append([s0])
length = len(result)
print(length)


alth = 'abcdefghijklmnopqrstuvwxyz'
alth2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
n = int(input())
strokes = [input().split() for i in range(n)]
temp0 = -1
temp = [0] * n
tem = [0] * n
tem1 = [0] * n
temp1 = [[''] * n for i in range(n)]
for z in range(n):
	temp2 = ''
	temp3 = ''
	for nu in strokes[z][0]:
		num2 = alth2.find(nu)
		if num2 != -1:
			temp2 += alth[num2]
		else:
			temp2 += nu
	for nu in strokes[z][2]:
		num2 = alth2.find(nu)
		if num2 != -1:
			temp3 += alth[num2]
		else:
			temp3 += nu
	if temp3 == 'polycarp':
		temp0 += 1
		temp[temp0] += 1
		tem[temp0] += 2
		temp1[temp0][0] = temp2
		tem1[temp0] = 1
	else:
		error = 0
		for i in range(temp0 + 1):
			if temp1[i][temp[i] - 1] == temp3:
				tem[i] += 1
				temp1[i][temp[i]] = temp2
				temp[i] += 1
				break
			for j in range(temp[i] - 1):
				if temp1[i][j] == temp3:
					temp0 += 1
					temp[temp0] += 1
					temp1[temp0][0] = temp2
					tem1[temp0] = tem1[i] + j + 1
					tem[temp0] = tem1[temp0] + 1
					error = 1
					break
			if error == 1:
				break
print(max(tem))


n = int(input())
repost_height = {}
repost_height['polycarp'] = 1
for i in range(n):
	repost = input()
	(person1, person2) = (repost.split(' ')[0].lower(), repost.split(' ')[-1].lower())
	if person2 in list(repost_height.keys()):
		repost_height[person1] = repost_height[person2] + 1
print(sorted(repost_height.items(), key=lambda x: x[1])[-1][1])


users = {'polycarp': 1}
for _ in range(int(input())):
	(u_to, s, u_from) = map(str.lower, input().split())
	users[u_to] = users[u_from] + 1
print(max(users.values()))


n = int(input())
order = {}
order['polycarp'] = 1
m = 1
for i in range(n):
	(s1, s2, s3) = [i.lower() for i in input().split()]
	order[s1] = order[s3] + 1
	m = max(order[s1], m)
print(m)


def track(s):
	if s == 'polycarp':
		return 0
	else:
		return 1 + track(par[s])
n = int(input())
par = {}
lst = []
for i in range(n):
	s = input().split()
	par[s[0].lower()] = s[2].lower()
	lst.append(s[0].lower())
ans = 0
for s in lst:
	if track(s) > ans:
		ans = track(s)
print(ans + 1)


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

class Graph(object):

	def __init__(self, n, d):
		self.n = n
		self.graph = [[] for i in range(n)]
		self.parent = [-1 for i in range(n)]
		self.directed = d

	def addEdge(self, x, y):
		self.graph[x].append(y)
		if not self.directed:
			self.graph[y].append(x)

	def bfs(self, root):
		queue = [root]
		queue = deque(queue)
		vis = [0] * self.n
		while len(queue) != 0:
			element = queue.popleft()
			vis[element] = 1
			for i in self.graph[element]:
				if vis[i] == 0:
					queue.append(i)
					self.parent[i] = element
					vis[i] = 1

	def dfs(self, root, ans):
		stack = []
		while len(self.graph[root]) != 0:
			stack.append(root)
			root = g.graph[root][0]
			if count[root]:
				break
		while len(stack) != 0:
			e = stack.pop()
			count[e] = count[self.graph[e][0]] + 1

	def shortestpath(self, source, dest):
		self.bfs(source)
		path = [dest]
		while self.parent[path[-1]] != -1:
			path.append(parent[path[-1]])
		return path[::-1]

	def detect_cycle(self):
		indeg = [0] * self.n
		for i in range(self.n):
			for j in self.graph[i]:
				indeg[j] += 1
		q = deque()
		vis = 0
		for i in range(self.n):
			if indeg[i] == 0:
				q.append(i)
		while len(q) != 0:
			e = q.popleft()
			vis += 1
			for i in self.graph[e]:
				indeg[i] -= 1
				if indeg[i] == 0:
					q.append(i)
		if vis != self.n:
			return True
		return False

	def reroot(self, root, ans):
		stack = [root]
		vis = [0] * n
		while len(stack) != 0:
			e = stack[-1]
			if vis[e]:
				stack.pop()
				continue
			vis[e] = 1
			for i in graph[e]:
				if not vis[e]:
					stack.append(i)
			if self.parent[e] == -1:
				continue
n = int(input())
names = {'polycarp': 0}
a = []
for i in range(n):
	s = input().split()
	a.append(s)
	if s[0] not in names:
		names[s[0].lower()] = i + 1
g = Graph(len(names), True)
for i in a:
	g.addEdge(names[i[0].lower()], names[i[-1].lower()])
count = [0] * (n + 1)
count[0] = 1
for i in range(n + 1):
	if not count[i]:
		g.dfs(i, count)
print(max(count))


n = int(input())
code = {}
for i in range(n):
	s = input().lower().split()
	if s[2] not in code.keys():
		code[s[2]] = 0
	code[s[0]] = code[s[2]] + 1
print(max([value for (key, value) in code.items()]) + 1)


count = []

def DFS(d1, d, node, c):
	d1[node] = 1
	c = c + 1
	for i in d[node]:
		DFS(d1, d, i, c)
	count.append(c)
	return c
n = int(input())
d = {}
d1 = {}
for _ in range(n):
	s = input()
	y = list(s.split(' '))
	y[0] = y[0].lower()
	y[2] = y[2].lower()
	if y[2] not in d.keys():
		d[y[2]] = [y[0]]
		if y[0] not in d.keys():
			d[y[0]] = []
		d1[y[2]] = 0
		if y[0] not in d1.keys():
			d1[y[0]] = 0
	else:
		d[y[2]].append(y[0])
		if y[0] not in d.keys():
			d[y[0]] = []
		if y[0] not in d1.keys():
			d1[y[0]] = 0
for i in d1.keys():
	if d1[i] == 0:
		c = 0
		DFS(d1, d, i, c)
print(max(count))


class Node:

	def __init__(self, name, children):
		self.name = name
		self.children = children

def lowercase(word):
	alphabet = 'abcdefghijklmnopqrstuvwxyz'
	Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
	ans = ''
	for char in word:
		if char in Alphabet:
			ans += alphabet[Alphabet.index(char)]
		else:
			ans += char
	return ans
n = int(input())
parent_child_set = []
for i in range(n):
	string = input().split()
	parent_child_set.append([lowercase(string[-1]), lowercase(string[0])])
dictionary = {}
for pair in parent_child_set:
	parent = pair[0]
	child = pair[1]
	try:
		dictionary[parent].append(child)
	except KeyError:
		dictionary[parent] = [child]
tree = Node('polycarp', {})

def build(tree_graph, node):
	try:
		for name in dictionary[node]:
			tree_graph.children[name] = Node(name, {})
			build(tree_graph.children[name], name)
	except KeyError:
		pass
build(tree, 'polycarp')

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


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()
d = {'polycarp': 'polycarp'}
arr = []
for i in range(n):
	s = [i.lower() for i in isa()]
	d[s[0]] = s[-1]
	arr.append(s[0])
res = 0
for i in arr:
	(cur, length) = (i, 1)
	while cur != d[cur]:
		cur = d[cur]
		length += 1
	res = max(res, length)
print(res)


def find_names(qr):
	return (qr.split(' reposted ')[0].lower(), qr.split(' reposted ')[1].lower())
n = int(input())
tree = {'polycarp': 1}
curmax = 1
for i in range(n):
	qr = input()
	(name1, name2) = find_names(qr)
	tree[name1] = tree[name2] + 1
	curmax = curmax < tree[name1] and curmax + 1 or curmax
print(curmax)


n = int(input())
d = {}
d['polycarp'] = 1
max = 1
for i in range(n):
	(a, b, c) = [x.lower() for x in input().split()]
	d[a] = d[c] + 1
	if d[a] > max:
		max = d[a]
print(max)


t = int(input())
chain = {}
chain['polycarp'] = 1
ans = 1
for _ in range(t):
	(s1, _, s2) = map(str, input().split())
	s1 = s1.lower()
	s2 = s2.lower()
	chain[s1] = chain[s2] + 1
	ans = max(chain[s1], ans)
print(ans)


n = int(input())
g = {}
for _ in range(n):
	s = input().split('reposted')
	s1 = s[0].strip().lower()
	s2 = s[1].strip().lower()
	if s2 not in g:
		g[s2] = set()
	g[s2].add(s1)
mx = 0

def find(v, cnt):
	global mx
	if v not in g:
		if cnt > mx:
			mx = cnt
		return
	for name in g[v]:
		find(name, cnt + 1)
find('polycarp', 1)
print(mx)


n = int(input())
prnt = {'polycarp': None}
s = set({'polycarp'})
for i in range(n):
	(c, p) = input().lower().split(' reposted ')
	prnt[c] = p
	s.update({c, p})
ans = -1
for i in s:
	h = 0
	k = i
	while k is not None:
		h = h + 1
		k = prnt[k]
	ans = max(ans, h)
print(ans)


import os
import sys
from io import BytesIO, IOBase
from collections import deque
from collections import defaultdict

def main():
	n = int(input())
	d = dict()
	for _ in range(n):
		(a, b, c) = input().lower().split()
		if a not in d:
			d[a] = []
		if c not in d:
			d[c] = []
		d[a].append(c)
		d[c].append(a)
	ans = 0
	vis = defaultdict(int)
	stack = [('polycarp', 1)]
	while stack:
		(z, zz) = stack.pop()
		if vis[z]:
			continue
		vis[z] = zz
		ans = max(ans, zz)
		for item in d[z]:
			if vis[item] == 0:
				stack.append((item, zz + 1))
			elif vis[z] < zz:
				vis[z] = 0
				stack.append((item, zz + 1))
	print(ans)
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()


n = int(input())
dic = 1
father = {'polycarp': '#'}
while n > 0:
	(a, _, b) = input().split()
	a = a.lower()
	b = b.lower()
	father[a] = b
	i = 1
	while True:
		i += 1
		b = father[b]
		if b == '#':
			break
	dic = max(dic, i)
	n -= 1
print(dic)


import collections
n = int(input())
post = collections.defaultdict(int)
for i in range(n):
	(a, _, b) = input().split()
	post[a.lower()] = post[b.lower()] + 1
print(max(post.values()) + 1)


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

def dfs(visited, graph, node):
	global k
	global ret
	global p
	if len(graph[node]) > 0:
		k += 1
		if len(graph[node]) > 1:
			for i in range(len(graph[node]) - 1):
				p.append(k - 1)
	else:
		ret = max(k, ret)
		if p:
			k = p[-1] + 1
			p.pop()
		else:
			k = 2
	for child in graph[node]:
		dfs(visited, graph, child)
	return ret
n = int(inp())
adj = [[] for x in range(n + 1)]
dic = {}
visited = [0] * (n + 1)
k = 1
ans = 0
ret = 0
p = []
for i in range(n):
	(a, b, c) = [x.lower() for x in inp().split()]
	if c not in dic:
		dic[c] = len(dic)
	if a not in dic:
		dic[a] = len(dic)
	adj[dic[c]].append(dic[a])
res = dfs(visited, adj, 0)
ans = max(ans, res)
k = 1
print(ans)


def main():
	n = int(input())
	depth = {'polycarp': 1}
	for _ in range(n):
		(b, _, a) = map(lambda x: x.lower(), input().split())
		depth[b] = depth[a] + 1
	print(max(depth.values()))
main()


n = int(input())
people = {}
suma = 0
maxa = 0
res = []
for i in range(n):
	(s1, s2, s3) = input().split()
	s4 = s1.lower()
	s5 = s3.lower()
	res.append(s4)
	people[s4] = s5
for i in range(n):
	m = res[i]
	while people[m] != 'polycarp':
		m = people[m]
		suma += 1
	suma += 2
	if suma > maxa:
		maxa = suma
	suma = 0
print(maxa)


import sys

def dfs(graf, used, k, now):
	global m
	used[now] = 1
	if k > m:
		m = k
	for i in graf[now]:
		if used[i] == 0:
			dfs(graf, used, k + 1, i)
sys.setrecursionlimit(10 ** 9)
n = int(input())
names = {'polycarp': 0}
graf = [[]]
k = 1
m = 2
used = [0 for i in range(n + 1)]
for i in range(n):
	(a, b) = input().lower().split(' reposted ')
	if b in names.keys():
		names[a] = k
		graf[names[b]].append(names[a])
		graf.append([])
		k += 1
	else:
		names[b] = k
		graf[k].append(k + 1)
		k += 1
		names[a] = k
		k += 1
dfs(graf, used, 1, 0)
print(m)


t = int(input())
dict = {}
dict['polycarp'] = 1
maxi = 1
for i in range(t):
	s = list(input().split())
	dict[s[0].lower()] = dict[s[2].lower()] + 1
	maxi = max(maxi, dict[s[0].lower()])
print(maxi)


n = int(input())
m = {'polycarp': 0}
for i in range(n):
	(s, r, t) = input().lower().split()
	m[s] = m[t] + 1
mx = 0
for y in list(m.values()):
	mx = max(mx, y)
print(mx + 1)


n = int(input())
gr = [[] for i in range(n + n)]
mp = {}
j = 0
ans = []

def bfs():
	i = 0
	q = [0]
	dis = {0: 0}
	par = {0: 0}
	while q:
		next = []
		for u in q:
			for v in gr[u]:
				if v not in par:
					par[v] = u
					dis[v] = i
					next.append(v)
		q = next
		i += 1
	print(max(dis.values()) + 2)
for i in range(n):
	(a, z, b) = map(str, input().strip().split())
	a = a.lower()
	b = b.lower()
	if b not in mp:
		mp[b] = j
		j += 1
	if a not in mp:
		mp[a] = j
		j += 1
	gr[mp[a]].append(mp[b])
	gr[mp[b]].append(mp[a])
bfs()


def strans(s):
	c = []
	for x in s:
		c.append(x.lower())
	return ''.join(c)
d = {}
d['polycarp'] = 1
s = int(input())
for x in range(0, s):
	temp = input().split(' ')
	d[strans(temp[0])] = d[strans(temp[2])] + 1
print(max(d.values()))


n = int(input())
d = {'POLYCARP': 1}
for i in range(n):
	s = input().split()
	a = s[0].upper()
	b = s[2].upper()
	d[a] = d[b] + 1
print(max(d.values()))


n = int(input())
d = {}
for i in range(n):
	l = [a.lower() for a in input().split()]
	if l[2] in d:
		d[l[2]].append(l[0])
	else:
		d[l[2]] = [l[0]]
dist = {}
vis = {}

def dfs(b):
	vis[b] = True
	if b in d:
		for i in d[b]:
			val = vis.get(i, False)
			if not val:
				dist[i] = dist[b] + 1
				dfs(i)
dist['polycarp'] = 1
dfs('polycarp')
print(max(dist.values()))


n = int(input())
data = [['polycarp', 1]]
for i in range(n):
	(a, b) = input().split(' reposted ')
	s = ''
	x = ''
	for i in range(len(a)):
		if 'Z' >= a[i] >= 'A':
			s += chr(ord(a[i]) - ord('A') + ord('a'))
		else:
			s += a[i]
	for i in range(len(b)):
		if 'Z' >= b[i] >= 'A':
			x += chr(ord(b[i]) - ord('A') + ord('a'))
		else:
			x += b[i]
	for i in data:
		if i[0] == x:
			data.append([s, i[1] + 1])
ans = 1
for i in data:
	ans = max(ans, i[1])
print(ans)


def find_man(list1, list2, name, i, result_list):
	index = list1.index(name)
	if list2[index].lower() != 'polycarp':
		i += 1
		find_man(list1, list2, list2[index], i, result_list)
	else:
		result_list.append(i + 1)

def main():
	number = eval(input())
	list1 = []
	list2 = []
	for i in range(number):
		phrase = input()
		temp_list = phrase.split(' ')
		list1.append(temp_list[0].lower())
		list2.append(temp_list[2].lower())
	longest_chain = 2
	result_list = []
	for i in range(len(list1)):
		current_chain = 1
		find_man(list1, list2, list1[i], current_chain, result_list)
	longest_chain = max(result_list)
	print(longest_chain)
main()


n = int(input())
d = {}
for i in range(n):
	(name1, _, name2) = input().lower().split(' ')
	try:
		d[name2]
	except:
		d[name2] = []
	d[name2].append(name1)

def recurs(name, depth=1):
	try:
		for child in d[name]:
			yield from recurs(child, depth + 1)
	except:
		yield depth
print(max(recurs('polycarp')))


N = 300
adj = [[] for i in range(300)]
visited = [0 for i in range(300)]

def dfs(s):
	if visited[s]:
		return 0
	visited[s] = 1
	ans = 0
	for k in adj[s]:
		ans = max(ans, 1 + dfs(k))
	return ans

def main():
	n = int(input())
	(d, cnt) = ({}, 0)
	for i in range(n):
		(a, b, c) = [i.lower() for i in input().split()]
		if a not in d:
			d[a] = cnt
			cnt += 1
		if c not in d:
			d[c] = cnt
			cnt += 1
		adj[d[a]].append(d[c])
		adj[d[c]].append(d[a])
	ans = dfs(d['polycarp'])
	print(ans)
main()


n = int(input())
l = {'POLYCARP': 1}
ans = 0
for i in range(n):
	s = input().split(' ')
	a = s[0].upper()
	b = s[2].upper()
	curr = l[b] + 1
	if curr > ans:
		ans = curr
	l[a] = curr
print(ans)


n = int(input())
lst = []
for line in range(n):
	i = input()
	i = i.strip()
	i = i.split()
	lst.append((i[0].lower(), i[2].lower()))

def main(lst):
	dct = {lst[0][1]: 1}
	for pair in lst:
		if pair[1] in dct:
			dct[pair[0]] = dct[pair[1]] + 1
	return max(dct.values())
print(main(lst))


def dfs(graph, node, visited):
	visited[node] = True
	Max = 0
	for child in graph[node]:
		print
		k = None
		if not visited[child]:
			k = 1 + dfs(graph, child, visited)
			if k > Max:
				Max = k
	visited[node] = False
	return Max
n = int(input())
queries = []
for i in range(n):
	queries.append(input())
names = dict()
names['polycarp'] = 0
count = 0
for query in queries:
	names_list = query.split(' ')
	if names_list[0].lower() not in names:
		count += 1
		names[names_list[0].lower()] = count
	if names_list[2].lower() not in names:
		count += 1
		names[names_list[2].lower()] = count
graph = []
for i in range(count + 1):
	graph.append([])
for query in queries:
	names_list = query.split(' ')
	graph[names[names_list[2].lower()]].append(names[names_list[0].lower()])
visited = [False] * (count + 1)
print(dfs(graph, 0, visited) + 1)


n = int(input())
d = dict()
d['polycarp'] = 1
maximum = 1
for _ in range(n):
	a = input().split()
	From = a[2].lower()
	To = a[0].lower()
	d[To] = d[From] + 1
	maximum = max(maximum, d[To])
print(maximum)


n = int(input())
d = {'polycarp': 1}
m = 1
for i in range(n):
	s = input().lower().split()
	d[s[0]] = d[s[2]] + 1
	if d[s[0]] > m:
		m = d[s[0]]
print(m)


n = int(input())
dists = {'polycarp': 1}
for _ in range(n):
	tokens = input().split()
	left_name = tokens[0].strip().lower()
	right_name = tokens[-1].strip().lower()
	dists[left_name] = dists[right_name] + 1
print(max(dists.values()))


global maxval
maxval = 0

def dfs(node, g, val):
	global maxval
	maxval = max(maxval, val)
	if node in g:
		for i in g[node]:
			dfs(i, g, val + 1)
n = int(input())
g = {}
for i in range(n):
	s = input()
	s = s.lower().split()
	if s[2] in g:
		g[s[2]].append(s[0])
	else:
		g[s[2]] = [s[0]]
dfs('polycarp', g, 1)
print(maxval)


userMapper = {}
i = 0
tree = [[] for i in range(201)]
for _ in range(int(input())):
	(user1, reposted, user2) = input().strip().split()
	user1 = user1.lower()
	user2 = user2.lower()
	if not user2 in userMapper:
		userMapper[user2] = i
		i += 1
	if not user1 in userMapper:
		userMapper[user1] = i
		i += 1
	tree[userMapper[user2]].append(userMapper[user1])
dp = [0] * (len(userMapper) + 1)

def dfs(st, par):
	dp[st] = 1
	mx = 0
	for child in tree[st]:
		if child == par:
			continue
		dfs(child, st)
		mx = max(mx, dp[child])
	dp[st] += mx

def solution():
	start = userMapper['polycarp']
	dfs(start, None)
	print(dp[start])
solution()


n = int(input())
people = {}
for i in range(n):
	(a, b) = (x.casefold() for x in input().split(' reposted '))
	people[a] = (b, None) if b != 'polycarp' else (b, 2)

def calculate_distance(name):
	if people[name][1] is not None:
		return people[name][1]
	else:
		distance = calculate_distance(people[name][0])
		people[name] = (people[name][0], distance + 1)
		return distance + 1
for i in list(people):
	calculate_distance(i)
print(people[max(people, key=lambda x: people[x][1])][1])


n = int(input())
a = {'polycarp': 1}
for i in range(n):
	t = list(map(str, input().split()))
	t[0] = t[0].lower()
	t[2] = t[2].lower()
	if a.setdefault(t[0], 0) < a[t[2]]:
		a[t[0]] = a[t[2]] + 1
m = 0
d = list(a.values())
for i in range(len(d)):
	m = max(m, d[i])
print(m)


num = int(input())
d = {'polycarp': None}
for z in range(num):
	l = input().split()
	d[l[0].lower()] = l[2].lower()
m = 0
for i in d:
	ans = 0
	tmp = i
	while tmp != None:
		ans += 1
		tmp = d[tmp]
	if ans > m:
		m = ans
print(m)


n = int(input())
dic = {'polycarp': 1}
ans = 1
for i in range(n):
	(name1, temp, name2) = input().split()
	name1 = name1.lower()
	name2 = name2.lower()
	dic[name1] = dic[name2] + 1
	ans = max(ans, dic[name2] + 1)
print(ans)


n = int(input())
ht = {'polycarp': 1}
m = 0
for i in range(n):
	inp = input().split(' ')
	ht[inp[0].lower()] = ht[inp[2].lower()] + 1
	temp = ht[inp[0].lower()]
	m = max(m, temp)
print(m)


n = int(input())
g = [[] for i in range(n + 1)]
names = ['polycarp']
used = [-1] * (n + 1)
used[0] = 0
for i in range(n):
	(n1, rep, n2) = map(str, input().split())
	n1 = n1.lower()
	n2 = n2.lower()
	if names.count(n1) == 0:
		names.append(n1)
	v = names.index(n1)
	u = names.index(n2)
	g[v].append(u)
	g[u].append(v)
queue = [0]

def bfs(start):
	while queue != []:
		for v in g[queue[0]]:
			if used[v] == -1:
				used[v] = used[queue[0]] + 1
				queue.append(v)
		del queue[0]
bfs(0)
print(max(used) + 1)


n = int(input())
g = {}
dist = {}
for i in range(n):
	line = input().split()
	copier = line[0].lower()
	source = line[-1].lower()
	dist[copier] = 0
	dist[source] = 0
	if source not in g:
		g[source] = []
	if copier not in g:
		g[copier] = []
	g[source].append(copier)

def dfs(name):
	for next in g[name]:
		if dist[next] < dist[name] + 1:
			dist[next] = dist[name] + 1
			dfs(next)
dfs('polycarp')
ans = 0
for val in dist.values():
	if val > ans:
		ans = val
print(ans + 1)


lis = {}
lis['polycarp'] = 1
for i in range(int(input())):
	(name1, post, name2) = map(str, input().split())
	lis[name1.lower()] = lis[name2.lower()] + 1
print(max(lis.values()))


from sys import stdin, stdout
n = int(stdin.readline())
reps = {'polycarp': 1}
for _ in range(n):
	(cur, dummy, prev) = stdin.readline().lower().split()
	reps[cur] = reps[prev] + 1
stdout.write(str(max(reps.values())))


import sys
readline = sys.stdin.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 sl():
	return [s for s in readline().split()]

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()
children = {'polycarp': []}
for _ in range(n):
	(i, _, p) = readline().split()
	children[i.lower()] = []
	children[p.lower()].append(i.lower())
roots = ['polycarp']
depth = 0
while roots:
	depth += 1
	roots = [i for r in roots for i in children[r]]
print(depth)


n = int(input())
g = [[] for _ in range(n)]
d = {'polycarp': 1}
for i in range(n):
	(a, b) = input().lower().split(' reposted ')
	d[a] = d[b] + 1
print(max(d.values()))


n = int(input())
a = []
name = set()
name.add('polycarp')
for i in range(n):
	s = list(input().lower().split(' '))
	a.append([s[0], s[2]])
	name.add(s[0])
	name.add(s[2])
name = list(name)

def idx(s):
	return name.index(s)
g = [[] for i in range(len(name))]
for i in range(len(a)):
	(x, y) = a[i]
	g[idx(y)].append(idx(x))
start = idx('polycarp')
ans = -1

def dfs(node, cnt):
	global ans
	if len(g[node]) == 0:
		ans = max(ans, cnt)
		return
	for to in g[node]:
		dfs(to, cnt + 1)
dfs(start, 0)
print(ans + 1)


posts = {'Polycarp'.lower(): 1}
max_len = 1
n = int(input())
for _ in range(n):
	(n1, n2) = input().lower().split(' reposted ')
	posts[n1] = posts[n2] + 1
	max_len = max(max_len, posts[n1])
print(max_len)


a = int(input())
b = [['polycarp'.lower(), 0]]
for i in range(a):
	report = input().split()
	(reporter, feed) = (report[0].lower(), report[2].lower())
	for i in range(len(b)):
		if feed == b[i][0]:
			b.append([reporter, b[i][1] + 1])
			break
max = 0
for i in b:
	if i[1] > max:
		max = i[1]
print(max + 1)


import collections
(height, visited) = ({}, {})

def bfs(s):
	height[s] = 1
	ans.append(1)
	visited[s] = True
	q = collections.deque()
	q.append(s)
	while len(q) > 0:
		s = q.popleft()
		if dic.get(s, -1) == -1:
			continue
		for i in dic[s]:
			if visited.get(i, False) == True:
				continue
			visited[i] = True
			height[i] = height[s] + 1
			ans.append(height[i])
			q.append(i)
ans = []
dic = {}
for n in range(int(input())):
	(n1, x, n2) = input().split()
	n1 = n1.lower()
	n2 = n2.lower()
	if dic.get(n2, -1) == -1:
		dic[n2] = []
	dic[n2].append(n1)
bfs('polycarp')
print(max(ans))


from sys import stdin, stdout
from collections import Counter
from itertools import permutations
import bisect
import math
I = lambda : map(int, stdin.readline().split())
I1 = lambda : stdin.readline()
n = int(I1())
d = {'polycarp': 1}
for _ in range(n):
	(a, b, c) = map(str, input().lower().strip().split())
	d[a] = d[c] + 1
print(max(d.values()))


def input_arr():
	n = int(input())
	return [input() for i in range(n)]
reposts = [s.split(' reposted ') for s in input_arr()]
user_distances = {'polycarp': 1}
for (reposter, reposted) in reposts:
	user_distances[reposter.lower()] = user_distances[reposted.lower()] + 1
print(max(user_distances.values()))


from collections import defaultdict

def giveMaxRepost(i, dp, graph):
	if dp.get(i) == None:
		temp = 0
		for j in graph[i]:
			temp = max(giveMaxRepost(j, dp, graph), temp)
		dp[i] = 1 + temp
	return dp[i]
n = int(input())
graph = defaultdict(list)
dp = {}
for i in range(n):
	t = input().split()
	graph[t[2].lower()].append(t[0].lower())
print(giveMaxRepost('polycarp', dp, graph))


n = int(input())
ans = 1
reposts = {'polycarp': 1}
for i in range(n):
	repost = [s.lower() for s in input().split(' reposted ')]
	reposts[repost[0]] = reposts[repost[1]] + 1
	if reposts[repost[0]] > ans:
		ans = reposts[repost[0]]
print(ans)


n = int(input())
dic = {}
dic['polycarp'] = 1
for _ in range(n):
	sentence = input().lower().split()
	dic[sentence[0]] = dic[sentence[-1]] + 1
max = -1
for key in dic.keys():
	if dic[key] > max:
		max = dic[key]
print(max)


from collections import defaultdict

class Graph:

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

	def edge(self, s1, s2):
		self.adj[s2].append(s1)

	def p(self):
		print(self.adj)

	def dfs(self, i):
		if i not in self.adj:
			return 1
		ans = 0
		for j in self.adj[i]:
			ans = max(ans, self.dfs(j))
		return ans + 1
t = int(input())
gr = Graph()
for _ in range(t):
	(s1, ignore, s2) = input().split()
	gr.edge(s1.upper(), s2.upper())
print(gr.dfs('POLYCARP'))


n = int(input())
adj = dict()
visited = dict()
height = dict()
while n > 0:
	a = list(map(str, input().split()))
	if not str(a[2].lower()) in adj.keys():
		adj[str(a[2].lower())] = list()
	visited[str(a[2].lower())] = 0
	visited[str(a[0].lower())] = 0
	adj[str(a[2].lower())].append(str(a[0].lower()))
	n = n - 1
height['polycarp'] = 1

def dfs(a):
	visited[a] = 1
	if a in adj.keys():
		for item in adj[a]:
			height[item] = height[a] + 1
			if visited[item] == 0:
				dfs(item)
dfs('polycarp')
print(max(height.values()))


s = {'Polycarp'.upper(): 1}
a = int(input())
ans = 0
for i in range(0, a):
	(s1, s2, s3) = input().split()
	s1 = s1.upper()
	s3 = s3.upper()
	s[s1] = s[s3] + 1
	ans = max(ans, int(s[s1]))
print(ans)


from math import *
from itertools import *
from collections import *
from bisect import *
g = [[] for _ in range(210)]
idx = 0
name = dict()
n = int(input())
for _ in range(n):
	(a, _, b) = input().lower().split()
	if a not in name:
		name[a] = idx
		idx += 1
	if b not in name:
		name[b] = idx
		idx += 1
	v = name[a]
	u = name[b]
	g[u].append(v)
depth = [-1 for _ in range(210)]
root = name['polycarp']
depth[root] = 0
q = deque([root])
while len(q):
	u = q.popleft()
	for v in g[u]:
		if depth[v] == -1:
			depth[v] = depth[u] + 1
			q.append(v)
print(max(depth) + 1)


import sys

def main():
	mx = 1
	n = int(input())
	D = {}
	D['polycarp'] = 1
	for i in range(n):
		(s, r, t) = input().split()
		s = s.lower()
		t = t.lower()
		D[s] = D[t] + 1
		mx = max(mx, D[s])
	print(mx)
main()


n = int(input())
d = {}
c = {}
msf = 1
for _ in range(n):
	(n1, _, n2) = input().upper().split()
	if n2 not in d:
		d[n2] = n1
	if n2 not in c:
		c[n2] = 1
	if n1 not in c:
		c[n1] = c[n2] + 1
		msf = max(msf, c[n1])
print(msf)


class Node(object):

	def __init__(self, name):
		self.name = name
		self.childs = []

	def add_child(self, child):
		self.childs.append(child)
max_depth = 1

def dfs(node, depth):
	if len(node.childs) == 0:
		global max_depth
		max_depth = max(max_depth, depth)
		return
	for child in node.childs:
		dfs(child, depth + 1)
p2node = {}
root_p = 'polycarp'
n = int(input())
for i in range(n):
	(p_to, _, p_from) = input().split()
	p_from = p_from.lower()
	p_to = p_to.lower()
	if p_from not in p2node:
		p2node[p_from] = Node(p_from)
	if p_to not in p2node:
		p2node[p_to] = Node(p_to)
	p2node[p_from].add_child(p2node[p_to])
dfs(p2node[root_p], 1)
print(max_depth)


from collections import defaultdict
n = int(input())
L = [input().split(' reposted ') for _ in range(n)]
G = defaultdict(list)
for (b, a) in L:
	G[a.lower()].append(b.lower())

def longest_chain(node):
	if not G[node]:
		return 1
	else:
		return 1 + max((longest_chain(child) for child in G[node]))
print(longest_chain('polycarp'))


def dfs(s):
	if s in visited:
		return 0
	dist = 0
	if reposts.get(s) == None:
		return 0
	for i in reposts[s]:
		visited.append(s)
		dist = max(dfs(i), dist)
	return dist + 1
visited = list()
n = int(input())
reposts = dict()
for i in range(n):
	tmp = input().split()
	reposts.setdefault(tmp[2].lower(), []).append(tmp[0].lower())
	reposts.setdefault(tmp[0].lower(), []).append(tmp[2].lower())
print(dfs('polycarp'))


import sys
maxLen = 1

def DFS(V, U, cur, leng):
	global maxLen
	if leng > maxLen:
		maxLen = leng
	for i in range(len(vec[cur])):
		if U[i] == False and V[cur][i] == 1:
			U[i] = True
			DFS(V, U, i, leng + 1)
			U[i] = False
n = int(input())
name2int = {}
vec = []
for i in range(n * 2):
	vec.append([])
	for j in range(n * 2):
		vec[i].append(0)
pos = 0
for i in range(n):
	(name1, tmp, name2) = sys.stdin.readline().lower().split()
	if name2int.get(name2) == None:
		name2int[name2] = pos
		pos += 1
	if name2int.get(name1) == None:
		name2int[name1] = pos
		pos += 1
	vec[name2int[name2]][name2int[name1]] = 1
	vec[name2int[name1]][name2int[name2]] = 1
used = []
for i in range(2 * n):
	used.append(False)
used[0] = True
DFS(vec, used, 0, 1)
print(maxLen)


import math as mt
import sys, string
from collections import Counter, defaultdict
input = sys.stdin.readline
MOD = 1000000007
I = lambda : int(input())
M = lambda : map(int, input().split())
Ms = lambda : map(str, input().split())
ARR = lambda : list(map(int, input().split()))

def dfs(u, graph, visited):
	if not visited[u]:
		visited[u] = True
		mx = 0
		for child in graph[u]:
			mx = max(mx, 1 + dfs(child, graph, visited))
		return mx
	return 0

def main():
	root = 'polycarp'
	n = I()
	graph = defaultdict(list)
	for _ in range(n):
		(n1, tg, n2) = Ms()
		n1 = n1.lower()
		n2 = n2.lower()
		graph[n1].append(n2)
		graph[n2].append(n1)
	visited = dict()
	for k in graph.keys():
		visited[k] = False
	print(dfs(root, graph, visited))
tc = 1
for _ in range(tc):
	main()


n = int(input())
d = dict()
while n:
	n -= 1
	(c, x, p) = input().split()
	p = p.lower()
	c = c.lower()
	if p not in d:
		d[p] = 1
	d[c] = d[p] + 1
m = 1
for k in d:
	m = max(m, d[k])
print(m)


def get_max_chain_length():
	users = int(input())
	user_map = {'polycarp': 0}
	tree = {0: -1}
	for i in range(users):
		(n1, _repost, n2) = map(str.lower, input().split())
		user_map[n1] = i + 1
		tree[i + 1] = user_map[n2]
	max_count = 0
	for node in user_map:
		count = 0
		j = user_map[node]
		while j != -1:
			count += 1
			j = tree[j]
		if count > max_count:
			max_count = count
	print(max_count)
get_max_chain_length()


def init(i):
	arr = list()
	arr.append(['polycarp', 1])
	for i in range(i):
		temp = input().lower().split(' ')
		for i in range(len(arr)):
			if temp[2] == arr[i][0]:
				arr.append([temp[0], arr[i][1] + 1])
	return arr

def count(arr):
	maximum = arr[0][1]
	for i in range(len(arr)):
		maximum = max(maximum, arr[i][1])
	return maximum
a = init(int(input()))
print(count(a))


class Node(object):

	def __init__(self, value=None):
		self.value = value
		self.children = []

	def set_value(self, new_value):
		self.value = new_value

class Tree(object):

	def __init__(self):
		self.root = Node()

	def add_node(self, curr_node, new_node):
		curr_node.children.append(new_node)
		return new_node

	def search(self, item):
		q = [self.root]
		while len(q) != 0:
			node = q.pop()
			if node.value == item:
				return node
			else:
				q += node.children
		return None

	def height(self, node):
		if len(node.children) == 0:
			return 0
		else:
			return max([self.height(x) for x in node.children]) + 1

def transfrom_string(raw):
	arr = [x.lower() for x in raw.split(' ')]
	return [arr[2], arr[0]]

def read_data():
	n = int(input())
	data = []
	for i in range(0, n):
		data.append(transfrom_string(input()))
	return data

def solution(data):
	tree = Tree()
	tree.root.set_value('polycarp')
	for arr in data:
		_from = arr[0]
		_to = arr[1]
		node = tree.search(_from)
		new_node = tree.add_node(node, Node(_to))
	return tree.height(tree.root) + 1
data = read_data()
print(solution(data))


import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')
from collections import defaultdict
n = int(input())
depth = defaultdict(lambda : 0)
depth['polycarp'] = 1
for _ in range(n):
	(u, x, v) = input().split()
	u = u.lower()
	v = v.lower()
	depth[u] = depth[v] + 1
print(max(depth.values()))


n = int(input())
dp = {'polycarp': 1}
ans = 1
for i in range(n):
	inf = input().split()
	re = inf[0].lower()
	so = inf[2].lower()
	dp[re] = max(dp.get(re, 1), dp[so] + 1)
	ans = max(ans, dp[re])
print(ans)


def dfs(x, count, res):
	count += 1
	for y in child[x]:
		dfs(y, count, res)
	res.append(count)
n = int(input())
people = []
ip = []
for x in range(n):
	temp = input()
	ip.append(temp)
	temp = temp.split(' ')
	if temp[2].lower() not in people:
		people.append(temp[2].lower())
	if temp[0] not in people:
		people.append(temp[0].lower())
child = []
for x in range(len(people)):
	child.append([])
for x in range(len(people)):
	nodename = people[x].lower()
	for y in ip:
		temp = y.split(' ')
		if temp[2].lower() == nodename:
			ch = people.index(temp[0].lower())
			child[x].append(ch)
res = []
count = 0
res = []
dfs(0, count, res)
print(max(res))


n = int(input())
tr = {}
gr = [[] for i in range(n)]
(ch, par) = input().split(' reposted ')
pa = ''
for i in range(len(par)):
	if ord(par[i]) - ord('a') >= 0 or par[i] in '0123456789':
		pa += par[i]
	else:
		pa += chr(ord(par[i]) - ord('A') + ord('a'))
c = ''
for i in range(len(ch)):
	if ord(ch[i]) - ord('a') >= 0 or ch[i] in '0123456789':
		c += ch[i]
	else:
		c += chr(ord(ch[i]) - ord('A') + ord('a'))
tr[pa] = 0
tr[c] = 1
gr[tr[pa]].append(tr[c])
cnt = 1
for i in range(1, n):
	(ch, par) = input().split(' reposted ')
	pa = ''
	for i in range(len(par)):
		if ord(par[i]) - ord('a') >= 0 or par[i] in '0123456789':
			pa += par[i]
		else:
			pa += chr(ord(par[i]) - ord('A') + ord('a'))
	c = ''
	for i in range(len(ch)):
		if ord(ch[i]) - ord('a') >= 0 or ch[i] in '0123456789':
			c += ch[i]
		else:
			c += chr(ord(ch[i]) - ord('A') + ord('a'))
	if c not in tr.keys():
		cnt += 1
		tr[c] = cnt
	gr[tr[pa]].append(tr[c])
s = [0]
l = {}
l[0] = 1
while s:
	x = s.pop()
	for j in gr[x]:
		l[j] = l[x] + 1
		if j < n:
			s.append(j)
print(max(l.values()))


from collections import defaultdict
adj = defaultdict(lambda : 1)
adj['polycarp'] = 1
n = int(input())
l = 0
while n > 0:
	n -= 1
	s = input().lower().split()
	adj[s[0]] = adj[s[-1]] + 1
	l = max(adj[s[0]], l)
print(l)


n = int(input())
(Max, x) = (1, {})
x['polycarp'] = 1
for i in range(n):
	(a, b) = input().lower().split(' reposted ')
	x[a] = x[b] + 1
for i in x:
	Max = max(x[i], Max)
print(Max)


n = int(input())
str = [input().lower() for i in range(n)]
r = []
all = []
for i in range(n):
	tmp = str[i].split(' ')
	r.append((tmp[0], tmp[2]))
	if not r[i][1] in all:
		all.append(r[i][1])
	if not r[i][0] in all:
		all.append(r[i][0])
l = len(all)
g = [list() for i in range(l)]
for i in range(n):
	a = all.index(r[i][0])
	b = all.index(r[i][1])
	g[a].append(b)
	g[b].append(a)
used = [0 for i in range(l)]
d = [0 for i in range(l)]
q = [0]
d[0] = 1
used[0] = 1
while len(q) > 0:
	v = q.pop(0)
	for i in range(len(g[v])):
		to = g[v][i]
		if used[to] == 0:
			q.append(to)
			d[to] = d[v] + 1
			used[to] = 1
print(max(d))


s = ''
x = eval(input())
s = input()
s = s.lower()
if 1 <= x <= 200:
	z = 1
for i in range(x - 1):
	s = s + ' reposted ' + input()
	s = s.lower()
d = s.split(sep=' reposted ')
aList = []
for jkl in range(len(d)):
	if 2 > len(d[jkl]) or len(d[jkl]) > 24:
		if jkl % 2 == 0:
			del d[jkl + 1]
			del d[jkl]
		else:
			del d[jkl]
			del d[jkl - 1]
gGk = []
for jmn in range(len(d) - 1, -1, -2):
	if jmn in gGk and d(jmn) != 'polycarp':
		continue
	name1 = d[jmn]
	k = 2
	while name1 != 'polycarp':
		for jmk in range(len(d) - 1, -1, -1):
			if d[jmk] == name1 and jmk % 2 == 0:
				gGk.append(jmk)
				k = k + 1
				name1 = d[jmk + 1]
	aList.append(k)
if z == 1:
	print(max(aList))


n = int(input())
res = {'polycarp': 1}
ans = 0
for i in range(n):
	(u1, s, u2) = input().split()
	u1 = u1.lower()
	u2 = u2.lower()
	res[u1] = res[u2] + 1
	ans = max(ans, res[u1])
print(ans)


reposted = int(input())
d = {'polycarp': 1}
for _ in range(reposted):
	line = input()
	(x, y, z) = line.lower().split()
	d[x] = d[z] + 1
print(max(d.values()))


id = {'polycarp': 0}
chain = [1]
n = int(input())
for i in range(1, n + 1):
	(t1, t2) = map(str, input().split(' reposted '))
	id[t1.lower()] = i
	chain += [chain[id[t2.lower()]] + 1]
print(max(chain))


def maxReposts(l, key, arr):
	if len(arr) == 0:
		return l
	dp_arrl = [l]
	for (i, pairl) in enumerate(arr):
		ll = l
		if pairl[1] == key:
			ll += 1
			dp_arrl.append(maxReposts(ll, pairl[0], arr[i + 1:]))
	return max(dp_arrl)
t = int(input())
arr = []
for i in range(t):
	s = input().split()
	if s[1] == 'reposted':
		arr.append((s[0].lower(), s[2].lower()))
dp_arr = []
for (i, pair) in enumerate(arr):
	if pair[1] == 'polycarp':
		l = 2
		dp_arr.append(maxReposts(l, pair[0], arr[i + 1:]))
print(max(dp_arr))


def dfs(node, parent=None):
	val = 0
	for child in g.get(node, list()):
		if child != parent:
			val = max(val, dfs(child, node))
	return val + 1
n = int(input().strip())
g = dict()
for i in range(n):
	s = input().strip().split()
	s[0] = s[0].lower()
	s[2] = s[2].lower()
	l = g.get(s[2], list())
	l.append(s[0])
	g[s[2]] = l
print(dfs('polycarp'))


m = {}

def dfs(par, i):
	global m
	ret = 1
	if i not in m:
		return 1
	for j in m[i]:
		if j == par:
			continue
		ret = max(ret, dfs(i, j) + 1)
	return ret

def main():
	global m
	n = int(input())
	for i in range(n):
		(a, _, b) = map(lambda x: x.lower(), input().split(' '))
		if b in m:
			m[b].append(a)
		else:
			m[b] = [a]
	ret = 0
	for i in m:
		ret = max(ret, dfs(None, i))
	print(ret)
main()


from collections import defaultdict as dfl
s = dfl(list)
for _ in range(int(input())):
	(a, c, b) = input().split()
	s[b.lower()].append(a.lower())

def find_ans(a):
	g = 1
	p = 0
	for i in s[a]:
		p = max(p, find_ans(i))
	g += p
	return g
print(find_ans('polycarp'))


lines = int(input())
successor = {}
chain = {}
longest = [0]
for x in range(lines):
	[a, b] = [x.lower() for x in input().split(' reposted ', 2)]
	successor[a] = b

def dfs(node, current):
	if node in chain:
		chain[node] = max(chain[node], current)
	else:
		chain[node] = current
	longest[0] = max(chain[node], longest[0])
	if node in successor:
		dfs(successor[node], current + 1)
for x in successor:
	dfs(x, 1)
print(longest[0])


def dfs(st, l):
	global mx
	if l > mx:
		mx = l
	for i in range(n):
		if a[st][i]:
			dfs(i, l + 1)
n = 1
d = {'polycarp': 0}
a = [0] * 220
for i in range(220):
	a[i] = [0] * 220
for t in range(int(input())):
	s = input().split()
	s[0] = s[0].lower()
	s[2] = s[2].lower()
	if s[0] not in d.keys():
		d[s[0]] = n
		n += 1
	a[d[s[2]]][d[s[0]]] = 1
mx = 0
dfs(0, 1)
print(mx)


class DFS:
	visited = None
	edge_to = None
	graph = None

	def __init__(self, graph):
		self.visited = set()
		self.edge_to = {}
		self.graph = graph

	def dfs(self, node):
		self.visited.add(node)
		for v in self.graph[node]:
			if v not in self.visited:
				self.visited.add(v)
				self.edge_to[v] = node
				self.dfs(v)

	def path_to(self, node):
		res = []
		while node in self.edge_to:
			res.append(node)
			node = self.edge_to[node]
		return res

def solve(g):
	d = DFS(g)
	d.dfs('polycarp')
	res = max([len(d.path_to(node)) for node in g.keys()])
	return res + 1
from collections import defaultdict
n = int(input())
graph = defaultdict(list)
for _ in range(n):
	(destination, source) = map(str.lower, map(str.strip, input().split('reposted')))
	graph[source].append(destination)
print(solve(graph))


from bisect import bisect_left as bs
from math import log as lg
log = lambda *x: print(*x)

def cin(*fn, def_fn=str):
	(i, r) = (0, [])
	if fn:
		def_fn = fn[0]
	for c in input().split(' '):
		r += [(fn[i] if len(fn) > i else def_fn)(c)]
		i += 1
	return r
(n,) = cin(int)
(mx, u) = (1, {'polycarp': 1})
for i in range(n):
	(n1, r, n2) = cin(str)
	(n1, n2) = (n1.lower(), n2.lower())
	u[n1] = 1 + u[n2]
	mx = max(u[n1], mx)
log(mx)


from collections import deque
n = int(input())
graph = {}
for i in range(n):
	(name1, reposted, name2) = input().split()
	name1 = name1.lower()
	name2 = name2.lower()
	if name2 not in graph:
		graph[name2] = []
	if name1 not in graph:
		graph[name1] = []
	graph[name2].append(name1)
queue = deque(['polycarp'])
distance = {name: -1 for name in graph.keys()}
distance['polycarp'] = 1
while queue:
	name = queue.popleft()
	for second_name in graph[name]:
		if distance[second_name] != -1:
			continue
		distance[second_name] = distance[name] + 1
		queue.append(second_name)
print(max(distance.values()))


from collections import deque
from math import *
import heapq
d = {}
n = int(input())
l = []
for i in range(n):
	x = input()
	ind = []
	for j in range(len(x)):
		if x[j] == ' ':
			ind.append(j)
	name1 = x[:ind[0]]
	name2 = x[ind[1] + 1:]
	l.append([name1.lower(), name2.lower()])
DAD = name1.lower()
visited = {}
distance = {}
for i in range(len(l)):
	if l[i][1] not in d:
		d[l[i][1]] = [l[i][0]]
	else:
		d[l[i][1]].append(l[i][0])
	visited[l[i][0]] = 0
	visited[l[i][1]] = 0
distance = {}
for i in d:
	distance[i] = 0

def bfs(root):
	queue = deque([root])
	counter = 0
	visited[root] = 1
	distance[root] = 0
	while queue:
		vertex = queue.popleft()
		if vertex not in d:
			continue
		for neighbour in d[vertex]:
			if visited[neighbour] == 0:
				distance[neighbour] = distance[vertex] + 1
				visited[neighbour] = 1
				queue.append(neighbour)
	return
bfs('polycarp')
m = -1
for i in distance:
	if distance[i] > m:
		m = distance[i]
print(m + 1)


m = dict()
n = int(input().strip())
m['polycarp'] = 0
for i in range(n):
	(n1, n2) = input().rstrip().lower().split(' reposted ', 1)
	m[n1] = m[n2] + 1
print(max(m.values()) + 1)


inp = int(input())
ist = {'polycarp': 1}
for i in range(inp):
	(n1, repost, n2) = input().lower().split(' ')
	ist[n1] = 1 + ist[n2]
z = ist.values()
print(max(z))


def dfs(node, d):
	global maxD
	maxD = max(maxD, d)
	stack = [node]
	seen[node] = 1
	while stack:
		ele = stack.pop()
		for each in arr[ele]:
			if seen[each] == 0:
				dfs(each, d + 1)
dic = {}
arr = [list() for i in range(205)]
ind = 0
maxD = 0
seen = [0] * 205
for i in range(int(input())):
	(a, _, b) = input().split()
	a = a.lower()
	b = b.lower()
	if b not in dic:
		dic[b] = ind
		ind += 1
	if a not in dic:
		dic[a] = ind
		ind += 1
	arr[dic[a]].append(dic[b])
	arr[dic[b]].append(dic[a])
dfs(0, 1)
print(maxD)


a = {'polycarp': 1}
max = 0
for i in range(int(input())):
	(n, m) = input().lower().split(' reposted ')
	a[n] = a[m] + 1
	if a[m] + 1 > max:
		max = a[m] + 1
print(max)


n = int(input())
g = {}
used = set()
max_level = 1

def dfs(v, level=1):
	global g, used, max_level
	if level > max_level:
		max_level = level
	used.add(v)
	if v in g:
		for vertex in g[v]:
			if not vertex in used:
				dfs(vertex, level + 1)

def main():
	for i in range(n):
		(name1, _, name2) = map(str.lower, input().split())
		if name2 not in g:
			g[name2] = {name1}
		else:
			g[name2].add(name1)
	dfs('polycarp')
	print(max_level)
main()


num_posts = int(input())
repost_length = {}
repost_length['polycarp'] = 1
for _ in range(num_posts):
	(name1, _, name2) = input().lower().split(' ')
	repost_length[name1] = repost_length[name2] + 1
print(max(repost_length.values()))


n = int(input())
c = {}
c['polycarp'] = []
for i in range(n):
	s = input().split(' reposted ')
	s[0] = s[0].lower()
	s[1] = s[1].lower()
	if s[0] not in c:
		c[s[0]] = []
	c[s[1]] += [c[s[0]]]
answ = str(c['polycarp'])
count = 0
m = 0
for i in answ:
	if i == '[':
		count += 1
		if count > m:
			m = count
	elif i == ']':
		count -= 1
print(m)


p = {}
visited = {}

def dfs(name):
	global p
	if name not in visited:
		return 1
	if visited[name] == True:
		return 0
	visited[name] = True
	maxx = 0
	for i in p[name]:
		maxx = max(maxx, dfs(i))
	return maxx + 1

def main():
	global p
	mode = 'filee'
	if mode == 'file':
		f = open('test.txt', 'r')
	get = lambda : [str(x) for x in (f.readline() if mode == 'file' else input()).split()]
	n = int(input())
	for z in range(n):
		[a, b, c] = get()
		a = a.lower()
		c = c.lower()
		if c not in p:
			p[c] = []
		p[c].append(a)
	for i in p:
		visited[i] = False
	print(dfs('polycarp'))
	if mode == 'file':
		f.close()
main()


def main():
	n = int(input())
	vertices = set()
	graph = {}
	for i in range(n):
		s = input().split()
		r1 = s[0].lower()
		r2 = s[2].lower()
		if r1 not in vertices:
			graph[r1] = []
		vertices.add(r1)
		if r2 not in vertices:
			graph[r2] = []
		vertices.add(r2)
		graph[r2].append(r1)
	print(depth('polycarp', graph))

def depth(name, graph):
	d = 0
	for i in graph[name]:
		d = max(d, depth(i, graph))
	return d + 1
main()


(n, qwe) = (int(input()), {'polycarp': 1})
for _ in range(n):
	t = input().split(' reposted ')
	qwe[t[0].lower()] = qwe[t[1].lower()] + 1
print(max(qwe.values()))


class node:

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

	def getdata(self):
		return self._data

	def getchildren(self):
		return self._children

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

	def go(self, data):
		for child in self._children:
			if child.getdata() == data:
				return child
		return None

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

	def height(self):
		if self.is_leaf():
			return 1
		else:
			return 1 + max((c.height() for c in self._children))

class tree:

	def __init__(self):
		self._head = node('header')

	def linktohead(self, node):
		self._head.add(node)

	def insert(self, path, data):
		cur = self._head
		for step in path:
			if cur.go(step) == None:
				return False
			else:
				cur = cur.go(step)
		cur.add(node(data))
		return True

	def search(self, path):
		cur = self._head
		for step in path:
			if cur.go(step) == None:
				return None
			else:
				cur = cur.go(step)
		return cur
a = []
k = 0
n = int(input())
for i in range(n):
	string = input()
	s1 = string.split()[0]
	s1 = s1.lower()
	s2 = string.split()[2]
	s2 = s2.lower()
	boolean = 1
	for j in range(0, k):
		h = a[j].getdata()
		if h == s1:
			boolean = 0
			ts1 = j
			break
	if boolean == 1:
		k += 1
		a.append(node(s1))
		ts1 = k - 1
	boolean = 1
	for j in range(0, k):
		h = a[j].getdata()
		if h == s2:
			boolean = 0
			ts2 = j
			break
	if boolean == 1:
		k += 1
		a.append(node(s2))
		ts2 = k - 1
	a[ts2].add(a[ts1])
root = 0
for i in range(k):
	h = a[i].getdata()
	if h == 'polycarp':
		root = i
		break
t = a[root].height()
print(t)


import sys
readints = lambda : map(int, input().strip('\n').split())
n = int(input())
reposts = {}
for _ in range(n):
	s = input().split(' ')
	a = s[0].strip().lower()
	b = s[2].strip().lower()
	if b not in reposts:
		reposts[b] = 1
	reposts[a] = reposts[b] + 1
ans = 0
for k in reposts:
	ans = max(ans, reposts[k])
print(ans)


n = int(input())
arr = []
for i in range(n):
	line = input().split()
	arr.append((line[0].lower(), line[-1].lower()))
chains = {'polycarp': 1}
for (a, b) in arr:
	chains[a] = chains[b] + 1
print(max(chains.values()))


n = int(input())
matrix = {}
shares = []
paths = []
for i in range(n):
	st = input().split()
	shares.append(st)
	shares[i][0] = shares[i][0].lower()
	shares[i][2] = shares[i][2].lower()
	matrix[shares[i][0]] = []
	matrix[shares[i][2]] = []
for i in range(n):
	matrix[shares[i][2]].append(shares[i][0])

def DFS(graph, start, end, path=[]):
	path = path + [start]
	if start == end:
		paths.append(path)
	for w in graph[start]:
		if w not in path:
			DFS(graph, w, end, path)
for i in matrix:
	if len(matrix[i]) == 0:
		DFS(matrix, 'polycarp', i)
count = 0
for path in paths:
	if len(path) > count:
		count = len(path)
print(count)


from collections import defaultdict
n = int(input())
d = defaultdict(list)
for i in range(n):
	s = list(map(str, input().split()))
	for i in range(3):
		s[i] = s[i].lower()
	d[s[2]].append(s[0])
q = list()
q.append('polycarp')
q.append(None)
c = 0
b = 1
while q:
	a = q[0]
	q.pop(0)
	b -= 1
	if a == None:
		c += 1
		q.append(None)
	elif a in d:
		a = d[a]
		b = len(a)
		for i in range(len(a)):
			q.append(a[i])
	if len(q) == 1:
		c += 1
		break
print(c)


def nafig(s):
	for i in range(len(s)):
		x = ord(s[i])
		if x <= 90 and x >= 65:
			x += 32
			s = s[:i] + chr(x) + s[i + 1:]
	return s
n = int(input())
dic = dict()
dic['polycarp'] = 1
maxim = 1
for i in range(n):
	st = list(map(str, input().split()))
	st[0] = nafig(st[0])
	st[2] = nafig(st[2])
	dic[st[0]] = dic[st[2]] + 1
	if dic[st[0]] > maxim:
		maxim = dic[st[0]]
print(maxim)


from math import gcd
import bisect
import collections
import copy
import functools
import heapq
import itertools
import math
import random
import re
import sys
import time
import string
from typing import List
sys.setrecursionlimit(99999)
(n,) = map(int, input().split())
dp = collections.defaultdict(int)
dp['polycarp'] = 1
for _ in [0] * n:
	(name1, op, name2) = input().lower().split()
	dp[name1] = dp[name2] + 1
print(max(dp.values()))


n = int(input())
i = 0
s = []
k = []
x = []
while i < n:
	s.append(input().lower().split(' reposted '))
	i = i + 1
k.append(['polycarp', 1])
for l in k:
	for z in s:
		if z[1] == l[0]:
			k.append([z[0], l[1] + 1])
for l in k:
	x.append(l[1])
print(max(x))


n = int(input())
list = {}
for i in range(n):
	string = input().lower().split(' ')
	list[string[0]] = string[2]
vallist = {}

def find_relation(key):
	if key not in vallist:
		if key not in list:
			vallist[key] = 1
			return vallist[key]
		else:
			vallist[key] = find_relation(list[key]) + 1
			return vallist[key]
	else:
		return vallist[key]
max = 0
for key in list:
	find_relation(key)
	if vallist[key] > max:
		max = vallist[key]
print(max)


n = int(input())
arr = []
brr = {}
for i in range(n):
	arr = [str(i) for i in input().split(' reposted ')]
	(arr[0], arr[1]) = (arr[0].lower(), arr[1].lower())
	if arr[1] == 'polycarp':
		brr.update({arr[0]: 2})
	elif arr[1] in brr.keys():
		brr.update({arr[0]: brr[arr[1]] + 1})
print(max(brr.values()))


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
eps = 1.0 / 10 ** 10
mod = 998244353
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 list(map(int, sys.stdin.readline().split()))

def LLI():
	return [list(map(int, l.split())) for l in sys.stdin.readlines()]

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 pe(s):
	return print(str(s), file=sys.stderr)

def JA(a, sep):
	return sep.join(map(str, a))

def JAA(a, s, t):
	return s.join((t.join(map(str, b)) for b in a))

def main():
	n = I()
	aa = [LS() for _ in range(n)]
	e = collections.defaultdict(set)
	for (a, _, b) in aa:
		e[b.lower()].add(a.lower())
	m = {}

	def f(c):
		if c in m:
			return m[c]
		r = 1
		for nc in e[c]:
			t = f(nc)
			if r <= t:
				r = t + 1
		m[c] = r
		return r
	r = 0
	for k in list(e.keys()):
		t = f(k)
		if r < t:
			r = t
	return r
print(main())


adj = [[] for _ in range(205)]
visi = [False for _ in range(205)]
maxd = 1

def dfs(i, d):
	global maxd
	visi[i] = True
	for j in adj[i]:
		if visi[j] == False:
			dfs(j, d + 1)
			if maxd < d + 1:
				maxd = d + 1
l = ['polycarp']
n = int(input())
for i in range(n):
	tem = list(map(str, input().split()))
	if tem[2].lower() == l[0]:
		adj[1].append(i + 2)
		adj[i + 2].append(1)
		l.append(tem[0].lower())
	else:
		for j in range(len(l)):
			if l[j] == tem[2].lower():
				adj[j + 1].append(i + 2)
				adj[i + 2].append(j + 1)
				l.append(tem[0].lower())
				break
dfs(1, 1)
print(maxd)


n = int(input())
a = [[1000 for j in range(n + 1)] for i in range(n + 1)]
d = {'polycarp': 0}
s = set('polycarp')
k = 1
for i in range(n):
	(c, b) = input().lower().split(' reposted ')
	if c not in d.keys():
		d[c] = k
		k += 1
	if b not in d.keys():
		d[b] = k
		k += 1
	a[d[b]][d[c]] = 1
dist = [9 ** 10 for i in range(n + 1)]
dist[0] = 0
q = []
q.append(0)
l = 0
while l < len(q):
	v = q[l]
	for i in range(n + 1):
		if a[v][i] == 1 and dist[i] > dist[v] + 1:
			q.append(i)
			dist[i] = dist[v] + 1
	l += 1
t = 0
for i in dist:
	if i != 9 ** 10 and i > t:
		t = i
print(t + 1)


from collections import defaultdict
n = int(input())
s = defaultdict(set)
for i in range(n):
	(name1, _, name2) = input().lower().split()
	if name2 in s:
		s[name1] |= s[name2]
	s[name1].add(name2)
res = 0
for i in s.values():
	res = max(res, 1 + len(i))
print(res)


n = int(input())
d = {'POLYCARP': 1}
for i in range(n):
	(a, r, b) = input().split()
	d[a.upper()] = d[b.upper()] + 1
print(max(d.values()))


n = int(input())
status = {'polycarp': 1}
for i in range(n):
	(x, y) = [char for char in input().lower().split(' reposted ')]
	status[x] = status[y] + 1
print(max(status.values()))


def add_to_tree(tree, parent, elem, key='polycarp'):
	if parent == key:
		tree.get(parent).update({elem: {}})
		return
	if parent in tree.get(key).keys():
		tree.get(key).get(parent).update({elem: {}})
		return
	else:
		for x in tree.get(key).keys():
			add_to_tree(tree.get(key), parent, elem, x)

def find_max_way(tree, key='polycarp'):
	if not tree.get(key):
		return 1
	return max([find_max_way(tree.get(key), key=x) + 1 for x in tree.get(key).keys()])

def main():
	n = int(input())
	d = {'polycarp': {}}
	for i in range(n):
		s = str(input()).split()
		add_to_tree(d, s[2].lower(), s[0].lower())
	print(find_max_way(d))
main()


def dfs(x, depth):
	for i in range(len(adj[x])):
		if adj[x][i] in adj:
			dfs(adj[x][i], depth + 1)
	ans.append(max(ans[-1], depth))
N = int(input())
adj = {}
for i in range(N):
	s = input().split()
	for i in range(3):
		s[i] = s[i].lower()
	if s[2] not in adj:
		adj[s[2]] = [s[0]]
	else:
		adj[s[2]].append(s[0])
stack = []
ans = [0]
dfs('polycarp', 1)
print(max(ans) + 1)


adj = {}
ans = -1

def dfs(node, prev, depth):
	global ans
	ans = max(ans, depth)
	for neighbor in adj[node]:
		if neighbor != prev:
			dfs(neighbor, node, depth + 1)
n = int(input())
for i in range(n):
	(a, s, b) = input().split(' ')
	(a, b) = (a.lower(), b.lower())
	if a not in adj:
		adj[a] = [b]
	else:
		adj[a].append(b)
	if b not in adj:
		adj[b] = [a]
	else:
		adj[b].append(a)
dfs('polycarp', '', 1)
print(ans)


result = []
pol = 'polycarp'
for i in range(int(input())):
	point = False
	(new_person, _, was) = [x.lower() for x in input().split()]
	if was == pol:
		result.append([pol, new_person])
	elif was in [x[-1] for x in result]:
		for line in result:
			if line[-1] == was:
				line.append(new_person)
				break
	else:
		for line in result:
			for name in line[1:-1]:
				if name == was:
					i = line.index(name)
					new_person_line = line[:i + 1]
					new_person_line.append(new_person)
					result.append(new_person_line)
					point = True
					break
			if point:
				break
m = max((len(line) for line in result))
print(m)


num_reposts = int(input())
dic = {}
for i in range(0, num_reposts):
	repost = input().split()
	dic[repost[0].lower()] = repost[-1].lower()
length = 2
for (user, source) in dic.items():
	length_tmp = 2
	while source != 'polycarp':
		length_tmp += 1
		user = source
		source = dic[user]
	length = max(length, length_tmp)
print(length)


from sys import stdin
from collections import defaultdict
dist = defaultdict(lambda : 1)

def maxi(arr, start):
	parent = start
	for i in arr[parent]:
		dist[i] = dist[parent] + 1
		maxi(arr, i)
	ans = list(dist.values())
	return max(ans)
I = stdin.readline
n = int(I())
arr = defaultdict(lambda : [])
for i in range(n):
	inp = [x.lower() for x in I().split()]
	arr[inp[-1]].append(inp[0])
dist['polycarp'] = 1
parent = 'polycarp'
ans = maxi(arr, 'polycarp')
print(ans)


n = int(input())
repost = {}
boss = ''
for i in range(n):
	ns = input()
	name1 = ns.split()[0].lower()
	name2 = ns.split()[2].lower()
	if i == 0:
		boss = name2
	if repost.get(name2):
		repost[name2].append(name1)
	else:
		repost.update({name2: [name1]})
t_len = 1
max_len = 1

def dfs(name):
	global t_len
	global max_len
	if repost.get(name):
		for n in repost[name]:
			t_len += 1
			dfs(n)
	if t_len > max_len:
		max_len = t_len
	t_len -= 1
	return
dfs(boss)
print(max_len)


import sys
LI = lambda : list(map(int, sys.stdin.readline().split()))
MI = lambda : map(int, sys.stdin.readline().split())
SI = lambda : sys.stdin.readline().strip('\n')
II = lambda : int(sys.stdin.readline())

def dfs(s, l):
	global g, ans
	ans = max(ans, l)
	try:
		for v in g[s]:
			dfs(v, l + 1)
	except:
		pass
g = {}
n = II()
for _ in range(n):
	(a, b, c) = SI().upper().split()
	try:
		g[c].append(a)
	except:
		g[c] = [a]
ans = 0
dfs('Polycarp'.upper(), 1)
print(ans)


n = int(input())
arr = [['POLYCARP', 1]]
for i in range(n):
	(a, placeHolder, b) = list(input().split())
	a = a.upper()
	b = b.upper()
	for g in range(len(arr)):
		if arr[g][0] == b:
			arr.append([a, arr[g][1] + 1])
			break
m = 0
for i in range(len(arr)):
	m = max(m, arr[i][1])
print(m)


n = int(input())
ans = 1
mp = dict()
for _ in range(n):
	(t, _, f) = input().lower().split()
	if f in mp.keys():
		mp[f].append(t)
	else:
		mp[f] = [t]
d = 1

def req(curr):
	global d, ans, mp
	d += 1
	if d > ans:
		ans = d
	for el in mp[curr]:
		if el in mp.keys():
			req(el)
	d -= 1
req('polycarp')
print(ans)


n = int(input())
s1 = []
s2 = []
visit = [0 for i in range(205)]
ans = 0

def dfs(num, cnt):
	global ans
	if cnt > ans:
		ans = cnt
	for i in range(n):
		if visit[i] == 1:
			continue
		if num == -1 or s1[i] == s2[num]:
			visit[i] = 1
			dfs(i, cnt + 1)
			visit[i] = 0
for i in range(n):
	s = [j for j in input().split()]
	a = s[0]
	b = s[-1]
	if a.islower() == False:
		a = a.lower()
	if b.islower() == False:
		b = b.lower()
	s1.append(a)
	s2.append(b)
dfs(-1, 1)
print(ans)


import sys
import re
import collections
sys.setrecursionlimit(10 ** 6)

def dfs(pos):
	visit[pos] = 1
	length = len(edges[pos])
	for i in range(length):
		if visit[edges[pos][i]] != 1:
			depth[edges[pos][i]] = depth[pos] + 1
			dfs(edges[pos][i])
n = int(sys.stdin.readline())
a = [sys.stdin.readline().strip().lower().split(' reposted ') for i in range(n)]
node = ['polycarp']
for i in range(n):
	for j in range(1, -1, -1):
		if a[i][j] not in node:
			node.append(a[i][j])
for i in range(n):
	for j in range(1, -1, -1):
		for k in range(len(node)):
			if a[i][j] == node[k]:
				a[i][j] = k
node_len = len(node)
edges = [[] for i in range(node_len)]
visit = [0] * node_len
depth = [0] * node_len
for i in range(n):
	edges[a[i][0]].append(a[i][1])
	edges[a[i][1]].append(a[i][0])
depth[0] = 1
dfs(0)
print(max(depth))


n = int(input())
graph = {'polycarp': 1}
maximum = 0
for _ in range(n):
	sentence = input()
	(l, r) = sentence.split(' reposted ')
	graph[l.lower()] = graph[r.lower()] + 1
	maximum = max(graph[l.lower()], maximum)
print(maximum)


N = int(input())
chainsDict = {'polycarp': 1}
for i in range(N):
	(first, second) = input().lower().split(' reposted ')
	if first in chainsDict:
		chainsDict[first] += 1
	else:
		chainsDict[first] = chainsDict[second] + 1
print(max((chainsDict[x] for x in chainsDict)))


count = {'POLYCARP': 1}
n = int(input())
for _ in range(n):
	(a, b, c) = input().upper().split()
	count[a] = count[c] + 1
print(max(count.values()))


from collections import defaultdict
n = int(input())
d = defaultdict(int)
for i in range(n):
	toks = input().lower().split()
	d[toks[0]] = d[toks[2]] + 1
print(max(d.values()) + 1)


n = int(input())
children = dict()
for i in range(n):
	(per1, per2, per3) = input().split()
	per1 = list(per1)
	per3 = list(per3)
	for i in range(len(per1)):
		if ord(per1[i]) < 91:
			per1[i] = chr(ord(per1[i]) + 32)
	per1 = ''.join(per1)
	for i in range(len(per3)):
		if ord(per3[i]) < 91:
			per3[i] = chr(ord(per3[i]) + 32)
	per3 = ''.join(per3)
	if per3 not in children:
		children[per3] = {per1}
	else:
		children[per3].add(per1)
	if per1 not in children:
		children[per1] = set()
answer = []
from pprint import *
from collections import deque
root = 'polycarp'
queue = deque()
queue.append(root)
high = 0
per1 = 1
while queue:
	per2 = 0
	for i in range(per1):
		per = queue.pop()
		if per in children:
			for i in children[per]:
				per2 += 1
				queue.appendleft(i)
	high += 1
	per1 = per2
print(high)


def main():
	(n, ba) = (int(input()), {})
	for _ in range(n):
		(a, _, b) = input().lower().split()
		s = ba.get(b)
		if s:
			s.add(a)
		else:
			ba[b] = {a}
	res = 0

	def deeper(head, n):
		nonlocal res
		tail = ba.get(head)
		if tail:
			n += 1
			for t in tail:
				deeper(t, n)
		elif res < n:
			res = n
	deeper('polycarp', 1)
	print(res)
main()


n = int(input())
reposts = [input().lower().split(' reposted ') for _ in range(n)]
STARTING_VALUE = 'Polycarp'.lower()

def get_longest_joke():
	tree = Tree(STARTING_VALUE)
	for (reposter, op) in reposts:
		node = tree_search(tree, op)
		node.add_child_with_value(reposter)
	return tree.depth

def tree_search(tree, value):
	if tree.value == value:
		return tree
	elif tree.is_leaf():
		return
	for child in tree.children:
		result = tree_search(child, value)
		if result:
			return result

class Tree(object):

	def __init__(self, value, children=None):
		self.value = value
		self.children = children

	def __repr__(self):
		if self.children:
			return 'Tree(%s, %s)' % (self.value, self.children)
		return 'Tree(%s)' % self.value

	def is_leaf(self):
		return not self.children

	def add_child(self, child):
		if self.is_leaf():
			self.children = [child]
		else:
			self.children.append(child)

	def add_child_with_value(self, value):
		self.add_child(Tree(value))

	@property
	def depth(self):
		if self.is_leaf():
			return 1
		return 1 + max([child.depth for child in self.children])
print(get_longest_joke())


n = int(input())
dic = {}
for i in range(n):
	s = input().split()
	a = s[0]
	b = s[2]
	a = a.lower()
	b = b.lower()
	if b in dic:
		dic[b].append(a)
	else:
		dic[b] = [a]

def maxl(node, par=-1):
	if not node in dic:
		return 1
	ans = 0
	for i in dic[node]:
		if i != par:
			ans = max(ans, maxl(i, node))
	return 1 + ans
print(maxl('polycarp'))


n = int(input())
e = {}
for i in range(n):
	(u, v) = map(str, input().split(' reposted '))
	try:
		e[v.lower()].append(u.lower())
	except:
		e[v.lower()] = [u.lower()]
dp = {}

def dfs(x, par):
	maxx = 0
	dp[x] = 1
	try:
		for i in range(len(e[x])):
			dfs(e[x][i].lower(), x)
			maxx = max(maxx, dp[e[x][i].lower()])
	except:
		pass
	dp[x] += maxx
dfs('Polycarp'.lower(), 0)
print(dp['Polycarp'.lower()])


class Node:

	def __init__(self, name, length):
		self.name = name
		self.chain_length = length
n_posts = int(input())
poly = Node('polycarp', 1)
nodes = []
max_length = 1
nodes.append(poly)
for i in range(n_posts):
	line = input().lower().split(' ')
	for j in nodes:
		if j.name == line[2]:
			new_node = Node(line[0], j.chain_length + 1)
			nodes.append(new_node)
			if j.chain_length + 1 > max_length:
				max_length = j.chain_length + 1
print(max_length)


import sys
from collections import defaultdict as dd

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

def write(a):
	sys.stdout.write(a)

def dfs(d, u, v, cnt):
	if v[u] == True:
		return cnt
	v[u] = True
	ans = cnt
	for i in d[u]:
		ans = max(ans, dfs(d, i, v, cnt + 1))
	return ans

def main():
	n = int(read())
	d = dd(list)
	p = set()
	for i in range(n):
		(b, _, a) = read().split()
		a = a.lower()
		b = b.lower()
		p.add(a)
		p.add(b)
		d[a] += [b]
	v = {i: False for i in p}
	print(dfs(d, 'polycarp', v, 1))
main()


def dfs(count, cur, dic):
	out = 0
	if cur not in dic:
		return count
	for i in range(len(dic[cur])):
		out = max(out, dfs(count + 1, dic[cur][i], dic))
	return out
a = int(input())
b = {}
for i in range(a):
	c = input().lower().split()
	if c[2] in b:
		b[c[2]].append(c[0])
	else:
		b[c[2]] = [c[0]]
print(dfs(1, 'polycarp', b))


chain = {}
n = int(input())
for i in range(n):
	try:
		(first, last) = [x.strip().lower() for x in input().split('reposted')]
		if last == 'polycarp':
			chain[first] = {'next': first, 'chain': 2}
		else:
			previous = list(filter(lambda x: last == x, chain.keys())) if chain else []
			if previous:
				chain[first] = {'next': first, 'chain': chain[previous[0]]['chain'] + 1}
			else:
				previous = list(filter(lambda x: last == x.get('next'), chain.values())) if chain else []
				previous[0]['next'] = first
				previous[0]['chain'] += 1
	except Exception as e:
		print(str(e))
print(max([x['chain'] for x in chain.values()]))


from collections import defaultdict
graph = defaultdict(list)
n = int(input())
d = {}
cnt = 0
for _ in range(n):
	(u, v) = list(map(str, input().split('reposted')))
	u = u.lower().lstrip().rstrip()
	v = v.lower().lstrip().rstrip()
	if u not in d:
		d[u] = cnt
		cnt += 1
	if v not in d:
		d[v] = cnt
		cnt += 1
	if d[v] in graph:
		graph[d[v]].append(d[u])
	else:
		graph[d[v]] = [d[u]]
x = 'polycarp'
y = d[x]
q = [(y, 1)]
visited = [False for i in range(len(d))]
visited[y] = True
ans = 0
while q != []:
	(parent, val) = q[0]
	q.pop(0)
	ans = max(ans, val)
	for i in graph[parent]:
		if visited[i] == False:
			visited[i] = True
			q.append((i, val + 1))
print(ans)


from math import *
import threading
import sys
from collections import defaultdict
from pprint import pprint
sys.setrecursionlimit(300000)
mod = 10 ** 9
inf = 10 ** 15
yes = 'YES'
no = 'NO'
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 npr(n, r):
	return factorial(n) // factorial(n - r) if n >= r else 0

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(n - r)) if n >= r else 0

def lower_bound(li, num):
	answer = -1
	start = 0
	end = len(li) - 1
	while start <= end:
		middle = (end + start) // 2
		if li[middle] >= num:
			answer = middle
			end = middle - 1
		else:
			start = middle + 1
	return answer

def upper_bound(li, num):
	answer = -1
	start = 0
	end = len(li) - 1
	while start <= end:
		middle = (end + start) // 2
		if li[middle] <= num:
			answer = middle
			start = middle + 1
		else:
			end = middle - 1
	return answer

def abs(x):
	return x if x >= 0 else -x

def binary_search(li, val):
	ans = -1
	lb = 0
	ub = len(li) - 1
	while lb <= ub:
		mid = (lb + ub) // 2
		if li[mid] > val:
			ub = mid - 1
		elif val > li[mid]:
			lb = mid + 1
		else:
			ans = mid
			break
	return ans

def kadane(x):
	sum_so_far = 0
	current_sum = 0
	for i in x:
		current_sum += i
		if current_sum < 0:
			current_sum = 0
		else:
			sum_so_far = max(sum_so_far, current_sum)
	return sum_so_far

def pref(li):
	pref_sum = [0]
	for i in li:
		pref_sum.append(pref_sum[-1] + i)
	return pref_sum

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	li = []
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	for p in range(2, len(prime)):
		if prime[p]:
			li.append(p)
	return li

def primefactors(n):
	factors = []
	while n % 2 == 0:
		factors.append(2)
		n //= 2
	for i in range(3, int(sqrt(n)) + 1, 2):
		while n % i == 0:
			factors.append(i)
			n //= i
	if n > 2:
		factors.append(n)
	return factors

def prod(li):
	ans = 1
	for i in li:
		ans *= i
	return ans

def dist(a, b):
	d = abs(a[1] - b[1]) + abs(a[2] - b[2])
	return d

def power_of_n(x, n):
	cnt = 0
	while x % n == 0:
		cnt += 1
		x //= n
	return cnt
for _ in range(1):
	n = int(input())
	d = {}
	enum = {}
	for i in range(1, n + 1):
		(a, c, b) = input().split()
		a = a.upper()
		b = b.upper()
		if a not in d:
			d[a] = [b]
		else:
			d[a] += [b]
		if b not in d:
			d[b] = [a]
		else:
			d[b] += [a]
	i = 0
	for j in d.keys():
		enum[j] = i
		i += 1
	vis = [0] * i
	dist = [0] * i

	def dfs(person, x):
		vis[enum[person]] = 1
		dist[enum[person]] = x
		for child in d[person]:
			if vis[enum[child]] == 0:
				dfs(child, x + 1)
	dfs('POLYCARP', 1)
	print(max(dist))


n = int(input())
from collections import defaultdict
ax = dict()
ax['polycarp'] = 1
ans = 1
for i in range(n):
	(a, b, c) = map(str, input().split())
	a = a.lower()
	c = c.lower()
	ax[a] = ax[c] + 1
	e = ax[a]
	ans = max(ans, e)
print(ans)


from sys import stdin, stdout, setrecursionlimit
import threading

class Tail_Recursion_Optimization:

	def __init__(self, recursion_limit, stack_size):
		setrecursionlimit(recursion_limit)
		threading.stack_size(stack_size)
		return None

class SOLVE:

	def dfs(self, u, node, dis):
		depth = 1
		for v in node[u]:
			if v in node and v not in dis:
				dis[v] = self.dfs(v, node, dis) + 1
				depth = max(depth, dis[v])
		dis[u] = depth
		return dis[u]

	def solve(self):
		R = stdin.readline
		W = stdout.write
		node = {}
		for i in range(int(R())):
			(u, c, v) = R().split()
			(u, v) = (u.lower(), v.lower())
			if u not in node:
				node[u] = []
			node[u].append(v)
			if v not in node:
				node[v] = []
		mx = 2
		for u in node:
			dis = {u: 0}
			mx = max(mx, self.dfs(u, node, dis))
		W('%d\n' % mx)
		return 0

def main():
	s = SOLVE()
	s.solve()
Tail_Recursion_Optimization(10 ** 5, 2 ** 20)
threading.Thread(target=main).start()


n = int(input())
D = dict()
D['polycarp'] = 1
max1 = 0
for i in range(n):
	str1 = input()
	sp = str1.split(' ')
	D[sp[0].lower()] = D[sp[2].lower()] + 1
	if D[sp[0].lower()] > max1:
		max1 = D[sp[0].lower()]
print(max1)


import sys

def dfs(cur, len):
	global a, mark, cur_max
	mark[cur] = True
	cur_max = max(cur_max, len)
	for v in a[cur]:
		if not mark[v]:
			dfs(v, len + 1)
cur_max = 0
text = sys.stdin.read().split('\n')
n = int(text[0])
a = [[] for i in range(n + 1)]
mark = [False] * (n + 1)
amount = 1
names = {}
names['polycarp'] = 0
for line in text[1:]:
	s = line.split()
	if len(s) == 0:
		continue
	name1 = s[0].lower()
	name2 = s[2].lower()
	if not name1 in names.keys():
		names[name1] = amount
		amount += 1
	if not name2 in names.keys():
		names[name2] = amount
		amount += 1
	num1 = names[name1]
	num2 = names[name2]
	a[num2].append(num1)
dfs(0, 0)
print(cur_max + 1)


n = int(input())
nameP = 'polycarp'
count = 2
names = {}
(name1, name2) = input().lower().split(' reposted ')
names[name1] = count
for i in range(n - 1):
	(name1, name2) = input().lower().split(' reposted ')
	if name2 == nameP:
		names[name1] = count
	elif name2 in names:
		names[name1] = names[name2] + 1
for key in names:
	if count < names[key]:
		count = names[key]
print(count)


n = int(input())
maxlen = 1
nodes = dict()
nodes['polycarp'] = 1
for _ in range(n):
	(a, _, b) = [s.lower() for s in input().split()]
	tmp = nodes.get(b) + 1
	nodes[a] = tmp
	maxlen = max(maxlen, tmp)
print(maxlen)


n = int(input())
x = {'polycarp': 1}
for i in range(n):
	(j, k, l) = input().lower().split()
	x[j] = x[l] + 1
print(max(x.values()))


dict = {'polycarp': 1}
n = int(input())
for i in range(n):
	lst = input().lower().split(' reposted ')
	dict[lst[0]] = dict[lst[1]] + 1
mass = []
for i in dict:
	mass.append(dict[i])
print(max(mass))


n = int(input())
a = {}
a['polycarp'] = 1
for i in range(n):
	inp = input().split()
	a[inp[0].lower()] = a[inp[2].lower()] + 1
mx = 0
for key in a:
	mx = max(mx, a[key])
print(mx)


def readInt():
	return int(input())

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

def readIntList():
	return list(map(int, input().split()))
n = readInt()
graph = {}
ans = 0

def search(node, sum):
	global graph
	global ans
	if graph.get(node) == None:
		ans = max(ans, sum)
	else:
		for child in graph[node]:
			search(child, sum + 1)
for i in range(n):
	(child, _, parent) = map(str.lower, input().split())
	if graph.get(parent) == None:
		graph[parent] = []
	graph[parent].append(child)
for child in graph['polycarp']:
	search(child, 2)
print(ans)


n = int(input())
parents = {'polycarp': 1}
for i in range(n):
	(name1, name2) = [i.lower() for i in input().split(' reposted ')]
	parents[name1] = parents[name2] + 1
ans = max(parents.values())
print(ans)


def r(d, key):
	if key in d:
		s = 0
		for i in d[key]:
			m = r(d, i)
			if m > s:
				s = m
		return s + 1
	else:
		return 1

def size(d):
	s = 0
	for i in d:
		m = r(d, i)
		if m > s:
			s = m
	return s
n = int(input())
a = [input().lower().split() for i in range(n)]
d = {}
for i in a:
	d[i[2]] = []
for i in a:
	d[i[2]].append(i[0])
s = size(d)
print(s)


n = int(input())
tree = {}

def dfs(g, start, visited=None):
	if visited is None:
		visited = set()
	visited.add(start)
	if start in g.keys():
		for nxt in g[start] - visited:
			dfs(g, nxt, visited)
	return visited
for i in range(n):
	t = list(map(str, input().split()))
	(a, b) = (t[0], t[2])
	if a.lower() in tree.keys():
		tree[a.lower()].append(b.lower())
	else:
		tree[a.lower()] = set()
		tree[a.lower()].add(b.lower())
ans = 0
for st in tree.keys():
	ans = max(ans, len(dfs(tree, st)))
print(ans)


n = int(input())
adj = [[] for i in range(201)]
vert = {}
vert['polycarp'] = 0
i = 1
for k in range(n):
	s = [j for j in input().split()]
	f = s[0]
	sec = s[2]
	f = f.lower()
	sec = sec.lower()
	vert[f] = i
	i = i + 1
	adj[vert[f]].append(vert[sec])
	adj[vert[sec]].append(vert[f])
count = [0] * len(vert)

def bfs():
	lst = []
	visited = [0] * len(vert)
	lst.append(0)
	visited[0] = 1
	count[0] = 1
	while len(lst) != 0:
		fr = lst.pop(0)
		for x in adj[fr]:
			if visited[x] == 0:
				visited[x] = 1
				lst.append(x)
				count[x] = count[fr] + 1
bfs()
print(max(count))


n = int(input())
repost_level = {'polycarp': 1}
for i in range(n):
	(name1, _, name2) = input().split()
	repost_level[name1.lower()] = repost_level[name2.lower()] + 1
print(max(repost_level.values()))


nodes = {'polycarp': 1}
n = int(input())
max_len = 1
for i in range(n):
	(child, dummy, parent) = [x.lower() for x in input().split()]
	nodes[child] = nodes[parent] + 1
	if nodes[child] > max_len:
		max_len = nodes[child]
print(max_len)


d = {'POLYCARP': 1}
for i in range(int(input())):
	p = input().split()
	d[p[0].upper()] = d[p[2].upper()] + 1
print(max(d.values()))


n = int(input())
d = dict()
d['polycarp'] = 1
maximum = 1
for i in range(0, n):
	a = list(map(str, input().split()))
	fromW = a[2].lower()
	toW = a[0].lower()
	d[toW] = d[fromW] + 1
	maximum = max(d[toW], maximum)
print(maximum)


count = int(input())
tree = {'polycarp': 1}
max = 1
for i in range(0, count):
	try:
		rel = input().lower().split(' ')
		if not rel[1] == 'reposted':
			continue
		tree[rel[0]] = tree[rel[2]] + 1
		if tree[rel[0]] > max:
			max = tree[rel[0]]
	except BaseException:
		continue
print(max)


class Repost:

	def __init__(self, name1, name2, reposts):
		self.reposted = name2.lower()
		self.reposter = name1.lower()
		self.depth = 1
		for repost in reposts:
			if repost.reposter == self.reposted:
				self.depth = repost.depth + 1
				break
count = int(input())
notes = []
for i in range(count):
	notes.append(input())
reposts = []
for note in notes:
	names = note.split(' ')
	new_repost = Repost(names[0], names[2], reposts)
	reposts.append(new_repost)
max_depth = 0
for repost in reposts:
	if repost.depth > max_depth:
		max_depth = repost.depth
print(max_depth + 1)


from collections import defaultdict

def dfs(graph, vis, start, ans, arr):
	vis[start] = True
	if len(graph[start]) == 1 and start != 'POLYCARP':
		ans[start] = 1
		return 1
	for neighbour in graph[start]:
		if vis[neighbour] == False:
			arr[start] = max(arr[start], 1 + dfs(graph, vis, neighbour, ans, arr))
	ans[start] = arr[start]
	return ans[start]
n = int(input())
graph = defaultdict(list)
for i in range(n):
	(name1, x, name2) = map(str, input().split())
	name1 = name1.upper()
	name2 = name2.upper()
	graph[name1].append(name2)
	graph[name2].append(name1)
visited = {}
ans = {}
arr = {}
for i in graph:
	visited[i] = False
	ans[i] = 0
	arr[i] = 0
dfs(graph, visited, 'POLYCARP', ans, arr)
maxi = 0
for i in ans:
	maxi = max(maxi, ans[i])
print(maxi)


d = {'polycarp': 1}
for i in range(int(input())):
	(to, _, frm) = input().lower().split()
	d[to] = d[frm] + 1
print(max(d.values()))


from sys import stdin, stdout, setrecursionlimit
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, accumulate
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
import copy
import time
starttime = time.time()
mod = int(pow(10, 9) + 7)
mod2 = 998244353

def data():
	return input()

def num():
	return int(input())

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)]

def pmat(A):
	for ele in A:
		print(*ele, end='\n')

def pmat2(A):
	for ele in A:
		for j in ele:
			print(j, end='')
		print()

def seive():
	prime = [1 for i in range(10 ** 6 + 1)]
	prime[0] = 0
	prime[1] = 0
	for i in range(10 ** 6 + 1):
		if prime[i]:
			for j in range(2 * i, 10 ** 6 + 1, i):
				prime[j] = 0
	return prime
n = int(data())
ht = {'polycarp': 1}
for _ in range(n):
	(s, r, f) = ssp()
	s = s.lower()
	f = f.lower()
	ht[s] = ht[f] + 1
print(max(ht.values()))
endtime = time.time()


d = {'polycarp': 1}
for item in range(int(input())):
	current = str(input()).lower().split(' ')[::2]
	d[current[0]] = d[current[1]] + 1
print(max(d.values()))


n = int(input())
G = {'polycarp': 1}
for i in range(n):
	X = list(input().split())
	a = X[0].lower()
	b = X[2].lower()
	if b in G:
		G[a] = G[b] + 1
	else:
		G[a] = 1
print(max(G.values()))


from collections import defaultdict

class Graph:

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

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

	def BFS(self, s):
		visited = [False] * 201
		dist = [0] * 201
		queue = []
		queue.append(s)
		visited[s] = True
		dist[s] = 0
		while queue:
			s = queue.pop(0)
			for i in self.graph[s]:
				if visited[i] == False:
					queue.append(i)
					visited[i] = True
					dist[i] = dist[s] + 1
		return max(dist) + 1
n = int(input())
dic = dict()
ind = 0
g = Graph()
while n > 0:
	x = input()
	s = x.split()
	if s[2].lower() not in dic.keys():
		dic[s[2].lower()] = ind
		ind = ind + 1
	if s[0].lower() not in dic.keys():
		dic[s[0].lower()] = ind
		ind = ind + 1
	g.addEdge(dic[s[2].lower()], dic[s[0].lower()])
	n = n - 1
print(g.BFS(0))


dict = {'polycarp': 1}
for i in range(int(input())):
	s = input().lower().split(' reposted ')
	dict[s[0]] = dict[s[1]] + 1
print(dict[max(dict, key=dict.get)])


n = int(input())
from collections import defaultdict
graph = defaultdict(list)
visited = {}
level = {}
visited['polycarp'] = 0
level['polycarp'] = 1
for i in range(n):
	(k, p, r) = [j.lower() for j in input().split(' ')]
	graph[r].append(k)
	visited[k] = 0
	level[k] = 0

def dfs(graph, s):
	visited[s] = 1
	for j in graph[s]:
		if not visited[j]:
			level[j] = 1 + level[s]
			dfs(graph, j)
dfs(graph, 'polycarp')
print(max(level.values()))


tree = {'polycarp': 1}
n = int(input())
maxLevel = 1
for i in range(n):
	(reposter, sourcer) = input().split(' reposted ')
	reposter = reposter.lower()
	sourcer = sourcer.lower()
	tree[reposter] = tree[sourcer] + 1
	if tree[reposter] > maxLevel:
		maxLevel = tree[reposter]
print(maxLevel)


def dfs(a):
	su = 1
	for i in arr[a]:
		su = max(su, dfs(i) + 1)
	return su
dic = {}
dic['polycarp'] = 0
nex = 1
n = int(input())
arr = []
for _ in range(250):
	arr.append([])
for _ in range(n):
	s = input()
	s = s.lower()
	s = s.split(' ')
	if s[2] not in dic:
		dic[s[2]] = nex
		nex += 1
	if s[0] not in dic:
		dic[s[0]] = nex
		nex += 1
	arr[dic[s[2]]].append(dic[s[0]])
ans = dfs(0)
print(ans)


def find_repost_rank(user_name):
	n = int(input())
	repost_list = []
	i = 0
	while i < n:
		r = input()
		repost_list.append([r.split()[0], r.split()[2]])
		i += 1
	return find_max(repost_list, user_name)

def find_max(repost_array, user_name, current=0, max_rank=1):
	while current < len(repost_array):
		current_rank = 1
		if repost_array[current][1].lower() == user_name.lower():
			current_rank += find_max(repost_array, repost_array[current][0], current + 1, current_rank)
		if current_rank > max_rank:
			max_rank = current_rank
		current += 1
	return max_rank
print(find_repost_rank('Polycarp'))