{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TupleSections #-}

import Control.Monad
import Control.Monad.Primitive
import Control.Monad.ST
import qualified Data.ByteString.Char8 as C
import qualified Data.Set as S
import Data.Maybe
import Data.Vector.Generic ((!))
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as VM
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM

main = C.interact $ put . sol . get

get = U.unfoldr (C.readInt . C.dropWhile (<'0'))

put = C.pack

sol v = if c1==cn
  then if even d then "Fennec" else "Snuke"
  else if c1>cn then "Fennec" else "Snuke"
  where
  n = U.head v
  u = U.tail v
  t1 = go $ f U.empty n u
  c1 = U.length $ U.filter (== t1!1) t1
  tn = go $ f U.empty 1 u
  cn = U.length $ U.filter (== tn!n) tn
  -- union-find
  go es = runST $ do
    uf <- newUF n
    U.foldM'_ upd uf es
    U.freeze (ids uf)
  upd uf (i,j) = do
    b <- findUF uf i j
    unless b $ do
      uniteUF uf i j
    return uf
  -- number of levels between #1 and #n
  d = levels n tree $ S.singleton (0,1)
  tree = build n $ U.unfoldrN (n-1) split2 u
  split2 u = Just ((U.head v,U.last v), w) where (v,w) = U.splitAt 2 u


-- edges excluding a node
f e x v
  | U.null v    = e
  | U.elem x h  = f e x t
  | otherwise   = f (U.cons (U.head h, U.last h) e) x t
  where
  (h,t) = U.splitAt 2 v

data UnionFind s = UnionFind {ids :: UM.STVector s Int, szs :: UM.STVector s Int}

newUF :: Int -> ST s (UnionFind s)
newUF n = UnionFind <$> U.unsafeThaw (U.enumFromN 0 (n+1)) <*> UM.replicate (n+1) 1

findUF :: UnionFind s -> Int -> Int -> ST s Bool
findUF uf p q = (==) <$> rootUF uf p <*> rootUF uf q

rootUF :: PrimMonad m => UnionFind (PrimState m) -> Int -> m Int
rootUF uf i = do
  p <- UM.unsafeRead (ids uf) i
  if p==i
    then return i
    else do
      gp <- UM.unsafeRead (ids uf) p
      if gp==p
        then return p
        else do
          UM.unsafeWrite (ids uf) i gp
          rootUF uf i

uniteUF :: UnionFind s -> Int -> Int -> ST s ()
uniteUF uf p q = do
  i <- rootUF uf p
  j <- rootUF uf q
  si <- UM.unsafeRead (szs uf) i
  sj <- UM.unsafeRead (szs uf) j
  if si<sj
    then do
      UM.unsafeWrite (ids uf) i j
      UM.unsafeWrite (szs uf) j (si+sj)
    else do
      UM.unsafeWrite (ids uf) j i
      UM.unsafeWrite (szs uf) i (si+sj)

build :: Int -> U.Vector (Int, Int) -> V.Vector (U.Vector Int)
build n es = V.create $ do
  v <- VM.replicate (n+1) U.empty
  let add a b = VM.read v a >>= VM.write v a . (U.cons b) 
  U.forM_ es $ \(a,b) -> do
    add a b
    add b a
  return v

levels :: Int -> V.Vector (U.Vector Int) -> S.Set (Int, Int) -> Int
levels goal tree q
  | goal == nd = lvl
  | otherwise = levels goal tree q''
  where
  ((lvl,nd),q') = fromJust $ S.minView q
  q'' = U.foldr' (S.insert . (lvl+1,)) q' $ tree!nd