CodeEff/ECCO huggingface dataset:
# Original solution
#高速化heapqダイクストラ
from collections import *
from heapq import*
import sys
input=lambda:sys.stdin.readline()


def DIJKSTRA(point,d):
    cost      = [float("inf")]*(n+1)
    Q         = []
    cost[point]=0
    heappush(Q,(point,cost[point]))
    while Q:
        prefnd,tmpC=heappop(Q)
        if cost[prefnd]<tmpC:
            continue
        for node,c in d[prefnd]:
            altC=c+tmpC
            if cost[node]>altC:
                cost[node]=altC
                heappush(Q,(node,altC))
    return cost

n=int(eval(input()))
d={}
for i in range(n-1):
    a,b=list(map(int,input().split()))
    if a in list(d.keys()):
        d[a].append([b,1])
    else:
        d[a]=[[b,1]]
    if b in list(d.keys()):
        d[b].append([a,1])
    else:
        d[b]=[[a,1]]
        
x=DIJKSTRA(1,d)[1:]
y=DIJKSTRA(n,d)[1:]
#print(x)
#print(y)
F=0
S=0
for i in range(n):
    if x[i]<=y[i]:
        F+=1
    else:
        S+=1
if F<=S:
    print("Snuke")
else:
    print("Fennec")

# Optimized solution
#高速化heapqダイクストラ
from collections import *
from heapq import*
import sys
input=lambda:sys.stdin.readline()


def BFS(point,d):
    cost=[1e7]*(n+1)
    cost[point]=0
    Q=[]
    heappush(Q,(0,point))
    
    while Q:
        c,p=heappop(Q)
        for np in d[p]:
            if cost[np]==1e7:
                cost[np]=c+1
                heappush(Q,(c+1,np))
    return cost

n=int(eval(input()))
d={}
for i in range(n-1):
    a,b=list(map(int,input().split()))
    if a in list(d.keys()):
        d[a].append(b)
    else:
        d[a]=[b]
    if b in list(d.keys()):
        d[b].append(a)
    else:
        d[b]=[a]
        
x=BFS(1,d)[1:]
y=BFS(n,d)[1:]

#print(x,y)

F=0
S=0

for s,t in zip(x,y):
    if s<=t:
        F+=1
    else:
        S+=1

if F<=S:
    print("Snuke")
else:
    print("Fennec")
# Original solution
#高速化heapqダイクストラ
from collections import *
from heapq import*
import sys
input=lambda:sys.stdin.readline()


def BFS(point,d):
    cost=[1e7]*(n+1)
    cost[point]=0
    Q=[]
    heappush(Q,(0,point))
    
    while Q:
        c,p=heappop(Q)
        for np in d[p]:
            if cost[np]==1e7:
                cost[np]=c+1
                heappush(Q,(c+1,np))
    return cost

n=int(eval(input()))
d={}
for i in range(n-1):
    a,b=list(map(int,input().split()))
    if a in list(d.keys()):
        d[a].append(b)
    else:
        d[a]=[b]
    if b in list(d.keys()):
        d[b].append(a)
    else:
        d[b]=[a]
        
x=BFS(1,d)[1:]
y=BFS(n,d)[1:]

#print(x,y)

F=0
S=0

for s,t in zip(x,y):
    if s<=t:
        F+=1
    else:
        S+=1

if F<=S:
    print("Snuke")
else:
    print("Fennec")

# Optimized solution
#高速化heapqダイクストラ
from collections import *
from heapq import*
import sys
input=lambda:sys.stdin.readline()


def BFS(point,d):
    cost=[1e7]*(n+1)
    cost[point]=0
    Q=[]
    heappush(Q,(0,point))
    
    while Q:
        c,p=heappop(Q)
        for np in d[p]:
            if cost[np]==1e7:
                cost[np]=c+1
                heappush(Q,(c+1,np))
    return cost

