Problem:
 Score : 800 points    Problem Statement Takahashi and Aoki will play a game on a tree.
The tree has N vertices numbered 1 to N , and the i -th of the N-1 edges connects Vertex a_i and Vertex b_i .  At the beginning of the game, each vertex contains a coin.
Starting from Takahashi, he and Aoki will alternately perform the following operation:   Choose a vertex v that contains one or more coins, and remove all the coins from v .  Then, move each coin remaining on the tree to the vertex that is nearest to v among the adjacent vertices of the coin's current vertex.   The player who becomes unable to play, loses the game.
That is, the player who takes his turn when there is no coin remaining on the tree, loses the game.
Determine the winner of the game when both players play optimally.      Constraints  1 \leq N \leq 2 \times 10^5  1 \leq a_i, b_i \leq N  a_i \neq b_i  The graph given as input is a tree.         Input Input is given from Standard Input in the following format:  N  a_1  b_1  a_2  b_2  :  a_{N-1}  b_{N-1}       Output Print First if Takahashi will win, and print Second if Aoki will win.        Sample Input 1 3
1 2
2 3      Sample Output 1 First  Here is one possible progress of the game:   Takahashi removes the coin from Vertex 1 . Now, Vertex 1 and Vertex 2 contain one coin each.  Aoki removes the coin from Vertex 2 . Now, Vertex 2 contains one coin.  Takahashi removes the coin from Vertex 2 . Now, there is no coin remaining on the tree.  Aoki takes his turn when there is no coin on the tree and loses.        Sample Input 2 6
1 2
2 3
2 4
4 6
5 6      Sample Output 2 Second       Sample Input 3 7
1 7
7 4
3 4
7 5
6 3
2 1      Sample Output 3 First

Solution (Python):

from collections import deque
import numpy as np

N = int(input())
graph = {i:[] for i in range(N)}
for _ in range(N-1):
    a,b = map(int,input().split())
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)






def bfs(graph,root):
    distance  = [0]*N
    visited = set()
    queue = deque([root])
    while queue:
        vertex = queue.popleft()
        for neighbour in graph[vertex]:
            if neighbour not in visited:
                distance[neighbour] = distance[vertex] + 1
                visited.add(neighbour)
                queue.append(neighbour)

    farthest_node = np.argmax(distance)
    farthest_dist = distance[farthest_node]
    return farthest_node, farthest_dist

u, _ = bfs(graph, root=0)
_, diamiter = bfs(graph, root=u)

if diamiter%3==1:
    ans = 'Second'
else:
    ans = 'First'
print(ans)

Solution (Python):
import collections
N=int(input())
inarr=[[int(j) for j in input().split()] for i in range(N-1)]
nodes={}
if N == 1:
    print("First")
    exit()

for i,j in inarr:
    if not i in nodes: nodes[i] = [j]
    else: nodes[i].append(j)
    if not j in nodes: nodes[j] = [i]
    else: nodes[j].append(i)

visited = {1}
queue = collections.deque([[1, 0]])
while queue:
    i, d = queue.popleft()
    for node in nodes[i]:
        if not node in visited:
            visited.add(node)
            queue += [[node, d + 1]]



visited = {i}
queue = collections.deque([[i, 0]])
while queue:
    i, d = queue.popleft()
    for node in nodes[i]:
        if not node in visited:
            visited.add(node)
            queue += [[node, d + 1]]



print('Second' if (d + 1) % 3 == 2 else 'First')

Solution (Python):
import collections
N = int(input())
AB = [[int(_) for _ in input().split()] for _ in range(N - 1)]
G = collections.defaultdict(set)
for a, b in AB:
    G[a].add(b)
    G[b].add(a)
visited = [False] * (N + 1)
visited[1] = True
Q = collections.deque([1])
while Q:
    i = Q.popleft()
    for j in G[i]:
        if not visited[j]:
            visited[j] = True
            Q += [j]
visited = [False] * (N + 1)
visited[i] = True
Q = collections.deque([[i, 0]])
while Q:
    i, d = Q.popleft()
    for j in G[i]:
        if not visited[j]:
            visited[j] = True
            Q += [[j, d + 1]]
