Problem: 2063C - Remove Exactly Two
Language: python

Solution 1 (runtime: 1937 ms):
import sys, math, random; from heapq import heapify, heappop, heappush;
from collections import defaultdict, Counter, deque; from bisect import bisect_left, bisect_right
def IL(): return list(map(int, sys.stdin.readline().strip().split()))
def S(): return sys.stdin.readline().strip()

def solve():
    n = IL()[0]
    adj = [[] for _ in range(n + 1)]
    degree = [0] * (n + 1)
    ind = [0] * (n + 1)
    for _ in range(n - 1):
        x, y = IL()
        adj[x].append(y)
        adj[y].append(x)
        degree[x] += 1
        degree[y] += 1
        ind[x] += 1
        ind[y] += 1

    que = deque()
    for node in range(1, n + 1):
        if degree[node] == 1:
            que.append(node)
    val = [-1] * (n + 1)
    level = 0
    while que:
        for _ in range(len(que)):
            node = que.popleft()
            val[node] = level
            for nei in adj[node]:
                ind[nei] -= 1
                if ind[nei] == 1:
                    que.append(nei)
            level += 1
    
    arr = []
    for node in range(1, n + 1):
        arr.append((degree[node], -val[node], node))
    arr.sort()

    ans = 1
    deg, _, first = arr.pop()
    ans += deg - 1
    for nei in adj[first]:
        degree[nei] -= 1
    arr = []
    for node in range(1, n + 1):
        if node != first:
            arr.append((degree[node], -val[node], node))
    arr.sort()
    deg, _, _ = arr.pop()
    ans += deg - 1
    print(ans)

    


    

tt = 1
tt = IL()[0]
for _ in range(tt):
    solve()

Solution 2 (runtime: 781 ms):
t = int(input())

for x in range(t):
    n = int(input())
    edges = []
    adj_list = []

    for y in range(n+1):
        adj_list.append([])

    for e in range(n-1):
        a,b = list(map(int, input().split(" ")))
        
        adj_list[a].append(b)
        adj_list[b].append(a)


    for i in range(2):
        cnt_max_edges = 0
        max_edges = []
        for node in range(1, n+1):
            if adj_list[node] != None:
                if len(adj_list[node]) > cnt_max_edges:
                    cnt_max_edges = len(adj_list[node])
                    max_edges = [node]
                elif len(adj_list[node]) == cnt_max_edges:
                    max_edges.append(node)


        if len(max_edges) <= 2 or i == 1:
            max_edges = [max_edges[0]]
        else:
            f = False
            for idx1 in range(0, len(max_edges)):
                if f: break
                for idx2 in range(idx1+1, len(max_edges)):
                    if not max_edges[idx2] in adj_list[max_edges[idx1]]:
                        max_edges = [max_edges[idx1], max_edges[idx2]]
                        f = True
                        break


        for most_edges_node in max_edges:
            for node in adj_list[most_edges_node]:
                adj_list[node].remove(most_edges_node)

            adj_list[most_edges_node] = None

        if len(max_edges) >= 2:
            break

    count_cc = 0
    connected = {}
    v = 1
    for node in range(1, n+1):
        if adj_list[node] != None and not node in connected:
            queue = [node]

            while len(queue) > 0:
                curr = queue.pop()
                connected[curr] = count_cc
                for adj_node in adj_list[curr]:
                    if not adj_node in connected:
                        queue.append(adj_node)
                        connected[adj_node] = count_cc

            count_cc += 1

    print(count_cc)