n=int(eval(input()))
d={}
for i in range(n-1):
    a,b=list(map(int,input().split()))
    if a in d:
        d[a].append(b)
    else:
        d[a]=[b]
    if b in d:
        d[b].append(a)
    else:
        d[b]=[a]
        
x=BFS(1,d)[1:]
y=BFS(n,d)[1:]

#print(x,y)

F=0
S=0

for s,t in zip(x,y):
    if s<=t:
        F+=1
    else:
        S+=1

if F<=S:
    print("Snuke")
else:
    print("Fennec")
# Original solution
#高速化heapqダイクストラ
from collections import *
from heapq import*
import sys
input=lambda:sys.stdin.readline()


def BFS(point,d):
    cost=[1e7]*(n+1)
    cost[point]=0
    Q=[]
    heappush(Q,(0,point))
    
    while Q:
        c,p=heappop(Q)
        for np in d[p]:
            if cost[np]==1e7:
                cost[np]=c+1
                heappush(Q,(c+1,np))
    return cost

n=int(eval(input()))
d=[deque()for i in range(n+1)]
for i in range(n-1):
    a,b=list(map(int,input().split()))
    d[a].append(b)
    d[b].append(a)
        
x=BFS(1,d)[1:]
y=BFS(n,d)[1:]

#print(x,y)

F=0
S=0

for s,t in zip(x,y):
    if s<=t:
        F+=1
    else:
        S+=1

if F<=S:
    print("Snuke")
else:
    print("Fennec")


# Optimized solution
from collections import *
from heapq import*
import sys
input=lambda:sys.stdin.readline()


def BFS(point,d):
    cost=[1e7]*(n+1)
    cost[point]=0
    Q=[]
    Q.append((0,point))
    
    while Q:
        c,p=Q.pop()
        for np in d[p]:
            if cost[np]==1e7:
                cost[np]=c+1
                Q.append((c+1,np))
    return cost

n=int(eval(input()))
d=[deque()for i in range(n+1)]
for i in range(n-1):
    a,b=list(map(int,input().split()))
    d[a].append(b)
    d[b].append(a)
        
x=BFS(1,d)[1:]
y=BFS(n,d)[1:]

#print(x,y)

F=0
S=0

for s,t in zip(x,y):
    if s<=t:
        F+=1
    else:
        S+=1

if F<=S:
    print("Snuke")
else:
    print("Fennec")
# Original solution
from collections import *
from heapq import*
import sys
input=lambda:sys.stdin.readline()


def BFS(point,d):
    cost=[1e7]*(n+1)
    cost[point]=0
    Q=[]
    Q.append((0,point))
    
    while Q:
        c,p=Q.pop()
        for np in d[p]:
            if cost[np]==1e7:
                cost[np]=c+1
                Q.append((c+1,np))
    return cost

n=int(eval(input()))
d=[deque()for i in range(n+1)]
for i in range(n-1):
    a,b=list(map(int,input().split()))
    d[a].append(b)
    d[b].append(a)
        
x=BFS(1,d)[1:]
y=BFS(n,d)[1:]

#print(x,y)

F=0
S=0

for s,t in zip(x,y):
    if s<=t:
        F+=1
    else:
        S+=1

if F<=S:
    print("Snuke")
else:
    print("Fennec")


# Optimized solution
from collections import *
from heapq import*
import sys
input=lambda:sys.stdin.readline()


def BFS(point,d):
    cost=[1e7]*(n+1)
    cost[point]=0
    Q=deque()
    Q.appendleft((0,point))
    
    while Q:
        c,p=Q.pop()
        for np in d[p]:
            if cost[np]==1e7:
                cost[np]=c+1
                Q.appendleft((c+1,np))
    return cost

n=int(eval(input()))
d=[[]for i in range(n+1)]
for i in range(n-1):
    a,b=list(map(int,input().split()))
    d[a].append(b)
    d[b].append(a)
        
