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

Solution 1 (runtime: 280 ms):
#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
//#include <iomanip>
#include<complex>
#include<bits/stdc++.h>


#include<cmath>
#define INF 1000000005
#define PI M_PI


using namespace std;

void fun() {
	int n;
	cin >> n;
	vector<vector<int> > e(n);
	vector<int> cnt(n,0);
	for(int i=0;i<=n-2;i++){
		int u,v;
		cin >> u >> v;
		e[u-1].push_back(v-1);
		e[v-1].push_back(u-1);
		cnt[u-1]++;
		cnt[v-1]++;
	}
	int mx=0,mxnode;
	int bigcnt=0;
	for(int i=0;i<n;i++){
		if(cnt[i]>=mx){
			mx=cnt[i];
			mxnode=i;
		}
	}
	for(int i=0;i<n;i++){
		if(cnt[i] == mx){
			bigcnt++;
		}
	}
	if(bigcnt>2){
		cout << mx*2-1 << '\n';
		return;
	}
	int re=mx;
	mx=-1;
	int secnode;
	for(int i=0;i<e[mxnode].size();i++){
		cnt[e[mxnode][i]]-=1;
	}
	for(int i=0;i<n;i++){
		if(cnt[i]>mx&&i!=mxnode){
			mx=cnt[i];
			secnode=i;
		}
	}
//	cout << secnode << '\n';
	re += (mx-1);
	cout << re << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T = 1;
	cin >> T;
//	getchar();
    while (T--) fun();

    return 0;
}


Solution 2 (runtime: 233 ms):
#include <iostream>
//#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <random>
#include <iterator>
#include <numeric>
#include <unordered_map>
#include <map>
#include <unordered_set>
#include <set>
#include <bitset>
//#include <limits>
#include <climits>
#include <queue>
#include <stack>
#include <deque>
#include <tuple>
#include <list>
#include <math.h> 
#include <random> 
#include <algorithm>
#include <chrono>
#include <iomanip>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#include <array>
#include <tuple>
#include <functional>
#include <cctype>
#include <cstdlib>
#include <ctime>
#include <float.h>


/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
typedef __gnu_pbds::tree<int, __gnu_pbds::null_type, less<int>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update> ordered_set;

ordered_set st; 
*/

// g++-13 -std=c++11 codeforce.cpp -o codeforce
// g++ -std=c++11 codeforce.cpp -o codeforce
// ./codeforce <codef.txt 


using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
//typedef string str;

vector<int> manacher_odd(string s) {
    int n = s.size();
    s = "$" + s + "^";
    vector<int> p(n + 2);
    int l = 1, r = 1;
    for(int i = 1; i <= n; i++) {
        p[i] = max(0, min(r - i, p[l + (r - i)]));
        while(s[i - p[i]] == s[i + p[i]]) {
            p[i]++;
        }
        if(i + p[i] > r) {
            l = i - p[i], r = i + p[i];
        }
    }
    return vector<int>(begin(p) + 1, end(p) - 1);
}
vector<int> manacher(string s) {
    string t;
    for(auto c: s) {
        t += string("#") + c;
    }
    auto res = manacher_odd(t + "#");
    return vector<int>(begin(res) + 1, end(res) - 1);
}

