module DirectedGraph
  (* 道の表現 *)
  (Path : sig
    type t
    (* 辺の名前 *)
    type edge
    (* 長さ0の道 *)
    val nil : t
    (* 道の後ろに辺を付け足した道 *)
    val snoc : t -> edge -> t
  end) :
sig
  (* BFSにより，重みのないグラフの最短経路を求める *)
  val bfs :
    (* 頂点数（Hashtblを用いるので目安程度） *)
    int ->
    (* 辺の名前が付いた隣接リスト *)
    ('v -> ('v * Path.edge) list) ->
    (* 始点 *)
    'v ->
    (* 最短経路を返す関数 辿り着けなければNoneを返す） *)
    ('v -> Path.t option)
end = struct
  let rec bfs_aux es d frontier t =
    try Some (Hashtbl.find d t) with
    | Not_found ->
        match !frontier with
        | [] -> None
        | _ :: _ ->
            frontier := List.fold_right (fun u ->
              List.fold_right (fun (v, e) frontier ->
                if Hashtbl.mem d v
                then frontier
                else (Hashtbl.add d v (Path.snoc (Hashtbl.find d u) e); v :: frontier))
              (es u)) !frontier [];
            bfs_aux es d frontier t

  (*
   * 終点に辿り着いた時点で探索を切り上げるが，
   * 戻り値の関数を覚えておくと，途中まで探索した結果が再利用される
   * （#trace bfs_aux すると分かりやすい）
   *)
  let bfs n es s =
    let d = Hashtbl.create n in
    Hashtbl.add d s Path.nil;
    let frontier = ref [s] in
    bfs_aux es d frontier
end

(* 配列版素集合データ構造 *)
module RawUnionFind : sig
  type t
  type class_

  (* n要素の素集合データ構造を作る *)
  val make : int -> t
  (* 要素がどの集合に属するか調べる *)
  (* 要素は0からn-1の整数である必要がある *)
  val find : t -> int -> class_
  (* 与えられた要素が属する集合同士を合併する *)
  val unite : t -> int -> int -> unit

  val compare_class : class_ -> class_ -> int
end = struct
  type t = { rank : int array; parent : int array }
  type class_ = int

  let make n =
    { rank = Array.make n 0;
      parent = Array.init n (fun c -> c) }

  let rec find uf x =
    if x = uf.parent.(x) then x
    else begin
      let y = find uf uf.parent.(x) in
      uf.parent.(x) <- y; y
    end

  let unite uf i j =
    let x = find uf i in
    let y = find uf j in
    if x <> y then begin
      if uf.rank.(x) < uf.rank.(y) then uf.parent.(x) <- y
      else begin
        uf.parent.(y) <- x;
        if uf.rank.(x) = uf.rank.(y) then
          uf.rank.(x) <- 1 + uf.rank.(x)
      end
    end

  let compare_class = compare
end

module G = DirectedGraph (struct
  type t = int list
  type edge = int
  let nil = []
  let snoc t e = e :: t
end)

let () = Scanf.scanf "%d\n" @@ fun n ->
  let abs = Array.init (n - 1) @@ fun _ ->
    Scanf.scanf "%d %d\n" @@ fun a b -> a, b in
  let es = Array.make n [] in
  Array.iteri (fun i (a, b) ->
    es.(a - 1) <- (b - 1, i) :: es.(a - 1);
    es.(b - 1) <- (a - 1, i) :: es.(b - 1)) abs;
  let (Some route) = G.bfs n (fun v -> es.(v)) 0 (n - 1) in
  let i = List.nth route ((List.length route - 1) / 2) in
  let uf = RawUnionFind.make n in
  Array.iteri (fun j (a, b) ->
    if i <> j then RawUnionFind.unite uf (a - 1) (b - 1)) abs;
  print_endline @@
    if
      List.length (List.filter (fun i ->
        RawUnionFind.compare_class (RawUnionFind.find uf 0) (RawUnionFind.find uf i) = 0)
      @@ Array.to_list @@ Array.init n @@ fun i -> i)
      <= List.length (List.filter (fun i ->
          RawUnionFind.compare_class (RawUnionFind.find uf (n - 1)) (RawUnionFind.find uf i) = 0)
        @@ Array.to_list @@ Array.init n @@ fun i -> i)
    then "Snuke" else "Fennec"

Measured memory_bytes: 34684