if (d + 1) % 3 == 2:
    print('Second')
else:
    print('First')

Solution (Python):

n = int(input())
edges = set(tuple(int(i) for i in input().split()) for _ in range(n-1))


from collections import deque


def make_connection(tree):
    con = [[] for _ in range(n+1)]
    for edge in tree:
        con[edge[0]].append(edge[1])
        con[edge[1]].append(edge[0])
    return con


def diameter(tree):
    c = make_connection(tree)
    _, s = farest(tree, c, 1)
    diam, _ = farest(tree, c, s)
    return diam


def farest(tree, con, i):
    dp = [None for _ in range(n+1)]
    dp[i] = 0
    cand_q = deque()
    cand_q.append(i)

    while len(cand_q) > 0:
        u = cand_q.popleft()

        for v in con[u]:
            if dp[v] is None:
                cand_q.append(v)
                dp[v] = dp[u] + 1
    max_ = max(dp[1:])
    i_max = dp.index(max_)
    return max_, i_max


d = diameter(edges)


print('Second' if d % 3 == 1 else 'First')

Solution (Python):

n = int(input())
edges = set(tuple(int(i) for i in input().split()) for _ in range(n-1))


from collections import deque


def make_connection(tree):
    con = [[] for _ in range(n+1)]
    for edge in tree:
        con[edge[0]].append(edge[1])
        con[edge[1]].append(edge[0])
    return con


def diameter(tree):
    c = make_connection(tree)
    _, s = farest(tree, c, 1)
    diam, _ = farest(tree, c, s)
    return diam


def farest(tree, con, i):
    dp = [None for _ in range(n+1)]
    dp[i] = 0
    cand_q = deque()
    cand_q.append(i)

    while len(cand_q) > 0:
        u = cand_q.popleft()

        for v in con[u]:
            if dp[v] is None:
                cand_q.append(v)
                dp[v] = dp[u] + 1
    max_ = max(dp[1:])
    i_max = dp.index(max_)
    return max_, i_max


d = diameter(edges)


print('Second' if d % 3 == 1 else 'First')

Solution (Python):


from bisect import bisect_left as binl
from copy import copy, deepcopy

def intin():
    input_tuple = input().split()
    if len(input_tuple) <= 1:
        return int(input_tuple[0])
    return tuple(map(int, input_tuple))


def intina():
    return [int(i) for i in input().split()]


def intinl(count):
    return [intin() for _ in range(count)]


def modadd(x, y):
    global mod
    return (x + y) % mod


def modmlt(x, y):
    global mod
    return (x * sy) % mod


def lcm(x, y):
    while y != 0:
        z = x % y
        x = y
        y = z
    return x


def make_linklist(xylist):
    linklist = {}
    for a, b in xylist:
        linklist.setdefault(a, [])
        linklist.setdefault(b, [])
        linklist[a].append(b)
        linklist[b].append(a)
    return linklist


def calc_longest_distance(linklist, v=1):
    distance_list = {}
    distance_count = 0
    distance = 0
    vlist_previous = []
    vlist = [v]
    nodecount = len(linklist)

    while distance_count < nodecount:
        vlist_next = []
        for v in vlist:
            distance_list[v] = distance
            distance_count += 1
            vlist_next.extend(linklist[v])
        distance += 1
        vlist_to_del = vlist_previous
        vlist_previous = vlist
        vlist = list(set(vlist_next) - set(vlist_to_del))

    max_distance = -1
    max_v = None
    for v, distance in distance_list.items():
        if distance > max_distance:
            max_distance = distance
            max_v = v

    return (max_distance, max_v)


def calc_tree_diameter(linklist, v=1):
    _, u = calc_longest_distance(linklist, v)
    distance, _ = calc_longest_distance(linklist, u)
    return distance





def main():
    n = intin()
    ablist = intinl(n-1)

    linklist = make_linklist(ablist)
    diameter = calc_tree_diameter(linklist)

    if diameter % 3 == 1:
        print('Second')
    else:
        print('First')


if __name__ == '__main__':
    main()