// mt19937_64 rnd(98275314);
// ll gen(){
//     ll x=0;
//     while(x==0){
//         x=rnd();
//     }
//     return x;
// }
vector<int> z_function(string s) {
    int n = s.size();
    vector<int> z(n);
    int l = 0, r = 0;
    for(int i = 1; i < n; i++) {
        if(i < r) {
            z[i] = min(r - i, z[i - l]);
        }
        while(i + z[i] < n && s[z[i]] == s[i + z[i]]) {
            z[i]++;
        }
        if(i + z[i] > r) {
            l = i;
            r = i + z[i];
        }
    }
    return z;
}
/*
template<class T>
struct MaxFlow {
    struct _Edge {
        int to;
        T cap;
        _Edge(int to, T cap) : to(to), cap(cap) {}
    };
    int n;
    std::vector<_Edge> e;
    std::vector<std::vector<int> > g;
    std::vector<int> cur, h;
    MaxFlow() {}
    MaxFlow(int n) {
        init(n);
    }
    void init(int n) {
        this->n = n;
        e.clear();
        g.assign(n, {});
        cur.resize(n);
        h.resize(n);
    }
    bool bfs(int s, int t) {
        h.assign(n, -1);
        std::queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            const int u = que.front();
            que.pop();
            for (int i : g[u]) {
                auto [v, c] = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t) {
                        return true;
                    }
                    que.push(v);
                }
            }
        }
        return false;
    }
    T dfs(int u, int t, T f) {
        if (u == t) {
            return f;
        }
        auto r = f;
        for (int &i = cur[u]; i < int(g[u].size()); ++i) {
            const int j = g[u][i];
            auto [v, c] = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                auto a = dfs(v, t, std::min(r, c));
                e[j].cap -= a;
                e[j ^ 1].cap += a;
                r -= a;
                if (r == 0) {
                    return f;
                }
            }
        }
        return f - r;
    }
    void addEdge(int u, int v, T c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    T flow(int s, int t) {
        T ans = 0;
        while (bfs(s, t)) {
            cur.assign(n, 0);
            ans += dfs(s, t, std::numeric_limits<T>::max());
        }
        return ans;
    }
    std::vector<bool> minCut() {
        std::vector<bool> c(n);
        for (int i = 0; i < n; i++) {
            c[i] = (h[i] != -1);
        }
        return c;
    }
    struct Edge {
        int from;
        int to;
        T cap;
        T flow;
    };
    std::vector<Edge> edges() {
        std::vector<Edge> a;
        for (int i = 0; i < e.size(); i += 2) {
            Edge x;
            x.from = e[i + 1].to;
            x.to = e[i].to;
            x.cap = e[i].cap + e[i + 1].cap;
            x.flow = e[i + 1].cap;
            a.push_back(x);
        }
        return a;
    }
};
*/
// std::mt19937_64 rng {std::chrono::steady_clock::now().time_since_epoch().count()};
const int N=2e5;
vector<int>G[N];
void solve(){
    int n;
    cin>>n;
    vector<int>deg(n);
    for(int i=0;i<n-1;++i){
        int u,v;
        cin>>u>>v;
        --u,--v;
        G[u].push_back(v);
        G[v].push_back(u);
        deg[u]++;
        deg[v]++;
    }
    vector<int>idx(n);
    int mx=*max_element(deg.begin(),deg.end());
    iota(idx.begin(),idx.end(),0);
    sort(idx.begin(),idx.end(), [&](int a, int b){
        return deg[a]>deg[b];
    });
    int ans=0;
    for(int j=0;j<min(3,n);++j){
        for(int i=0;i<n;++i){
            if(i==idx[j]){
                continue;
            }
            int adj=0;
            for(int it:G[i]){
                if(it==idx[j]){
                    adj=1;
                    break;
                }
            }
            ans=max(deg[idx[j]]+deg[i]-1-adj,ans);
        }
    }
    cout<<ans<<endl;
    for(int i=0;i<n;++i){
        G[i].clear();
    }
}
int main(int argc, char *argv[]) {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cout<<std::setprecision(20);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
}

/*

FOR ICPC style rounds, read all problems! don't get stuck on 1.
*/
/*prvb
nice trick: 
up is down?

Fenwick
int lowbit(int i) { // gets the lowest set bit
	return (-i)&i;
}
adds 1 from [1,i];
void bitadd(int i) {
	for(;i<=n;i+=lowbit(i)) bit[i]++;
}
queries [1,i];
int bitqu(int i) {
	int ans=0;
	for(;i;i-=lowbit(i)) ans+=bit[i];
	return ans;
}
*/