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: Time Limit Exceeded)

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

namespace AtCoder
{
	public class Program
	{
		// TLEがないやつ
		// http://abc067.contest.atcoder.jp/submissions/1431970
		// クラスにしたやつ
		// http://abc067.contest.atcoder.jp/submissions/1431941

		static string フェネックの名前 = "Fennec";
		static string すぬけくんの名前 = "Snuke";

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

		enum プレイヤー
		{
			謎の第三者 = マスの色.透明,
			フェネック = マスの色.黒,
			すぬけくん = マスの色.白,
		};

		public static void Main(string[] args)
		{
			var str = Console.ReadLine().Split(' ');
			var マスの数 = int.Parse(str[0]); // 2 ~ 10^5
			var 道の数 = マスの数 - 1;
			var マスの情報 = new List<int>[マスの数 + 1];

			for (var マスの番号 = 0; マスの番号 < マスの数 + 1; マスの番号++)
			{
				マスの情報[マスの番号] = new List<int>();
			}

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

			// ループしない木なので、相手に向かって塗って、その後は自分の面積の大きい方が勝ちみたいな感じにしたい
			// 同点なら後攻のすぬけくんの勝ち
			// よくわかんないのでモンテカルロっぽい何かで挑む
			int 一回のシミュレート回数 = 1;
			int 繰り返す数 = 60;
			var マスの色の情報 = new マスの色[マスの数 + 1];
			var フェネックの最初のマス = 1;
			var すぬけくんの最初のマス = マスの数;
			var 乱数 = new System.Random();
			var フェネックの定跡本 = new List<int>();
			var すぬけくんの定跡本 = new List<int>();

			var 生き延びた最大ターン = -1;
			var フェネックの生き延びた最大ターン = -1;
			var すぬけくんの生き延びた最大ターン = -1;
			var 只今の勝者 = プレイヤー.謎の第三者;

			Func<int, List<int>, List<int>, プレイヤー> シミュレート = (シミュレート回数, フェネックの定跡, すぬけくんの定跡) =>
			{
				var 新しいフェネックの定跡 = new List<int>();
				var 新しいすぬけくんの定跡 = new List<int>();

				for (var 回数 = 0; 回数 < シミュレート回数; 回数++)
				{
					var フェネックの進める箇所 = new List<int>();
					var すぬけくんの進める箇所 = new List<int>();

					var フェネックの今回の選択 = new List<int>();
					var すぬけくんの今回の選択 = new List<int>();

					for (var マスの番号 = 0; マスの番号 < マスの数 + 1; マスの番号++)
					{
						マスの色の情報[マスの番号] = マスの色.透明;
					}
					マスの色の情報[フェネックの最初のマス] = マスの色.黒;
					マスの色の情報[すぬけくんの最初のマス] = マスの色.白;

					フェネックの進める箇所.AddRange(マスの情報[フェネックの最初のマス]);
					すぬけくんの進める箇所.AddRange(マスの情報[すぬけくんの最初のマス]);

					var 最大ターン数 = 1 + マスの数 / 2;
					for (var ターン = 0; ターン < 最大ターン数; ターン++)
					{
						// 先行はフェネック
						bool フェネックが移動していない = true;
						if (フェネックの進める箇所.Count > 1)
						{
							var 次の移動候補で一番優先したいところ = ターン < フェネックの定跡.Count ? フェネックの定跡[ターン] : 乱数.Next(0, フェネックの進める箇所.Count);
							var 保存領域 = フェネックの進める箇所[0];
							フェネックの進める箇所[0] = フェネックの進める箇所[次の移動候補で一番優先したいところ];
							フェネックの進める箇所[次の移動候補で一番優先したいところ] = 保存領域;
						}
						for (var 移動候補の番号 = 0; 移動候補の番号 < フェネックの進める箇所.Count; 移動候補の番号++)
						{
							var 移動候補 = フェネックの進める箇所[移動候補の番号];
							if (マスの色の情報[移動候補] == マスの色.透明)
							{
								フェネックの今回の選択.Add(移動候補の番号);
								マスの色の情報[移動候補] = マスの色.黒;
								フェネックの進める箇所.AddRange(マスの情報[移動候補]);
								フェネックが移動していない = false;
								break;
							}
							フェネックの進める箇所.RemoveAt(移動候補の番号);
							移動候補の番号--;
						}

						if (フェネックが移動していない)
						{
							if (生き延びた最大ターン < ターン)
							{
								只今の勝者 = プレイヤー.すぬけくん;
								生き延びた最大ターン = ターン;
							}
							if (すぬけくんの生き延びた最大ターン < ターン)
							{
								すぬけくんの生き延びた最大ターン = ターン;
								新しいすぬけくんの定跡 = すぬけくんの今回の選択;
							}
							break;
						}

						bool すぬけくんが移動していない = true;
						if (すぬけくんの進める箇所.Count > 1)
						{
							var 次の移動候補で一番優先したいところ = ターン < すぬけくんの定跡.Count ? すぬけくんの定跡[ターン] : 乱数.Next(0, すぬけくんの進める箇所.Count);
							var 保存領域 = すぬけくんの進める箇所[0];
							すぬけくんの進める箇所[0] = すぬけくんの進める箇所[次の移動候補で一番優先したいところ];
							すぬけくんの進める箇所[次の移動候補で一番優先したいところ] = 保存領域;
						}
						for (var 移動候補の番号 = 0; 移動候補の番号 < すぬけくんの進める箇所.Count; 移動候補の番号++)
						{
							var 移動候補 = すぬけくんの進める箇所[移動候補の番号];
							if (マスの色の情報[移動候補] == マスの色.透明)
							{
								すぬけくんの今回の選択.Add(移動候補の番号);
								マスの色の情報[移動候補] = マスの色.白;
								すぬけくんの進める箇所.AddRange(マスの情報[移動候補]);
								すぬけくんが移動していない = false;
								break;
							}
							すぬけくんの進める箇所.RemoveAt(移動候補の番号);
							移動候補の番号--;
						}

						if (すぬけくんが移動していない)
						{
							if (生き延びた最大ターン < ターン)
							{
								只今の勝者 = プレイヤー.フェネック;
								生き延びた最大ターン = ターン;
							}
							if (フェネックの生き延びた最大ターン < ターン)
							{
								フェネックの生き延びた最大ターン = ターン;
								新しいフェネックの定跡 = フェネックの今回の選択;
							}
							break;
						}
					}
				}

				switch (只今の勝者)
				{
					case プレイヤー.フェネック:
						フェネックの定跡 = 新しいフェネックの定跡;
						すぬけくんの定跡.Clear();
						break;
					case プレイヤー.すぬけくん:
						フェネックの定跡.Clear();
						すぬけくんの定跡 = 新しいすぬけくんの定跡;
						break;
				}

				return 只今の勝者;
			};

			for (var 世代 = 0; 世代 < 繰り返す数; 世代++)
			{
				シミュレート(一回のシミュレート回数, フェネックの定跡本, すぬけくんの定跡本);
			}

			Console.WriteLine(只今の勝者 == プレイヤー.フェネック ? フェネックの名前 : すぬけくんの名前);
		}
	}
}