Solution (Python):


from bisect import bisect_left as binl
from copy import copy, deepcopy

def intin():
    input_tuple = input().split()
    if len(input_tuple) <= 1:
        return int(input_tuple[0])
    return tuple(map(int, input_tuple))


def intina():
    return [int(i) for i in input().split()]


def intinl(count):
    return [intin() for _ in range(count)]


def modadd(x, y):
    global mod
    return (x + y) % mod


def modmlt(x, y):
    global mod
    return (x * sy) % mod


def lcm(x, y):
    while y != 0:
        z = x % y
        x = y
        y = z
    return x


def make_linklist(xylist):
    linklist = {}
    for a, b in xylist:
        linklist.setdefault(a, [])
        linklist.setdefault(b, [])
        linklist[a].append(b)
        linklist[b].append(a)
    return linklist


def calc_longest_distance(linklist, v=1):
    distance_list = {}
    distance_count = 0
    distance = 0
    vlist_previous = []
    vlist = [v]
    nodecount = len(linklist)

    while distance_count < nodecount:
        vlist_next = []
        for v in vlist:
            distance_list[v] = distance
            distance_count += 1
            vlist_next.extend(linklist[v])
        distance += 1
        vlist_to_del = vlist_previous
        vlist_previous = vlist
        vlist = list(set(vlist_next) - set(vlist_to_del))

    max_distance = -1
    max_v = None
    for v, distance in distance_list.items():
        if distance > max_distance:
            max_distance = distance
            max_v = v

    return (max_distance, max_v)


def calc_tree_diameter(linklist, v=1):
    _, u = calc_longest_distance(linklist, v)
    distance, _ = calc_longest_distance(linklist, u)
    return distance





def main():
    n = intin()
    ablist = intinl(n-1)

    linklist = make_linklist(ablist)
    diameter = calc_tree_diameter(linklist)

    if diameter % 3 == 1:
        print('Second')
    else:
        print('First')


if __name__ == '__main__':
    main()

Solution (Python):
from collections import deque
from heapq import heappush,heappop
import re
def int_raw():
    return int(input())

def ss_raw():
    return input().split()

def ints_raw():
    return list(map(int, ss_raw()))

INF = 1<<29

def getDeci(tree):
    def saiki(v):
        root = [0,v,-1]
        cur = None
        qu = deque()
        qu.append(root)
        while len(qu)!=0:
            cur = qu.popleft()
            for e in tree[cur[1]]:
                if e ==cur[2]:
                    continue
                qu.append([cur[0]+1,e,cur[1]])
        return cur
    leaf = saiki(0)
    ans = saiki(leaf[1])
    return ans

    
N = int_raw()
tree = [[] for _ in range(N)]
for _ in range(N-1):
    a,b = ints_raw()
    a = a-1
    b = b-1
    tree[a].append(b)
    tree[b].append(a)



def main():
    ans = getDeci(tree)
    if (ans[0]+2)%3==0:
        return "Second"
    else:
        return "First"

print(main())

Solution (Python):
def getD(graph):
    
    origin=1
    d = 0
    queue = Queue()
    for it in graph[origin]:
        queue.enqueue((it, origin, d+1)) 

    while queue.size() > 0:
        leaf, origin, d = queue.dequeue()
        for it in graph[leaf]:
            if it != origin:
                queue.enqueue((it, leaf, d+1)) 
    

    
    origin=leaf
    d = 0
    queue = Queue()
    for it in graph[origin]:
        queue.enqueue((it, origin, d+1)) 

    while queue.size() > 0:
        leaf, origin, d = queue.dequeue()
        for it in graph[leaf]:
            if it != origin:
                queue.enqueue((it, leaf, d+1)) 
    
    return d

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None


class Queue:
    def __init__(self):
        self.head = None
        self.last = None
        self._size = 0

    def enqueue(self, data):
        if self.last is None:
            self.head = Node(data)
            self.last = self.head
        else:
            self.last.next = Node(data)
            self.last = self.last.next
            
        self._size += 1

    def dequeue(self):
        if self.head is None:
            return None
        else:
            to_return = self.head.data
            self.head = self.head.next
            self._size -= 1
            
            if self._size == 0:
                self.head = None
                self.last = None
            return to_return
        
    def size(self):
        return self._size
    
