Problem: 2063C - Remove Exactly Two
Language: C++20 (GCC 13-64)

Previous submission (verdict: Wrong answer on test 4):
#include <bits/stdc++.h>
using namespace std;
 
#define int long long
#define pii pair<int,int>
#define all(v) v.begin(),v.end()
#define pb push_back
#define F first
#define S second
#define MP make_pair
 
// #define forr(i, j, k) for (int i = j; i < k; i++)
// #define frange(i, j) forr(i, 0, j)
// typedef vector<int> vi;
// typedef vector<vi> vvi;
 
// vvi minv;
// vi vec;
 
// void init(int n) {
//     minv = vvi(20, vi(n));
//     frange(i, n) minv[0][i] = vec[i];
 
//     forr(i, 1, 20) {
//         frange(j, n) {
//             minv[i][j] = max(minv[i-1][j], minv[i-1][min(n-1, j+(1<<(i-1)))]);
//         }
//     }
// }
 
// int query(int l, int r) {
//     int ln = r - l +1;
//     int msb = 31 - __builtin_clz(ln);
 
//     return max(minv[msb][l], minv[msb][r-(1<<msb)+1]);
// }
 
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
 
// typedef __gnu_pbds::tree<pair<int,int>, __gnu_pbds::null_type, less<pair<int,int>>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update> ordered_set;//find_by_order, order_of_key
 
const int N = 5e3+5;
const int mod = 1e9+7;
const int maxi = 2e5+10;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
// // int fact[N];
// // int primes[N];
// // vector<int> prime;
 
// inline int add(int a, int b){
//     a = (a+b)%mod;
//     return a;
// }
// inline int sub(int a, int b){
//   a = (a-b)%mod;
//   if (a<0)a += mod;
//   return a;
// }
inline int mul(int a, int b){
    a = (1LL*a*b)%mod;
    return a;
}
// inline int power(int a, int b) {
//   int res = 1;
//   while (b > 0) {
//     if (b & 1) {
//       res = mul(res, a);
//     }
//     a = mul(a, a);
//     b >>= 1;
//   }
//   return res;
// }
// inline int inv(int a) {
//   a %= mod;
//   if (a < 0) a += mod;
//   int b = mod, u = 0, v = 1;
//   while (a) {
//     int t = b / a;
//     b -= t * a; swap(a, b);
//     u -= t * v; swap(u, v);
//   }
//   assert(b == 1);
//   if (u < 0) u += mod;
//   return u;
// }
// inline int inv(int a){
//   return power(a,mod-2);
// }
// void rec(){
//     fact[0] = 1;
//     for (int i=1;i<N;i++){
//         fact[i] = mul(fact[i-1],i);
//     }
// }
 
// int ncr(int a, int b){
//   int val = fact[a];
//   val = mul(val,inv(fact[b]));
//   val = mul(val,inv(fact[a-b]));
//   return val;
// }
 
struct node{
    node *child[201];
    int cnt;
    node(){
        for (int i=0;i<201;i++)child[i] = NULL;
        cnt = 0;
    }
};
void insert(vector<int> arr, node *head){
    node *cur = head;
    int m = arr.size();
    for (int i=0;i<m;i++){
        int x = arr[i];
        if (x==-1)break;
        if (cur->child[x] == NULL){
            cur->child[x] = new node();
        }
        cur = cur->child[x];
        cur->cnt++;
    }
}
int find_max(vector<int> arr, node *head){
    int m = arr.size();
    int  len = 0;
    node *cur = head;
    for (int i=0;i<m;i++){
        int x = arr[i];
        if (x==-1)break;
        if (cur->child[x] == NULL)return 0;
        cur = cur->child[x];
        len = cur->cnt;
    }
    return len;
}
 
// struct node1{
//     int cnt;
//     node1(int mm = 0){
//         cnt = mm;
//     }
// };
 
// vector<int> a11;
// node1 t1[800080];
 
// void build1(int id, int l, int r){
//     //if (l>r)return;
//     if (l==r){
//       //cout<<l<<" "<<id<<" ifif"<<"\n";
//       t1[id].cnt = a11[l];
//       //cout<<t1[id].cnt<<"\n";
//         return;
//     }
//     int mid = (l+r)/2;
//     build1(2*id, l, mid);
//     build1(2*id+1, mid+1, r);
//     t1[id].cnt = t1[2*id].cnt+ t1[2*id+1].cnt;
// }
 
