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 in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace AtCoder
{
	public class Program
	{
		static string フェネックの名前 = "Fennec";
		static string すぬけくんの名前 = "Snuke";

		public enum マスの色
		{
			透明 = 0,
			黒,
			白,
		};

		public class マス
		{
			public List<int> 隣接情報 = new List<int>();
			マスの色 _色;
			public マスの色 色
			{
				get { return _色; }
				set
				{
					_色 = value;
					移動可能 = _色 == マスの色.透明;
				}
			}

			public bool 移動可能 { get; private set;}
		}

		public class ボード
		{
			public int マスの数 { get; private set; }
			public マス[] マスの情報;

			public int デュエリスト黒のスタート地点 { get; private set; }
			public int デュエリスト白のスタート地点 { get; private set; }

			public void データを標準入力から読み込む()
			{
				var str = Console.ReadLine().Split(' ');
				マスの数 = int.Parse(str[0]); // 2 ~ 10^5
				var 道の数 = マスの数 - 1;

				マスの情報 = new マス[マスの数 + 1]; // マスは1スタートなので1個増やす

				for (var マスの番号 = 0; マスの番号 < マスの情報.Length; マスの番号++)
				{
					マスの情報[マスの番号] = new マス();
				}

				for (var 道の番号 = 0; 道の番号 < 道の数; 道の番号++)
				{
					var 一つの道の情報 = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
					マスの情報[一つの道の情報[0]].隣接情報.Add(一つの道の情報[1]);
					マスの情報[一つの道の情報[1]].隣接情報.Add(一つの道の情報[0]);
				}

				デュエリスト黒のスタート地点 = 1;
				デュエリスト白のスタート地点 = マスの数;
			}

			public void 新しいゲームを始める()
			{
				for (var マスの番号 = 0; マスの番号 < マスの情報.Length; マスの番号++)
				{
					マスの情報[マスの番号].色 = マスの色.透明;
				}

				マスの情報[デュエリスト黒のスタート地点].色 = マスの色.黒;
				マスの情報[デュエリスト白のスタート地点].色 = マスの色.白;
			}
		}

		public class デュエリスト
		{
			public string 真名 { get; private set; }

			int 最初のマス;
			マスの色 色;
			ボード ボード;

			ゲーム ゲーム;

			List<int> 定跡本 = new List<int>();
			int 今までで一番生きたときのターン数 = -1;

			List<int> 新しい定跡 = new List<int>();
			List<int> 進める箇所 = new List<int>();
			List<int> 今回の選択 = new List<int>();

			Random 乱数 = new Random();

			public デュエリスト(string 真名)
			{
				this.真名 = 真名;
			}

			public void ゲームの情報を取得する(int 最初のマス, マスの色 色, ボード ボード)
			{
				this.最初のマス = 最初のマス;
				this.色 = 色;
				this.ボード = ボード;
			}

			public void ゲームを開始する(ゲーム ゲーム)
			{
				this.ゲーム = ゲーム;
				新しい定跡 = new List<int>();
				進める箇所 = new List<int>();
				今回の選択 = new List<int>();

				移動する(最初のマス);
			}

			public bool 移動先を考えて移動する()
			{
				if (進める箇所.Count > 1)
				{
					var 第一移動候補 = ゲーム.ターン < 定跡本.Count ? 定跡本[ゲーム.ターン] : 乱数.Next(0, 進める箇所.Count);
					var 保存領域 = 進める箇所[0];
					進める箇所[0] = 進める箇所[第一移動候補];
					進める箇所[第一移動候補] = 保存領域;
				}

				for (var 移動候補の番号 = 0; 移動候補の番号 < 進める箇所.Count; 移動候補の番号++)
				{
					var 移動候補 = 進める箇所[移動候補の番号];
					var 移動候補のマスの情報 = ボード.マスの情報[移動候補];

					if (移動候補のマスの情報.移動可能)
					{
						今回の選択.Add(移動候補の番号);
						移動候補のマスの情報.色 = マスの色.黒;
						移動する(移動候補);
						return true;
					}
				}

				負けたので反省する();
				return false;
			}

			void 移動する(int 移動するマス)
			{
				for (var i = 0; i < 進める箇所.Count; i++)
				{
					if (ボード.マスの情報[進める箇所[i]].色 != マスの色.透明)
					{
						進める箇所.RemoveAt(i);
						i--;
					}
				}
				var 進んだ先のマスの情報 = ボード.マスの情報[移動するマス].隣接情報;
				for (var i = 0; i < 進んだ先のマスの情報.Count; i++)
				{
					if (ボード.マスの情報[進んだ先のマスの情報[i]].色 == マスの色.透明)
					{
						進める箇所.Add(進んだ先のマスの情報[i]);
					}
				}
			}

			public void 負けたので反省する()
			{
				新しい定跡.Clear();
			}

			public void 勝利したので次に向けて準備する()
			{
				ゲーム.ランキングに登録する(this);

				if (今までで一番生きたときのターン数 < ゲーム.ターン)
				{
					今までで一番生きたときのターン数 = ゲーム.ターン;
					新しい定跡 = 今回の選択.Take(ゲーム.ターン/2).ToList();
				}
			}

			public void 定跡を更新する()
			{
				定跡本 = 新しい定跡;
			}
		}

		public class ゲーム
		{
			public int ターン { get; private set; }
			public int 最大ターン { get; private set; }

			public int 今までで一番長く続いたターン { get; private set; }

			public デュエリスト 只今の勝者 { get; private set; }

			public void データを初期化する()
			{
				今までで一番長く続いたターン = -1;
			}

			public void 始める(ボード ボード, デュエリスト 黒, デュエリスト 白)
			{
				ボード.新しいゲームを始める();
				黒.ゲームを開始する(this);
				白.ゲームを開始する(this);

				ターン = 0;
				最大ターン = 1 + ボード.マスの数 / 2;

				for (ターン = 0; ターン < 最大ターン; ターン++)
				{
					var 黒が移動できない = !黒.移動先を考えて移動する();
					if (黒が移動できない)
					{
						白.勝利したので次に向けて準備する();
						break;
					}
					var 白が移動できない = !白.移動先を考えて移動する();
					if (白が移動できない)
					{
						黒.勝利したので次に向けて準備する();
						break;
					}
				}
			}

			public void ランキングに登録する(デュエリスト デュエリスト)
			{
				if (今までで一番長く続いたターン >= ターン) return;

				今までで一番長く続いたターン = ターン;
				只今の勝者 = デュエリスト;
			}
		}

		public static void Main(string[] args)
		{
			var ゲーム = new ゲーム();
			ゲーム.データを初期化する();
			var ボード = new ボード();
			ボード.データを標準入力から読み込む();

			var フェネック = new デュエリスト(フェネックの名前);
			フェネック.ゲームの情報を取得する(ボード.デュエリスト黒のスタート地点, マスの色.黒, ボード);
			var すぬけくん = new デュエリスト(すぬけくんの名前);
			すぬけくん.ゲームの情報を取得する(ボード.デュエリスト白のスタート地点, マスの色.白, ボード);

			// ループしない木なので、相手に向かって塗って、その後は自分の面積の大きい方が勝ちみたいな感じにしたい
			// 同点なら後攻のすぬけくんの勝ち
			// よくわかんないのでモンテカルロっぽい何かで挑む
			var 合計シミュレート回数 = Math.Max(1, 30000 / ボード.マスの数);
			var シミュレート回数 = Math.Max(1, Math.Sqrt(合計シミュレート回数) / 2 );
			var 世代数 = Math.Max(1, 合計シミュレート回数 / シミュレート回数);
			for (var 世代 = 0; 世代 < 世代数; 世代++)
			{
				for (var 回数 = 0; 回数 < シミュレート回数; 回数++)
				{
					ゲーム.始める(ボード, フェネック, すぬけくん);
				}
				フェネック.定跡を更新する();
				すぬけくん.定跡を更新する();
			}

			Console.WriteLine(ゲーム.只今の勝者.真名);
		}
	}
}