#include<cstdio>
#include<queue>
#include<utility>
#include<cstring>
#include<stack>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<vector>
using namespace std;
#define MAX_N 100001
#define INF 2147483647
#define REP(i,COUNT) for(int i=0;i<(int)(COUNT);i++)
struct edge{
  int to, cost;
};
typedef vector<vector<edge> > AdjList;
AdjList graph;
typedef pair<int, int> P;
typedef long long int ll;

void init(int n);
int find(int n);
void unite(int x,int y);
bool same(int x, int y);
int dx[4] = {1,0,0,-1};
int dy[4] = {0,1,-1,0};
vector<int> dist;
vector<int> prever;
void dijkstra(int n,int s){
  dist = vector<int>(n,INF);
  prever = vector<int>(n,-1);
  dist[s] = 0;

  priority_queue<P, vector<P> , greater<P> > que;
  que.push(P(0,s));

  while(!que.empty()){
    P p = que.top();
    que.pop();
    int v = p.second;
    if(dist[v] < p.first)
      continue;
    REP(i,graph[v].size()){
      edge e = graph[v][i];
      if(dist[e.to] > dist[v] + e.cost){
        dist[e.to] = dist[v] + e.cost;
        prever[e.to] = v;
        que.push(P(dist[e.to],e.to));
      }

    }

  }
}

bool bellman_ford(int n,int s){
  dist = vector<int>(n,INF);
  dist[s] = 0;
  REP(i,n)REP(v,n)REP(k,graph[v].size()){
    edge e = graph[v][k];
    if(dist[v] != INF && dist[e.to] > dist[v] + e.cost){
      dist[e.to] = dist[v] + e.cost;
      if(i == n - 1) return true;
    }
  }
  return false;
}

/*vector<vector<ll> > d; //d[u][v]は辺e=(u,v)のコスト, 辺が存在しないときINF
void warshall_floyd(int n){
  REP(i,n)REP(j,n)REP(k,n){
    d[j][k] = min(d[j][k],d[j][i] + d[i][k]);
  }
  }*/

int main()
{
  int N,a,b;
  vector<ll> v,visited,prev,to,next;
  ll res=10000000000000,tmp,fscore=0,sscore=0;
  vector<vector<edge> > d;
  cin >> N;
  d = vector<vector<edge > >(N+2,vector<edge>());
  v = vector<ll>(N,0);
  REP(i,N-1){
    cin >> a >> b;
    a--;
    b--;
    d[a].push_back((edge){b,1});
    d[b].push_back((edge){a,1});
  }
  v[0] = 1;
  v[N-1] = -1;
  visited = vector<ll>(N,-1);
  prev = vector<ll>(N,-1);
  to = vector<ll>(N,-1);
  next = vector<ll>(N,-1);
  queue<P> que;
  que.push(P(0,0));
  while(!que.empty()){
    P p = que.front();que.pop();
    if(visited[p.first] == -1){
      prev[p.first] = to[p.first];;
      visited[p.first] = 1;
    }else
      continue;
    if(p.first == N-1){
      break;
    }
    for(int i=0;i<d[p.first].size();i++){
      if(to[d[p.first][i].to] == -1){
        to[d[p.first][i].to] = p.first;
        que.push(P(d[p.first][i].to,p.second+1));
      }
    }
  }
  int f=N-1;
  do{
    next[prev[f]] = f;
    f = prev[f];
  }while(f != 0);
  fill(visited.begin(),visited.end(),-1);
  que.push(P(0,-1));
  que.push(P(N-1,1));
  int fnow=0,pnow=N-1;
  while(!que.empty())
    que.pop();
  while(1){
    if(next[fnow] == pnow)
      break;
    else{
      fnow = next[fnow];
      que.push(P(fnow,-1));
    }

    if(prev[pnow] == fnow)
      break;
    else{
      pnow = prev[pnow];
      que.push(P(pnow,1));
    }
  }
  while(!que.empty()){
    P p = que.front();que.pop();
    if(visited[p.first] == -1){
      visited[p.first] = 1;
      if(p.second == -1){
        fscore++;
      }else
        sscore++;
    }else
      continue;
    for(int i=0;i<d[p.first].size();i++){
        que.push(P(d[p.first][i].to,p.second));
      }
  }
  if(fscore <= sscore)
    cout << "Snuke" << endl;
  else
    cout << "Fennec" << endl;
  return 0;

}

int par[MAX_N];
int ranks[MAX_N];

//n要素で初期化
void init(int n){
  REP(i,n){
    par[i] = i;
    ranks[i] = 0;
  }

}

//木の根を求める
int find(int x){
  if(par[x] == x){
    return x;
  }else{
    return par[x] = find(par[x]);
  }
}

void unite(int x,int y){
  x = find(x);
  y = find(y);
  if(x == y) return ;
  if(ranks[x] < ranks[y]){
    par[x] = y;
  }else{
    par[y] = x;
    if(ranks[x] == ranks[y]) ranks[x]++;
  }
}

bool same(int x, int y){
  return find(x) == find(y);
}



Measured memory_bytes: 11264