Problem:
 Score : 400 points    Problem Statement 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 1 7
3 6
1 2
3 1
7 4
5 7
1 4      Sample Output 1 Fennec  For example, if Fennec first paints Cell 2 black, she will win regardless of Snuke's moves.       Sample Input 2 4
1 4
4 2
2 3      Sample Output 2 Snuke

Solution (Python):

import sys
from collections import deque, Counter
from heapq import heappop, heappush
from bisect import bisect_right
from itertools import accumulate

sys.setrecursionlimit(10**6)
INF = 10**12
m = 10**9 + 7


def main():
    N = int(input())
    adj = [[] for _ in range(N)]
    for _ in range(N - 1):
        a, b = map(lambda x: int(x) - 1, input().split())
        adj[a].append(b)
        adj[b].append(a)

    queue = deque([0])
    visit = [-1] * N
    visit[0] = 0

    while queue:
        now = queue.popleft()
        for u in adj[now]:
            if visit[u] < 0:
                queue.append(u)
                visit[u] = visit[now] + 1

    queue = deque([N-1])
    visit2 = [-1] * N
    visit2[N-1] = 0

    while queue:
        now = queue.popleft()
        for u in adj[now]:
            if visit2[u] < 0:
                queue.append(u)
                visit2[u] = visit2[now] + 1

    cnt = 0
    for i in range(N):
        if visit[i] <= visit2[i]:
            cnt += 1
    print('Fennec') if cnt > N-cnt else print('Snuke')
    


if __name__ == "__main__":
    main()

Solution (Python):
class Graph:
    
    def __init__(self,vertex=[]):
        self.vertex=list(vertex)
        self.edge_number=0
        self.adjacent={v:set() for v in vertex}

    
    def add_vertex(self,*adder):
        k=len(self.vertex)
        m=0

        for u in adder:
            if u not in self.adjacent:
                self.adjacent[u]=set()
                self.vertex.append(u)

    
    def add_edge(self,From,To):
        for w in [From,To]:
            if w not in self.adjacent:
                self.add_vertex(w)

        if To not in self.adjacent[From]:
            self.adjacent[From].add(To)
            self.adjacent[To].add(From)
            self.edge_number+=1

    
    def remove_edge(self,u,v):
        for w in [u,v]:
            if w not in self.adjacent:
                self.add_vertex(w)

        if u in self.adjacent[v]:
            self.adjacent[u].remove(v)
            self.adjacent[v].remove(u)
            self.edge_number-=1

    
    def remove_vertex(self,*v):
        for w in v:
            if w in self.adjacent:
                self.edge_number-=len(self.adjacent[w])
                for u in self.adjacent[w]:
                    self.adjacent[u].remove(w)
                del self.adjacent[w]


    
    def add_walk(self,*walk):
        n=len(walk)
        for i in range(n-1):
            self.add_edge(walk[i],walk[i+1])

    
    def add_cycle(self,*cycle):
        self.add_walk(*cycle)
        self.add_edge(cycle[-1],cycle[0])

    
    def __vertex_swap(self,p,q):
        self.vertex.sort()

    
    def vertex_exist(self,v):
        return v in self.adjacent

    
    def edge_exist(self,u,v):
        if not(self.vertex_exist(u) and self.vertex_exist(v)):
            return False
        return u in self.adjacent[v]

    
    def neighbohood(self,v):
        if not self.vertex_exist(v):
            return []
        return list(self.adjacent[v])

    
    def degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return len(self.adjacent[v])

    
    def vertex_count(self):
        return len(self.vertex)

    
    def edge_count(self):
        return self.edge_number

    
    def connected_component(self,v):
        if v not in self.adjacent:
            return []

        from collections import deque
        T={u:False for u in self.adjacent}
        T[v]=True
        S=deque([v])

        while S:
            u=S.popleft()
            for w in self.adjacent[u]:
                if not T[w]:
                    T[w]=True
                    S.append(w)

        return [x for x in self.adjacent if T[x]]

    
    def distance(self,u,v):
        from collections import deque
        inf=float("inf")
        T={v:inf  for v in self.adjacent}

        if u==v:
            return 0

        Q=deque([u])
        T[u]=0
        while Q:
            w=Q.popleft()
            for x in self.adjacent[w]:
                if T[x]==inf:
                    T[x]=T[w]+1
                    Q.append(x)
                    if x==v:
                        return T[x]
        return inf

    
    def distance_all(self,u):
        from collections import deque
        inf=float("inf")
        T={v:inf  for v in self.adjacent}

        Q=deque([u])
        T[u]=0
        while Q:
            w=Q.popleft()
            for x in self.adjacent[w]:
                if T[x]==inf:
                    T[x]=T[w]+1
                    Q.append(x)
        return T

    
    def shortest_path(self,u,v):
        from collections import deque
        T={v:None for v in self.vertex}

        if u==v:
            return [u]

        Q=deque([u])
        T[u]=u
        while Q:
            w=Q.popleft()
            for x in self.adjacent[w]:
                if not T[x]:
                    T[x]=w
                    Q.append(x)
                    if x==v:
                        P=[v]
                        a=v
                        while a!=u:
                            a=T[a]
                            P.append(a)
                        return P[::-1]
        return None

