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

Solution 1 (runtime: 250 ms):
//Bismillahir Rahmanir Rahim
#include <bits/stdc++.h>
using namespace std;

// PBDS:
#include <ext/pb_ds/assoc_container.hpp> // find_by_order(x) = s[x]
#include <ext/pb_ds/tree_policy.hpp>     // order_of_key(x)  = # of elements strictly smaller than x
using namespace __gnu_pbds;
template<typename dataType>
using ordered_set = tree<dataType, null_type, less<dataType>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename dataType1, typename dataType2>
using ordered_map = tree<dataType1, dataType2, less<dataType1>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename dataType>
using ordered_multiset = tree<dataType, null_type, less_equal<dataType>, rb_tree_tag, tree_order_statistics_node_update>;


typedef long long int          ll;
typedef long double            ld;
typedef pair<int, int>         pi;
typedef vector<int>            vi;
typedef vector<long long>      vll;
typedef vector<pair<int, int>> vpi;

#define pb            push_back
#define pf            push_front
#define all(x)        begin(x), end(x)
#define sz(x)         (int)(x).size()
#define ff            first
#define ss            second
#define mp            make_pair
#define mt            make_tuple
#define lb            lower_bound
#define ub            upper_bound
#define Tcase()       int tcc; cin >> tcc; while(tcc--)
#define FOR(i, a, b)  for(ll i = (a); i < (b); i++)
#define F0R(i, a)     FOR(i, 0, a)
#define YES           cout << "YES\n"
#define NO            cout << "NO\n"
#define lcm(a, b)     ((a / __gcd(a, b)) * b)
#define rrep(i, a, b)  for(ll i = (a); i < (b); i++)
#define rep(i, a)     FOR(i, 0, a)

const ll  MOD   = 1e9 + 7;   //
const ll  MOD2  = 998244353;
const ll  INF   = 9e18;
const int MX    = 2e5 + 5;
const ld  PI    = acos((ld) -1);
const int dx[8] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[8] = {1, 0, -1, 0, 1, -1, -1, 1};

void setIO(string name = "") {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    if(sz(name)){
        freopen((name+".in").c_str(), "r", stdin);
        freopen((name+".out").c_str(), "w", stdout);
    }
}

inline bool EQ(double a, double b) { return fabs(a-b) < 1e-9; }
inline bool isLeapYear(ll year) { return (year%400==0) || (year%4==0 && year%100!=0); }
inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1LL; while(p) { if(p&1) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modDiv(ll a, ll b) { return modMul(a, modPow(b, MOD-2)); }


ll Bigmod(ll a, ll b, ll m){
    if(b == 0) return 1 % m;
    ll x = Bigmod(a, b / 2LL, m);
    x = (x * x) % m;
    if(b % 2 == 1) x = (x * a) % m;
    return x;
}

struct DSU { // 0 - indexed.
    vi e; void init(int N){ e = vi(N,-1); }
    // get representive component, uses path compression
    int get(int x){ return e[x] < 0 ? x : e[x] = get(e[x]); }
    bool sameSet(int a, int b){ return get(a) == get(b); }
    int size(int x){ return -e[get(x)]; }
    bool unite(int x, int y) { // union by size
        x = get(x), y = get(y); if(x == y) return 0;
        if(e[x] > e[y]) swap(x, y); // e[x] < 0 means size = -e[x],
        e[x] += e[y]; e[y] = x; return 1; // e[x] >= 0 means root path of x = e[x].
    }
};

vi adj[MX];
int n, deg[MX], aa, bb, ans = 0;
bool vis[MX];

void dfs(int u){
    if(u == aa || u == bb || vis[u]) return;
    vis[u] = true;

    for(auto v : adj[u]) dfs(v);
}

void clr(int n){
    F0R(i, n + 1){
        adj[i].clear();
        vis[i] = false;
        deg[i] = 0;
    }
    ans = 0, aa = 0, bb = 0;
}


void E(int tt){

    cin >> n;
    clr(n);
    int mx = -1, best = 0, mx2 = -1;
    F0R(i, n - 1){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
        adj[v].pb(u);
        deg[u]++;
        deg[v]++;
        mx = max({mx, deg[u], deg[v]});
    }

    int c = 0;
    FOR(i, 1, n + 1){
        if(deg[i] == mx){
            c++;
            if(c == 3){
                cout << 2 * mx - 1 << "\n";
                return;
            }
            int curr = -1;
            bool bad[n + 1] = {0};
            for(auto u : adj[i]){
                bad[u] = true;
            }
            FOR(j, 1, n + 1){
                if(j == i) continue;
                curr = max(curr, deg[j] - bad[j]);
            }
            if(curr > mx2){
                mx = deg[i];
                best = i;
            }
        }
    }

    for(auto u : adj[best]){
        deg[u]--;
    }
    deg[best] = -1;
    adj[best].clear();
    aa = best;

    mx = -1, best = 0;
    FOR(i, 1, n + 1){
        if(deg[i] > mx && i != aa){
            mx = deg[i];
            best = i;
        }
    }
    bb = best;
    adj[best].clear();

    FOR(i, 1, n + 1){
        if(i == aa || i == bb) continue;
        if(!vis[i]){
            dfs(i);
            ans++;
        }
    }

    cout << ans << "\n";
}


int main(){

    setIO();

    int t = 1;
    Tcase(){
        E(t++);
    }
}


Solution 2 (runtime: 531 ms):
#include <bits/stdc++.h>
#define all(v) v.begin(),v.end()
#define mid (l+r)/2
#define lc 2*node
#define rc lc+1
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ordered_set(X) tree<X, null_type,less_equal<X>, rb_tree_tag,tree_order_statistics_node_update>
///#define int int_fast64_t
///#define double long double
#define endl '\n'

using namespace std;
using namespace __gnu_pbds;

const int_fast64_t inf = 2e12+1;
const int NN = 2e5+1;
const int mod = 1e9+7;
int tc=1;
int n;
vector<int> adj[NN];
int degree[NN];

void solve()
{
    multiset<int> degs;
    for (int i=1 ; i<=n ; i++) degs.insert(degree[i]);

    int ans = 0;

    for (int node = 1; node<=n ; node++)
    {
        degs.erase(degs.find(degree[node]));
        int temp = 0;
        for (int child : adj[node])
        {
            temp = max (temp , degree[child]);
            degs.erase(degs.find(degree[child]));
        }
        ans = max (ans , temp + degree[node] - 1);

        if (degs.size()) ans = max (ans , degree[node] + *--degs.end());
        for (int child : adj[node])
        {
            degs.insert(degree[child]);
        }
        degs.insert(degree[node]);
    }
    ans -- ;
    cout << ans << endl;
}

signed main()
{
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    auto time_start = clock();

    ///freopen("test_input.txt" , "r" , stdin);
    ///freopen("test_output.txt" , "w" , stdout);
    cin >> tc;
    while (tc--)
    {
        cin >> n;
        for (int i=1 ; i<=n ; i++) degree[i]=0 , adj[i].clear();

        for (int i=2 ; i<=n ; i++)
        {
            int u, v;
            cin >> u >> v;
            adj[u].push_back(v);
            adj[v].push_back(u);
            degree[u]++;
            degree[v]++;
        }
        solve();
    }


    auto time_end = clock();
    ///cerr<<fixed<<setprecision(10)<<"\nTime Taken: "<<(double)(time_end- time_start)/CLOCKS_PER_SEC<<endl;

    return 0;
}