def inside(y,x,H,W):
    if 0<=y<H and 0<=x<W:
        return True
    else:
        return False
    
def addQueueIfPossible(new_y, new_x, new_val, data, queue):
    if inside(new_y, new_x, H, W) and data[new_y][new_x]==-1:
        data[new_y][new_x] = new_val
        queue.enqueue((new_y, new_x, new_val))
        return True
    else:
        return False


n = int(input())
graph = [[] for _ in range(n+1)]
for i in range(n-1):
    a,b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)

if n==1:
    print('First')
else:
    d = getD(graph)

    if (d+2)%3==0:
        print('Second')
    else:
        print('First')

Solution (Python):
def getD(graph):
    
    origin=1
    d = 0
    queue = Queue()
    for it in graph[origin]:
        queue.enqueue((it, origin, d+1)) 

    while queue.size() > 0:
        leaf, origin, d = queue.dequeue()
        for it in graph[leaf]:
            if it != origin:
                queue.enqueue((it, leaf, d+1)) 
    

    
    origin=leaf
    d = 0
    queue = Queue()
    for it in graph[origin]:
        queue.enqueue((it, origin, d+1)) 

    while queue.size() > 0:
        leaf, origin, d = queue.dequeue()
        for it in graph[leaf]:
            if it != origin:
                queue.enqueue((it, leaf, d+1)) 
    
    return d

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None


class Queue:
    def __init__(self):
        self.head = None
        self.last = None
        self._size = 0

    def enqueue(self, data):
        if self.last is None:
            self.head = Node(data)
            self.last = self.head
        else:
            self.last.next = Node(data)
            self.last = self.last.next
            
        self._size += 1

    def dequeue(self):
        if self.head is None:
            return None
        else:
            to_return = self.head.data
            self.head = self.head.next
            self._size -= 1
            
            if self._size == 0:
                self.head = None
                self.last = None
            return to_return
        
    def size(self):
        return self._size
    
def inside(y,x,H,W):
    if 0<=y<H and 0<=x<W:
        return True
    else:
        return False
    
def addQueueIfPossible(new_y, new_x, new_val, data, queue):
    if inside(new_y, new_x, H, W) and data[new_y][new_x]==-1:
        data[new_y][new_x] = new_val
        queue.enqueue((new_y, new_x, new_val))
        return True
    else:
        return False


n = int(input())
graph = [[] for _ in range(n+1)]
for i in range(n-1):
    a,b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)

if n==1:
    print('First')
else:
    d = getD(graph)

    if (d+2)%3==0:
        print('Second')
    else:
        print('First')

Solution (Python):

N = int(input())

E = [ [] for _ in range(N)]
for i in range(N-1):
    a,b = map(int, input().split())
    E[a-1].append(b-1)
    E[b-1].append(a-1)














    
def farthest(s):
    visited = [False]*N
    stack = [[s,0]]
    best = [s,0]
    while len(stack)>0:


        current = stack.pop()
        currentPosition = current[0] 
        currentLength = current[1]
        visited[currentPosition] = True
        
        if currentLength > best[1]:
            best = [currentPosition, currentLength]
        visited.append(currentPosition)
        
        for position in E[currentPosition]:
            if not visited[position]:
                stack.append([position, currentLength+1])
    return best


u = farthest(0)[0]
best = farthest(u)


diameter = best[1]

ans = "First"
if diameter % 3 == 1:
    ans = "Second"
print(ans)

Solution (Python):


from bisect import bisect_left as binl

def intin():
    input_tuple = input().split()
    if len(input_tuple) <= 1:
        return int(input_tuple[0])
    return tuple(map(int, input_tuple))


def intina():
    return [int(i) for i in input().split()]


def intinl(count):
    return [intin() for _ in range(count)]


def modadd(x, y):
    global mod
    return (x + y) % mod


def modmlt(x, y):
    global mod
    return (x * sy) % mod