x=BFS(1,d)[1:]
y=BFS(n,d)[1:]

#print(x,y)

F=0
S=0

for s,t in zip(x,y):
    if s<=t:
        F+=1
    else:
        S+=1

if F<=S:
    print("Snuke")
else:
    print("Fennec")
# Original solution
from collections import deque

N = int(eval(input()))
edges = [[] for _ in range(N)]

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

que = deque([])
que.append((0, 0))

minDist = [float('inf') for _ in range(N)]

while que:
    now, dist = que.popleft()

    if minDist[now] <= dist:
        continue
    minDist[now] = dist

    for to in edges[now]:
        if dist + 1 < minDist[to]:
            que.append((to, dist + 1))

now = N - 1
minPath = [now]
dist = minDist[N - 1]
while dist > 0:
    for back in edges[now]:
        if minDist[back] == dist - 1:
            minPath.append(back)
            dist -= 1
            now = back
            break


edges[minPath[len(minPath) // 2]].remove(minPath[len(minPath) // 2 - 1])
edges[minPath[len(minPath) // 2 - 1]].remove(minPath[len(minPath) // 2])

confilm = [0 for _ in range(N)]
que.clear()
que.append(0)

while que:
    now = que.popleft()

    confilm[now] = 1

    for to in edges[now]:
        if confilm[to] == 0:
            que.append(to)

blackCount = sum(confilm)
witeCount = N - blackCount

if blackCount > witeCount:
    print('Fennec')
else:
    print('Snuke')

# Optimized solution
N = int(eval(input()))
edges = [[] for _ in range(N)]

for _ in range(N - 1):
    fr, to = list(map(int, input().split()))
    fr -= 1
    to -= 1
    edges[fr].append(to)
    edges[to].append(fr)

def calc(s):
    st = [s]
    minDist = [10**18] * N
    minDist[s] = 0
    while st:
        now = st.pop()
        for to in edges[now]:
            if minDist[to] > minDist[now] + 1:
                minDist[to] = minDist[now] + 1
                st.append(to)
    return minDist

A = calc(0)
B = calc(N - 1)

ans = 0
for i in range(N):
    ans += 1 if A[i] <= B[i] else -1
print(('Fennec' if ans > 0 else 'Snuke'))
# Original solution
N = int(eval(input()))
T = [[] for i in range(N)]
for i in range(N - 1):
  a, b = list(map(int, input().split()))
  T[a - 1].append(b - 1)
  T[b - 1].append(a - 1)
def dijkstra(N, s0):
  D = [N] * N
  Q = [s0]
  D[s0] = 0
  while Q:
    s = Q[0]
    Q = Q[1:]
    for adj in T[s]:
      if D[s] + 1 < D[adj]:
        D[adj] = D[s] + 1
        Q.append(adj)
  return D
D1 = dijkstra(N, 0)
D2 = dijkstra(N, N - 1)
score = 0
for i in range(N):
  score += 1 if D1[i] <= D2[i] else -1
print(('Fennec' if score > 0 else 'Snuke'))

# Optimized solution
N = int(eval(input()))
T = [[] for i in range(N)]
for i in range(N - 1):
  a, b = list(map(int, input().split()))
  T[a - 1].append(b - 1)
  T[b - 1].append(a - 1)
def dijkstra(N, s0):
  D = [N] * N
  D[s0] = 0
  Q = [N] * N
  Q[0] = s0
  tail = 1
  for i in range(N):
    s = Q[i]
    for adj in T[s]:
      if D[s] + 1 < D[adj]:
        D[adj] = D[s] + 1
        Q[tail] = adj
        tail += 1
  return D
D1 = dijkstra(N, 0)
D2 = dijkstra(N, N - 1)
score = 0
for i in range(N):
  score += 1 if D1[i] <= D2[i] else -1
print(('Fennec' if score > 0 else 'Snuke'))
# Original solution
N = int(eval(input()))

inf = float('inf')

import heapq
def dijkstra(adj, n, st=1):
    dj = [inf] * (n + 1)
    paths = dict((x, [x]) for x in range(n + 1))
    dj[st] = 0
    q = []
    heapq.heappush(q, (0, st))
    while q:
        fc, fn = heapq.heappop(q)
        if dj[fn] < fc: continue
        for tn, lc in adj[fn]:
            if dj[fn] + lc < dj[tn]:
                dj[tn] = dj[fn] + lc
                paths[tn] = paths[fn] + [tn]
                heapq.heappush(q, (dj[tn], tn))
    return dj, paths

import itertools
def reachable(adj, st):
    reached = set([st])
    cur = set([st])
    while cur:
        nxt = set(itertools.chain(*[[y[0] for y in adj[x]] for x in cur]))
        reached.update(cur)
        cur = nxt - reached
    return reached

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

costs, paths = dijkstra(adj, N, 1)
main_street = paths[N]
import math
mid = math.ceil(len(main_street) / 2) - 1
mid_v0 = main_street[mid]
mid_v1 = main_street[mid + 1]
adj[mid_v0] = [x for x in adj[mid_v0] if x[0] != mid_v1]
adj[mid_v1] = [x for x in adj[mid_v1] if x[0] != mid_v0]

fennec = len(reachable(adj, 1))
snuke = N - fennec

print(("Fennec" if fennec > snuke else "Snuke"))

# Optimized solution
N = int(eval(input()))

inf = float('inf')

import heapq
def dijkstra(adj, n, st=1):
    dj = [inf] * (n + 1)
    dj[st] = 0
    q = []
    heapq.heappush(q, (0, st))
    while q:
        fc, fn = heapq.heappop(q)
        if dj[fn] < fc: continue
        for tn, lc in adj[fn]:
            if dj[fn] + lc < dj[tn]:
                dj[tn] = dj[fn] + lc
                heapq.heappush(q, (dj[tn], tn))
    return dj

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

c_f = dijkstra(adj, N, 1)
c_s = dijkstra(adj, N, N)

score = 0
for i in range(1, N + 1):
    if c_f[i] > c_s[i]:
        score -= 1
    else:
        score += 1

print(("Fennec" if score > 0 else "Snuke"))
# Original solution

from collections import deque

def bfs(s, dist):
    visited = [False] * (N+1)
    q = [(s, 1)]
    visited[s] = True

    while q:
        u, c = q.pop()
        for v in graph[u]:
            if not visited[v]:
                visited[v] = True
                dist[v] = c
                q.append((v, c+1))


N = int(eval(input()))
graph = [deque() for i in range(N+1)]
dist = [[0] * (N+1) for i in range(2)]

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

bfs(1, dist[0])
bfs(N, dist[1])

b = w = 0
for i in range(2, N):
    if dist[0][i] <= dist[1][i]:
        b += 1
    else:
        w += 1
if b <= w:
    print('Snuke')
else:
    print('Fennec')

# Optimized solution

from collections import deque

# BFSで、B/Wそれぞれのスタート地点から拡張点への距離を取得
def bfs(s, distance):
    visited = [False] * (N+1)
    q = [(s, 1)]
    visited[s] = True

    while q:
        u, dist = q.pop()
        for v in graph[u]:
            if not visited[v]:
                visited[v] = True
                distance[v] = dist
                q.append((v, dist+1))
#    print(distance)


N = int(eval(input()))
graph = [deque() for i in range(N+1)]
distance = [[0] * (N+1) for i in range(2)]

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

#print(graph)

bfs(1, distance[0])
bfs(N, distance[1])

# 各頂点について、より近いほうが塗れたことに
b = w = 0
for i in range(2, N):
    if distance[0][i] <= distance[1][i]:
        b += 1
    else:
        w += 1
if b <= w:
    print('Snuke')
else:
    print('Fennec')
# Original solution
# [数学、特にグラフ理論の分野における木（き、）とは、連結で閉路を持たないグラフである。]
# なので1->Nは1通り。つまり1->Nの最短経路上にあるマスをつぶすのが先
# で、残ったのを探索できるが、こういう二段構えで実装するのが面倒。
# もうちょっと考えると、1->i とi->Nの距離をみたとき、前者が小さければ先に到達できるので黒で埋められることが分かる
# （進めなくなったら負け、がめんどくさいが、すすめなくなったらパス、とすると、勝敗は変わらないことになる）
# 1とNからスタートして2回BFSすりゃいいか

import sys
from collections import deque

sys.setrecursionlimit(10 ** 8)

n = int(eval(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)

table_from_one = [10 ** 5 for _ in range(n)]
table_from_one[0] = 0
table_from_n = [10 ** 5 for _ in range(n)]
table_from_n[-1] = 0
arr_from_one = deque([0])
arr_from_n = deque([n - 1])


def set_table(table, arr):
    while len(arr) > 0:
        cur = arr.popleft()
        for next_node in graph[cur]:
            if table[next_node] < 10 ** 5:
                continue
            table[next_node] = table[cur] + 1
            arr.append(next_node)


set_table(table_from_one, arr_from_one)
set_table(table_from_n, arr_from_n)
result = 0
for i in range(n):
    if table_from_one[i] <= table_from_n[i]:
        result += 1
    else:
        result -= 1
print(("Fennec" if result > 0 else "Snuke"))


# Optimized solution
from collections import deque
import sys
sys.setrecursionlimit(10**8)
n = int(eval(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)
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
# なんでans>=0じゃないん？？？？？？？？？？？
print(("Fennec" if ans > 0 else "Snuke"))
# Original solution
from collections import defaultdict
N = int(eval(input()))
dic = defaultdict(list)

for i in range(N-1):
  a, b  = list(map(int, input().split()))
  dic[a-1] += [b-1]
  dic[b-1] += [a-1]

dist1 = [float('inf')]*N
dist2 = [float('inf')]*N

q1 = [0]
q2 = [N-1]

dist1[0] = 0
dist2[N-1] = 0

while q1:
  e = q1.pop()
  for p in dic[e]:
    if dist1[p]>dist1[e]+1:
      dist1[p] = dist1[e]+1
      q1 += [p]

while q2:
  e = q2.pop()
  for p in dic[e]:
    if dist2[p]>dist2[e]+1:
      dist2[p] = dist2[e]+1
      q2 += [p]

fennec = 0
snuke = 0
for i in range(N):
  if dist1[i]<=dist2[i]:
    fennec += 1
  else:
    snuke += 1
if fennec>snuke:
  print('Fennec')
else:
  print('Snuke')

# Optimized solution
from collections import deque
N, *L = list(map(int, open(0).read().split()))
dic = [[] for i in range(N+1)]
for a,b in zip(*[iter(L)]*2):
  dic[a] += [b]
  dic[b] += [a]
fdist = [-1]*(N+1)
sdist = [-1]*(N+1)
fdist[1] = 0
sdist[N] = 0
q = deque([1])
while q:
  v = q.popleft()
  for u in dic[v]:
    if fdist[u] == -1:
      fdist[u] = fdist[v] + 1
      q.append(u)
q = deque([N])
while q:
  v = q.popleft()
  for u in dic[v]:
    if sdist[u]==-1:
      sdist[u] = sdist[v] + 1
      q.append(u)
ans = sum(a<=b for a,b in zip(fdist,sdist))-1
if 2*ans>N:
  print('Fennec')
else:
  print('Snuke')
# Original solution
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


### 木の読み込み tree

# サイズが大きいとdefaultdictが早い(for文を書かなくて済む)
from collections import defaultdict
n = int(eval(input()))
ns = defaultdict(set)
for _ in range(n-1):
    u,v = list(map(int, input().split()))
    u -= 1
    v -= 1
    ns[u].add(v)
    ns[v].add(u)
    
### BFS 幅優先探索

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

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


### 木の読み込み tree

# サイズが大きいとdefaultdictが早い(for文を書かなくて済む)
from collections import defaultdict
n = int(eval(input()))
ns = [[] for _ in range(n)]
for _ in range(n-1):
    u,v = list(map(int, input().split()))
    u -= 1
    v -= 1
    ns[u].append(v)
    ns[v].append(u)
    
### BFS 幅優先探索

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")
# Original solution
from collections import deque


N, *AB = list(map(int, open(0).read().split()))

E = [[] for _ in range(N + 1)]
for a, b in zip(*[iter(AB)] * 2):
    E[a].append(b)
    E[b].append(a)


def get_dist(src):
    Q = deque([(src, 0)])
    dist = [-1] * (N + 1)
    while Q:
        v, d = Q.popleft()
        dist[v] = d
        for u in E[v]:
            if dist[u] < 0:
                Q.append((u, d + 1))
    return dist[1:]

F = get_dist(1)
S = get_dist(N)
fennec, snuke = 0, 0
for f, s in zip(F, S):
    if f <= s:
        fennec += 1
    else:
        snuke += 1

if fennec > snuke:
    print("Fennec")
else:
    print("Snuke")


# Optimized solution
from collections import deque

N, *AB = list(map(int, open(0).read().split()))

E = [[] for _ in range(N + 1)]
for a, b in zip(*[iter(AB)] * 2):
    E[a].append(b)
    E[b].append(a)


def get_dist(src):
    Q = deque([src])
    dist = [0] * (N + 1)
    while Q:
        v =  Q.popleft()
        for u in E[v]:
            if dist[u] == 0:
                Q.append(u)
                dist[u] = dist[v] + 1
    return dist[1:]

F = get_dist(1)
S = get_dist(N)

fennec, snuke = 0, 0
for f, s in zip(F, S):
    if f <= s:
        fennec += 1
    else:
        snuke += 1

if fennec > snuke:
    print("Fennec")
else:
    print("Snuke")
# Original solution
import sys
input = sys.stdin.readline

#O(ElogV)
import heapq
def dijkstra_heap(s):
    #始点sから各頂点への最短距離
    d = [float("inf")] * n
    used = [True] * n #True:未確定
    d[s] = 0
    used[s] = False
    edgelist = []
    for e in edge[s]:
        heapq.heappush(edgelist,e)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        #まだ使われてない頂点の中から最小の距離のものを探す
        if not used[minedge[1]]:
            continue
        v = minedge[1]
        d[v] = minedge[0]
        used[v] = False
        for e in edge[v]:
            if used[e[1]]:
                heapq.heappush(edgelist,[e[0]+d[v],e[1]])
    return d

################################
n = int(eval(input())) #n:頂点数　w:辺の数
w = n - 1

edge = [[] for i in range(n)]
#edge[i] : iから出る道の[重み,行先]の配列
for i in range(w):
    x,y = list(map(int,input().split()))
    x -= 1
    y -= 1
    z = 1
    edge[x].append([z,y])
    edge[y].append([z,x]) 

dis_from_f = dijkstra_heap(0)
dis_from_s = dijkstra_heap(n - 1)

cnt = 0
for i, j in zip(dis_from_f, dis_from_s):
    if i <= j:
        cnt += 1
if cnt > n - cnt:
    print("Fennec")
else:
    print("Snuke")

# Optimized solution
import sys
input = sys.stdin.readline

import heapq
def dijkstra(s):
    # 始点sから各頂点への最短距離
    d = [float('inf')]*n
    d[s] = 0
    # 各頂点が訪問済みかどうか
    used = [False]*n
    used[s] = True
    # 仮の距離を記録するヒープ
    que = []
    for e in edge[s]:
        heapq.heappush(que, e)
    while que:
        minedge = heapq.heappop(que)
        if used[minedge[1]]:
            continue
        v = minedge[1]
        d[v] = minedge[0]
        used[v] = True
        for e in edge[v]:
            if not used[e[1]]:
                heapq.heappush(que, [e[0] + d[v], e[1]])
    return d

################################
n = int(eval(input())) #n:頂点数　w:辺の数
w = n - 1

edge = [[] for i in range(n)]
#edge[i] : iから出る道の[重み,行先]の配列
for i in range(w):
    x,y = list(map(int,input().split()))
    x -= 1
    y -= 1
    z = 1
    edge[x].append([z,y])
    edge[y].append([z,x]) 

dis_from_f = dijkstra(0)
dis_from_s = dijkstra(n - 1)

cnt = 0
for i, j in zip(dis_from_f, dis_from_s):
    if i <= j:
        cnt += 1
if cnt > n - cnt:
    print("Fennec")
else:
    print("Snuke")
# Original solution
# -*- coding: utf-8 -*-
#Python
import sys

N=eval(input())
a=[[] for i in range(N+1)]

for i in range(N-1):
    u,v=list(map(int,input().split()))
    a[u].append(v)
    a[v].append(u)

#print a

#初期化
kyori=(N+1)*[0]

sys.setrecursionlimit(1000000)
#深さ優先探索
def dfs(Graph, Start, Visited=None):
	if (Visited==None):  Visited = [] #開始点のときに探索済みリストをつくる
	Visited.append(Start)  #現在の頂点を探索済みリストに加える
	#print(Start, "\n", Visited)  #現在の頂点と探索済みリストを表示
	for Next in Graph[Start]:  #次に探索する頂点の候補
		#print "Next::"+str(Next)
		if ( Next in Visited ):  continue  #訪問済みリストにある頂点は飛ばす
		kyori[Next]=kyori[Start]+1
		dfs(Graph, Next, Visited)  #再帰
	return kyori


kyori_from_start=dfs(a,1)


kyori=(N+1)*[0]
dfs(a,N)




f_p=0
s_p=0
for k in range(1,N+1):
	if kyori_from_start[k]<=kyori[k]:
		f_p+=1
	else:
		s_p+=1

#print f_p
#print s_p

if f_p>s_p:
	print('Fennec')
else:
	print('Snuke')


# Optimized solution
# -*- coding: utf-8 -*-
#Python
import sys

N=eval(input())
adj=[[] for i in range(N+1)]

#隣接リスト
for i in range(N-1):
    x,y=list(map(int,input().split()))
    adj[x].append(y)
    adj[y].append(x)

#print adj

#訪問判別フラグ
F=(N+1)*[0]

#Stack
S=[]

#距離
dist=(N+1)*[0]


#先頭から深さ優先探索
S.append(1)
while len(S) != 0:
	#print S
	v=S.pop()
	#print v
	
	if F[v]==0:
		F[v]=1
		#print F
		for u in adj[v]:
			#print "u::"+str(u)
			if F[u]==0:
				S.append(u)
				dist[u]=dist[v]+1
				#print S

#print dist



#訪問判別フラグ
F=(N+1)*[0]

#Stack
S=[]

#距離
dist2=(N+1)*[0]

#最後から深さ優先探索
S.append(N)
while len(S) != 0:
	#print S
	v=S.pop()
	#print v
	
	if F[v]==0:
		F[v]=1
		#print F
		for u in adj[v]:
			#print "u::"+str(u)
			if F[u]==0:
				S.append(u)
				dist2[u]=dist2[v]+1
				#print S

#print dist2



f_p=0
s_p=0
for k in range(1,N+1):
	if dist[k]<=dist2[k]:
		f_p+=1
	else:
		s_p+=1


if f_p>s_p:
	print('Fennec')
else:
	print('Snuke')