AtCoder Regular Contest 078 - Fennec VS. Snuke

Fennec and Snuke are playing a board game.
On the board, there are N cells numbered 1 through N, and N-1 roads, each connecting two cells. Cell a_i is adjacent to Cell b_i through the i-th road. Every cell can be reached from every other cell by repeatedly traveling to an adjacent cell. In terms of graph theory, the graph formed by the cells and the roads is a tree.
Initially, Cell 1 is painted black, and Cell N is painted white. The other cells are not yet colored.
Fennec (who goes first) and Snuke (who goes second) alternately paint an uncolored cell.
More specifically, each player performs the following action in her/his turn:
 - Fennec: selects an uncolored cell that is adjacent to a black cell, and paints it black.
 - Snuke: selects an uncolored cell that is adjacent to a white cell, and paints it white.
A player loses when she/he cannot paint a cell. Determine the winner of the game when Fennec and Snuke play optimally.

-----Constraints-----
 - 2 \leq N \leq 10^5
 - 1 \leq a_i, b_i \leq N
 - The given graph is a tree.

-----Input-----
Input is given from Standard Input in the following format:
N
a_1 b_1
:
a_{N-1} b_{N-1}

-----Output-----
If Fennec wins, print Fennec; if Snuke wins, print Snuke.

-----Sample Input-----
7
3 6
1 2
3 1
7 4
5 7
1 4

-----Sample Output-----
Fennec

For example, if Fennec first paints Cell 2 black, she will win regardless of Snuke's moves.

Difficulty: HARD

Starter code:

Solutions:
import sys
from collections import deque
cin = sys.stdin

def line2N():
	return map(int, cin.readline().split())
(N,) = line2N()
adj = [[] for i in range(N + 1)]
for i in range(N - 1):
	(u, v) = line2N()
	adj[u].append(v)
	adj[v].append(u)
color = [0] * (N + 1)
h_cnt = 1
t_cnt = 1
dq_head = deque([1])
color[1] = 1
dq_tail = deque([N])
color[N] = 1
for step in range(N):
	if step % 2 == 0:
		if not dq_head:
			t_cnt = N - h_cnt
			break
		dq_head_n = deque()
		for u in dq_head:
			for v in adj[u]:
				if color[v] == 0:
					color[v] = 1
					dq_head_n.append(v)
					h_cnt += 1
		dq_head = dq_head_n
	else:
		if not dq_tail:
			h_cnt = N - t_cnt
			break
		dq_tail_n = deque()
		for u in dq_tail:
			for v in adj[u]:
				if color[v] == 0:
					color[v] = 2
					dq_tail_n.append(v)
					t_cnt += 1
		dq_tail = dq_tail_n
if h_cnt > t_cnt:
	print('Fennec')
else:
	print('Snuke')


import sys
sys.setrecursionlimit(1000000)
N = int(input())
B = [[] for i in range(N + 1)]
F = [10 ** 10 for i in range(N + 1)]
F[1] = 0
S = [10 ** 10 for i in range(N + 1)]
S[N] = 0
for i in range(N - 1):
	(a, b) = map(int, input().split())
	B[a].append(b)
	B[b].append(a)

def dfsF(f):
	for i in B[f]:
		if F[i] == 10 ** 10:
			F[i] = F[f] + 1
			dfsF(i)
dfsF(1)

def dfsS(s):
	for i in B[s]:
		if S[i] == 10 ** 10:
			S[i] = S[s] + 1
			dfsS(i)
dfsS(N)
Fennec = 0
Snuke = 0
for i in range(1, N + 1):
	if F[i] <= S[i]:
		Fennec += 1
	else:
		Snuke += 1
if Fennec > Snuke:
	print('Fennec')
else:
	print('Snuke')


import math
import sys
sys.setrecursionlimit(1000000)
N = int(input())
graph = {}
SCORE = 0

def dfs(visited, v, depth):
	visited[v] = depth
	for next_v in graph[v]:
		if visited[next_v] == -1:
			dfs(visited, next_v, depth + 1)
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	if a not in graph:
		graph[a] = [b]
	else:
		graph[a].append(b)
	if b not in graph:
		graph[b] = [a]
	else:
		graph[b].append(a)
vF = [-1] * (N + 1)
vF[1] = 0
dfs(vF, 1, 0)
vS = [-1] * (N + 1)
vS[N] = 0
dfs(vS, N, 0)
fc = 0
sc = 0
for (f, s) in zip(vF[1:N + 1], vS[1:N + 1]):
	if f <= s:
		fc += 1
	else:
		sc += 1
if fc > sc:
	print('Fennec')
else:
	print('Snuke')


N = int(input())
import sys
sys.setrecursionlimit(10 ** 5)
ab = [list(map(int, input().split())) for _ in range(N - 1)]
con = [[] for _ in range(N + 1)]
for (a, b) in ab:
	con[a].append(b)
	con[b].append(a)
pc = [0] * (N + 1)
q = [(1, 0)]
vis = [False] * (N + 1)
vis[1] = True
Fcnt = N
while q:
	(n, c) = q.pop()
	pc[n] = c
	for ch in con[n]:
		if vis[ch] == True:
			continue
		vis[ch] = True
		q.append((ch, c + 1))
q = [(N, 0)]
vis = [False] * (N + 1)
vis[N] = True
while q:
	(n, c) = q.pop()
	if pc[n] > c:
		Fcnt -= 1
	for ch in con[n]:
		if vis[ch] == True:
			continue
		vis[ch] = True
		q.append((ch, c + 1))
if Fcnt > N - Fcnt:
	print('Fennec')
else:
	print('Snuke')


class Node:

	def __init__(self):
		pass

class Edge:

	def __init__(self, edge, cost=1):
		self.node_from = edge[0]
		self.node_to = edge[1]
		self.cost = cost

	def add_node(self, node):
		self.nodes.append(node)

class myGraph:

	def __init__(self):
		self.adj = {}
		self.nodes = {}

	def add_edge(self, edge, cost):
		if len(edge) == 1:
			edge = list(edge)
		(u, v) = (edge[0], edge[1])
		if u not in self.nodes:
			self.adj[u] = {}
			self.nodes[u] = {}
		if v not in self.nodes:
			self.adj[v] = {}
			self.nodes[v] = {}
		self.adj[u][v] = cost
		self.adj[v][u] = cost

	def add_directed_edge(self, edge, cost):
		if len(edge) == 1:
			edge = list(edge)
		(u, v) = (edge[0], edge[1])
		if u not in self.nodes:
			self.adj[u] = {}
			self.nodes[u] = {}
		if v not in self.nodes:
			self.adj[v] = {}
			self.nodes[v] = {}
		self.adj[u][v] = cost

	def get_edges_from(self, node):
		return [(self.adj[node][nn], node, nn) for nn in self.adj[node]]

	def makeEdgeobj(self):
		edges = []
		for sn in self.nodes:
			for e in self.get_edges_from(sn):
				edges.append(Edge([e[1], e[2]], e[0]))
		return edges

	def _add(self, edges, add_edges):
		for e in add_edges:
			hq.heappush(edges, e)
		return edges

	def bermn_ford(self, start, init=0):
		nodes = self.nodes
		dists = {}
		for n in nodes:
			dists[n] = float('inf')
		dists[start] = init
		edges = self.makeEdgeobj()
		for i in range(len(nodes)):
			update = False
			for k in range(len(edges)):
				e = edges[k]
				if dists[e.node_from] != float('inf') and dists[e.node_to] > dists[e.node_from] + e.cost:
					dists[e.node_to] = dists[e.node_from] + e.cost
					update = True
			if i == len(nodes) - 1:
				return False
			if not update:
				break
		return dists

	def dijkstra(self, start, goal=None):
		import heapq
		N = len(self.adj)
		dist = {k: float('inf') for k in self.nodes}
		dist[start] = 0
		visited = []
		koho = []
		heapq.heappush(koho, (0, start))
		vtx = list(self.nodes)
		vtx.remove(start)
		while len(koho) != 0:
			(d, mini) = heapq.heappop(koho)
			if dist[mini] < d:
				continue
			for k in list(self.adj[mini]):
				cost = self.adj[mini][k]
				if cost != float('inf') and dist[k] > dist[mini] + cost:
					dist[k] = dist[mini] + cost
					heapq.heappush(koho, (dist[k], k))
		return dist
N = int(input())
g = myGraph()
for i in range(N - 1):
	(a, b) = list(map(int, input().split(' ')))
	g.add_edge([a, b], 1)
b1 = g.dijkstra(1)
b2 = g.dijkstra(N)
count = 0
for k in range(1, N + 1):
	if b1[k] <= b2[k]:
		count += 1
if count > N / 2:
	print('Fennec')
else:
	print('Snuke')


n = int(input())
a = [[] for i in range(n)]
for i in range(n - 1):
	b = [int(j) - 1 for j in input().split()]
	a[b[0]].append(b[1])
	a[b[1]].append(b[0])

def dfs(v):
	d = [-1 for i in range(n)]
	q = []
	d[v] = 0
	q.append(v)
	while len(q):
		v = q.pop()
		for i in a[v]:
			if d[i] == -1:
				d[i] = d[v] + 1
				q.append(i)
	return d
c1 = dfs(0)
c2 = dfs(n - 1)
c = 0
for i in range(n):
	if c1[i] > c2[i]:
		c += 1
if c >= n / 2:
	print('Snuke')
else:
	print('Fennec')


from collections import *
input = open(0).readline
n = int(input())
e = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	e[a - 1].append(b - 1)
	e[b - 1].append(a - 1)
f = [0] * n
v = [1] + [0] * ~-n
q = deque([(0, 0)])
while q:
	(t, c) = q.pop()
	v[t] = 1
	f[t] = c
	for i in e[t]:
		if not v[i]:
			q.append((i, c + 1))
s = [0] * n
v = [0] * ~-n + [1]
q = deque([(n - 1, 0)])
while q:
	(t, c) = q.pop()
	v[t] = 1
	s[t] = c
	for i in e[t]:
		if not v[i]:
			q.append((i, c + 1))
a = b = 0
for (i, j) in zip(f, s):
	if i <= j:
		a += 1
	else:
		b += 1
if a > b:
	print('Fennec')
else:
	print('Snuke')


N = int(input())
tree = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = list(map(int, input().split()))
	a -= 1
	b -= 1
	tree[a].append(b)
	tree[b].append(a)

def dist(n, lis):
	lis[n] = 0
	node = [n]
	while node:
		s = node.pop()
		d = lis[s]
		for t in tree[s]:
			if lis[t] != -1:
				continue
			lis[t] = d + 1
			node.append(t)
	return lis
from_feneck = dist(0, [-1] * N)
from_Snuke = dist(N - 1, [-1] * N)
feneck = 0
for (i, j) in zip(from_feneck, from_Snuke):
	if i <= j:
		feneck += 1
	else:
		feneck -= 1
if feneck <= 0:
	print('Snuke')
else:
	print('Fennec')


from networkx import *
((N,), *t) = map(str.split, open(0))
G = Graph(t)
s = shortest_path_length
x = s(G, '1')
y = s(G, N)
print('FSennunkeec'[sum((x[k] > y[k] for k in x)) * 2 >= int(N)::2])


import sys
p = []
path = [0 for i in range(10 ** 5 + 1)]