from collections import deque
N=int(input())
G=Graph(range(1,N+1))

for _ in range(N-1):
    a,b=map(int,input().split())
    G.add_edge(a,b)

sp=G.shortest_path(1,N)
dist=len(sp)-1

u,v=sp[dist//2],sp[dist//2+1]
G.remove_edge(u,v)

A=len(G.connected_component(1))
B=len(G.connected_component(N))

if A>B:
    print("Fennec")
else:
    print("Snuke")

Solution (Python):
from collections import defaultdict
import heapq
N = int(input())
graph = defaultdict(list)
for i in range(N-1):
    a, b = map(int, input().split())
    graph[a] += [b]
    graph[b] += [a]
is_visited = [False for i in range(N+1)]
q = []
heapq.heappush(q, (0, 0, 1))
t2f = {}
while q:
    c, f, t = heapq.heappop(q)
    t2f[t] = f
    if t == N:
        break
    for nt in graph[t]:
        if is_visited[nt]:
            continue
        heapq.heappush(q, (c+1, t, nt))
        is_visited[nt] = True
is_visited = [False for i in range(N+1)]
is_visited[1] = True
is_visited[N] = True
for i in range((c-1)//2):
    t = t2f[t]
    is_visited[t] = True
q = []
heapq.heappush(q, (0, 1))
ans = 0
while q:
    c, t = heapq.heappop(q)
    ans += 1
    for nt in graph[t]:
        if is_visited[nt]:
            continue
        heapq.heappush(q, (c+1, nt))
        is_visited[nt] = True
if N // 2 < ans:
    print('Fennec')
else:
    print('Snuke')

Solution (Python):
from collections import deque

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


def bfs(G, root):
    n = len(G)
    Parents = [-1] * n
    Depth = [0] * n
    dq = deque([root])
    dq2 = deque()
    visited = [0] * n
    while dq:
        u = dq.pop()
        for v in G[u]:
            if visited[v]:
                continue
            else:
                dq2 += [v]
                Depth[v] = Depth[u] + 1
                Parents[v] = u
        dq.extend(dq2)
        dq2 = deque()
        visited[u] = 1
    return Depth, Parents


Depth, Parents = bfs(Edge, 0)
cnt = (Depth[-1] - 1)//2
now = N-1
while cnt:
    cnt -= 1
    now = Parents[now]
Edge[Parents[now]].remove(now)

Q = deque()
Q.append(0)
Done = [0] * N
Done[0] = 1
ans = 1
while Q:
    now = Q.popleft()
    for nex in Edge[now]:
        if Done[nex]:
            continue
        else:
            Q.append(nex)
            Done[nex] = 1
            ans += 1

if ans > N // 2:
    print('Fennec')
else:
    print('Snuke')

Solution (Python):
n = int(input())
g = [set() for _ in range(n)]
for i in range(n-1):
    a, b = map(int, input().split())
    g[a-1].add(b-1)
    g[b-1].add(a-1)

def dfs(s):
    visited = [-1]*n
    visited[s] = 0
    temp = [s]
    lst = []
    while temp:
        p = temp.pop()
        for a in g[p]:
            if visited[a] != -1:continue
            visited[a] = visited[p] + 1
            temp.append(a)
    return visited

lst0 = dfs(0)
lstn = dfs(n-1)
cnt = 0
for i in range(n):
    if lst0[i] <= lstn[i]: cnt += 1

if cnt > n - cnt: print('Fennec')
else:print('Snuke')

Solution (Python):
import typing
from typing import List, NamedTuple, Deque, Set, Counter

class node:
    def __init__(self, id: int) -> None:
        self.id: int = id
        self.parent: node = self
        self.root: node = self
        self.rank: int = 0
        self.connection: List[node] = []

    def addConnection(self, other: 'node') -> None:
        self.connection.append(other)
        other.connection.append(self)

    def delConnection(self, other: 'node') -> None:
        self.connection.remove(other)
        other.connection.remove(self)

    def setParent(self, other: 'node') -> None:
        self.parent = other
        self.rank = other.rank +1
    
    def setRoot(self, other: 'node') -> None:
        self.root = other

    def setAsRoot(self) -> None:
        self.parent = self
        self.root = self
        self.rank = 0


def makePath(root: node, target: node) -> Deque[node]:
    path: Deque[node] = Deque()
    path.append(target)
    while path[0] != root:
        path.appendleft(path[0].parent)
    return path


def bfs(root: node):
    reserved: Deque[node] = Deque([root])
    seen: Set[int] = {root.id}
    while len(reserved) > 0:
        current_node = reserved.popleft()
        for next_node in current_node.connection:
            if next_node.id in seen:
                continue
            next_node.setParent(current_node)
            next_node.setRoot(root)
            seen.add(next_node.id)
            reserved.append(next_node)


def main():
    N = int(input())
    Edge = [map(int, input().split()) for _ in range(N-1)]

    Node: List[node] = [node(i) for i in range(N)]
    for a, b in Edge:
        Node[a-1].addConnection(Node[b-1])

    
    bfs(Node[0])
    
    between: int = Node[N-1].rank -1
    
    sep = (between+1)//2
    path = makePath(Node[0], Node[N-1])
    
    path[sep].delConnection(path[sep+1])
    path[sep+1].setAsRoot()
    bfs(path[sep+1])
    
    fennec, snuke = Counter([n.root.id for n in Node]).values()
    
    print('Fennec' if fennec > snuke else 'Snuke')


if __name__ == '__main__':
    main()

Solution (Python):
n = int(input())
graph = [[] for _ in range(n)]
for _ in range(n-1):
  a, b = (int(x)-1 for x in input().split())
  graph[a].append(b)
  graph[b].append(a)

from collections import deque
def bfs(s:int)->list:
  dist = [-1]*n
  dist[s] = 0
  que = deque([s])
  while que:
    u = que.popleft()
    for v in graph[u]:
      if dist[v] != -1: continue
      dist[v] = dist[u] + 1
      que.append(v)
  return dist

dfen = bfs(0)
dsnu = bfs(n-1)
pfen = 0
psnu = 0
for i in range(n):
  if dfen[i] <= dsnu[i]: pfen += 1
  else: psnu += 1
ans = 'Fennec' if pfen > psnu else 'Snuke'
print(ans)

Solution (Python):
import sys
from collections import deque
import bisect
import copy
import heapq
import itertools
import math
input = sys.stdin.readline
sys.setrecursionlimit(1000000)
mod = 10 ** 9 + 7

def read_values(): return map(int, input().split())
def read_index(): return map(lambda x: int(x) - 1, input().split())
def read_list(): return list(read_values())
def read_lists(N): return [read_list() for n in range(N)]


def main():
    N = int(input())
    F = [set() for _ in range(N)]
    for _ in range(N - 1):
        a, b = read_index()
        F[a].add(b)
        F[b].add(a)

    D = [0] * N
    S = deque()
    S.append((1, 0))
    S.append((-1, N - 1))
    D[0] = 1
    D[N - 1] = -1
    while S:
        c, p = S.popleft()
        for q in F[p]:
            if D[q] != 0:
                continue
            D[q] = c
            S.append((c, q))
    a = D.count(1)
    b = N - a
    print("Fennec" if a > b else "Snuke")
        

if __name__ == "__main__":
    main()

Solution (Python):
N=int(input())
graph=[[] for i in range(N)]
for i in range(N-1):
  a,b=map(int,input().split())
  graph[a-1].append(b-1)
  graph[b-1].append(a-1)
from collections import deque  
def dfs(k):
  visited=[-1 for i in range(N)]
  visited[k]=0
  q=deque([])
  q.append(k)
  while q:
    u=q.popleft()
    for v in graph[u]:
      if visited[v]==-1:
        visited[v]=visited[u]+1
        q.append(v)
  return visited
a=dfs(0)
b=dfs(N-1)
count=0
for i in range(N):
  if a[i]<=b[i]:
    count+=1
if count>N//2:
  print("Fennec")
else:
  print("Snuke")

Solution (Python):
from collections import defaultdict, deque
N = int(input())
G = defaultdict(lambda: [])
for _ in range(N-1):
    a, b = map(int, input().split())
    G[a].append(b)
    G[b].append(a)


def bfs(v):
    seen = [0]*(N+1)
    queue = deque()
    dist = [-1]*(N+1)
    dist[v] = 0
    seen[v] = 1
    queue.append(v)
    while queue:
        q = queue.popleft()
        for nx in G[q]:
            if seen[nx]:
                continue
            dist[nx] = dist[q] + 1
            seen[nx] = 1
            queue.append(nx)
        
        
        
        
        
        
        
        
        
    return dist

d_1 = bfs(1)
d_N = bfs(N)
f = 1
s = 1
for v in range(2, N):
    if d_1[v] <= d_N[v]:
        f += 1
    else:
        s += 1
if f > s:
    print("Fennec")
else:
    print("Snuke")

Solution (Python):
import heapq as hq
from collections import deque
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,1))
    edges[b].append((a,1))
