Problem: 2063C - Remove Exactly Two
Language: c++17 

Solution 1 (runtime: 999 ms):
#include "bits/stdc++.h"
using namespace std;

#define int long long
#define endl '\n'
#define ss second
#define ff first

const int MOD2 = 998244353;
const int MOD1 = 1e9 + 7;
const int INF = 1e18 + 5;
const int N = 2e5 + 5;

signed main() {
    // ios_base::sync_with_stdio(NULL);
    // cin.tie(NULL); cout.tie(NULL);

    // #ifndef ONLINE_JUDGE
    //     freopen("input.txt", "r", stdin);
    //     freopen("output.txt", "w", stdout);
    // #endif
    
    int TC;
    cin >> TC;
    while (TC--){
        int n;cin >> n;
        vector<int> D(n + 1);
        vector<set<int>> A(n + 1);

        int in = -1;
        int mx = -1;
        for(int i = 0; i < n - 1; i++){
            int u, v;
            cin >> u >> v;
            A[u].insert(v);
            A[v].insert(u);
            D[u]++; D[v]++;
            mx = max({mx, D[u], D[v]});
        }

        if(n == 2){
            cout << 0 << endl;
            continue;
        }

        multiset<int, greater<int>> ms;
        for(int i = 1; i <= n; i++)
            ms.insert(D[i]);

        vector<pair<int,int>> a;
        for(int i = 1; i <= n; i++){
            if(D[i] == mx){
                ms.erase(ms.find(mx));
                for(auto k : A[i]){
                    ms.erase(ms.find(D[k]));
                    ms.insert(D[k] - 1);
                }

                a.push_back({*ms.begin(), i});
                ms.insert(mx);
                for(auto k : A[i]){
                    ms.erase(ms.find(D[k] - 1));
                    ms.insert(D[k]);
                }
            }
        }

        sort(a.rbegin(), a.rend());
        function<void(int)> DELETE = [&](int in){
            for(auto k : A[in]){
                A[k].erase(in);
                D[k]--;
            }
 
            A[in].clear();
            D[in] = 0;          
        };

        DELETE(a[0].ss);
        
        in = -1;
        mx = -1;
        for(int i = 1; i <= n; i++){
            if(D[i] > mx){
                mx = D[i];
                in = i;
            }
        }
        
        DELETE(in);
        
        vector<int> vis(n + 1, 0);
        function<void(int)> DFS = [&](int i){
            vis[i] = 1;
            for(auto k : A[i]){
                if(!vis[k])
                    DFS(k);
            }
        };

        int com = 0;
        for(int i = 1; i <= n; i++){
            if(!vis[i]){
                DFS(i);
                com++;  
            }
        }

        cout << (com - 2) << endl;
    }

    return 0;
}
/*
*/

Solution 2 (runtime: 812 ms):
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <set>

#define inout std::ios::sync_with_stdio(false); std::cin.tie(nullptr);
using ll = long long;

std::vector<std::vector<int>> graph;
std::vector<int> degree;
std::vector<bool> visited;

void solve()
{
    int n, u, v;
    std::cin >> n;

    graph.clear();
    degree.clear();
    visited.clear();
    graph.resize(n + 1);
    degree.resize(n + 1, 0);
    visited.resize(n + 1, false);

    for (int i = 0; i < n - 1; i++)
    {
        std::cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
        degree[u]++;
        degree[v]++;
    }

    // get the two nodes with the largest degree value
    // remove those nodes. use dfs to find how many separated graphs are left.
    // _from the future_ it's not really correct but very close.
    // _future future_ tirili minda
    // :sob:

    std::multiset<int> set;
    for (int i = 1; i <= n; i++) 
    {
        set.insert(graph[i].size());
        set.insert(graph[i].size()-1);
    }

    int answer = 0;
    for (int i = 1; i <= n; i++)
    {
        for (int neighbor : graph[i]) set.erase(set.find(graph[neighbor].size()));
        set.erase(set.find(graph[i].size()));
        set.erase(set.find(graph[i].size()-1));

        answer = std::max(answer, (int)graph[i].size() + *set.rbegin()-1);
        for (int neighbor : graph[i]) set.insert(graph[neighbor].size());
        set.insert(graph[i].size());
        set.insert(graph[i].size()-1);
    }

    std::cout << answer << '\n';
}

int main()
{
    inout;
    int t;
    std::cin >> t;
    while (t--) solve();
}