def lcm(x, y):
    while y != 0:
        z = x % y
        x = y
        y = z
    return x


def make_linklist(xylist):
    linklist = {}
    for a, b in xylist:
        linklist.setdefault(a, [])
        linklist.setdefault(b, [])
        linklist[a].append(b)
        linklist[b].append(a)
    return linklist


def calc_longest_distance(linklist, v=1):
    distance_list = {}
    distance_count = 0
    distance = 0
    vlist_previous = []
    vlist = [v]
    nodecount = len(linklist)

    while distance_count < nodecount:
        vlist_next = []
        for v in vlist:
            distance_list[v] = distance
            distance_count += 1
            vlist_next.extend(linklist[v])
        distance += 1
        vlist_to_del = vlist_previous
        vlist_previous = vlist
        vlist = list(set(vlist_next) - set(vlist_to_del))

    max_distance = -1
    max_v = None
    for v, distance in distance_list.items():
        if distance > max_distance:
            max_distance = distance
            max_v = v

    return (max_distance, max_v)


def calc_tree_diameter(linklist, v=1):
    _, u = calc_longest_distance(linklist, v)
    distance, _ = calc_longest_distance(linklist, u)
    return distance





def main():
    n = intin()
    ablist = intinl(n-1)

    linklist = make_linklist(ablist)
    diameter = calc_tree_diameter(linklist)

    if diameter % 3 == 1:
        print('Second')
    else:
        print('First')


if __name__ == '__main__':
    main()

Solution (Python):


from bisect import bisect_left as binl

def intin():
    input_tuple = input().split()
    if len(input_tuple) <= 1:
        return int(input_tuple[0])
    return tuple(map(int, input_tuple))


def intina():
    return [int(i) for i in input().split()]


def intinl(count):
    return [intin() for _ in range(count)]


def modadd(x, y):
    global mod
    return (x + y) % mod


def modmlt(x, y):
    global mod
    return (x * sy) % mod


def lcm(x, y):
    while y != 0:
        z = x % y
        x = y
        y = z
    return x


def make_linklist(xylist):
    linklist = {}
    for a, b in xylist:
        linklist.setdefault(a, [])
        linklist.setdefault(b, [])
        linklist[a].append(b)
        linklist[b].append(a)
    return linklist


def calc_longest_distance(linklist, v=1):
    distance_list = {}
    distance_count = 0
    distance = 0
    vlist_previous = []
    vlist = [v]
    nodecount = len(linklist)

    while distance_count < nodecount:
        vlist_next = []
        for v in vlist:
            distance_list[v] = distance
            distance_count += 1
            vlist_next.extend(linklist[v])
        distance += 1
        vlist_to_del = vlist_previous
        vlist_previous = vlist
        vlist = list(set(vlist_next) - set(vlist_to_del))

    max_distance = -1
    max_v = None
    for v, distance in distance_list.items():
        if distance > max_distance:
            max_distance = distance
            max_v = v

    return (max_distance, max_v)


def calc_tree_diameter(linklist, v=1):
    _, u = calc_longest_distance(linklist, v)
    distance, _ = calc_longest_distance(linklist, u)
    return distance





def main():
    n = intin()
    ablist = intinl(n-1)

    linklist = make_linklist(ablist)
    diameter = calc_tree_diameter(linklist)

    if diameter % 3 == 1:
        print('Second')
    else:
        print('First')


if __name__ == '__main__':
    main()

Solution (Python):


import collections


class Node(object):

  def __init__(self):
    self.edges = set()
    self.distance = 1


def main():
  N = int(input())
  nodes = [Node() for _ in range(N)]

  if N == 0:
    print('Second', flush=True)
    return
  elif N == 1:
    print('First', flush=True)
    return

  for _ in range(N - 1):
    a, b = map(int, input().split())
    nodes[a - 1].edges.add(nodes[b - 1])
    nodes[b - 1].edges.add(nodes[a - 1])

  leaves = collections.deque(n for n in nodes if len(n.edges) == 1)

  while True:
    leaf = leaves.popleft()
    parent = leaf.edges.pop()

    if len(parent.edges) == 1:
      size = leaf.distance + parent.distance
      break

    parent.distance = max(parent.distance, leaf.distance + 1)
    parent.edges.remove(leaf)

    if len(parent.edges) == 1:
      leaves.append(parent)

  if size % 3 == 2:
    print('Second', flush=True)
  else:
    print('First', flush=True)