INF = float("inf")
d = [INF]*N
d[0] = 0
prev = [None]*N
q = [(0,0)]
while q:
    dist, i = hq.heappop(q)
    if d[i] < dist:
        continue
    for j, w in edges[i]:
        if d[j] > d[i]+w:
            d[j] = d[i]+w
            prev[j] = i
            hq.heappush(q, (d[j], j))
path = deque()
i = N-1
while prev[i] != 0:
    path.append(prev[i])
    i = prev[i]
fncq = deque([0])
snkq = deque([N-1])
fnc = 1
snk = 1
visited = [False]*N
visited[0] = True
visited[N-1] = True
while path:
    v = path.pop()
    fncq.append(v)
    visited[v] = True
    fnc += 1
    if path:
        v = path.popleft()
        snkq.append(v)
        visited[v] = True
        snk += 1
po = [fncq, snkq]
while fncq or snkq:
    for i in range(2):
        q = po[i]
        if q:
            v = q.popleft()
            for w,_ in edges[v]:
                if not visited[w]:
                    visited[w] = True
                    q.append(w)
                    if i == 0:
                        fnc += 1
                    else:
                        snk += 1
print("Fennec" if fnc > snk else "Snuke")

Solution (Python):
n = int(input())
graph = [[] for _ in range(n)]
for _ in range(n-1):
  a, b = (int(x)-1 for x in input().split())
  graph[a].append(b)
  graph[b].append(a)