// int query1(int id, int l, int r, int lq, int rq){
//     if (l>rq || r<lq){
//         return 0;
//     }
//     if (lq>=l && rq<=r){
//       //cout<<l<<" "<<id<<" "<<" "<<"fjjf"<<"\n";
//         return t1[id].cnt;
//     }
//     int mid = (lq+rq)/2;
//     return (query1(2*id,l,r,lq,mid) + query1(2*id+1,l,r,mid+1,rq));
// }
 
// void update1(int id, int l, int r, int pos, int val){
//   if (l>pos || r<pos){
//         return ;
//     }
//     if (l==r && l==pos){
//         t1[id].cnt = val;
//         a11[l] = val;
//         return;
//     }
//     int mid = (l+r)/2;
//     update1(2*id,l,mid,pos,val);
//     update1(2*id+1,mid+1,r,pos,val);
//     t1[id].cnt =  (t1[2*id].cnt + t1[2*id+1].cnt);
// }
 
// void pre(){
//     for (int i=2;i<N;i++){int
        
//         for (int j=2;j*j<=i;j++){
//             int f = 0;
//             while (x%j==0){
//                 f = 1;
//                 x /= j;
//             }
//             if (f==1){
//                 factors[i].pb(j);
//             }
//             if (x != 1)factors[i].pb(x);
//         }
//         sort(aint(factors[i]));
//     }
// }
 
// struct unionfind{
//   int n,st_size,*rank,*par;
//   unionfind(){}
//   unionfind(int a){
//     n = a;
//     st_size = n-1;
//     rank = new int[n];
//     par = new int[n];
//     for (int i=0;i<n;i++){
//       par[i] = i;
//       rank[i] = 1;
//     }
//   }
//   int find(int x){
//     if (x==par[x])return x;
//     else return (par[x]=find(par[x]));
//   }
//   void merge(int x, int y){
//     int x1 = find(x);
//     int y1 = find(y);
//     if (x1 != y1){
//       if (rank[x1]>=rank[y1]){
//         rank[x1] += rank[y1];
//         par[y1] = x1;
//       }
//       else {
//         rank[y1] += rank[x1];
//         par[x1] = y1;
//       }
//       st_size--;
//     }
//     else rank[x1]++;
//   }
//   int comp_size(){
//     int maxi = 0;
//     for (int i=1;i<n;i++){
//         maxi = max(maxi,rank[i]-1);
//     }
//     return maxi;
//   }
// };
 
// void all_primes(){
//   for (int i=1;i<N;i++)primes[i] = i;
//   for (int i=2;i<N;i++){
//     if (primes[i] != i)continue;
//       primes[j] = min(primes[j],i);
//     }
//   }
// }
 
// struct hasher {
//     int sz;
//     int mod, p;
//     vector<int> fHash;
//     vector<int> pk;
//     void init(string s, int _p, int _mod){
//         mod = _mod;
//         p = _p;
//         sz = s.length();
//         fHash.resize(sz);
//         pk.resize(sz);
//         fHash[0] = (s[0]-'a'+1);
//         pk[0] = 1;
//         for (int i=1;i<s.length();i++){
//             fHash[i] = (fHash[i-1]*p + (s[i]-'a'+1))%mod;
//             pk[i] = (pk[i-1]*p)%mod;
//         }
//     }
//     int getfHash(int l, int r){
//         if (l==0)return fHash[r];
//         else return ((fHash[r] - fHash[l-1]*pk[r-l+1])%mod + mod)%mod;
//     }
// };

void solve(){
    int n;cin>>n;
    vector<vector<int>> g;
    g.resize(n+1);
    for (int i=1;i<n;i++){
        int a,b;cin>>a>>b;
        g[a].pb(b);
        g[b].pb(a);
    }
    vector<pair<int,int>> v;
    for (int i=1;i<=n;i++){
        v.pb({g[i].size(), i});
    }
    sort(all(v));
    int ans = 0;
    for (int i=1;i<=n;i++){
        if (i != v[n-1].S)continue;
        if (g[i].size()==0)continue;
        int val = g[i].size();
        int sum = 0;
        vector<int> arr(n+1,0);
        for (auto it : g[i]){
            int a = g[it].size();
            sum = max(sum, val + a - 2LL);
            arr[it] = 1;
        }
        ans = max(ans, sum);
        //cout<<ans<<"\n";
        for (int j=n-1;j>=0;j--){
            if (v[j].S != i && arr[v[j].S]==0){
                ans = max(ans, val - 1LL + v[j].F);
                break;
            }
        }
        //cout<<ans<<"\n";
    }
    cout<<ans<<"\n";
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cout.precision(10); cout.setf(ios::fixed);
    int T;cin>>T;while(T--)
    solve();
}