if __name__ == '__main__':
  main()

Solution (Python):
N = int(input())
E = [[] for _ in range(N)]
for i in range(N - 1):
	a, b = map(int, input().split())
	E[a - 1].append(b - 1)
	E[b - 1].append(a - 1)


def farthest(s):
	visited = [False] * N
	stack = [(s, 0)]
	best = s, 0
	while stack:
		i, d = stack.pop()
		visited[i] = True
		if best[1] < d:
			best = i, d
		stack.extend((v, d + 1) for v in E[i] if not visited[v])
	return best

print('First' if (farthest(farthest(0)[0])[1] % 3 != 1) else 'Second')

Solution (Python):
from collections import deque

N = int(input())
g = [[] for _ in range(N)]
for _ in range(N-1):
    a, b = map(int, input().split())
    g[a-1].append(b-1)
    g[b-1].append(a-1)


def farthest(s):
    maxlen = 0
    farthest = s
    q = deque()
    q.append((s, 0, -1))
    while len(q):
        c, l, prev = q.pop()
        if prev >= 0 and len(g[c]) <= 1:
            if l > maxlen:
                maxlen = l
                farthest = c
            continue
        for n in g[c]:
            if n != prev:
                q.append((n, l+1, c))
    return maxlen, farthest


_, a = farthest(0)
diameter, b = farthest(a)

print("First" if diameter % 3 != 1 else "Second")

Solution (Python):

import sys
import heapq
INF = float("inf")


def argmax(a):
    m, n = -(1 << 31), -1
    for i, v in enumerate(a):
        if m < v:
            m, n = v, i
    return m, n




class Graph(object):
    def __init__(self, N):
        self.N = N
        self.V = list(range(N))
        self.E = [[] for _ in range(N)]

    def add_edge(self, edge):
        """辺を加える。edgeは(始点, 終点、重み)からなるリスト
        重みがなければ、重み1とする。
        """
        if len(edge) == 2:
            edge.append(1)
        elif len(edge) != 3:
            print("error in add_edge")
            pass

        s, t, w = edge
        self.E[s].append([t, w])
        self.E[t].append([s, w])  

        pass


def shortestPath(g: Graph, s: int):
    """ グラフgにおいて、始点sから各頂点への最短路を求める
    引数
    g: グラフ, s: 始点
    返り値
    dist: 始点からの距離が格納されたリスト
    prev: 始点から最短経路で移動する場合、各頂点に至る前の頂点のリスト
    """
    dist = [INF]*g.N
    dist[s] = 0

    prev = [None]*g.N
    Q = []
    heapq.heappush(Q, (dist[s], s))

    while len(Q) > 0:
        _, u = heapq.heappop(Q)
        for v, w in g.E[u]:
            if dist[v] > dist[u] + w:
                dist[v] = dist[u] + w
                prev[v] = u
                heapq.heappush(Q, (dist[v], v))
    return dist, prev


def tree_diameter(g):
    
    
    dist, prev = shortestPath(g, 0)
    m, s = argmax(dist)
    dist, prev = shortestPath(g, s)
    return max(dist)


def solve(N: int, a: "List[int]", b: "List[int]"):
    g = Graph(N)
    for aa, bb in zip(a, b):
        g.add_edge([aa-1, bb-1])

    L = tree_diameter(g)
    if L % 3 == 1:
        print("Second")
    else:
        print("First")
    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    a = [int()] * (N-1)  
    b = [int()] * (N-1)  
    for i in range(N-1):
        a[i] = int(next(tokens))
        b[i] = int(next(tokens))
    solve(N, a, b)


if __name__ == '__main__':
    main()