from collections import deque
def bfs(s:int)->list:
  dist = [-1]*n
  dist[s] = 0
  que = deque([s])
  while que:
    u = que.popleft()
    for v in graph[u]:
      if dist[v] != -1: continue
      dist[v] = dist[u] + 1
      que.append(v)
  return dist

dfen = bfs(0)
dsnu = bfs(n-1)
pfen = 0
psnu = 0
for i in range(n):
  if dfen[i] <= dsnu[i]: pfen += 1
  else: psnu += 1
ans = 'Fennec' if pfen > psnu else 'Snuke'
print(ans)

Solution (Python):
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")





from collections import defaultdict
n = int(input())
ns = [[] for _ in range(n)]
for _ in range(n-1):
    u,v = map(int, input().split())
    u -= 1
    v -= 1
    ns[u].append(v)
    ns[v].append(u)
    


def bfs(start):
    from collections import deque
    q = deque([start])
    seen = [None] * n
    seen[start] = 0
    while q:
        u = q.pop()
        d = seen[u]
        for v in ns[u]:
            if seen[v] is None:
                seen[v] = d + 1
                q.appendleft(v)
    return seen
d1 = bfs(0)
d2 = bfs(n-1)
v = sum(d1[i]<=d2[i] for i in range(n))
v2 = n-v
if v>v2:
    print("Fennec")