Submission (verdict: Accepted):
#include <bits/stdc++.h>
using namespace std;
 
#define int long long
#define pii pair<int,int>
#define all(v) v.begin(),v.end()
#define pb push_back
#define F first
#define S second
#define MP make_pair
 
// #define forr(i, j, k) for (int i = j; i < k; i++)
// #define frange(i, j) forr(i, 0, j)
// typedef vector<int> vi;
// typedef vector<vi> vvi;
 
// vvi minv;
// vi vec;
 
// void init(int n) {
//     minv = vvi(20, vi(n));
//     frange(i, n) minv[0][i] = vec[i];
 
//     forr(i, 1, 20) {
//         frange(j, n) {
//             minv[i][j] = max(minv[i-1][j], minv[i-1][min(n-1, j+(1<<(i-1)))]);
//         }
//     }
// }
 
// int query(int l, int r) {
//     int ln = r - l +1;
//     int msb = 31 - __builtin_clz(ln);
 
//     return max(minv[msb][l], minv[msb][r-(1<<msb)+1]);
// }
 
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
 
// typedef __gnu_pbds::tree<pair<int,int>, __gnu_pbds::null_type, less<pair<int,int>>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update> ordered_set;//find_by_order, order_of_key
 
const int N = 5e3+5;
const int mod = 1e9+7;
const int maxi = 2e5+10;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
// // int fact[N];
// // int primes[N];
// // vector<int> prime;
 
// inline int add(int a, int b){
//     a = (a+b)%mod;
//     return a;
// }
// inline int sub(int a, int b){
//   a = (a-b)%mod;
//   if (a<0)a += mod;
//   return a;
// }
inline int mul(int a, int b){
    a = (1LL*a*b)%mod;
    return a;
}
// inline int power(int a, int b) {
//   int res = 1;
//   while (b > 0) {
//     if (b & 1) {
//       res = mul(res, a);
//     }
//     a = mul(a, a);
//     b >>= 1;
//   }
//   return res;
// }
// inline int inv(int a) {
//   a %= mod;
//   if (a < 0) a += mod;
//   int b = mod, u = 0, v = 1;
//   while (a) {
//     int t = b / a;
//     b -= t * a; swap(a, b);
//     u -= t * v; swap(u, v);
//   }
//   assert(b == 1);
//   if (u < 0) u += mod;
//   return u;
// }
// inline int inv(int a){
//   return power(a,mod-2);
// }
// void rec(){
//     fact[0] = 1;
//     for (int i=1;i<N;i++){
//         fact[i] = mul(fact[i-1],i);
//     }
// }
 
// int ncr(int a, int b){
//   int val = fact[a];
//   val = mul(val,inv(fact[b]));
//   val = mul(val,inv(fact[a-b]));
//   return val;
// }
 
struct node{
    node *child[201];
    int cnt;
    node(){
        for (int i=0;i<201;i++)child[i] = NULL;
        cnt = 0;
    }
};
void insert(vector<int> arr, node *head){
    node *cur = head;
    int m = arr.size();
    for (int i=0;i<m;i++){
        int x = arr[i];
        if (x==-1)break;
        if (cur->child[x] == NULL){
            cur->child[x] = new node();
        }
        cur = cur->child[x];
        cur->cnt++;
    }
}
int find_max(vector<int> arr, node *head){
    int m = arr.size();
    int  len = 0;
    node *cur = head;
    for (int i=0;i<m;i++){
        int x = arr[i];
        if (x==-1)break;
        if (cur->child[x] == NULL)return 0;
        cur = cur->child[x];
        len = cur->cnt;
    }
    return len;
}
 
// struct node1{
//     int cnt;
//     node1(int mm = 0){
//         cnt = mm;
//     }
// };
 
// vector<int> a11;
// node1 t1[800080];
 
// void build1(int id, int l, int r){
//     //if (l>r)return;
//     if (l==r){
//       //cout<<l<<" "<<id<<" ifif"<<"\n";
//       t1[id].cnt = a11[l];
//       //cout<<t1[id].cnt<<"\n";
//         return;
//     }
//     int mid = (l+r)/2;
//     build1(2*id, l, mid);
//     build1(2*id+1, mid+1, r);
//     t1[id].cnt = t1[2*id].cnt+ t1[2*id+1].cnt;
// }
 
// int query1(int id, int l, int r, int lq, int rq){
//     if (l>rq || r<lq){
//         return 0;
//     }
//     if (lq>=l && rq<=r){
//       //cout<<l<<" "<<id<<" "<<" "<<"fjjf"<<"\n";
//         return t1[id].cnt;
//     }
//     int mid = (lq+rq)/2;
//     return (query1(2*id,l,r,lq,mid) + query1(2*id+1,l,r,mid+1,rq));
// }
 