Solution (Python):
from collections import deque
def dia(i):
	lst = [-1]*N
	lst[i] = 0
	q = deque([i])
	while q:
		c = q.popleft()
		l = lst[c]
		for i in A[c]:
			if lst[i] != -1:
				continue
			else:
				lst[i] = l+1
				q.append(i)
	return lst.index(max(lst))
def dia2(i):
	lst = [-1]*N
	lst[i] = 0
	q = deque([i])
	while q:
		c = q.popleft()
		l = lst[c]
		for i in A[c]:
			if lst[i] != -1:
				continue
			else:
				lst[i] = l+1
				q.append(i)
	return max(lst)+1
N = input()
A = [[] for i in range(N)]
for i in range(N-1):
	a2,b2 = map(int, raw_input().split())
	A[a2-1].append(b2-1)
	A[b2-1].append(a2-1)
if((dia2(dia(0))) % 3 == 2):
	print("Second")
else:
	print("First")

Solution (Python):
from collections import deque
import sys
readline = sys.stdin.readline
N = int(readline())
G = [[] for i in range(N)]
for i in range(N-1):
    a, b = map(int, readline().split())
    G[a-1].append(b-1)
    G[b-1].append(a-1)
def bfs(s):
    dist = [None]*N
    que = deque([s])
    dist[s] = 0
    while que:
        v = que.popleft()
        d = dist[v]
        for w in G[v]:
            if dist[w] is not None:
                continue
            dist[w] = d + 1
            que.append(w)
    d = max(dist)
    return dist.index(d), d
u, _ = bfs(0)
v, d = bfs(u)
print("Second" if d % 3 == 1 else "First")

Solution (Python):
from collections import defaultdict
from collections import deque

def getlist():
	return list(map(int, input().split()))

class Graph(object):

    def __init__(self):
        self.graph = defaultdict(list)

    def __len__(self):
        return len(self.graph)

    def add_edge(self, a, b):
        self.graph[a].append(b)


class breadth(object):
    def __init__(self, graph, s):
        self.g = graph.graph
        self.dist = defaultdict(lambda: float('inf'))
        self.dist[s] = 0
        self.visit = ["no" for i in range(len(graph) + 1)]
        self.visit[s] = "yes"

        self.Q = deque()
        self.Q.append([self.dist[s], s])

        while self.Q:
            dist_u, u = self.Q.popleft()
            for v in self.g[u]:
                if self.visit[v] == "yes":
                    continue
                else:
                    self.dist[v] = dist_u + 1
                    self.visit[v] = "yes"
                    self.Q.append([self.dist[v], v])


N = int(input())
if N == 1:
	print("First")
else:
	g_a = Graph()
	for i in range(N - 1):
		a, b = getlist()
		g_a.add_edge(a, b)
		g_a.add_edge(b, a)
	
	s = 1
	E = breadth(g_a, s)
	x = 0
	for i in E.dist:
		if E.dist[i] > x:
			x = E.dist[i]
			y = i
	F = breadth(g_a, y)
	x = 0
	for i in F.dist:
		if F.dist[i] > x:
			x = F.dist[i]
			y = i

	if x % 3 == 0 or x % 3 == 2:
		print("First")
	else:
		print("Second")

Solution (Python):
import sys
range = xrange

inp = [int(x) for x in sys.stdin.read().split()]
ii = 0

n = inp[ii]
ii += 1

coupl = [[] for _ in range(n)]
for _ in range(n-1):
    u,v = inp[ii]-1, inp[ii+1]-1
    ii += 2
    
    coupl[u].append(v)
    coupl[v].append(u)

root = 0
for _ in range(2):
    depth = [-1]*n
    depth[root] = 1
    Q = [root]
    for node in Q:
        d = depth[node]
        for nei in coupl[node]:
            if depth[nei]==-1:
                depth[nei] = d+1
                Q.append(nei)

    root = max(range(n), key = lambda i:depth[i])
dia = depth[root]
if dia%3!=2:
    print 'First'
else:
    print 'Second'

Solution (Python):
import sys
range = xrange
input = sys.stdin.readline

n = int(input())
coupl = [[] for _ in range(n)]
for _ in range(n-1):
    u,v = [int(x)-1 for x in input().split()]
    
    coupl[u].append(v)
    coupl[v].append(u)