else:
    print("Snuke")

Solution (Python):
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")





from collections import defaultdict
n = int(input())
ns = defaultdict(set)
for _ in range(n-1):
    u,v = map(int, input().split())
    u -= 1
    v -= 1
    ns[u].add(v)
    ns[v].add(u)
    


def bfs(start):
    from collections import deque
    q = deque([start])
    seen = [None] * n
    seen[start] = 0
    while q:
        u = q.pop()
        d = seen[u]
        for v in ns[u]:
            if seen[v] is None:
                seen[v] = d + 1
                q.appendleft(v)
    return seen
d1 = bfs(0)
d2 = bfs(n-1)
v = sum(d1[i]<=d2[i] for i in range(n))
v2 = n-v
if v>v2:
    print("Fennec")
else:
    print("Snuke")

Solution (Python):
from sys import stdin, setrecursionlimit
def input():
    return stdin.readline().strip()

setrecursionlimit(10**5)

n = int(input())
edge = [[] for _ in range(n)]
for _ in range(n-1):
    i, j = map(int, input().split())
    i -= 1
    j -= 1
    edge[i].append(j)
    edge[j].append(i)





tf = [False] * n
tf[0] = True
edge1 = [[] for _ in range(n)]
edge2 = [-1] * n

def divide(i):
    for j in edge[i]:
        if tf[j]:
            continue
        else:
            tf[j] = True
            edge1[i].append(j)
            edge2[j] = i
            divide(j)

divide(0)

now = n - 1
l = [n-1]
while edge2[now] != -1:
    now = edge2[now]
    l.append(now)