// void update1(int id, int l, int r, int pos, int val){
//   if (l>pos || r<pos){
//         return ;
//     }
//     if (l==r && l==pos){
//         t1[id].cnt = val;
//         a11[l] = val;
//         return;
//     }
//     int mid = (l+r)/2;
//     update1(2*id,l,mid,pos,val);
//     update1(2*id+1,mid+1,r,pos,val);
//     t1[id].cnt =  (t1[2*id].cnt + t1[2*id+1].cnt);
// }
 
// void pre(){
//     for (int i=2;i<N;i++){int
        
//         for (int j=2;j*j<=i;j++){
//             int f = 0;
//             while (x%j==0){
//                 f = 1;
//                 x /= j;
//             }
//             if (f==1){
//                 factors[i].pb(j);
//             }
//             if (x != 1)factors[i].pb(x);
//         }
//         sort(aint(factors[i]));
//     }
// }
 
// struct unionfind{
//   int n,st_size,*rank,*par;
//   unionfind(){}
//   unionfind(int a){
//     n = a;
//     st_size = n-1;
//     rank = new int[n];
//     par = new int[n];
//     for (int i=0;i<n;i++){
//       par[i] = i;
//       rank[i] = 1;
//     }
//   }
//   int find(int x){
//     if (x==par[x])return x;
//     else return (par[x]=find(par[x]));
//   }
//   void merge(int x, int y){
//     int x1 = find(x);
//     int y1 = find(y);
//     if (x1 != y1){
//       if (rank[x1]>=rank[y1]){
//         rank[x1] += rank[y1];
//         par[y1] = x1;
//       }
//       else {
//         rank[y1] += rank[x1];
//         par[x1] = y1;
//       }
//       st_size--;
//     }
//     else rank[x1]++;
//   }
//   int comp_size(){
//     int maxi = 0;
//     for (int i=1;i<n;i++){
//         maxi = max(maxi,rank[i]-1);
//     }
//     return maxi;
//   }
// };
 
// void all_primes(){
//   for (int i=1;i<N;i++)primes[i] = i;
//   for (int i=2;i<N;i++){
//     if (primes[i] != i)continue;
//       primes[j] = min(primes[j],i);
//     }
//   }
// }
 
// struct hasher {
//     int sz;
//     int mod, p;
//     vector<int> fHash;
//     vector<int> pk;
//     void init(string s, int _p, int _mod){
//         mod = _mod;
//         p = _p;
//         sz = s.length();
//         fHash.resize(sz);
//         pk.resize(sz);
//         fHash[0] = (s[0]-'a'+1);
//         pk[0] = 1;
//         for (int i=1;i<s.length();i++){
//             fHash[i] = (fHash[i-1]*p + (s[i]-'a'+1))%mod;
//             pk[i] = (pk[i-1]*p)%mod;
//         }
//     }
//     int getfHash(int l, int r){
//         if (l==0)return fHash[r];
//         else return ((fHash[r] - fHash[l-1]*pk[r-l+1])%mod + mod)%mod;
//     }
// };

void solve(){
    int n;cin>>n;
    vector<vector<int>> g;
    g.resize(n+1);
    for (int i=1;i<n;i++){
        int a,b;cin>>a>>b;
        g[a].pb(b);
        g[b].pb(a);
    }
    vector<pair<int,int>> v;
    for (int i=1;i<=n;i++){
        v.pb({g[i].size(), i});
    }
    sort(all(v));
    int ans = 0;
    if (n==1){
        cout<<"0"<<"\n";
        return;
    }
    for (int i=1;i<=n;i++){
        if (!(i == v[n-1].S || i == v[n-2].S))continue;
        if (g[i].size()==0)continue;
        int val = g[i].size();
        int sum = 0;
        vector<int> arr(n+1,0);
        for (auto it : g[i]){
            int a = g[it].size();
            sum = max(sum, val + a - 2LL);
            arr[it] = 1;
        }
        ans = max(ans, sum);
        //cout<<ans<<"\n";
        for (int j=n-1;j>=0;j--){
            if (v[j].S != i && arr[v[j].S]==0){
                ans = max(ans, val - 1LL + v[j].F);
                break;
            }
        }
        //cout<<ans<<"\n";
    }
    cout<<ans<<"\n";
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cout.precision(10); cout.setf(ios::fixed);
    int T;cin>>T;while(T--)
    solve();
}