def main():
	sys.setrecursionlimit(1000000)
	N = int(input())
	e = [[] for i in range(N)]
	for i in range(N - 1):
		(a, b) = map(int, input().split())
		a -= 1
		b -= 1
		e[a].append(b)
		e[b].append(a)
	col = [-1 for i in range(N)]
	col[0] = 0

	def dfs(n, c):
		global p
		if n == N - 1:
			p = path
		path[c] = n
		for v in e[n]:
			if col[v] == -1:
				col[v] = c + 1
				dfs(v, c + 1)
				if p:
					return
	dfs(0, 0)
	t = col[N - 1] + 1
	if t % 2 == 0:
		sn = p[t // 2]
	else:
		sn = p[t // 2 + 1]
	colfn = [-1 for i in range(N)]
	colfn[0] = 0

	def dfs2(n, c):
		for v in e[n]:
			if v == sn:
				continue
			elif colfn[v] == -1:
				colfn[v] = c + 1
				dfs2(v, c + 1)
	dfs2(0, 0)
	fennec = -1
	for i in range(N):
		if colfn[i] != -1:
			fennec += 1
	snuke = N - fennec - 2
	if fennec > snuke:
		print('Fennec')
	else:
		print('Snuke')
main()


from collections import deque

def bfs(s: int, d: 'List[int]') -> None:
	q = deque([s])
	while q:
		v = q.popleft()
		for u in G[v]:
			if not d[u]:
				q.append(u)
				d[u] = d[v] + 1

def main():
	global G, DB, DW
	(N, *E) = map(int, open(0).read().split())
	G = [[] for _ in range(N + 1)]
	for i in range(0, (N - 1) * 2, 2):
		(v, u) = E[i:i + 2]
		G[v] += [u]
		G[u] += [v]
	(DB, DW) = ([0] * (N + 1), [0] * (N + 1))
	(bfs(1, DB), bfs(N, DW))
	(b, w) = (0, 0)
	for (i, j) in zip(DB[1:], DW[1:]):
		if i <= j:
			b += 1
		else:
			w += 1
	flg = b > w
	print('Fennec' if flg else 'Snuke')
main()


N = int(input())
from collections import defaultdict, deque
branch = defaultdict(set)
for i in range(N - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	branch[a] |= {b}
	branch[b] |= {a}
check = {0}
bef = [-2] * N
bef[0] = -1
dist = [float('inf')] * N
dist[0] = 0
while len(check) > 0:
	now = check.pop()
	for nex in branch[now]:
		if bef[nex] == -2:
			bef[nex] = now
			check |= {nex}
			dist[nex] = dist[now] + 1
NG = set()
OK = {0}
now = N - 1
checked = {0}
for i in range((1 + dist[N - 1]) // 2):
	NG |= {now}
	now = bef[now]
checked |= NG
for i in range(N):
	if i in checked:
		continue
	else:
		visited = {i}
		now = i
		while True:
			now = bef[now]
			visited |= {now}
			if now in NG:
				NG |= visited
				checked |= visited
				break
			elif now in OK:
				OK |= visited
				checked |= visited
				break
if len(OK) > N // 2:
	print('Fennec')
else:
	print('Snuke')


import sys
from collections import deque
inf = float('inf')

def solve(N: int, a: 'List[int]', b: 'List[int]'):
	adj = [set() for _ in range(N)]
	for (u, v) in zip(a, b):
		adj[u].add(v)
		adj[v].add(u)
	dist_F = [inf for _ in range(N)]
	dist_F[0] = 0
	dist_S = [inf for _ in range(N)]
	dist_S[N - 1] = 0
	Q = deque([(0, 0)], N)
	while len(Q) > 0:
		(du, u) = Q.pop()
		for v in adj[u]:
			if dist_F[v] < inf:
				continue
			dist_F[v] = du + 1
			Q.append((du + 1, v))
	Q = deque([(0, N - 1)], N)
	while len(Q) > 0:
		(du, u) = Q.pop()
		for v in adj[u]:
			if dist_S[v] < inf:
				continue
			dist_S[v] = du + 1
			Q.append((du + 1, v))
	c_S = 0
	c_F = 0
	for (df, ds) in zip(dist_F, dist_S):
		if df <= ds:
			c_F += 1
		else:
			c_S += 1
	if c_F <= c_S:
		print('Snuke')
	else:
		print('Fennec')
	return

def main():

	def iterate_tokens():
		for line in sys.stdin:
			for word in line.split():
				yield word
	tokens = iterate_tokens()
	N = int(next(tokens))
	a = [int()] * (N - 1)
	b = [int()] * (N - 1)
	for i in range(N - 1):
		a[i] = int(next(tokens)) - 1
		b[i] = int(next(tokens)) - 1
	solve(N, a, b)

def __starting_point():
	main()
__starting_point()


def read_data():
	N = int(input())
	Es = [[] for i in range(N)]
	for i in range(N - 1):
		(a, b) = map(int, input().split())
		Es[a - 1].append(b - 1)
		Es[b - 1].append(a - 1)
	return (N, Es)

def solve(N, Es):
	if N == 2:
		return 'Snuke'
	visited = [0] * N
	f1 = [0]
	fN = [N - 1]
	visited[0] = 1
	visited[N - 1] = -1
	while f1 or fN:
		new_f1 = []
		for v in f1:
			for u in Es[v]:
				if visited[u]:
					continue
				visited[u] = 1
				new_f1.append(u)
		f1 = new_f1
		new_fN = []
		for v in fN:
			for u in Es[v]:
				if visited[u]:
					continue
				visited[u] = -1
				new_fN.append(u)
		fN = new_fN
	if sum(visited) > 0:
		return 'Fennec'
	else:
		return 'Snuke'
(N, Es) = read_data()
print(solve(N, Es))


from collections import deque
n = int(input())
board = [0] * n
edge = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	edge[a - 1].append(b - 1)
	edge[b - 1].append(a - 1)
q = deque()
q.append((0, 1))
q.append((-1, -1))
while q:
	(from_, color) = q.popleft()
	if board[from_] != 0:
		continue
	board[from_] = color
	for i in edge[from_]:
		q.append((i, color))
if sum(board) > 0:
	print('Fennec')
else:
	print('Snuke')


import sys
sys.setrecursionlimit(10 ** 6)

class Node:

	def __init__(self, num):
		self.num = num
		self.v = 1
		self.parent = 0
		self.deep = None

def LI():
	return list(map(int, input().split()))
N = int(input())
AB = [LI() for _ in range(N - 1)]
link = [[] for _ in range(N + 1)]
for (a, b) in AB:
	link[a].append(b)
	link[b].append(a)
nodes = [Node(i) for i in range(N + 1)]

def create_tree(parent):
	for child in link[parent.num]:
		if child == parent.parent:
			continue
		node = nodes[child]
		node.parent = parent.num
		node.deep = parent.deep + 1
		create_tree(node)
		parent.v += node.v

def main():
	nodes[1].deep = 1
	create_tree(nodes[1])
	x = (nodes[N].deep - nodes[1].deep - 1) // 2
	v = nodes[N]
	for _ in range(x):
		v = nodes[v.parent]
	snuke = v.v
	fennec = N - snuke
	ans = 'Fennec' if fennec > snuke else 'Snuke'
	print(ans)
main()


from collections import defaultdict
N = int(input())
M = defaultdict(list)
for i in range(N - 1):
	(a, b) = map(int, input().split())
	M[a - 1].append(b - 1)
	M[b - 1].append(a - 1)

def bfs(s):
	res = [-1 for x in range(N)]
	res[s] = 0
	queue = [s]
	while queue:
		np = queue.pop()
		for nx in M[np]:
			if res[nx] < 0:
				res[nx] = res[np] + 1
				queue.append(nx)
	return res
ans0 = bfs(0)
ansN = bfs(N - 1)
cnt = 0
for i in range(N):
	if ans0[i] <= ansN[i]:
		cnt += 1
if cnt > N / 2:
	print('Fennec')
else:
	print('Snuke')


import heapq

def dijkstra(v, s, path):
	inf = float('inf')
	d = [inf for i in range(v)]
	d[s] = 0
	q = [[0, s]]
	heapq.heapify(q)
	while q:
		p = heapq.heappop(q)
		if d[p[1]] < p[0]:
			continue
		for i in range(len(path[p[1]])):
			if d[path[p[1]][i][1]] > d[p[1]] + path[p[1]][i][0]:
				d[path[p[1]][i][1]] = d[p[1]] + path[p[1]][i][0]
				heapq.heappush(q, [d[path[p[1]][i][1]], path[p[1]][i][1]])
	return d

def path_recovery(e, d, path):
	route = [e]
	a = d[e]
	while a != 0:
		for i in range(len(path[e])):
			if d[path[e][i][1]] + path[e][i][0] == a:
				route.append(path[e][i][1])
				a -= path[e][i][0]
				e = path[e][i][1]
				break
	route.reverse()
	return route

class UnionFind:

	def __init__(self, n):
		self.par = [-1] * n
		self.rank = [0] * n

	def find(self, x):
		if self.par[x] < 0:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x != y:
			if self.rank[x] < self.rank[y]:
				(x, y) = (y, x)
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1
			self.par[x] += self.par[y]
			self.par[y] = x

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def size(self, x):
		return -self.par[self.find(x)]
n = int(input())
l = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	l[a - 1].append([1, b - 1])
	l[b - 1].append([1, a - 1])
d = dijkstra(n, 0, l)
p = path_recovery(n - 1, d, l)
x = p[(len(p) - 1) // 2]
y = p[(len(p) - 1) // 2 + 1]
for i in range(len(l[x])):
	if l[x][i][1] == y:
		l[x].pop(i)
		break
for i in range(len(l[y])):
	if l[y][i][1] == x:
		l[y].pop(i)
		break
u = UnionFind(n)
for i in range(len(l)):
	for j in range(len(l[i])):
		u.unite(i, l[i][j][1])
if u.size(0) > u.size(n - 1):
	print('Fennec')
else:
	print('Snuke')


class UnionFind:

	def __init__(self, n):
		self.par = [-1 for i in range(n + 1)]
		self.rank = [0] * (n + 1)

	def find(self, x):
		if self.par[x] < 0:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if not x == y:
			if self.rank[x] < self.rank[y]:
				self.par[y] += self.par[x]
				self.par[x] = y
			else:
				self.par[x] += self.par[y]
				self.par[y] = x
				if self.rank[x] == self.rank[y]:
					self.rank[x] += 1

	def same_check(self, x, y):
		return self.find(x) == self.find(y)

def main():
	import sys
	input = sys.stdin.readline
	N = int(input())
	from collections import defaultdict, deque
	G = defaultdict(list)
	D = []
	for i in range(N - 1):
		(a, b) = map(int, input().split())
		D.append([a, b])
		G[a].append(b)
		G[b].append(a)
	que = deque()
	que.append(1)
	visited = {}
	oya = [-1] * (10 ** 5 + 1)
	while que != deque():
		v = que.pop()
		visited[v] = 1
		if v == N:
			break
		else:
			for i in G[v]:
				if not i in visited:
					oya[i] = v
					que.append(i)
	now = N
	path = []
	while now != -1:
		path.append(now)
		now = oya[now]
	path = path[::-1]
	L = len(path)
	if L % 2 == 0:
		(d1, d2) = (path[L // 2 - 1], path[L // 2])
	else:
		(d1, d2) = (path[L // 2], path[L // 2 + 1])
	G2 = UnionFind(N)
	for i in D:
		(a, b) = i
		if not {a, b} == {d1, d2}:
			G2.union(a, b)
	one = -G2.par[G2.find(1)]
	enu = -G2.par[G2.find(N)]
	if one > enu:
		print('Fennec')
	else:
		print('Snuke')
main()


import sys
input = sys.stdin.readline
N = int(input())
tree = [[] for i in range(N + 1)]
for i in range(N - 1):
	(a, b) = list(map(int, input().split()))
	tree[a].append(b)
	tree[b].append(a)
dist_fennec = [100001] * (N + 1)
dist_snuke = [100001] * (N + 1)
q = [1]
dist_fennec[1] = 0
while q:
	now = q.pop()
	for next in tree[now]:
		if dist_fennec[next] == 100001:
			dist_fennec[next] = dist_fennec[now] + 1
			q.append(next)
q = [N]
dist_snuke[N] = 0
while q:
	now = q.pop()
	for next in tree[now]:
		if dist_snuke[next] == 100001:
			dist_snuke[next] = dist_snuke[now] + 1
			q.append(next)
(fennec, snuke) = (0, 0)
for i in range(1, N + 1):
	if dist_snuke[i] >= dist_fennec[i]:
		fennec += 1
	else:
		snuke += 1
if fennec > snuke:
	print('Fennec')
else:
	print('Snuke')


import heapq
N = int(input())
AB = [[int(_) for _ in input().split()] for _ in range(N - 1)]
G = {}
for (a, b) in AB:
	a -= 1
	b -= 1
	G[a] = G.get(a, set())
	G[b] = G.get(b, set())
	G[a].add(b)
	G[b].add(a)

def dijkstra_stack(i):
	D = [-1] * N
	D[i] = 0
	stack = [i]
	while True:
		i = stack.pop(0)
		update = False
		for j in G[i]:
			if D[j] == -1:
				update = True
				D[j] = D[i] + 1
				stack += [j]
		if not stack:
			break
	return D
D_Fennec = dijkstra_stack(0)
D_Snuke = dijkstra_stack(N - 1)
f = 0
s = 0
for i in range(N):
	if D_Fennec[i] <= D_Snuke[i]:
		f += 1
	else:
		s += 1
if f > s:
	print('Fennec')
else:
	print('Snuke')


from collections import deque

def dfs(graph, start):
	stack = deque()
	costs = [0] * (N + 1)
	stack.append([start, 0])
	costs[start] = -1
	while stack:
		(a, cost) = stack.popleft()
		for b in graph[a].keys():
			if not costs[b]:
				stack.append([b, cost + 1])
				costs[b] = cost + 1
	return costs
N = int(input())
graph = {}
for i in range(N - 1):
	(a, b) = map(int, input().split())
	if a not in graph:
		graph[a] = {}
	if b not in graph:
		graph[b] = {}
	graph[a][b] = graph[b][a] = 1
f_costs = dfs(graph, 1)
s_costs = dfs(graph, N)
f_cnt = 1
for i in range(2, N):
	if f_costs[i] <= s_costs[i]:
		f_cnt += 1
print('Fennec' if f_cnt > N - f_cnt else 'Snuke')


import sys
sys.setrecursionlimit(10 ** 8)
N = int(input())
G = [[] for i in range(N)]
F = [0 for i in range(N)]
A = []
for i in range(N - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	G[a].append(b)
	G[b].append(a)
	A.append([a, b])

def dfs(s, R):
	F[s] = 1
	if s == N - 1:
		return [s]
	else:
		for n in G[s]:
			if F[n] == 0:
				k = dfs(n, R)
				if len(k) != 0:
					k.append(s)
					return k
	return []
root = dfs(0, [])
p = root[::-1][len(root) // 2 + len(root) % 2 - 1]
q = root[::-1][len(root) // 2 + len(root) % 2]

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
uf = UnionFind(N)
for i in range(N - 1):
	(a, b) = map(int, A[i])
	if a == p and b == q:
		continue
	if a == q and b == p:
		continue
	uf.union(a, b)
scoreA = uf.size(0)
scoreB = N - scoreA
if scoreA > scoreB:
	print('Fennec')
else:
	print('Snuke')


import sys
sys.setrecursionlimit(10 ** 8)
from heapq import heappush, heappop
inf = 10 ** 10
n = int(input())
l = [[] for i in range(n + 1)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	l[a].append(b)
	l[b].append(a)
prev = [-1 for i in range(n + 1)]

def dijkstra(s):
	q = [(0, s)]
	dist = [inf] * (n + 1)
	dist[s] = 0
	while q:
		(c, v) = heappop(q)
		if dist[v] < c:
			continue
		for i in l[v]:
			t = i
			cost = 1
			if dist[v] + cost < dist[t]:
				dist[t] = dist[v] + cost
				prev[t] = v
				heappush(q, [dist[t], t])
	return dist
d = dijkstra(1)
p = [n]
num = n
next = [-1 for i in range(n + 1)]
while num != 1:
	num1 = prev[num]
	next[num1] = num
	p.append(num1)
	num = num1
countp = [0]
countf = [0]

def dfs(x, y):
	for i in l[x]:
		if prev[x] != i and next[x] != i:
			if y == 1:
				countp[0] += 1
			else:
				countf[0] += 1
			prev[i] = x
			dfs(i, y)
p = p[::-1]
num = len(p)
num1 = (num - 1) // 2 + 1
for i in range(num1):
	countp[0] += 1
	dfs(p[i], 1)
for i in range(num1, num):
	countf[0] += 1
	dfs(p[i], 0)
if countp[0] > countf[0]:
	print('Fennec')
else:
	print('Snuke')


from collections import deque
N = int(input())
INF = 100001
G = [[] for i in range(N)]
(dist1, dist2) = ([INF for j in range(N)], [INF for k in range(N)])

def bfs(s, d):
	(check, q) = ([0 for i in range(N)], deque())
	(check[s], d[s]) = (1, 0)
	q.append(s)
	while len(q) != 0:
		u = q.popleft()
		for i in G[u]:
			if check[i] == 0:
				(check[i], d[i]) = (1, d[u] + 1)
				q.append(i)
		check[u] = 2

def main():
	for i in range(N - 1):
		(a, b) = list(map(int, input().split()))
		G[a - 1].append(b - 1)
		G[b - 1].append(a - 1)
	bfs(0, dist1)
	bfs(N - 1, dist2)
	cnt_f = 0
	for i in range(N):
		if dist1[i] <= dist2[i]:
			cnt_f += 1
	if N // 2 < cnt_f:
		print('Fennec')
	else:
		print('Snuke')

def __starting_point():
	main()
__starting_point()


def bfs(n, links):
	painted = set()
	queues = [{0}, {n - 1}]
	scores = [0, 0]
	i = 0
	while True:
		nq = set()
		for v in queues[i]:
			cq = links[v] - painted
			if cq:
				painted.update(cq)
				nq.update(cq)
		queues[i] = nq
		scores[i] += len(nq)
		if not nq:
			scores[i ^ 1] = n - scores[i]
			break
		i ^= 1
	return scores[0] > scores[1]
n = int(input())
links = [set() for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	links[a].add(b)
	links[b].add(a)
print('Fennec' if bfs(n, links) else 'Snuke')


from collections import deque

def dfs(graph, start, goal):
	s_stack = deque()
	g_stack = deque()
	visited = [0 for i in range(N + 1)]
	s_stack.append([start, 0])
	g_stack.append([goal, 0])
	visited[start] = 1
	visited[goal] = 1
	s_cnt = 1
	g_cnt = 1
	round = 0
	while s_stack or g_stack:
		while s_stack:
			(a, cost) = s_stack.popleft()
			if cost > round:
				s_stack.appendleft([a, cost])
				break
			for b in graph[a].keys():
				if not visited[b]:
					s_stack.append([b, cost + 1])
					visited[b] += 1
					s_cnt += 1
		while g_stack:
			(a, cost) = g_stack.popleft()
			if cost > round:
				g_stack.appendleft([a, cost])
				break
			for b in graph[a].keys():
				if not visited[b]:
					g_stack.append([b, cost + 1])
					visited[b] += 1
					g_cnt += 1
		round += 1
	return s_cnt > g_cnt
N = int(input())
graph = {}
for i in range(N - 1):
	(a, b) = map(int, input().split())
	if a not in graph:
		graph[a] = {}
	if b not in graph:
		graph[b] = {}
	graph[a][b] = graph[b][a] = 1
print('Fennec' if dfs(graph, 1, N) else 'Snuke')


n = int(input())
edges = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	edges[a].append(b)
	edges[b].append(a)

def bfs(v):
	q = []
	depth = [n] * n
	q.append(v)
	depth[v] = 0
	i = 0
	while i < len(q):
		x = q[i]
		d = depth[x]
		for e in edges[x]:
			if depth[e] == n:
				depth[e] = d + 1
				q.append(e)
		i += 1
	return depth
d1 = bfs(0)
d2 = bfs(n - 1)
c = 0
for i in range(n):
	if d1[i] <= d2[i]:
		c += 1
if 2 * c > n:
	print('Fennec')
else:
	print('Snuke')


from collections import defaultdict

def inpl():
	return [int(i) for i in input().split()]
path = defaultdict(lambda : [])
N = int(input())
for _ in range(N - 1):
	(a, b) = inpl()
	path[a].append(b)
	path[b].append(a)
inf = float('inf')
ctr = 1
now = {1}
distF = [inf for _ in range(N + 1)]
distF[1] = 0
while True:
	for na in now.copy():
		na = now.pop()
		for nb in path[na]:
			if distF[nb] > distF[na] + 1:
				distF[nb] = distF[na] + 1
				now.add(nb)
				ctr += 1
	if ctr >= N:
		break
ctr = 1
now = {N}
distS = [inf for _ in range(N + 1)]
distS[N] = 0
while True:
	for na in now.copy():
		na = now.pop()
		for nb in path[na]:
			if distS[nb] > distS[na] + 1:
				distS[nb] = distS[na] + 1
				now.add(nb)
				ctr += 1
	if ctr >= N:
		break
D = distF[N]
for i in range(1, N + 1):
	if distF[i] == D // 2 and distF[i] + distS[i] == D:
		St = i
	if distF[i] == D // 2 + 1 and distF[i] + distS[i] == D:
		En = i
path[St].remove(En)
path[En].remove(St)
ctr = 1
now = {1}
distF = [inf for _ in range(N + 1)]
distF[1] = 0
ctr1 = 0
while ctr1 != ctr:
	ctr1 = ctr
	for na in now.copy():
		na = now.pop()
		for nb in path[na]:
			if distF[nb] > distF[na] + 1:
				distF[nb] = distF[na] + 1
				now.add(nb)
				ctr += 1
if 2 * ctr > N:
	print('Fennec')
else:
	print('Snuke')


def black(now):
	nextb = []
	while now:
		a = now.pop()
		while desn[a]:
			go = desn[a].pop()
			if nodes[go] == 'N':
				nodes[go] = 'B'
				nextb.append(go)
	return nextb

def white(now):
	nextb = []
	while now:
		a = now.pop()
		while desn[a]:
			go = desn[a].pop()
			if nodes[go] == 'N':
				nodes[go] = 'W'
				nextb.append(go)
	return nextb
n = int(input())
nodes = []
desn = []
for i in range(0, n + 1):
	nodes.append('N')
	desn.append([])
nodes[1] = 'B'
nodes[n] = 'W'
for i in range(0, n - 1):
	(b, c) = (int(i) for i in input().split())
	desn[b].append(c)
	desn[c].append(b)
nowb = [1]
noww = [n]
while nowb or noww:
	nowb = black(nowb)
	noww = white(noww)
b = nodes.count('B')
w = nodes.count('W')
if b > w:
	print('Fennec')
else:
	print('Snuke')


import heapq
import sys
input = sys.stdin.readline

def dijlstra_heap(N, s, edge):
	d = [float('inf')] * N
	used = [True] * N
	d[s] = 0
	edgelist = []
	for (a, b) in edge[s]:
		heapq.heappush(edgelist, a * 10 ** 6 + b)
	while len(edgelist):
		minedge = heapq.heappop(edgelist)
		if not used[minedge % 10 ** 6]:
			continue
		v = minedge % 10 ** 6
		d[v] = minedge // 10 ** 6
		used[v] = False
		for e in edge[v]:
			if used[e[1]]:
				heapq.heappush(edgelist, (e[0] + d[v]) * 10 ** 6 + e[1])
	return d

def main():
	N = int(input())
	edge = [[] for i in range(N)]
	for i in range(N - 1):
		(a, b) = map(int, input().split())
		a -= 1
		b -= 1
		edge[a].append([1, b])
		edge[b].append([1, a])
	d0 = dijlstra_heap(N, 0, edge)
	dn = dijlstra_heap(N, N - 1, edge)
	f_cnt = 0
	s_cnt = 0
	for i in range(N):
		if d0[i] <= dn[i]:
			f_cnt += 1
		else:
			s_cnt += 1
	if f_cnt > s_cnt:
		print('Fennec')
	else:
		print('Snuke')

def __starting_point():
	main()
__starting_point()


ai = lambda : list(map(int, input().split()))
ai_ = lambda : [int(x) - 1 for x in input().split()]
n = int(input())
path = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = ai_()
	path[a].append(b)
	path[b].append(a)
from collections import deque
q = deque()
q.append(0)
d1 = [float('inf') for _ in range(n)]
d1[0] = 0
w = set()
while q:
	v = q.popleft()
	w.add(v)
	for vv in path[v]:
		if vv not in w:
			d1[vv] = d1[v] + 1
			q.append(vv)
q = deque()
q.append(n - 1)
dn = [float('inf') for _ in range(n)]
dn[n - 1] = 0
w = set()
while q:
	v = q.popleft()
	w.add(v)
	for vv in path[v]:
		if vv not in w:
			dn[vv] = dn[v] + 1
			q.append(vv)
d = [1 if d1[v] <= dn[v] else -1 for v in range(n)]
if sum(d) > 0:
	print('Fennec')
else:
	print('Snuke')


n = int(input())
nl = {}
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	if a - 1 in nl:
		nl[a - 1].append(b - 1)
	else:
		nl[a - 1] = [b - 1]
	if b - 1 in nl:
		nl[b - 1].append(a - 1)
	else:
		nl[b - 1] = [a - 1]
fenl = [-1 for _ in range(n)]
sunl = [-1 for _ in range(n)]
fenl[0] = 1
sunl[-1] = 1
now = [0]
while now:
	tmp = []
	for _n in now:
		for nxt in nl[_n]:
			if fenl[nxt] == -1:
				tmp.append(nxt)
				fenl[nxt] = fenl[_n] + 1
	now = tmp
now = [n - 1]
while now:
	tmp = []
	for _n in now:
		for nxt in nl[_n]:
			if sunl[nxt] == -1:
				tmp.append(nxt)
				sunl[nxt] = sunl[_n] + 1
	now = tmp
(fm, sm) = (0, 0)
for i in range(n):
	if fenl[i] <= sunl[i]:
		fm += 1
	else:
		sm += 1
if fm <= sm:
	print('Snuke')
else:
	print('Fennec')


from collections import deque

def nearlist(N, LIST):
	NEAR = [set() for _ in range(N)]
	for (a, b) in LIST:
		NEAR[a - 1].add(b - 1)
		NEAR[b - 1].add(a - 1)
	return NEAR

def bfs(S):
	(dist, flag) = ([-1] * n, [0] * n)
	(dist[S], flag[S]) = (0, 1)
	que = deque([S])
	while que:
		q = que.popleft()
		for i in near[q]:
			if flag[i]:
				continue
			dist[i] = dist[q] + 1
			flag[i] = 1
			que.append(i)
	return dist
n = int(input())
ab = [list(map(int, input().split())) for _ in range(n - 1)]
near = nearlist(n, ab)
(fennec, snuke) = (bfs(0), bfs(n - 1))
ans = sum((fennec[i] <= snuke[i] for i in range(n)))
print('Fennec' if ans * 2 > n else 'Snuke')


from collections import deque
n = int(input())
graph = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	graph[a].append(b)
	graph[b].append(a)
distfrom1 = [-1] * n
distfromn = [-1] * n
distfrom1[0] = 0
distfromn[n - 1] = 0
d = deque([0])
while d:
	v = d.popleft()
	for i in graph[v]:
		if distfrom1[i] != -1:
			continue
		distfrom1[i] = distfrom1[v] + 1
		d.append(i)
d.append(n - 1)
while d:
	v = d.popleft()
	for i in graph[v]:
		if distfromn[i] != -1:
			continue
		distfromn[i] = distfromn[v] + 1
		d.append(i)
F = 0
for i in range(n):
	if distfrom1[i] <= distfromn[i]:
		F += 1
if F > n - F:
	print('Fennec')
else:
	print('Snuke')


from collections import deque
n = int(input())
edge = [[] for _ in range(n + 1)]
for _ in range(n - 1):
	(a, b) = list(map(int, input().split()))
	edge[a].append(b)
	edge[b].append(a)
inf = 10 ** 6
fvisited = [inf for _ in range(n + 1)]
fvisited[1] = 0
q = deque([1])
while len(q) > 0:
	s = q.popleft()
	for e in edge[s]:
		if fvisited[e] == inf:
			fvisited[e] = fvisited[s] + 1
			q.append(e)
svisited = [inf for _ in range(n + 1)]
svisited[n] = 0
q = deque([n])
while len(q) > 0:
	s = q.popleft()
	for e in edge[s]:
		if svisited[e] == inf:
			svisited[e] = svisited[s] + 1
			q.append(e)
fcnt = 0
scnt = 0
for i in range(1, n + 1):
	if fvisited[i] <= svisited[i]:
		fcnt += 1
	else:
		scnt += 1
if fcnt > scnt:
	print('Fennec')
else:
	print('Snuke')


import sys
sys.setrecursionlimit(2000000)
n = int(input())
p = []
for i in range(n - 1):
	p.append(list(map(int, input().split())) + [1])
l = [[] for i in range(n + 1)]
for pi in p:
	l[pi[0]].append([pi[0], pi[1]])
	l[pi[1]].append([pi[1], pi[0]])
kyo = [float('inf')] * (n + 1)
kyo[1] = 0
memo = [0] * (n + 1)
memo[1] = 1
ruto = []

def dfs(start, ruto):
	ruto.extend(l[start])
	memo[start] = 1
	while ruto:
		a = ruto.pop()
		if memo[a[1]] == 1:
			continue
		kyo[a[1]] = kyo[a[0]] + 1
		dfs(a[1], ruto)
	return
dfs(1, ruto)
nkyo = [float('inf')] * (n + 1)
nkyo[n] = 0
memo = [0] * (n + 1)
memo[n] = 1
ruto = []

def dfs(start, ruto):
	ruto.extend(l[start])
	memo[start] = 1
	while ruto:
		a = ruto.pop()
		if memo[a[1]] == 1:
			continue
		nkyo[a[1]] = nkyo[a[0]] + 1
		dfs(a[1], ruto)
	return
dfs(n, ruto)
iti = 0
nko = 0
for i in range(1, n + 1):
	if kyo[i] <= nkyo[i]:
		iti += 1
	else:
		nko += 1
if iti <= nko:
	print('Snuke')
else:
	print('Fennec')


import array, bisect, collections, copy, heapq, itertools, math, random, re, string, sys, time
sys.setrecursionlimit(10 ** 7)
INF = 10 ** 20
MOD = 10 ** 9 + 7

def II():
	return int(input())

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

def IAI(LINE):
	return [ILI() for __ in range(LINE)]

def IDI():
	return {key: value for (key, value) in ILI()}

def read():
	N = II()
	edges = collections.defaultdict(list)
	for __ in range(N - 1):
		(a, b) = ILI()
		edges[a].append(b)
		edges[b].append(a)
	return (N, edges)

def solve(N, edges):
	queue_from_f = set()
	queue_from_s = set()
	queue_from_f.add(1)
	queue_from_s.add(N)
	n_node_f = 1
	snuke_bool = True
	visited_f = [False] * (N + 1)
	visited_s = [False] * (N + 1)
	(visited_f[0], visited_f[1]) = (True, True)
	(visited_s[0], visited_s[N]) = (True, True)
	while len(queue_from_f) != 0:
		f_next_queue = set()
		for i in queue_from_f:
			next_point = edges[i]
			for point in next_point:
				if snuke_bool and point in queue_from_s:
					snuke_bool = False
					visited_f[point] = True
				if visited_f[point]:
					continue
				else:
					f_next_queue.add(point)
					visited_f[point] = True
		n_node_f += len(f_next_queue)
		queue_from_f = f_next_queue
		if snuke_bool:
			s_next_queue = set()
			for i in queue_from_s:
				next_point = edges[i]
				for point in next_point:
					if point in queue_from_f:
						visited_f[i] = True
						snuke_bool = False
						break
					if visited_s[point]:
						continue
					else:
						s_next_queue.add(point)
						visited_s[point] = True
			queue_from_s = s_next_queue
	if n_node_f > N // 2:
		ans = 'Fennec'
	else:
		ans = 'Snuke'
	return ans

def main():
	params = read()
	print(solve(*params))
main()


import sys

def main():
	sys.setrecursionlimit(1000000)
	buf = input()
	N = int(buf)
	a = []
	b = []
	for i in range(N - 1):
		buf = input()
		buflist = buf.split()
		a.append(int(buflist[0]) - 1)
		b.append(int(buflist[1]) - 1)
	graph = []
	for i in range(N):
		graph.append([])
	for i in range(N - 1):
		graph[a[i]].append(b[i])
		graph[b[i]].append(a[i])
	path = find_path(graph, 0, N - 1, [])
	split_point = (len(path) + 1) // 2
	fennec_base = path[0:split_point]
	snuke_base = path[split_point:len(path)]
	fennec_vertex_count = len(fennec_base)
	snuke_vertex_count = len(snuke_base)
	for (i, v) in enumerate(fennec_base):
		for j in graph[v]:
			if i != 0:
				if j == fennec_base[i - 1]:
					continue
			if i != len(fennec_base) - 1:
				if j == fennec_base[i + 1]:
					continue
			elif j == snuke_base[0]:
				continue
			fennec_vertex_count += get_vertex_count(graph, v, j)
	for (i, v) in enumerate(snuke_base):
		for j in graph[v]:
			if i != 0:
				if j == snuke_base[i - 1]:
					continue
			elif j == fennec_base[-1]:
				continue
			if i != len(snuke_base) - 1:
				if j == snuke_base[i + 1]:
					continue
			snuke_vertex_count += get_vertex_count(graph, v, j)
	if fennec_vertex_count > snuke_vertex_count:
		print('Fennec')
	else:
		print('Snuke')

def find_path(graph, current, target, path):
	path.append(current)
	if current == target:
		return path
	for i in graph[current]:
		if len(path) >= 2:
			if i == path[-2]:
				continue
		result = find_path(graph, i, target, path)
		if result:
			return path
	path.pop()
	return None

def get_vertex_count(graph, base, next):
	count = 1
	for i in graph[next]:
		if i == base:
			continue
		count += get_vertex_count(graph, next, i)
	return count
main()


from collections import deque

def bfs(start):
	queue = deque([start])
	visited = []
	while queue:
		label = queue.pop()
		visited.append(label)
		for v in d[label]:
			if tekazu[v] == float('inf'):
				tekazu[v] = tekazu[label] + 1
				queue.appendleft(v)
	return
n = int(input())
d = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	d[a - 1].append(b - 1)
	d[b - 1].append(a - 1)
tekazu = [float('inf') for _ in range(n)]
tekazu[0] = 0
bfs(0)
tekazu_Fennec = tekazu
tekazu = [float('inf') for _ in range(n)]
tekazu[-1] = 0
bfs(n - 1)
tekazu_Snuke = tekazu
Fennec = 0
Snuke = 0
for i in range(n):
	if tekazu_Fennec[i] <= tekazu_Snuke[i]:
		Fennec += 1
	else:
		Snuke += 1
if Fennec > Snuke:
	print('Fennec')
else:
	print('Snuke')


import sys
sys.setrecursionlimit(10 ** 5 + 100)

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

def read_int():
	return int(input())

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

def read_str():
	return input()
adj = []
p = []
state = []

def dfs(root, parent):
	state[root] = 1
	p[root] = parent
	for i in adj[root]:
		if i != parent:
			dfs(i, root)
	state[root] = 2

def get_size(root):
	res = 1
	for i in adj[root]:
		if i != p[root]:
			res += get_size(i)
	return res

def solve():
	global adj
	global p
	global state
	n = read_int()
	pairs = [read_int_list() for i in range(n - 1)]
	adj = [[] for i in range(n)]
	for (x, y) in pairs:
		x -= 1
		y -= 1
		adj[x].append(y)
		adj[y].append(x)
	state = [0] * n
	p = [-1] * n
	dfs(0, -1)
	j = n - 1
	q = []
	while j != 0:
		q.append(j)
		j = p[j]
	q.append(0)
	lq = len(q)
	half = lq // 2
	s = get_size(q[half - 1])
	if n - s > s:
		return 'Fennec'
	return 'Snuke'

def main():
	res = solve()
	print(res)
main()


N = int(input())
graph = [[] for i in range(N)]
for _ in range(N - 1):
	(a, b) = list(map(int, input().strip().split(' ')))
	graph[a - 1] += [b - 1]
	graph[b - 1] += [a - 1]
from collections import deque

def bfs(graph):
	q = deque([0])
	N = len(graph)
	visit = []
	parent = [-1] * N
	while q:
		v = q.popleft()
		visit += [v]
		for adj in graph[v]:
			if adj != parent[v]:
				parent[adj] = v
				q += [adj]
	return (visit, parent)
(visit, parent) = bfs(graph)
path = []
v = N - 1
path += [v]
while parent[v] != -1:
	v = parent[v]
	path += [v]
subtree = [0 for i in range(N)]
for i in range(1, len(visit) + 1):
	v = visit[-i]
	if graph[v] == [parent[v]]:
		subtree[v] = 1
	else:
		temp = 0
		for adj in graph[v]:
			if adj != parent[v]:
				temp += subtree[adj]
		subtree[v] = temp + 1
ca1 = 0
ca2 = 0
if len(path) % 2 == 0:
	stop = len(path) // 2 - 1
	stop = path[stop]
	ca2 = subtree[stop]
	ca1 = N - ca2
	if ca1 >= ca2 + 1:
		print('Fennec')
	else:
		print('Snuke')
else:
	stop = len(path) // 2 - 1
	stop = path[stop]
	ca2 = subtree[stop]
	ca1 = N - ca2
	if ca1 >= ca2 + 1:
		print('Fennec')
	else:
		print('Snuke')


import sys
from collections import deque

def solve(N: int, path):
	(f, s) = ([1], [N])
	black = set([1])
	white = set([N])
	while True:
		fn = []
		for ff in f:
			for fnext in path[ff]:
				if fnext not in white and fnext not in black:
					black.add(fnext)
					fn.append(fnext)
		f = fn
		sn = []
		for ss in s:
			for snext in path[ss]:
				if snext not in white and snext not in black:
					white.add(snext)
					sn.append(snext)
		s = sn
		if not s and (not f):
			break
	print('Fennec' if len(black) > len(white) else 'Snuke')
	return

def main():

	def iterate_tokens():
		for line in sys.stdin:
			for word in line.split():
				yield word
	tokens = iterate_tokens()
	N = int(next(tokens))
	path = {}
	for i in range(N - 1):
		a = int(next(tokens))
		b = int(next(tokens))
		if a in path:
			path[a].append(b)
		else:
			path[a] = [b]
		if b in path:
			path[b].append(a)
		else:
			path[b] = [a]
	solve(N, path)
main()


import sys
read = sys.stdin.read
readline = sys.stdin.readline
(n, *ab) = map(int, read().split())
m = iter(ab)
g = [[] for _ in range(n)]
for (a, b) in zip(m, m):
	g[a - 1].append(b - 1)
	g[b - 1].append(a - 1)

def dist(g, start):
	n = len(g)
	dist = [-1] * n
	q = [start]
	dist[start] = 0
	while q:
		v = q.pop()
		for c in g[v]:
			if dist[c] == -1:
				dist[c] = dist[v] + 1
				q.append(c)
	return dist
df = dist(g, 0)
ds = dist(g, n - 1)
cnt = 0
for (i, j) in zip(df, ds):
	if i <= j:
		cnt += 1
	else:
		cnt -= 1
if cnt >= 1:
	print('Fennec')
else:
	print('Snuke')


N = int(input())
edge = [[] * N for _ in range(N)]
for _ in range(N - 1):
	(go, to) = map(int, input().split())
	go -= 1
	to -= 1
	edge[go].append(to)
	edge[to].append(go)
from collections import deque
que = deque(maxlen=N)
que.append([0, 0])
dist0 = [None] * N
distn = [None] * N
while que:
	v = que.popleft()
	c = v[0]
	d = v[1]
	for i in edge[c]:
		if dist0[i] is None:
			dist0[i] = d + 1
			que.append([i, d + 1])
que.append([N - 1, 0])
while que:
	v = que.popleft()
	c = v[0]
	d = v[1]
	for i in edge[c]:
		if distn[i] is None:
			distn[i] = d + 1
			que.append([i, d + 1])
w = b = 0
for (d1, dn) in zip(dist0, distn):
	if d1 <= dn:
		b += 1
	else:
		w += 1
print('Fennec' if b - w > 0 else 'Snuke')


def read_data():
	N = int(input())
	Es = [[] for i in range(N)]
	for i in range(N - 1):
		(a, b) = map(int, input().split())
		Es[a - 1].append(b - 1)
		Es[b - 1].append(a - 1)
	return (N, Es)

def solve(N, Es):
	if N == 2:
		return 'Snuke'
	path = find_path(N, 0, N - 1, Es)
	len_path = len(path)
	a = (len_path - 1) // 2
	b = a + 1
	p1 = path[a]
	p2 = path[b]
	e1 = count_edges(N, p1, p2, Es)
	e2 = N - e1
	if e1 > e2:
		return 'Fennec'
	else:
		return 'Snuke'

def find_path(N, s, g, Es):
	stack = [(s, 0)]
	path = []
	visited = [False] * N
	visited[s] = True
	while True:
		(v, d) = stack[-1]
		if path and path[-1][0] == v:
			stack.pop()
			path.pop()
			continue
		if path and path[-1][1] >= d:
			path.pop()
		path.append((v, d))
		for u in Es[v]:
			if visited[u]:
				continue
			stack.append((u, d + 1))
			visited[u] = True
			if u == g:
				path = [p for (p, depth) in path] + [g]
				return path

def count_edges(N, p1, p2, Es):
	stack = [p1]
	visited = [False] * N
	visited[p1] = True
	visited[p2] = True
	count = 0
	while stack:
		v = stack.pop()
		count += 1
		for u in Es[v]:
			if visited[u]:
				continue
			stack.append(u)
			visited[u] = True
	return count
(N, Es) = read_data()
print(solve(N, Es))


import sys
sys.setrecursionlimit(100000)
N = int(input())
G = [[] for i in range(N)]
for i in range(N - 1):
	(a, b) = (int(i) for i in input().split())
	G[a - 1].append(b - 1)
	G[b - 1].append(a - 1)
prev = [-1] * N

def DFS(start):
	res = 0
	for u in G[start]:
		if u != prev[start]:
			prev[u] = start
			res += DFS(u)
	return res + 1
DFS(0)
start = N - 1
path = [N - 1]
while True:
	path.append(prev[start])
	start = prev[start]
	if start == 0:
		break
path.reverse()
num = len(path)
(c, d) = (path[(num + 1) // 2 - 1], path[(num + 1) // 2])
G[c].remove(d)
G[d].remove(c)
prev = [-1] * N
DFS0 = DFS(0)
prev = [-1] * N
if DFS0 > DFS(N - 1):
	print('Fennec')
else:
	print('Snuke')


from heapq import heappop, heappush
N = int(input())
L = [[] for i in range(N + 1)]
Fd = [float('inf') for i in range(N + 1)]
Sd = [float('inf') for i in range(N + 1)]
Fd[1] = 0
Sd[N] = 0
for i in range(N - 1):
	(a, b) = list(map(int, input().split()))
	L[a].append(b)
	L[b].append(a)
Q = []
heappush(Q, 1)
while Q:
	n = heappop(Q)
	d = Fd[n]
	for x in L[n]:
		if Fd[x] == float('inf'):
			Fd[x] = d + 1
			heappush(Q, x)
Q = []
heappush(Q, N)
while Q:
	n = heappop(Q)
	d = Sd[n]
	for x in L[n]:
		if Sd[x] == float('inf'):
			Sd[x] = d + 1
			heappush(Q, x)
f = 0
s = 0
for i in range(1, N + 1):
	if Fd[i] <= Sd[i]:
		f += 1
	else:
		s += 1
if f > s:
	print('Fennec')
else:
	print('Snuke')


from sys import setrecursionlimit
setrecursionlimit(10000000)

def solve():
	N = int(input())
	adj = [list() for _ in range(N)]
	for _ in range(N - 1):
		(a, b) = map(int, input().split())
		adj[a - 1].append(b - 1)
		adj[b - 1].append(a - 1)
	goal = N - 1
	path = [0]
	candidates = [adj[0][:]]
	while path[-1] != goal:
		while not candidates[-1]:
			candidates.pop()
			path.pop()
		u = candidates[-1].pop()
		candidates.append([n for n in adj[u] if n != path[-1]])
		path.append(u)
	black = path[(len(path) - 1) // 2]
	white = path[(len(path) - 1) // 2 + 1]
	path = [black]
	candidates = [[n for n in adj[black] if n != white]]
	cnt = 0
	try:
		while True:
			while not candidates[-1]:
				cnt += 1
				candidates.pop()
				path.pop()
			u = candidates[-1].pop()
			candidates.append([n for n in adj[u] if n != path[-1]])
			path.append(u)
	except IndexError:
		pass
	bscore = cnt
	print('Fennec' if bscore * 2 > N else 'Snuke')

def __starting_point():
	solve()
__starting_point()


N = int(input())
e_list = [[] for i in range(N)]
for i in range(N - 1):
	(a, b) = list(map(int, input().split()))
	(a, b) = (a - 1, b - 1)
	e_list[a].append(b)
	e_list[b].append(a)
vi = 0
from collections import deque
Q = deque([vi])
checked_list = [False for i in range(N)]
checked_list[vi] = True
prev_list = [-1 for i in range(N)]
min_path_list = [10 ** 27 for i in range(N)]
min_path_list[vi] = 0
while len(Q) > 0:
	v = Q.pop()
	for v1 in e_list[v]:
		if not checked_list[v1]:
			checked_list[v1] = True
			Q.appendleft(v1)
			prev_list[v1] = v
			min_path_list[v1] = min(min_path_list[v1], min_path_list[v] + 1)
path = [N - 1]
v = N - 1
while prev_list[v] != -1:
	path.append(prev_list[v])
	v = prev_list[v]
a = path[(min_path_list[N - 1] - 1) // 2]
b = path[(min_path_list[N - 1] - 1) // 2 + 1]
for i in range(len(e_list[a])):
	if e_list[a][i] == b:
		break
del e_list[a][i]
for i in range(len(e_list[b])):
	if e_list[b][i] == a:
		break
del e_list[b][i]
vi = 0
Q = deque([vi])
checked_list = [False for i in range(N)]
checked_list[vi] = True
count = 1
while len(Q) > 0:
	v = Q.pop()
	for v1 in e_list[v]:
		if not checked_list[v1]:
			checked_list[v1] = True
			Q.appendleft(v1)
			count += 1
if count > N - count:
	print('Fennec')
else:
	print('Snuke')


import heapq

def dijkstra(v, s, path):
	inf = float('inf')
	d = [inf for i in range(v)]
	d[s] = 0
	q = [[0, s]]
	heapq.heapify(q)
	while q:
		p = heapq.heappop(q)
		if d[p[1]] < p[0]:
			continue
		for i in range(len(path[p[1]])):
			if d[path[p[1]][i][1]] > d[p[1]] + path[p[1]][i][0]:
				d[path[p[1]][i][1]] = d[p[1]] + path[p[1]][i][0]
				heapq.heappush(q, [d[path[p[1]][i][1]], path[p[1]][i][1]])
	return d
n = int(input())
l = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	l[a - 1].append([1, b - 1])
	l[b - 1].append([1, a - 1])
d1 = dijkstra(n, 0, l)
d2 = dijkstra(n, n - 1, l)
a = 0
for i in range(n):
	if d1[i] <= d2[i]:
		a += 1
	else:
		a -= 1
print('Fennec' if a > 0 else 'Snuke')


N = int(input())
ab = [[int(_) for _ in input().split()] for n in range(N - 1)]
ns = [[] for _ in range(N + 1)]
for (a, b) in ab:
	ns[a].append(b)
	ns[b].append(a)
from heapq import *
queue = []
heappush(queue, (0, 1))
heappush(queue, (1, N))
counts = [0, 0]
while queue:
	(i, index) = heappop(queue)
	if ns[index]:
		counts[i % 2] += 1
		for t in ns[index]:
			if ns[t]:
				heappush(queue, (i + 2, t))
	ns[index] = None
if counts[0] > counts[1]:
	print('Fennec')
else:
	print('Snuke')


import sys
sys.setrecursionlimit(10 ** 7)
n = int(input())
edge = [[] for _ in range(n)]
for i in range(n - 1):
	(x, y) = map(int, input().split())
	edge[x - 1].append(y - 1)
	edge[y - 1].append(x - 1)

def dfs(node, dist, distl):
	distl[node] = dist
	for e in edge[node]:
		if distl[e] == -1:
			dfs(e, dist + 1, distl)
(dista, distb) = ([-1] * n, [-1] * n)
dfs(0, 0, dista)
dfs(n - 1, 0, distb)
(a, b) = (0, 0)
for i in range(n):
	if dista[i] <= distb[i]:
		a += 1
	else:
		b += 1
print('Fennec' if a > b else 'Snuke')


import sys
sys.setrecursionlimit(2 * 10 ** 5)
N = int(input())
(a, b) = zip(*(map(int, input().split()) for _ in range(N - 1))) if N - 1 else ((), ())
G = [set() for _ in range(N + 1)]
for (x, y) in zip(a, b):
	G[x].add(y)
	G[y].add(x)
dp = [0 for _ in range(N + 1)]
dp[1] = 1

def f(i):
	for j in G[i]:
		if dp[j] == 0:
			dp[j] = i
			f(j)
f(1)
p = []
i = N
while i != 1:
	p.append(i)
	i = dp[i]
p.append(1)
dp2 = [0 for _ in range(N + 1)]
for j in range(len(p)):
	if dp2[p[-(j + 1)]] == 0:
		dp2[p[-(j + 1)]] = 1
	if dp2[p[j]] == 0:
		dp2[p[j]] = -1
dp3 = [0 for _ in range(N + 1)]
dp3[1] = 1

def g(i):
	for j in G[i]:
		if dp3[j] == 0 and dp2[j] != -1:
			dp3[j] = 1
			g(j)
g(1)
ans = 'Fennec' if dp3.count(1) > N // 2 else 'Snuke'
print(ans)


from collections import deque

def inpl():
	return tuple(map(int, input().split()))
N = int(input())
G = [[] for i in range(N + 1)]
for _ in range(N - 1):
	(a, b) = inpl()
	G[a].append(b)
	G[b].append(a)
F = ['' for i in range(N + 1)]
S = ['' for i in range(N + 1)]
visited = [False for i in range(N + 1)]
Q = deque([(1, 0)])
while len(Q):
	(m, d) = Q.popleft()
	if visited[m]:
		continue
	else:
		F[m] = d
		visited[m] = True
	for nm in G[m]:
		Q.append((nm, d + 1))
visited = [False for i in range(N + 1)]
Q = deque([(N, 0)])
while len(Q):
	(m, d) = Q.popleft()
	if visited[m]:
		continue
	else:
		S[m] = d
		visited[m] = True
	for nm in G[m]:
		Q.append((nm, d + 1))
black = 0
for i in range(1, N + 1):
	if F[i] <= S[i]:
		black += 1
if 2 * black > N:
	print('Fennec')
else:
	print('Snuke')


def bfs(n, links):
	painted = set()
	fq = {0}
	sq = {n - 1}
	(fs, ss) = (0, 0)
	while True:
		(nfq, nsq) = (set(), set())
		for v in fq:
			cfq = links[v] - painted
			if cfq:
				fs += len(cfq)
				painted.update(cfq)
				nfq.update(cfq)
		fq = nfq
		for v in sq:
			csq = links[v] - painted
			if csq:
				ss += len(csq)
				painted.update(csq)
				nsq.update(csq)
		sq = nsq
		if not fq:
			ss = n - fs
			break
		if not sq:
			fs = n - ss
			break
	return fs > ss
n = int(input())
links = [set() for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	links[a].add(b)
	links[b].add(a)
print('Fennec' if bfs(n, links) else 'Snuke')


import sys
sys.setrecursionlimit(10000000)

def search(prev, start, stop):
	global nodes, edges
	for neigh in nodes[start]:
		if neigh == prev:
			continue
		if neigh == stop:
			return [stop, start]
		res = search(start, neigh, stop)
		if res != False:
			res.append(start)
			return res
	return False

def size(prev, curr):
	su = 1
	global nodes, edges
	for neigh in nodes[curr]:
		if neigh == prev:
			continue
		su += size(curr, neigh)
	return su
n = int(input())
nodes = [[] for i in range(n)]
edges = []
for i in range(n - 1):
	line = input().split()
	a = int(line[0]) - 1
	b = int(line[1]) - 1
	edges.append([a, b])
	nodes[b].append(a)
	nodes[a].append(b)
res = search(-1, n - 1, 0)
fennec = (len(res) - 1) // 2
snuke = fennec + 1
snuke = res[snuke]
fennec = res[fennec]
fennecsize = size(snuke, fennec)
snukesize = size(fennec, snuke)
if fennecsize > snukesize:
	print('Fennec')
else:
	print('Snuke')


from scipy.sparse import *
(n, *a) = map(int, open(0).read().split())
c = [1] * ~-n
print('FSennunkeec'[sum((g > h for (g, h) in zip(*csgraph.dijkstra(csr_matrix((c, (a[::2], a[1::2])), [n + 1] * 2), 0, [1, n])))) * 2 >= n::2])


from heapq import heappush, heappop
from collections import defaultdict

def dijkstra(V, E, s):
	INF = float('inf')
	dist = {v: INF for v in V}
	heap = []
	dist[s] = 0
	rem = len(V)
	heappush(heap, (0, s))
	while heap and rem:
		(d, v) = heappop(heap)
		if d > dist[v]:
			continue
		rem -= 1
		for (u, c) in E[v].items():
			temp = d + c
			if temp < dist[u]:
				dist[u] = temp
				heappush(heap, (temp, u))
	return dist
N = int(input())
V = list(range(1, N + 1))
E = defaultdict(dict)
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	E[a][b] = 1
	E[b][a] = 1
fen = dijkstra(V, E, 1)
sun = dijkstra(V, E, N)
(black, white) = (0, 0)
for v in V:
	if fen[v] <= sun[v]:
		black += 1
	else:
		white += 1
print('Fennec' if black > white else 'Snuke')


import sys
sys.setrecursionlimit(100000000)
n = int(input())
xys = [tuple(map(int, input().split())) for _ in range(n - 1)]
neighbors = [[] for _ in range(n)]
for (x, y) in xys:
	neighbors[x - 1].append(y - 1)
	neighbors[y - 1].append(x - 1)
froms = [-1 for _ in range(n)]
froms[0] = -2

def f(x):
	for y in neighbors[x]:
		if froms[y] == -1:
			froms[y] = x
			f(y)
f(0)
path = [n - 1]
while path[-1] != 0:
	if froms[path[-1]] == -1:
		break
	path.append(froms[path[-1]])
path.reverse()
blacks_l = path[:(len(path) + 1) // 2]
blacks = set(blacks_l)
whites = set(path[(len(path) + 1) // 2:])

def fennec(x):
	for y in neighbors[x]:
		if not y in blacks and (not y in whites):
			blacks.add(y)
			fennec(y)
for b in blacks_l:
	fennec(b)
if len(blacks) > n - len(blacks):
	print('Fennec')
else:
	print('Snuke')


(N,) = map(int, input().split())
G = [set() for _ in range(N + 1)]
for i in range(N - 1):
	(A, B) = map(int, input().split())
	G[A].add(B)
	G[B].add(A)
path = []
stack = [1]
vs = set()
while stack:
	v = stack.pop()
	if v > 0:
		vs.add(v)
		path.append(v)
		for u in G[v]:
			if u in vs:
				continue
			if u == N:
				stack = []
				path.append(u)
				break
			stack += [-v, u]
	else:
		path.pop()
x = path[-(-len(path) // 2)]
stack = [1]
vs = set()
while stack:
	v = stack.pop()
	vs.add(v)
	for u in G[v]:
		if u in vs:
			continue
		if u == x:
			continue
		stack.append(u)
x = len(vs) - 1
y = N - 2 - x
if x > y:
	print('Fennec')
else:
	print('Snuke')


n = int(input())
tree = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	tree[a - 1].append(b - 1)
	tree[b - 1].append(a - 1)

def dist(k):
	l = [-1] * n
	node = [k]
	while node:
		s = node.pop()
		d = l[s]
		for t in tree[s]:
			if l[t] != -1:
				continue
			l[t] = d + 1
			node.append(t)
	return l
from_fennec = dist(0)
from_snuke = dist(n - 1)
res = 0
for (i, j) in zip(from_fennec, from_snuke):
	if i <= j:
		res += 1
	else:
		res -= 1
print('Snuke' if res <= 0 else 'Fennec')


import sys

class UnionFind:

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

	def find(self, x):
		return self.table[x]

	def union(self, val, y):
		self.table[y] = val

	def same(self, x, y):
		x1 = self.find(x)
		y1 = self.find(y)
		return x1 == y1

	def get_table(self):
		return self.table
sys.setrecursionlimit(10 ** 9)
input = sys.stdin.readline
N = int(input())
adj = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = list(map(int, input().split()))
	adj[a - 1].append(b - 1)
	adj[b - 1].append(a - 1)
Un = UnionFind(N)
S = [N - 1]
F = [0]
S_or = N - 1
F_or = 0

def oneStep(turn):
	ret = []
	if turn == 1:
		while S:
			c = S.pop(0)
			for i in adj[c]:
				if not Un.same(S_or, i) and (not Un.same(F_or, i)):
					Un.union(S_or, i)
					ret.append(i)
	else:
		while F:
			c = F.pop(0)
			for i in adj[c]:
				if not Un.same(S_or, i) and (not Un.same(F_or, i)):
					Un.union(F_or, i)
					ret.append(i)
	return ret
turn = 0
while S or F:
	if turn == 1:
		if len(S) != 0:
			S = oneStep(turn)
		turn = 0
	else:
		if len(F) != 0:
			F = oneStep(turn)
		turn = 1
cntF = Un.get_table().count(0)
cntS = Un.get_table().count(N - 1)
if cntF > cntS:
	ans = 'Fennec'
else:
	ans = 'Snuke'
print(ans)


N = int(input())
import sys
sys.setrecursionlimit(N + 10)
ab = [[] for _ in range(N)]
for i in range(N - 1):
	(a, b) = map(int, input().split())
	(a, b) = (a - 1, b - 1)
	ab[a].append(b)
	ab[b].append(a)
dF = [0] * N
dS = [0] * N

def dfs(now, d, dlist, visited):
	if visited[now] == False:
		dlist[now] = d
		visited[now] = True
		for next in ab[now]:
			dfs(next, d + 1, dlist, visited)
vF = [False] * N
dfs(0, 0, dF, vF)
vS = [False] * N
dfs(N - 1, 0, dS, vS)
cnt_F = 0
cnt_S = 0
for i in range(N):
	if dF[i] <= dS[i]:
		cnt_F += 1
	else:
		cnt_S += 1
if cnt_F > cnt_S:
	print('Fennec')
else:
	print('Snuke')


import sys
sys.setrecursionlimit(10 ** 6)

def main():
	n = int(input())
	adj_list = [[] for i in range(n)]
	for i in range(n - 1):
		(a1, b1) = list(map(int, sys.stdin.readline().split()))
		adj_list[a1 - 1].append(b1 - 1)
		adj_list[b1 - 1].append(a1 - 1)
	path = list(reversed(dfs(0, -1, adj_list, n)))
	assert len(path) >= 2
	fpath = len(path) - len(path) // 2
	cut = set(path[fpath - 1:fpath + 1])
	f = dfs2(0, -1, adj_list, n, cut)
	s = dfs2(n - 1, -1, adj_list, n, cut)
	assert f + s == n
	print('Fennec' if f > s else 'Snuke')

def dfs(now, prev, adj_list, n):
	if now == n - 1:
		return [now]
	for next in adj_list[now]:
		if next == prev:
			continue
		p = dfs(next, now, adj_list, n)
		if p is not None:
			p.append(now)
			return p

def dfs2(now, prev, adj_list, n, cut):
	size = 1
	for next in adj_list[now]:
		if next == prev:
			continue
		if {now, next} == cut:
			continue
		s = dfs2(next, now, adj_list, n, cut)
		size += s
	return size

def __starting_point():
	main()
__starting_point()


from networkx import *
(N, *t) = open(0)
G = Graph()
for s in t:
	(a, b) = s.split()
	G.add_edge(a, b)
s = shortest_path_length
x = s(G, '1')
y = s(G, N[:-1])
print('FSennunkeec'[sum((x[k] > y[k] for k in x)) * 2 >= int(N)::2])


from sys import exit, setrecursionlimit, stderr
from functools import reduce
from itertools import *
from collections import *
from bisect import *

def read():
	return int(input())

def reads():
	return [int(x) for x in input().split()]
setrecursionlimit(1 << 30)
N = read()
edges = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = reads()
	(a, b) = (a - 1, b - 1)
	edges[a].append(b)
	edges[b].append(a)

def dist(u, d):
	for v in edges[u]:
		if d[v] >= 0:
			continue
		d[v] = d[u] + 1
		dist(v, d)
	return d
distf = dist(0, [0] + [-1] * (N - 1))
dists = dist(N - 1, [-1] * (N - 1) + [0])
numf = sum((distf[i] <= dists[i] for i in range(N)))
nums = N - numf
if numf > nums:
	print('Fennec')
else:
	print('Snuke')


n = int(input())
pt = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	pt[a - 1].append(b - 1)
	pt[b - 1].append(a - 1)

def dfs(v):
	d = [-1] * n
	d[v] = 0
	q = [v]
	c = 1
	while q:
		q1 = []
		for i in q:
			for j in pt[i]:
				if d[j] == -1:
					d[j] = c
					q1.append(j)
		q = q1
		c += 1
	return d
ans = 0
for (i, j) in zip(dfs(0), dfs(n - 1)):
	if i <= j:
		ans += 1
if ans <= n / 2:
	print('Snuke')
else:
	print('Fennec')


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

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

def rls():
	return list(input())

def pli(a):
	return ''.join(list(map(str, a)))
import copy
N = ri()
relation = [[] for _ in range(N + 1)]
dist = [[0 for i in range(N + 1)] for j in range(2)]
for i in range(N - 1):
	(a, b) = rli()
	relation[a].append(b)
	relation[b].append(a)

def dfs_visit(u):
	start = u
	rel = copy.deepcopy(relation)
	s = []
	color = [-1 for _ in range(N + 1)]
	s.append(u)
	color[u] = 0
	while s != list():
		u = s[-1]
		try:
			v = rel[u].pop()
		except IndexError:
			dist[0 if start == 1 else 1][s[-1]] = len(s)
			s.pop()
			color[u] = 1
			continue
		if color[v] == -1:
			color[v] = 0
			s.append(v)

def dfs():
	dfs_visit(1)
	dfs_visit(N)
dfs()
fe = 0
sn = 0
for i in range(1, N + 1):
	if dist[0][i] <= dist[1][i]:
		fe += 1
	else:
		sn += 1
print('Fennec' if fe > sn else 'Snuke')


import sys
sys.setrecursionlimit(10 ** 6)
N = int(input())
I = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = list(map(int, input().split()))
	I[a - 1].append(b - 1)
	I[b - 1].append(a - 1)

def path(s, t, pth, visited):
	pth.append(s)
	if s == t:
		return (pth, True)
	visited.add(s)
	flag = False
	for q in I[s]:
		if q not in visited:
			(pth, flag) = path(q, t, pth, visited)
			if flag:
				return (pth, True)
	pth.pop()
	return (pth, False)

def count(s, d, visited):
	visited.add(s)
	for q in I[s]:
		if q not in visited and q != d:
			visited = count(q, d, visited)
	return visited
(pth, flag) = path(0, N - 1, [], set())
if not flag:
	print('error')
d = pth[(len(pth) + 1) // 2]
n = len(count(0, d, set()))
if n > N // 2:
	print('Fennec')
else:
	print('Snuke')


n = int(input())
edges = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	edges[a].append(b)
	edges[b].append(a)
dp = [0] * n
dp[0] = 1
fp = [0] * n
fp[n - 1] = 1

def bfs(u):
	q = []
	q.append(u)
	while q:
		p = q.pop()
		for i in edges[p]:
			if dp[i] == 0:
				q.append(i)
				dp[i] += dp[p] + 1

def ffs(u):
	q = []
	q.append(u)
	while q:
		p = q.pop()
		for i in edges[p]:
			if fp[i] == 0:
				q.append(i)
				fp[i] += fp[p] + 1
bfs(0)
ffs(n - 1)
c = 0
for i in range(n):
	if dp[i] <= fp[i]:
		c += 1
if 2 * c > n:
	print('Fennec')
else:
	print('Snuke')


from collections import defaultdict
from heapq import heappop, heappush

class Graph(object):

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

	def __len__(self):
		return len(self.graph)

	def add_edge(self, src, dst, weight=1):
		self.graph[src].append((dst, weight))

	def get_nodes(self):
		return self.graph.keys()

class Dijkstra(object):

	def __init__(self, graph, start):
		self.g = graph.graph
		self.dist = defaultdict(lambda : float('inf'))
		self.dist[start] = 0
		self.prev = defaultdict(lambda : None)
		self.Q = []
		heappush(self.Q, (self.dist[start], start))
		while self.Q:
			(dist_u, u) = heappop(self.Q)
			if self.dist[u] < dist_u:
				continue
			for (v, weight) in self.g[u]:
				alt = dist_u + weight
				if self.dist[v] > alt:
					self.dist[v] = alt
					self.prev[v] = u
					heappush(self.Q, (alt, v))

	def shortest_distance(self, goal):
		return self.dist[goal]

	def shortest_path(self, goal):
		path = []
		node = goal
		while node is not None:
			path.append(node)
			node = self.prev[node]
		return path[::-1]
g = Graph()
N = int(input())
for i in range(N - 1):
	(u, v) = [int(i) for i in input().split()]
	g.add_edge(u - 1, v - 1, 1)
	g.add_edge(v - 1, u - 1, 1)
d1 = Dijkstra(g, 0)
d2 = Dijkstra(g, N - 1)
ans = 0
for i in range(N):
	if d1.dist[i] <= d2.dist[i]:
		ans += 1
if ans > N - ans:
	print('Fennec')
else:
	print('Snuke')


from heapq import heappush, heappop
inf = 10 ** 10
n = int(input())
l = [[] for i in range(n + 1)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	l[a].append(b)
	l[b].append(a)

def dijkstra(s):
	q = [(0, s)]
	dist = [inf] * (n + 1)
	dist[s] = 0
	while q:
		(c, v) = heappop(q)
		if dist[v] < c:
			continue
		for i in l[v]:
			t = i
			cost = 1
			if dist[v] + cost < dist[t]:
				dist[t] = dist[v] + cost
				heappush(q, [dist[t], t])
	return dist
d1 = dijkstra(1)
d2 = dijkstra(n)
countp = 0
counts = 0
for i in range(1, n + 1):
	if d1[i] > d2[i]:
		counts += 1
	else:
		countp += 1
if countp > counts:
	print('Fennec')
else:
	print('Snuke')


import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(10 ** 7)
from collections import deque

def bfs(s, flag):
	if flag:
		global check
	else:
		check = [-1] * (n + 1)
	cnt = 0
	ans = 0
	q = deque([s, cnt])
	while q:
		now = q.popleft()
		cnt = q.popleft()
		check[now] = cnt
		ans += 1
		for next in graph[now]:
			if flag:
				if check[next] > cnt + 1:
					q.append(next)
					q.append(cnt + 1)
			elif check[next] == -1:
				q.append(next)
				q.append(cnt + 1)
	if flag:
		return ans
	else:
		return check
n = int(readline())
graph = [[] for _ in range(n + 1)]
for i in range(n - 1):
	(a, b) = map(int, readline().split())
	graph[a].append(b)
	graph[b].append(a)
check = bfs(1, False)
print('Snuke' if bfs(n, True) >= n / 2 else 'Fennec')


from collections import deque
N = int(input())
G = dict()
for i in range(N):
	G[i + 1] = []
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	G[a].append(b)
	G[b].append(a)
dist_1 = [N] * (N + 1)
dist_1[1] = 0
que = deque([1])
while len(que) > 0:
	a = que.popleft()
	for b in G[a]:
		if dist_1[b] > dist_1[a] + 1:
			dist_1[b] = dist_1[a] + 1
			que.append(b)
dist_N = [N] * (N + 1)
dist_N[N] = 0
que = deque([N])
while len(que) > 0:
	a = que.popleft()
	for b in G[a]:
		if dist_N[b] > dist_N[a] + 1:
			dist_N[b] = dist_N[a] + 1
			que.append(b)
count_Fennec = 0
for i in range(N):
	if dist_1[i + 1] <= dist_N[i + 1]:
		count_Fennec += 1
if count_Fennec > N - count_Fennec:
	print('Fennec')
else:
	print('Snuke')


def bfs(graph, start, n, check):
	if check == False:
		arrival = [0 for i in range(n + 1)]
	else:
		arrival = [0 for i in range(n + 1)]
		arrival[check] = -1
	q = [start]
	arrival[start] = 1
	while len(q) != 0:
		for i in range(len(graph[q[0]])):
			if arrival[graph[q[0]][i]] == 0:
				q.append(graph[q[0]][i])
				arrival[graph[q[0]][i]] = arrival[q[0]] + 1
		q.pop(0)
	return arrival
n = int(input())
graph = dict()
for i in range(1, n + 1):
	graph[i] = []
for i in range(n - 1):
	(a, b) = map(int, input().split())
	graph[a].append(b)
	graph[b].append(a)
fstart = bfs(graph, 1, n, False)
sstart = bfs(graph, n, n, False)
fennec = 0
snuke = 0
for i in range(1, n + 1):
	if abs(fstart[i] - fstart[1]) <= abs(sstart[i] - sstart[n]):
		fennec += 1
	else:
		snuke += 1
if fennec > snuke:
	print('Fennec')
else:
	print('Snuke')


from collections import deque
N = int(input())
edge = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	edge[a - 1].append(b - 1)
	edge[b - 1].append(a - 1)
d = [[-1] * N for _ in range(2)]
for i in range(2):
	d[i][i * (N - 1)] = 0
	q = deque([i * (N - 1)])
	while len(q) > 0:
		u = q.popleft()
		for v in edge[u]:
			if d[i][v] > -1:
				continue
			d[i][v] = d[i][u] + 1
			q.append(v)
S = 0
F = 0
for i in range(N):
	if d[0][i] > d[1][i]:
		S += 1
	else:
		F += 1
if F > S:
	print('Fennec')
else:
	print('Snuke')


n = int(input())
ab = [list(map(int, input().split())) for i in range(n - 1)]
graph = [[] for i in range(n + 1)]
visited = [0 for i in range(n + 1)]
root = 1
stack = [root]
for (a, b) in ab:
	graph[a].append(b)
	graph[b].append(a)
visited[0] = -1
visited[root] = 1
while stack:
	x = stack.pop()
	if x == n:
		break
	for y in graph[x]:
		if visited[y] == 0:
			stack.append(y)
			visited[y] = visited[x] + 1
dist = visited[n] - 1
way = n
while True:
	if visited[way] == dist // 2 + 2:
		border = way
		break
	for y in graph[way]:
		if visited[y] == visited[way] - 1:
			way = y
stack = [1]
visited = [0 for i in range(n + 1)]
visited[border] = 1
fen = 0
while stack:
	x = stack.pop()
	fen += 1
	visited[x] = 1
	for y in graph[x]:
		if visited[y] == 0:
			stack.append(y)
snk = n - fen
if fen > snk:
	print('Fennec')
else:
	print('Snuke')


N = int(input())
edge = [list(map(int, input().split())) for i in range(N - 1)]
inf = 10 ** 20
c = [[] for i in range(N)]
for (i, j) in edge:
	c[i - 1].append(j - 1)
	c[j - 1].append(i - 1)
d = [0] + [inf] * (N - 1)
v = [0] * N
import sys
sys.setrecursionlimit(10 ** 6)

def dfs(p, v, d):
	for n in c[p]:
		if v[n] == 0:
			d[n] = min(d[n], d[p] + 1)
			v[n] = 1
			dfs(n, v, d)
dfs(0, v, d)
d2 = [inf] * (N - 1) + [0]
v = [0] * N
dfs(N - 1, v, d2)
c = 0
for (i, j) in zip(d, d2):
	c = c + 1 if i <= j else c - 1
print(['Snuke', 'Fennec'][c > 0])


from collections import Counter
N = int(input())
graph = [[] for _ in range(N + 1)]
visited = [None] * (N + 1)
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	graph[a].append(b)
	graph[b].append(a)
v = 1
adv_v = N
update = True
labels = [0, 1]
vs = [v, adv_v]
prev_vs = [-1, -1]
visited[1] = 0
visited[N] = 1
while update:
	update = False
	next_cand = []
	for (label, v, prev_v) in zip(labels, vs, prev_vs):
		for next_v in graph[v]:
			if next_v == prev_v:
				continue
			if visited[next_v] is None:
				update = True
				next_cand.append((next_v, label, v))
	vs = []
	labels = []
	prev_vs = []
	for (next_v, label, prev_v) in next_cand:
		if visited[next_v] is None:
			visited[next_v] = label
			vs.append(next_v)
			prev_vs.append(prev_v)
			labels.append(label)
c = Counter(visited)
if c[0] > c[1]:
	print('Fennec')
else:
	print('Snuke')


from collections import *
n = int(input())
ab = [[] for i in range(n)]
for i in range(n - 1):
	(x, y) = map(int, input().split())
	ab[x - 1].append(y - 1)
	ab[y - 1].append(x - 1)
s = [float('inf')] * n
f = [float('inf')] * n
q = deque()
q.append((0, 0))
while q:
	(a, b) = q.popleft()
	if f[a] == float('inf'):
		f[a] = b
		for j in ab[a]:
			if f[j] == float('inf'):
				q.append((j, b + 1))
d = deque()
d.append((n - 1, 0))
while d:
	(a, b) = d.popleft()
	if s[a] == float('inf'):
		s[a] = b
		for j in ab[a]:
			if s[j] == float('inf'):
				d.append((j, b + 1))
(sa, fa) = (0, 0)
for i in range(n):
	if s[i] >= f[i]:
		fa += 1
	else:
		sa += 1
if fa > sa:
	print('Fennec')
else:
	print('Snuke')


N = int(input())
ab = [[int(_) for _ in input().split()] for n in range(N - 1)]
from collections import defaultdict
ns = defaultdict(list)
for (a, b) in ab:
	ns[a].append(b)
	ns[b].append(a)
from heapq import *
queue = []
heappush(queue, (0, 1))
heappush(queue, (1, N))
colors = defaultdict(lambda : None)
(black_count, white_count) = (0, 0)
while queue:
	(i, index) = heappop(queue)
	color = i % 2
	if colors[index] is None:
		colors[index] = color
		if color:
			white_count += 1
		else:
			black_count += 1
		for t in ns[index]:
			if ns[t]:
				heappush(queue, (i + 2, t))
if black_count > white_count:
	print('Fennec')
else:
	print('Snuke')


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, random, time, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
mod = 10 ** 9 + 7

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

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

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

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

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

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

def S():
	return input()

def main():
	n = I()
	e = collections.defaultdict(list)
	for _ in range(n - 1):
		(a, b) = LI()
		e[a].append(b)
		e[b].append(a)

	def search(s):
		d = collections.defaultdict(lambda : inf)
		d[s] = 0
		q = []
		heapq.heappush(q, (0, s))
		v = collections.defaultdict(bool)
		while len(q):
			(k, u) = heapq.heappop(q)
			if v[u]:
				continue
			v[u] = True
			for uv in e[u]:
				ud = 1
				if v[uv]:
					continue
				vd = k + ud
				if d[uv] > vd:
					d[uv] = vd
					heapq.heappush(q, (vd, uv))
		return d
	ad = search(1)
	bd = search(n)
	t = -1
	for i in range(2, n):
		if ad[i] <= bd[i]:
			t += 1
		else:
			t -= 1
	if t >= 0:
		return 'Fennec'
	return 'Snuke'
print(main())


n = int(input())
node = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	node[a - 1].append(b - 1)
	node[b - 1].append(a - 1)
visited = [False] * n

def dfs(i):
	dis = [-1] * n
	dis[i] = 0
	stack = [i]
	while stack:
		p = stack.pop()
		for x in node[p]:
			if dis[x] == -1:
				dis[x] = dis[p] + 1
				stack.append(x)
	return dis
(d0, dn) = (dfs(0), dfs(n - 1))
cnt = 0
for i in range(n):
	if d0[i] > dn[i]:
		cnt += 1
if cnt >= n / 2:
	print('Snuke')
else:
	print('Fennec')


n = int(input())
node = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	node[a - 1].append(b - 1)
	node[b - 1].append(a - 1)

def dfs(v):
	dis = [10 ** 10] * n
	dis[v] = 0
	q = []
	q.append(v)
	while q:
		u = q.pop()
		for i in node[u]:
			if dis[i] > dis[u] + 1:
				dis[i] = dis[u] + 1
				q.append(i)
	return dis
d1 = dfs(0)
d2 = dfs(n - 1)
c = 0
for i in range(1, n - 1):
	if d1[i] <= d2[i]:
		c += 1
if c > (n - 2) // 2:
	print('Fennec')
else:
	print('Snuke')


from heapq import heappush, heappop
N = int(input())
(a, b) = zip(*(map(int, input().split()) for _ in range(N - 1))) if N - 1 else ((), ())
G = [{} for _ in range(N + 1)]
for (x, y) in zip(a, b):
	G[x][y] = 1
	G[y][x] = 1
INF = 10 ** 10

def dijkstra(G, s):
	dp = [INF for _ in range(len(G))]
	q = []
	heappush(q, (0, s))
	while q:
		(c, i) = heappop(q)
		if dp[i] == INF:
			dp[i] = c
			for (j, w) in G[i].items():
				heappush(q, (c + w, j))
	return dp
dp1 = dijkstra(G, 1)
dpN = dijkstra(G, N)
ans = 'Fennec' if sum((dp1[i] <= dpN[i] for i in range(1, N + 1))) > N // 2 else 'Snuke'
print(ans)


import sys
sys.setrecursionlimit(int(1000000.0))

class Graph(object):

	def __init__(self, N):
		self.N = N
		self.paths = [None] * (N + 1)
		for i in range(1, N + 1):
			self.paths[i] = set()

	def path(self, n1, n2):
		self.paths[n1].add(n2)
		self.paths[n2].add(n1)

	def dfs(self, n, f):
		if n == self.N:
			return [n]
		for nn in self.paths[n]:
			if nn != f:
				path = self.dfs(nn, n)
				if path is not None:
					path.append(n)
					return path
		return None

	def region(self, start, block, f):
		s = 1
		for nn in self.paths[start]:
			if nn != f and nn != block:
				s += self.region(nn, block, start)
		return s

def main():
	N = int(input())
	graph = Graph(N)
	for i in range(N - 1):
		(n1, n2) = map(int, input().split())
		graph.path(n1, n2)
	path = graph.dfs(1, None)
	l = len(path)
	fb = path[l // 2]
	sb = path[l // 2 - 1]
	fr = graph.region(1, sb, None)
	sr = graph.region(N, fb, None)
	if fr > sr:
		print('Fennec')
	else:
		print('Snuke')
main()


import sys

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

def mi():
	return map(int, input().split())
N = int(input())
ngb = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = mi()
	a -= 1
	b -= 1
	ngb[a].append(b)
	ngb[b].append(a)
start = 0
goal = N - 1
nodes = [[-1, -1] for _ in range(N)]
nodes[start][0] = 0
nodes[start][1] = -1
stack = []
for eachngb in ngb[start]:
	stack.append(eachngb)
	nodes[eachngb][0] = 1
	nodes[eachngb][1] = start
while 1:
	try:
		nownode = stack.pop()
	except:
		break
	if nownode == goal:
		break
	for eachngb in ngb[nownode]:
		if nodes[eachngb][0] == -1:
			stack.append(eachngb)
			nodes[eachngb][0] = nodes[nownode][0] + 1
			nodes[eachngb][1] = nownode
length = nodes[goal][0]
FenRootPos = length // 2
SnRootPos = FenRootPos + 1
FenRoot = -1
SnRoot = -1
nextnode = goal
for i in range(length, FenRootPos - 1, -1):
	nownode = nextnode
	if i == SnRootPos:
		SnRoot = nownode
	elif i == FenRootPos:
		FenRoot = nownode
	nextnode = nodes[nownode][1]
ndsFen = [-1] * N
ndsFen[SnRoot] = 0
ndsFen[FenRoot] = 0
stkFen = []
stkFen.append(FenRoot)
FenCnt = 0
while 1:
	try:
		nownode = stkFen.pop()
	except:
		break
	for eachngb in ngb[nownode]:
		if ndsFen[eachngb] == -1:
			stkFen.append(eachngb)
			ndsFen[eachngb] = 1
			FenCnt += 1
ndsSn = [-1] * N
ndsSn[FenRoot] = 0
ndsSn[SnRoot] = 0
stkSn = []
stkSn.append(SnRoot)
SnCnt = 0
while 1:
	try:
		nownode = stkSn.pop()
	except:
		break
	for eachngb in ngb[nownode]:
		if ndsSn[eachngb] == -1:
			stkSn.append(eachngb)
			ndsSn[eachngb] = 1
			SnCnt += 1
print('Fennec' if FenCnt > SnCnt else 'Snuke')


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

def main():
	INF = float('inf')
	N = int(readline())
	conn = [[] for _ in range(N)]
	for _ in range(N - 1):
		(a, b) = list(map(int, readline().split()))
		a -= 1
		b -= 1
		conn[a].append(b)
		conn[b].append(a)
	dist = [INF] * N
	prev = [-1] * N
	dist[0] = 0
	q = deque([0])
	while q:
		x = q.popleft()
		for y in conn[x]:
			if dist[y] == INF:
				dist[y] = dist[x] + 1
				prev[y] = x
				q.append(y)
	path = deque([])
	t = N - 1
	while t >= 0:
		path.appendleft(t)
		t = prev[t]
	(a, b) = (path[dist[-1] // 2], path[dist[-1] // 2 + 1])
	conn[a].remove(b)
	conn[b].remove(a)
	blacks = 0
	visited_b = [False] * N
	q_b = deque([0])
	visited_b[0] = True
	while q_b:
		x = q_b.popleft()
		blacks += 1
		for y in conn[x]:
			if not visited_b[y]:
				visited_b[y] = True
				q_b.append(y)
	whites = 0
	visited_w = [False] * N
	q_w = deque([N - 1])
	visited_w[N - 1] = True
	while q_w:
		x = q_w.popleft()
		whites += 1
		for y in conn[x]:
			if not visited_w[y]:
				visited_w[y] = True
				q_w.append(y)
	print('Fennec' if blacks > whites else 'Snuke')

def __starting_point():
	main()
__starting_point()


def dfs(x):
	(d, q) = ([-1 for i in range(n + 1)], [x])
	d[x] = 0
	while q:
		x = q.pop()
		for i in r[x]:
			if d[i] == -1:
				(d[i], q) = (d[x] + 1, q + [i])
	return d
n = int(input())
x = [[int(i) for i in input().split()] for i in range(n - 1)]
r = [[] for i in range(n + 1)]
for (i, j) in x:
	r[i].append(j)
	r[j].append(i)
(d1, dn, num) = (dfs(1), dfs(n), 0)
for i in range(1, n + 1):
	if d1[i] <= dn[i]:
		num += 1
if num > n // 2:
	print('Fennec')
else:
	print('Snuke')


n = int(input())
peer = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	peer[a].append(b)
	peer[b].append(a)
now = [0]
pre = [10 ** 6 for _ in range(n)]
pst = [[] for _ in range(n)]
seen = [0 for _ in range(n)]
seen[0] = 1
while now:
	last = now
	now = []
	for x in last:
		for y in peer[x]:
			if seen[y] == 0:
				seen[y] = 1
				pre[y] = x
				pst[x].append(y)
				now.append(y)
r = 0
z = n - 1
while True:
	r += 1
	z = pre[z]
	if z == 0:
		break
z = n - 1
for _ in range(r - r // 2 - 1):
	z = pre[z]
cnt = 0
nowz = [z]
while nowz:
	lastz = nowz
	nowz = []
	cnt += len(lastz)
	for x in lastz:
		nowz += pst[x]
if cnt >= (n + 1) // 2:
	print('Snuke')
else:
	print('Fennec')


import sys
sys.setrecursionlimit(2 * 10 ** 5)
N = int(input())
edges = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	edges[a - 1].append(b - 1)
	edges[b - 1].append(a - 1)
visited = [False for _ in range(N)]
fennec = [-1 for _ in range(N)]
snuke = [-1 for _ in range(N)]

def dfs(start, visited, distance, d):
	visited[start] = True
	d[start] = distance
	for term in edges[start]:
		if visited[term]:
			continue
		dfs(term, visited, distance + 1, d)
dfs(0, visited, 0, fennec)
visited = [False for _ in range(N)]
dfs(N - 1, visited, 0, snuke)
F = S = 0
for i in range(N):
	if fennec[i] <= snuke[i]:
		F += 1
	else:
		S += 1
if F > S:
	print('Fennec')
else:
	print('Snuke')


N = int(input())
eda = {}
for i in range(1, N + 1):
	eda[i] = set()
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	eda[a].add(b)
	eda[b].add(a)
fennec = 0
snuke = 0
fenneccheck = set([1])
snukecheck = set([N])
checked = set([1, N])
while len(checked) < N:
	nextfennec = set()
	for i in fenneccheck:
		for j in eda[i]:
			if j in checked:
				continue
			checked.add(j)
			nextfennec.add(j)
			fennec += 1
	fenneccheck = nextfennec
	nextsnuke = set()
	for i in snukecheck:
		for j in eda[i]:
			if j in checked:
				continue
			checked.add(j)
			nextsnuke.add(j)
			snuke += 1
	snukecheck = nextsnuke
if fennec > snuke:
	print('Fennec')
else:
	print('Snuke')


import sys
stdin = sys.stdin
sys.setrecursionlimit(10 ** 7)

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

def li_():
	return map(lambda x: int(x) - 1, stdin.readline().split())

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

def ls():
	return stdin.readline().split()

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

def lc():
	return list(ns())

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

def nf():
	return float(stdin.readline())
from collections import deque

def bfs(graph: list, start: int):
	n = len(graph)
	dist = [-1] * n
	que = deque([(start, 0)])
	while que:
		(cur_node, cur_dist) = que.popleft()
		dist[cur_node] = cur_dist
		for nex in graph[cur_node]:
			if dist[nex] < 0:
				dist[nex] = cur_dist + 1
				que.append((nex, cur_dist + 1))
	return dist
n = ni()
graph = [[] for _ in range(n)]
for _ in range(n - 1):
	(x, y) = li_()
	graph[x].append(y)
	graph[y].append(x)
fenec = bfs(graph, 0)
snuke = bfs(graph, n - 1)
fenec_saki = 0
for (d1, d2) in zip(fenec, snuke):
	if d1 <= d2:
		fenec_saki += 1
	elif d1 > d2:
		fenec_saki -= 1
if fenec_saki == 0:
	if n % 2:
		print('Fennec')
	else:
		print('Snuke')
elif fenec_saki > 0:
	print('Fennec')
else:
	print('Snuke')


import queue

class Edge:

	def __init__(self, to, cost):
		self.to = to
		self.cost = cost

class P:

	def __init__(self, distance, v):
		self.distance = distance
		self.v = v

def bfs(_s):
	q = queue.Queue()
	global d
	d = [float('inf') for i in range(N)]
	used = [False for i in range(N)]
	used[_s] = True
	d[_s] = 0
	q.put(_s)
	while not q.empty():
		p = q.get()
		for i in range(0, len(G[p])):
			if not used[G[p][i]]:
				used[G[p][i]] = True
				d[G[p][i]] = d[p] + 1
				q.put(G[p][i])
N = int(input())
a = []
b = []
for i in range(N - 1):
	(tmp_a, tmp_b) = list(map(int, input().split()))
	a.append(tmp_a - 1)
	b.append(tmp_b - 1)
G = [[] for i in range(N)]
for i in range(0, N - 1):
	G[a[i]].append(b[i])
	G[b[i]].append(a[i])
global d
bfs(0)
Fennec_d = d
bfs(N - 1)
sunuke_d = d
for i in range(0, len(Fennec_d)):
	if Fennec_d[i] <= sunuke_d[i]:
		sunuke_d[i] = -1
	else:
		Fennec_d[i] = -1
Fennec_count = 0
sunuke_count = 0
for i in range(0, len(Fennec_d)):
	if Fennec_d[i] < 0:
		sunuke_count += 1
	else:
		Fennec_count += 1
if sunuke_count < Fennec_count:
	print('Fennec')
else:
	print('Snuke')


def dfs(x):
	d = [-1] * (N + 1)
	stack = [x]
	while stack:
		x = stack.pop()
		for i in G[x]:
			if d[i] == -1:
				d[i] = d[x] + 1
				stack.append(i)
	return d
N = int(input())
G = [set() for _ in range(N + 1)]
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	G[a].add(b)
	G[b].add(a)
(d1, dn) = (dfs(1), dfs(N))
num = 0
for i in range(1, N + 1):
	if d1[i] <= dn[i]:
		num += 1
if num > N // 2:
	print('Fennec')
else:
	print('Snuke')


from collections import defaultdict as dd
tree = dd(list)

def dfs_route(tree, start, goal):
	visited = set()
	stack = list()
	visited.add(start)
	stack.append(start)
	while stack:
		node = stack[-1]
		if node == goal:
			return stack
		else:
			child = [x for x in tree[node] if x not in visited]
			if child == []:
				stack.pop()
			else:
				visited.add(child[0])
				stack.append(child[0])
n = int(input())
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	tree[a].append(b)
	tree[b].append(a)
l = dfs_route(tree, 1, n)
fl = l[(len(l) - 1) // 2]
sl = l[(len(l) + 1) // 2]
tree[fl].remove(sl)
tree[sl].remove(fl)

def gr(tree, start):
	island = set()
	rest = [start]
	while rest:
		node = rest.pop()
		island.add(node)
		for x in tree[node]:
			if x not in island:
				rest.append(x)
	return island
if len(gr(tree, 1)) * 2 > n:
	print('Fennec')
else:
	print('Snuke')