root = l[len(l)//2 - 1]

def divide2(i):
    ans = 1
    for j in edge1[i]:
        ans += divide2(j)
    return ans

Snuke = divide2(root)
Fennec = n - Snuke

if Snuke < Fennec:
    print('Fennec')
else:
    print('Snuke')

Solution (Python):
from sys import stdin, setrecursionlimit
def input():
    return stdin.readline().strip()

setrecursionlimit((10**5) * 2)

n = int(input())
edge = [[] for _ in range(n)]
for _ in range(n-1):
    i, j = map(int, input().split())
    i -= 1
    j -= 1
    edge[i].append(j)
    edge[j].append(i)





tf = [False] * n
tf[0] = True
edge1 = [[] for _ in range(n)]
edge2 = [-1] * n

def divide(i):
    for j in edge[i]:
        if tf[j]:
            continue
        else:
            tf[j] = True
            edge1[i].append(j)
            edge2[j] = i
            divide(j)

divide(0)

now = n - 1
l = [n-1]
while edge2[now] != -1:
    now = edge2[now]
    l.append(now)

root = l[len(l)//2 - 1]

def divide2(i):
    ans = 1
    for j in edge1[i]:
        ans += divide2(j)
    return ans

Snuke = divide2(root)
Fennec = n - Snuke

if Snuke < Fennec:
    print('Fennec')
else:
    print('Snuke')

Solution (Python):
N = int(input())
ab = [list(map(int,input().split())) for i in range(N-1)]

adj = [[]for i in range(N+1)]
for i in range(N-1):
    a,b = ab[i]
    adj[a].append(b)
    adj[b].append(a)


from collections import deque 

s = deque([])

cost = [10**10]*(N+1)

s.append([1,0])
while len(s)>0:
    place,time = s.pop()
    if time > cost[place]:
        continue
    cost[place]=time
    for i in adj[place]:
        if time < cost[i]:
            s.append([i,time+1])


root = [N]
nowp = N
nowt = cost[N]
while nowt>0:
    for i in adj[nowp]:
        if cost[i]==nowt-1:
            root.append(i)
            nowp=i
            nowt=nowt-1
            break

feneaba = len(root)//2-1
l,r = min(root[feneaba],root[feneaba+1]),max(root[feneaba],root[feneaba+1])



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

def unite(x,y):
    x = find(x)
    y = find(y)
    
    if x == y:
        return False
    else:
        
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True


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


def size(x):
    return -par[find(x)]



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

for i in range(N-1):
    a,b = ab[i]
    a,b = min(a,b),max(a,b)
    if a==l and b==r:
        continue
    unite(a,b)

print("Fennec" if size(1)>size(N) else "Snuke")

Solution (Python):
import collections

n = int(input())
graph = [[] for i in range(n + 1)]
for i in range(n - 1):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)
flag = [False for i in range(n + 1)]
flag2 = [False for i in range(n + 1)]
dis_f = [0 for i in range(n + 1)]
dis_s = [0 for i in range(n + 1)]
queue = collections.deque([1])
while queue:
    test = queue.popleft()
    flag[test] = True
    for i in graph[test]:
        if flag[i] == False:
            queue.append(i)
            dis_f[i] = dis_f[test] + 1
queue2 = collections.deque([n])
while queue2:
    test = queue2.popleft()
    flag2[test] = True
    for i in graph[test]:
        if flag2[i] == False:
            queue2.append(i)
            dis_s[i] = dis_s[test] + 1
count_f = 0
count_s = 0
for i in range(n):
    if dis_f[i + 1] <= dis_s[i + 1]:
        count_f += 1
    else:
        count_s += 1
if count_f > count_s:
    print("Fennec")
else:
    print("Snuke")

Solution (Python):
from collections import deque
n = int(input())
edges = [[] for i in range(n)]
for i in range(n - 1):
    a, b = map(int, input().split())
    edges[a - 1].append(b - 1)
    edges[b - 1].append(a - 1)
ans = [0] * n
ans[0] = 1
ans[-1] = -1
Q = deque([0, n - 1])
while Q:
    p = Q.popleft()
    cur = ans[p]
    for v in edges[p]:
        if ans[v] == 0:
            ans[v] = cur
            Q.append(v)
if ans.count(1) > ans.count(-1):
    print("Fennec")
else:
    print("Snuke")

Solution (Python):
from collections import deque
import sys
sys.setrecursionlimit(10**8)
n = int(input())
graph = [[] for _ in range(n)]
for _ in range(n - 1):
    a, b = map(lambda x: int(x) - 1, input().split())
    graph[a].append(b)
    graph[b].append(a)
fennec = [10**5 + 10] * n
fennec[0] = 0
snuke = [10**5 + 10] * n
snuke[n - 1] = 0


def bfs(arr, q):
    while len(q) > 0:
        nex_q = []
        for qq in q:
            for nex in graph[qq[0]]:
                if arr[nex] > qq[1] + 1:
                    arr[nex] = qq[1] + 1
                    nex_q.append([nex, arr[nex]])
        q = nex_q[:]


sq, gq = deque(), deque()
sq.append([0, 0])
gq.append([n - 1, 0])
bfs(fennec, sq)
bfs(snuke, gq)
ans = 0
for i in range(n):
    if fennec[i] <= snuke[i]:
        ans += 1
    else:
        ans -= 1



print("Fennec" if ans > 0 else "Snuke")

Solution (Python):
from collections import deque
import sys
sys.setrecursionlimit(10**8)
n = int(input())
graph = [[] for _ in range(n)]
for _ in range(n - 1):
    a, b = map(lambda x: int(x) - 1, input().split())
    graph[a].append(b)
    graph[b].append(a)
fennec = [10**5 + 10] * n
fennec[0] = 0
snuke = [10**5 + 10] * n
snuke[n - 1] = 0


def bfs(arr, q):
    while len(q) > 0:
        qq = q.popleft()
        for nex in graph[qq[0]]:
            if arr[nex] > qq[1] + 1:
                arr[nex] = qq[1] + 1
                q.append([nex, arr[nex]])


sq, gq = deque(), deque()
sq.append([0, 0])
gq.append([n - 1, 0])
bfs(fennec, sq)
bfs(snuke, gq)
ans = 0
for i in range(n):
    if fennec[i] <= snuke[i]:
        ans += 1
    else:
        ans -= 1

print("Fennec" if ans > 0 else "Snuke")

Solution (Python):
from collections import *
N = int(input())
G = [[] for n in range(N)]
for n in range(N-1):
  a,b = map(int,input().split())
  G[a-1].append(b-1)
  G[b-1].append(a-1)

color = N*[0]
color[0] = 1
color[N-1] = -1
q = deque([])
q.append(0)
q.append(N-1)

while q:
  node = q.popleft()
  c = color[node]
  for to in G[node]:
    if color[to]==0:
      color[to] = c
      q.append(to)

b = color.count(1)
w = color.count(-1)

if w<b:
  print("Fennec")
else:
  print("Snuke")

Solution (Python):
from collections import deque

def dfs(x):
    INF = 10**9
    q = deque()
    q.append(x)
    d = [INF] * n
    d[x] = 0
    while q:
        f = q.pop()
        now = d[f]
        for ce in e[f]:
            if d[ce] == INF:
                d[ce] = now + 1
                q.append(ce)
    return d    


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)

    
d0 = dfs(0)
dn = dfs(n-1)
f = 0
for i in range(n):
    if d0[i] <= dn[i]:
        f += 1