root = 0
for _ in range(2):
    depth = [-1]*n
    depth[root] = 1
    Q = [root]
    for node in Q:
        d = depth[node]
        for nei in coupl[node]:
            if depth[nei]==-1:
                depth[nei] = d+1
                Q.append(nei)

    root = max(range(n), key = lambda i:depth[i])
dia = depth[root]
if dia%3!=2:
    print 'First'
else:
    print 'Second'

Solution (Python):
import sys
sys.setrecursionlimit(10**7)
input = sys.stdin.readline

n = int(input())
graph = [[] for _ in range(n)]
for i in range(n-1):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    graph[a].append(b)
    graph[b].append(a)


def dfs(v, dist, memo):
    memo[v] = dist
    for nv in graph[v]:
        if memo[nv] >= 0:
            continue
        dfs(nv, dist+1, memo)

memo = [-1] * n
dfs(0, 0, memo)

node = 0
dist = 0
for i in range(n):
    if memo[i] > dist:
        dist = memo[i]
        node = i

memo = [-1] * n
dfs(node, 0, memo)

dist = max(memo)
count = dist + 1

dp = [0] * (count + 10)
dp[0] = 0
dp[1] = 1
dp[2] = 0
dp[3] = 1
dp[4] = 1


if count >= 5:
    for i in range(5, count+1):
        if dp[i-2] == 1 and dp[i-1] == 1:
            dp[i] = 0
        else:
            dp[i] = 1

if dp[count]:
    print("First")
else:
    print("Second")

Solution (Python):

import sys
sys.setrecursionlimit(300000)

def dfs(idx, con, visited):
    visited[idx] = True
    max_depth = 0
    max_len = 0
    depths = []
    if idx >= len(con):
        return max_depth, max_len
    for v in con[idx]:
        if v < len(visited) and not visited[v]:
            max_d, max_l = dfs(v, con, visited)
            max_len = max(max_len, max_l)
            depths.append(max_d + 1)
    if len(depths) > 0:
        depths.sort(reverse=True)
        max_depth = depths[0]
        if len(depths) > 1:
            max_len = max(max_len, depths[0] + depths[1])
        else:
            max_len = max(max_len, depths[0])
    visited[idx] = False
    return max_depth, max_len


def solve(N: int, A: "List[int]", B: "List[int]"):
    con = [[] for _ in range(N)]
    for i in range(len(A)):
        a = A[i] - 1
        b = B[i] - 1
        con[a].append(b)
        con[b].append(a)
    
    visited = [False] * N
    max_depth, max_len = dfs(0, con, visited)
    
    if (max_len + 1) % 3 == 2:
        ret = 'Second'
    else:
        ret = 'First'
    print(ret)
    return


def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    a = [int()] * (N-1)  
    b = [int()] * (N-1)  
    for i in range(N-1):
        a[i] = int(next(tokens))
        b[i] = int(next(tokens))
    solve(N, a, b)

if __name__ == '__main__':
    main()

Solution (Python):

import sys

inf = 10 ** 18
 
N = int(input())
ab = [list(map(int, input().split())) for _ in range(N - 1)]
 
cnct = [[] for _ in range(N)]
for ai, bi in ab:
    cnct[ai - 1].append(bi - 1)
    cnct[bi - 1].append(ai - 1)

 

for src in range(N):
    if len(cnct[src]) > 1: break

 
import heapq
 
len_max = 0
for i in range(2):
    q = []
    d = [inf] * N
    prev = [None] * N
    
    heapq.heappush(q, (0, src))
    d[src] = 0
    while len(q) > 0:
        du, u = heapq.heappop(q)
        
        for dst in cnct[u]:
            
            if d[dst] > du + 1:
                d[dst] = du + 1
                prev[dst] = u
                heapq.heappush(q, (du + 1, dst))
    
    if len_max == max(d):
        break
    elif len_max < max(d):
        len_max = max(d)
        src = d.index(len_max)
    else:
        continue
 

 
if len_max % 3 == 1:
    print('Second')    
else:
    print('First')