Buggy python submission (verdict: Time Limit Exceeded):

# -*- coding: utf-8 -*-

import sys


class UnionFind:
    '''
    配列を用いたUnionFind
    '''

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

    def find(self, x):
        '''
        xのグループ番号を返す
        '''
        return self.table[x]

    def union(self, x, y):
        '''
        xとyが同じグループならFalse
        xとyが違うグループなら、同じグループにする(くっつける)
        '''
        x1 = self.find(x)
        y1 = self.find(y)

        if x1 == y1:
            return False

        for i in range(len(self.table)):
            if self.table[i] == y1:
                self.table[i] = x1
        return True

    def same(self, x, y):
        '''
        xとyが同じグループならtrue
        '''
        x1 = self.find(x)
        y1 = self.find(y)
        return x1 == y1

    def get_table(self):
        return self.table
# python template for atcoder1


sys.setrecursionlimit(10**9)
input = sys.stdin.readline

N = int(input())
adj = [[] 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)

Un = UnionFind(N)
S = [N-1]
F = [0]
S_or = N-1
F_or = 0


def oneStep(turn):
    if turn == 1:
        if len(S) == 0:
            return
        c = S.pop(0)
        for i in adj[c]:
            #print("i->", i)
            #print("i2->", Un.find(i))
            if not Un.same(S_or, i) and not Un.same(F_or, i):
                #print("union Sun", i)
                Un.union(S_or, i)
                S.append(i)
    else:
        if len(F) == 0:
            return
        c = F.pop(0)
        for i in adj[c]:
            if not Un.same(S_or, i) and not Un.same(F_or, i):
                #print("union Fen", i)
                Un.union(F_or, i)
                F.append(i)
    # print(Un.get_table())
    # print(S)
    # print(F)


turn = 0
while S or F:
    # print("step")
    if turn == 1:
        if len(S) != 0:
            oneStep(turn)
        turn = 0
    else:
        if len(F) != 0:
            oneStep(turn)
        turn = 1

# print("end")
# print(Un.get_table())
if Un.get_table().count(0) > Un.get_table().count(N-1):
    ans = "Fennec"
else:
    ans = "Snuke"
print(ans)


Fixed submission:

# -*- coding: utf-8 -*-

import sys


class UnionFind:
    '''
    配列を用いたUnionFind
    '''

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

    def find(self, x):
        '''
        xのグループ番号を返す
        '''
        return self.table[x]

    def union(self, val, y):
        '''
        Fennecは0
         SnukeはN-1とすることで、O(1)にする
         '''
        self.table[y] = val

    def same(self, x, y):
        '''
        xとyが同じグループならtrue
        '''
        x1 = self.find(x)
        y1 = self.find(y)
        return x1 == y1

    def get_table(self):
        return self.table
# python template for atcoder1


sys.setrecursionlimit(10**9)
input = sys.stdin.readline

N = int(input())
adj = [[] 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)

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)