s = n - f
print('Fennec') if f > s else print('Snuke')

Solution (Python):
from collections import deque

def dfs(x):
    INF = 10**9
    q = deque()
    q.append(x)
    d = [INF] * n
    d[x] = 0
    while q:
        f = q.pop()
        now = d[f]
        for ce in e[f]:
            if d[ce] == INF:
                d[ce] = now + 1
                q.append(ce)
    return d    


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)

    
d0 = dfs(0)
dn = dfs(n-1)
f = 0
for i in range(n):
    if d0[i] <= dn[i]:
        f += 1
s = n - f
print('Fennec') if f > s else print('Snuke')

Solution (Python):
import sys
import math
import copy
from heapq import heappush, heappop, heapify
from functools import cmp_to_key
from bisect import bisect_left, bisect_right
from collections import defaultdict, deque, Counter



input = sys.stdin.readline
getS = lambda: input().strip()
getN = lambda: int(input())
getList = lambda: list(map(int, input().split()))
getZList = lambda: [int(x) - 1 for x in input().split()]

INF = float("inf")
MOD = 10**9 + 7
divide = lambda x: pow(x, MOD-2, MOD)

def nck(n, k, kaijyo):
    return (npk(n, k, kaijyo) * divide(kaijyo[k])) % MOD

def npk(n, k, kaijyo):
    if k == 0 or k == n:
        return n % MOD
    return (kaijyo[n] * divide(kaijyo[n-k])) % MOD

