#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <cfloat>

using std::cerr;
using std::cin;
using std::cout;
using std::endl;

template<typename CostType>
/// \brief 辺の情報
struct Edge{
  int      to;
  CostType cost;

  Edge(int t, CostType c): to(t), cost(c){
  }
};

template<typename CostType>
class Graph{

private:

  /// \brief adjacent_list_[n]=ノードnの隣接リストを表すvector<Edge>
  std::vector<std::vector<Edge<CostType>>> adjacent_list_;

public:

  /// \brief 頂点数
  const int NODE_SIZE_;

  /// \brief コンストラクタ
  /// \param node_size 頂点数
  explicit Graph(const int node_size): NODE_SIZE_(node_size),
                                       adjacent_list_(node_size){
  }

  /// \brief 有向グラフの辺を生やす
  /// \param from 辺の根本の頂点の番号
  /// \param to 辺の先の頂点の番号
  /// \param cost 辺のコスト
  void SetDirectedEdge(const int from, const int to, const CostType cost){
    adjacent_list_[from].push_back(Edge<CostType>(to, cost));
  }

  /// \brief 無向グラフの辺を生やす
  /// \param node_a 一方の頂点の番号
  /// \param node_b もう一方の頂点の番号
  /// \param cost 辺のコスト
  void
  SetUndirectedEdge(const int node_a, const int node_b, const CostType cost){
    SetDirectedEdge(node_a, node_b, cost);
    SetDirectedEdge(node_b, node_a, cost);
  }

  /// \brief ある頂点の隣接リストを取得
  /// \param node_num 頂点の番号
  /// \return 隣接リスト
  std::vector<Edge<CostType>> GetAdjacentList(int node_num) const{
    return adjacent_list_[node_num];
  }
};

typedef std::pair<int,int> P;

int TreeDiameter(const Graph<int>& graph){
  std::queue<P> q;
  q.push(std::make_pair(1,1));
  std::vector<int> depth(graph.NODE_SIZE_);
  int max_depth=0;
  int tmp_max_id=-1;
  std::vector<bool> pre_visited(graph.NODE_SIZE_);
  for(int i=1;i<graph.NODE_SIZE_;i++){
    depth[i]=-1;
  }
  pre_visited[1]=true;
  depth[1]=1;
  while(!q.empty()){
    P curr=q.front();
    q.pop();
    for(auto e:graph.GetAdjacentList(curr.first)){
      if(!pre_visited[e.to]){
        pre_visited[e.to]=true;
        depth[e.to]=curr.second+1;
        if(max_depth<curr.second+1){
          max_depth=curr.second+1;
          tmp_max_id=e.to;
        }

        q.push(std::make_pair(e.to,curr.second+1));
      }
    }
  }

  q.push(std::make_pair(tmp_max_id,1));
  int result=0;
  std::vector<bool> visited(graph.NODE_SIZE_);
  while(!q.empty()){
    P curr=q.front();
    q.pop();
    for(auto e:graph.GetAdjacentList(curr.first)){
      if(!visited[e.to]){
        visited[e.to]=true;
        result=std::max(curr.second+1,result);
        q.push(std::make_pair(e.to,curr.second+1));
      }
    }
  }
  return result;


}


int main(){
  cout << std::fixed << std::setprecision(16);
  cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  //木の直径が3の倍数ならSecond
  int n;
  cin>>n;
  Graph<int> graph(n+1);
  for(int i=0;i<n-1;i++){
    int a,b;
    cin>>a>>b;
    graph.SetUndirectedEdge(a,b,1);
  }
  int diameter=TreeDiameter(graph);
  if((diameter-2)%3==0){
    cout<<"Second"<<endl;
  }else{
    cout<<"First"<<endl;
  }


  return 0;
}

Measured memory_bytes: 16852