def fact_and_inv(SIZE):
    inv = [0] * SIZE  
    fac = [0] * SIZE  
    finv = [0] * SIZE  
    inv[1] = 1
    fac[0] = fac[1] = 1
    finv[0] = finv[1] = 1
    for i in range(2, SIZE):
        inv[i] = MOD - (MOD // i) * inv[MOD % i] % MOD
        fac[i] = fac[i - 1] * i % MOD
        finv[i] = finv[i - 1] * inv[i] % MOD

    return fac, finv

def renritsu(A, Y):
    
    
    
    A = np.matrix(A)
    Y = np.matrix(Y)
    Y = np.reshape(Y, (-1, 1))
    X = np.linalg.solve(A, Y)

    
    return X.flatten().tolist()[0]

class TwoDimGrid:
    
    def __init__(self, h, w, wall="
        self.h = h
        self.w = w
        self.size = (h+2) * (w+2)
        self.wall = wall
        self.get_grid()
        

    def get_grid(self):
        grid = [self.wall * (self.w + 2)]
        for i in range(self.h):
            grid.append(self.wall + getS() + self.wall)

        grid.append(self.wall * (self.w + 2))
        self.grid = grid
    def init_cost(self):
        self.cost = [INF] * self.size

    def pos(self, x, y):
        
        return y * (self.w + 2) + x
    def getgrid(self, x, y):
        return self.grid[y][x]
    def get(self, x, y):
        return self.cost[self.pos(x, y)]
    def set(self, x, y, v):
        self.cost[self.pos(x, y)] = v
        return
    def show(self):
        for i in range(self.h+2):
            print(self.cost[(self.w + 2) * i:(self.w + 2) * (i+1)])
    def showsome(self, tgt):
        for t in tgt:
            print(t)
        return
    def showsomejoin(self, tgt):
        for t in tgt:
            print("".join(t))
        return

    def search(self):
        grid = self.grid
        move = [(0, 1), (0, -1), (1, 0), (-1, 0)]
        move_eight = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]
        
        
        
        
        

def solve():
    n = getN()
    g = [[] for i in range(n)]

    for i in range(n - 1):
        a, b = getZList()
        g[a].append(b)
        g[b].append(a)

    cf = [INF for i in range(n)]
    cf[0] = 0
    cs = [INF for i in range(n)]
    cs[-1] = 0

    d = deque()
    d.append(0)
    while d:
        cur = d.popleft()
        cc = cf[cur]
        for nx in g[cur]:
            if cf[nx] > cc + 1:
                cf[nx] = cc + 1
                d.append(nx)

    d = deque()
    d.append(n-1)
    while d:
        cur = d.popleft()
        cc = cs[cur]
        for nx in g[cur]:
            if cs[nx] > cc + 1:
                cs[nx] = cc + 1
                d.append(nx)

    pf, ps = 0, 0
    for i in range(n):
        if cf[i] <= cs[i]:
            pf += 1
        else:
            ps += 1

    if pf > ps:
        print("Fennec")
    else:
        print("Snuke")
    return


def main():
    n = getN()
    for _ in range(n):
        solve()

    return
if __name__ == "__main__":
    
    solve()

Solution (Python):

import sys
from collections import deque
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

N = int(readline())
f_dist = [-1]*(N+1)
s_dist = [-1]*(N+1)
G = [[] for _ in range(N+1) ]
for _ in range(N-1):
    x, y = map(int,readline().split())
    G[x].append(y)
    G[y].append(x)
    
def dfs(q,dist):       
    while q:
        x = q.popleft()
        for nx in G[x]:
            if dist[nx] != -1:
                continue
            dist[nx] = dist[x] + 1
            q.append(nx)

q = deque([1])
f_dist[1] = 0
dfs(q,f_dist)
q = deque([N])
s_dist[N] = 0
dfs(q,s_dist)
f_cnt = 0
s_cnt = 0
for i in range(1,N+1):
    if f_dist[i] <= s_dist[i]:
        f_cnt += 1
    else:
        s_cnt += 1
if f_cnt > s_cnt:
    print('Fennec')
else:
    print('Snuke')

Solution (Python):
from collections import deque

N = int(input())
M = N - 1
graph = [[] for _ in range(N + 1)]
dis_f = []
dis_s = []

for i in range(M):
    a,b = map(int,input().rstrip().split(" "))
    graph[a].append(b)
    graph[b].append(a)

dist_f = [-1] * (N + 1)
dist_f[0] = 0
dist_f[1] = 0
d = deque()
d.append(1)
left = N -1
while(d):
    v = d.popleft()
    for i in graph[v]:
        if dist_f[i] != -1:
            continue
        dist_f[i] = dist_f[v] + 1
        d.append(i)
    


dist = [-1] * (N + 1)
dist[0] = 0
dist[N] = 0
d = deque()
d.append(N)
while(d):
    v = d.popleft()
    for i in graph[v]:
        if dist[i] != -1:
            continue
        dist[i] = dist[v] + 1
        d.append(i)

count_f = 0
count_s = 0
for i in range(N):
    if(dist_f[i + 1] <= dist[i + 1]):
        count_f += 1
    else:
        count_s += 1
if(count_f > count_s):
    print("Fennec")
else:
    print("Snuke")