#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define unmap unordered_map
#define unset unordered_set
#define MAXQ priority_queue
using namespace std;
template<typename T> using MINQ=priority_queue<T,vector<T>,greater<T> >;
using pii=pair<int,int>;
using vi=vector<int>;
using vii=vector<vi>;

#define maxn 1000010

int n;
int cnt,from[maxn],to[maxn],Next[maxn],head[maxn];
int f[maxn][2][2];

void add(int u,int v){
	cnt++;
	from[cnt]=u; to[cnt]=v;
	Next[cnt]=head[u]; head[u]=cnt;
}

void dfs(int u,int fa){
	int son=0,maxx=-1e9,maxy=-1e9;
	for(int i=head[u];i!=-1;i=Next[i]){
		int v=to[i]; if(v==fa)continue;
		dfs(v,u);son++;
		int x=max(f[v][1][0]-1,f[v][1][1]);
		if(x>maxx){
			maxy=maxx;
			maxx=x;
		}else{
			if(x>maxy)maxy=x;
		}
	}
	f[u][0][0]=1;
	f[u][1][1]=son;f[u][1][0]=-1e9;
	f[u][2][0]=f[u][2][1]=-1e9;
	f[u][2][0]=max(f[u][2][0],maxx+maxy+1);
	for(int i=head[u];i!=-1;i=Next[i]){
		int v=to[i]; if(v==fa)continue;
		f[u][2][0]=max(f[u][2][0],max(f[v][2][1]+1,f[v][2][0]));
		f[u][2][1]=max(f[u][2][1],max(f[v][1][0]+son-1,f[v][1][1]+son-1));
		f[u][1][0]=max(f[u][1][0],max(f[v][1][1]+1,f[v][1][0]));
	}
}

void solve(){cnt=0;
	cin>>n;
	for(int i=1;i<=n;i++)head[i]=-1;
	for(int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	dfs(1,0);
	// for(int i=1;i<=n;i++)cout<<f[i][1][0]<<' '<<f[i][1][1]<<endl;
	cout<<max(f[1][2][0],f[1][2][1])<<endl;

	return ;
}

signed main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int _t=1;
	cin>>_t;
	//cout<<fixed<<setprecision(20);
	for(int i=1;i<=_t;i++){
		//cout<<"Case "<<i<<": ";
		solve();
	}
	return 0;
}

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define unmap unordered_map
#define unset unordered_set
#define MAXQ priority_queue
using namespace std;
template<typename T> using MINQ=priority_queue<T,vector<T>,greater<T> >;
using pii=pair<int,int>;
using vi=vector<int>;
using vii=vector<vi>;

#define maxn 1000010

int n;
int cnt,from[maxn],to[maxn],Next[maxn],head[maxn];
int f[maxn][3][3];

void add(int u,int v){
	cnt++;
	from[cnt]=u; to[cnt]=v;
	Next[cnt]=head[u]; head[u]=cnt;
}

void dfs(int u,int fa){
	int son=0,maxx=-1e9,maxy=-1e9;
	for(int i=head[u];i!=-1;i=Next[i]){
		int v=to[i]; if(v==fa)continue;
		dfs(v,u);son++;
		int x=max(f[v][1][0]-1,f[v][1][1]);
		if(x>=maxx){
			maxy=maxx;
			maxx=x;
		}else{
			if(x>=maxy)maxy=x;
		}
	}
	f[u][0][0]=1;
	f[u][1][1]=son;f[u][1][0]=-1e9;
	f[u][2][0]=f[u][2][1]=-1e9;
	if(son>=2)f[u][2][0]=max(f[u][2][0],maxx+maxy+1);
	for(int i=head[u];i!=-1;i=Next[i]){
		int v=to[i]; if(v==fa)continue;
		f[u][2][0]=max(f[u][2][0],max(f[v][2][1]+1,f[v][2][0]));
		f[u][2][1]=max(f[u][2][1],max(f[v][1][0]+son-1,f[v][1][1]+son-1));
		f[u][1][0]=max(f[u][1][0],max(f[v][1][1]+1,f[v][1][0]));
	}
}

void solve(){cnt=0;
	cin>>n;
	for(int i=1;i<=n;i++)head[i]=-1;
	for(int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);add(v,u);
	}
	dfs(1,0);
	// for(int i=1;i<=n;i++)cout<<f[i][1][0]<<' '<<f[i][1][1]<<endl;
	cout<<max(f[1][2][0],f[1][2][1])<<endl;

	return ;
}

signed main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int _t=1;
	cin>>_t;
	//cout<<fixed<<setprecision(20);
	for(int i=1;i<=_t;i++){
		//cout<<"Case "<<i<<": ";
		solve();
	}
	return 0;
}

Answer: 2


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define  nl "\n"
#define forn(a, c) for (int a = 0; a < c; a++)
#define forl(a, b, c) for (int a = b; a <= c; a++)
#define forr(a, b, c) for (int a = b; a >= c; a--)
#define cin(v) for(auto &i:v){cin>>i;}
#define cout(v) for(auto &i:v){cout<<i<<" ";}cout<<nl;
#define all(a) a.begin(),a.end()
#define fast() (ios_base::sync_with_stdio(false), cin.tie(NULL));
mt19937_64 RNG(chrono::steady_clock::now().time_since_epoch().count());

void solve(){
    int n;cin>>n;
    std::vector<pair<int,int>> v;
    map<int,int> mp;
    int mx = 0;
    int e1 = 0;
    forn(i,n-1){
        int x,y;cin>>x>>y;
        v.push_back({min(x,y),max(x,y)});
        mp[x]++;
        mp[y]++;
        if( mx < mp[x]){mx = mp[x];e1 = x;}
        if(mx < mp[y]){mx = mp[y];e1 = y;}
    }
    sort(v.begin(),v.end());
    int mx2 = 0;
    int e2 = 0;
    for(auto &i:mp){
        if(mx-mx2 > mx-i.second && e1 != i.first){mx2 = i.second;e2 = i.first;}
    }
    int cn1=0,cn2=0;
    for(auto &i:mp){
        if(i.second == mx)cn1++;
        if(i.second == mx2)cn2++;
    }

    // cout<<mx<<" "<<mx2<<nl;
    // cout<<e1<<" "<<e2<<nl;
    int c = mx2 + mx -1;
    // cout<<edge[e1]<<nl;
    bool flag = false;
    pair<int,int> p = {e1,e2};
    pair<int,int> pp = {e2,e1};
    if(mx2 == mx){
        if(cn1 > 2){cout<<c<<nl;return;}
        if(binary_search(v.begin(),v.end(),p) || binary_search(v.begin(),v.end(),pp))c--;
        cout<<c<<nl;return;
    }
    // if(binary_search(v.begin(),v.end(),p) || binary_search(v.begin(),v.end(),pp)) flag = true;
    // if(flag)c--;
    // cout<<c<<nl;
    // cout<<e1<<nl;
    for(auto &i:mp){
        if(i.second == mx2){
            // cout<<i.first<<nl;
            pair<int,int> pr = {min(e1,i.first),max(e1,i.first)};
            if(binary_search(v.begin(),v.end(),pr) == false){cout<<c<<nl;return;}
        }
    }
    cout<<c-1<<nl;
}

signed main()
{
    auto begin = std::chrono::high_resolution_clock::now();
    fast();
    int tt;cin>>tt;
    while(tt--){
        solve();
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
    cerr << "Time measured: " << elapsed.count() * 1e-9 << " seconds.\n";
}

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define  nl "\n"
#define forn(a, c) for (int a = 0; a < c; a++)
#define forl(a, b, c) for (int a = b; a <= c; a++)
#define forr(a, b, c) for (int a = b; a >= c; a--)
#define cin(v) for(auto &i:v){cin>>i;}
#define cout(v) for(auto &i:v){cout<<i<<" ";}cout<<nl;
#define all(a) a.begin(),a.end()
#define fast() (ios_base::sync_with_stdio(false), cin.tie(NULL));
mt19937_64 RNG(chrono::steady_clock::now().time_since_epoch().count());

void solve(){
    int n;cin>>n;
    std::vector<pair<int,int>> v;
    map<int,int> mp;
    int mx = 0;
    int e1 = 0;
    forn(i,n-1){
        int x,y;cin>>x>>y;
        v.push_back({min(x,y),max(x,y)});
        mp[x]++;
        mp[y]++;
        if( mx < mp[x]){mx = mp[x];e1 = x;}
        if(mx < mp[y]){mx = mp[y];e1 = y;}
    }
    sort(v.begin(),v.end());
    int mx2 = 0;
    int e2 = 0;
    for(auto &i:mp){
        if(mx-mx2 > mx-i.second && e1 != i.first){mx2 = i.second;e2 = i.first;}
    }
    int cn1=0,cn2=0;
    for(auto &i:mp){
        if(i.second == mx)cn1++;
        if(i.second == mx2)cn2++;
    }

    // cout<<mx<<" "<<mx2<<nl;
    // cout<<e1<<" "<<e2<<nl;
    int c = mx2 + mx -1;
    // cout<<edge[e1]<<nl;
    bool flag = false;
    pair<int,int> p = {e1,e2};
    pair<int,int> pp = {e2,e1};
    if(mx2 == mx){
        if(cn1 > 2){cout<<c<<nl;return;}
        if(binary_search(v.begin(),v.end(),p) || binary_search(v.begin(),v.end(),pp))c--;
        cout<<c<<nl;return;
    }
    // if(binary_search(v.begin(),v.end(),p) || binary_search(v.begin(),v.end(),pp)) flag = true;
    // if(flag)c--;
    // cout<<c<<nl;
    for(auto &i:mp){
        if(i.second == mx2){
            pair<int,int> pr = {max(e1,i.first),min(e1,i.first)};
            if(binary_search(v.begin(),v.end(),pr) == false){cout<<c<<nl;return;}
        }
    }
    cout<<c-1<<nl;
}

signed main()
{
    auto begin = std::chrono::high_resolution_clock::now();
    fast();
    int tt;cin>>tt;
    while(tt--){
        solve();
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
    cerr << "Time measured: " << elapsed.count() * 1e-9 << " seconds.\n";
}

Answer: 1


#include <bits/stdc++.h>
using i64 = long long;
#ifndef ATCODER
consteval auto operator"" _f(const char* str, std::size_t len) {
    return [fmt = std::string_view(str, len)](auto&&... args) {
        return std::vformat(fmt, std::make_format_args(args...));
    };
}
#endif

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

    std::vector<std::vector<int>> adj(n);
    std::vector<int> max(n);
    for (int i = 1, u, v;i < n;i ++) {
        std::cin >> u >> v;
        u --, v --;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    int ans = 0;
    auto dfs = [&](this auto &&self, int ind, int p) -> void{
        int mx1 = 0, mx2 = 0;
        for (auto &to : adj[ind]) {
            if (to == p) continue;
            self(to, ind);
            max[ind] = std::max(max[ind], std::max(max[to], int(adj[to].size())));
            ans = std::max(ans, int(adj[ind].size() + adj[to].size()) - 2);
            ans = std::max(ans, int(adj[ind].size()) + max[to] - 1);
            int smx = std::max(max[to], int(adj[to].size()));
            if (mx1 <= smx) {
                mx2 = mx1;
                mx1 = smx;
            } else if (mx2 < smx) {
                mx2 = smx;
            }
        }
        ans = std::max(ans, mx1 + mx2 - 1);
    };
    dfs(0, -1);

    std::cout << ans << "\n";
}
int32_t main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    std::cin >> t;

    while (t --) {
        solve();
    }
    return 0;
}

#include <bits/stdc++.h>
using i64 = long long;
#ifndef ATCODER
consteval auto operator"" _f(const char* str, std::size_t len) {
    return [fmt = std::string_view(str, len)](auto&&... args) {
        return std::vformat(fmt, std::make_format_args(args...));
    };
}
#endif

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

    std::vector<std::vector<int>> adj(n);
    std::vector<std::array<int, 2>> a(n);
    for (int i = 1, u, v;i < n;i ++) {
        std::cin >> u >> v;
        u --, v --;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (int i = 0;i < n;i ++) {
        a[i] = {int(adj[i].size()), i};
    }

    std::sort(a.begin(), a.end());
    auto [d, id] = a.back();
    a.pop_back();
    std::sort(adj[id].begin(), adj[id].end());

    int ans = 0;
    while (a.size()) {
        int to = a.back()[1];
        if (auto it = std::lower_bound(adj[id].begin(), adj[id].end(), a.back()[1]); it != adj[id].end() and *it == a.back()[1]) {
            ans = std::max(ans, d + int(adj[to].size()) - 2);
        } else {
            ans = std::max(ans, d + int(adj[to].size()) - 1);
        }
        a.pop_back();
    }
    std::cout << ans << "\n";
}
int32_t main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    std::cin >> t;

    while (t --) {
        solve();
    }
    return 0;
}

Answer: 1


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define gcd __gcd
#define sz(v) (int) v.size()
#define pb push_back
#define pi pair<int,int>
#define all(v) (v).begin(), (v).end()
#define compact(v) (v).erase(unique(all(v)), (v).end())
#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
#define REV(i, a, b) for(int i = (a); i >= (b); i--)
#define dbg(x) "[" #x " = " << (x) << "]"
///#define int long long

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template<typename T> bool ckmx(T& a, const T& b){if(a < b) return a = b, true; return false;}
template<typename T> bool ckmn(T& a, const T& b){if(a > b) return a = b, true; return false;}

const int N = 2e5+5;
const ll MOD = 1e9+7;
const ll INF = 1e18;

void solve()
{
    int n; cin >> n;

    vector<vector<int>> adj(n+1, vector<int>());
    FOR(i, 1, n - 1){
        int u,v; cin >> u >> v;
        adj[u].pb(v), adj[v].pb(u);
    }

    multiset<int> s;
    FOR(i, 1, n){
        s.insert(sz(adj[i]));
    }

    int answer = 0;
    FOR(x, 1, n){
        s.erase(s.find(sz(adj[x])));
        for(int v : adj[x]){
            answer = max(answer, sz(adj[x]) + sz(adj[v]) - 2);
            s.erase(s.find(sz(adj[v])));
        }

        if(s.size() > 0)
            answer = max(answer, sz(adj[x]) + (*(--(s.end()))) - 1);

        for(int v : adj[x]){
            s.insert(sz(adj[v]));
        }
        s.insert(sz(adj[x]));
    }

    cout << answer << "\n";

    return;
}

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

    #define name "InvMOD"
    if(fopen(name".INP", "r")){
        freopen(name".INP","r",stdin);
        freopen(name".OUT","w",stdout);
    }

    int t = 1; cin >> t;
    while(t--) solve();
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define gcd __gcd
#define sz(v) (int) v.size()
#define pb push_back
#define pi pair<int,int>
#define all(v) (v).begin(), (v).end()
#define compact(v) (v).erase(unique(all(v)), (v).end())
#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
#define REV(i, a, b) for(int i = (a); i >= (b); i--)
#define dbg(x) "[" #x " = " << (x) << "]"
///#define int long long

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template<typename T> bool ckmx(T& a, const T& b){if(a < b) return a = b, true; return false;}
template<typename T> bool ckmn(T& a, const T& b){if(a > b) return a = b, true; return false;}

const int N = 2e5+5;
const ll MOD = 1e9+7;
const ll INF = 1e18;

void solve()
{
    int n; cin >> n;

    vector<vector<int>> adj(n + 1, vector<int>());
    FOR(i, 1, n - 1){
        int u,v; cin >> u >> v;
        adj[u].pb(v), adj[v].pb(u);
    }

    vector<int> f(n + 1, -1e9);

    int answer = 0;

    auto dfs = [&](auto&& dfs, int x, int p) -> void{
        for(int v : adj[x])if(v != p){
            dfs(dfs, v, x);

            f[x] = max(f[x], max(sz(adj[v]) - 1, f[v]));
            answer = max(answer, sz(adj[x]) + sz(adj[v]) - 2);
            answer = max(answer, sz(adj[x]) + f[v]);
        }
    };

    dfs(dfs, 1, -1);

    cout << answer << "\n";
}

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

    #define name "InvMOD"
    if(fopen(name".INP", "r")){
        freopen(name".INP","r",stdin);
        freopen(name".OUT","w",stdout);
    }

    int t = 1; cin >> t;
    while(t--) solve();
    return 0;
}

Answer: 1


#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;

    while (t--) {
        ll n;
        cin >> n;
        vector<vector<ll>> adj(n);
        set<pair<ll, ll>> s;

        for (int i = 0; i < n - 1; i++) {
            ll a, b;
            cin >> a >> b;
            a--;
            b--;
            adj[a].push_back(b);
            adj[b].push_back(a);
        }

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

        for (int i = 0; i < n; i++) {
            s.insert({adj[i].size(), i});
        }

        int maxi = INT_MIN;

        for (int i = 0; i < n; i++) {

             s.erase({adj[i].size(),i});
            for (auto x : adj[i]) {
                maxi = max(maxi, (int)(adj[i].size() + adj[x].size() - 1));
                s.erase({adj[x].size(), x});
            }

            if (!s.empty()) {
                auto maxElement = *s.rbegin();
                maxi = max(maxi, (int)(adj[i].size() + maxElement.first));
            }
            for (auto x : adj[i]) {

                s.insert({adj[x].size(), x});
            }
            s.insert({adj[i].size(),i});

        }

       cout << maxi - 1 << endl;
    }

    return 0;
}

#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll f(vector<vector<ll>>& adj, ll node, ll count, ll n, ll pre) {
    if (count == 0) {
        return 0;
    }
    if (node >= n) {
        return 0;
    }

    ll rem = 0, notrem = 0;

    if (pre == -1) {
        rem = adj[node].size() + f(adj, node + 1, count - 1, n, node);
    } else {
        rem = adj[node].size();
        if (find(adj[node].begin(), adj[node].end(), pre) != adj[node].end()) {
            rem--;
        }
        rem += f(adj, node + 1, count - 1, n, node);
    }

    notrem = f(adj, node + 1, count, n, pre);
    return max(rem, notrem);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;

    while (t--) {
        ll n;
        cin >> n;
        vector<vector<ll>> adj(n);

        for (int i = 0; i < n - 1; i++) {
            ll a, b;
            cin >> a >> b;
            a--;
            b--;
            adj[a].push_back(b);
            adj[b].push_back(a);
        }

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

        cout << f(adj, 0, 2, n, -1)-1 << endl;
    }

    return 0;
}

Answer: 1


import javax.swing.tree.TreeNode;
import java.io.*;
import java.util.*;

/**
 * @Author: _Djhhh
 * @Introduction：
 */

public class Main {
    static FastReader fr = new FastReader();
    static FastWriter fw = new FastWriter();

    public static void solve() {
        int n=fr.nextInt();
        int[] in = new int[n];
        ArrayList<ArrayList<Integer>> to = new ArrayList<>();
        for(int i=0;i<n;i++){
            to.add(new ArrayList<>());
        }
        for(int i=0;i<n-1;i++){
            int x=fr.nextInt()-1;
            int y=fr.nextInt()-1;
            in[x]++;
            in[y]++;
            to.get(x).add(y);
            to.get(y).add(x);
        }
        int mx=0;
        int id1=0;
        for(int i=0;i<n;i++){
            if(in[i]>=mx){
                mx=in[i];
                int cnt=0;
                for(var y:to.get(i)){
                    if(in[y]==mx)cnt++;
                }
                if(cnt>=2)break;
                id1=i;
            }
        }
        for(var y:to.get(id1)){
            in[y]--;
        }
        in[id1]=0;
        int mn=0;
        for(int i=0;i<n;i++){
            if(in[i]>=mn&&i!=id1){
                mn=in[i];
            }
        }
        fw.println((mx+mn-1));
    }

    public static void main(String[] args) {
        int t = 1;
        t = fr.nextInt();
        while (t-- > 0) solve();
    }
}

class DSU {
    int n;
    int[] fa;
    int[] dep;
    int[] siz;
    int[] edges;
    boolean[] v;
    DSU(int n) {
        fa = new int[n];
        dep = new int[n];
        siz = new int[n];
        edges = new int[n];
        v = new boolean[n];
        for (int i = 0; i < n; i++) {
            fa[i] = i;
            dep[i] = 0;
            siz[i] = 1;
            edges[i] = 0;
            v[i]=false;
        }
    }
    int look(int x) {
        if (fa[x] == x) return x;
        else return fa[x] = look(fa[x]);
    }
    void merge(int x, int y) {
        v[x]=v[y]=true;
        int xx = look(x);
        int yy = look(y);
        if (xx == yy) return;
        edges[xx] += edges[yy] + 1;
        siz[xx] += siz[yy];
        if (dep[xx] < dep[yy]) {
            fa[xx] = yy;
        } else {
            fa[yy] = xx;
        }

        if (dep[xx] == dep[yy]) dep[xx]++;
    }
    boolean isMerge(int x, int y) {
        return look(x) == look(y);
    }
    int getSize(int x) {
        return siz[look(x)];
    }
    int getEdges(int x) {
        return edges[look(x)];
    }
}
class Pair<T1, T2> {
    private T1 first;
    private T2 second;

    public Pair(T1 first, T2 second) {
        this.first = first;
        this.second = second;
    }
    public void setFirst(T1 first) {
        this.first=first;
    }

    public void setSecond(T2 second) {
        this.second=second;
    }
    public T1 getFirst() {
        return first;
    }

    public T2 getSecond() {
        return second;
    }
}
class Algorithm {
    /**
     * 查找第一个大于等于 x 的位置
     * @param arr 查找数组
     * @param x 值
     * @param L 左边界
     * @param R 右边界
     * @return 第一个大于等于 x 的位置
     */
    public static int lowBs(int[] arr, long x, int L, int R){
        int l = L;
        int r = R;
        int res = R + 1;
        while(l <= r){
            int mid = l+r>>1;
            if(arr[mid] >= x){
                res = mid;
                r = mid - 1;
            }
            else{
                l = mid + 1;
            }
        }
        return res;
    }

    /**
     * 查找第一个大于 x 的位置
     * @param arr 查找数组
     * @param x 值
     * @param L 左边界
     * @param R 右边界
     * @return 第一个大于 x 的位置
     */
    public static int highBs(int[] arr, long x, int L, int R) {
        int l = L;
        int r = R;
        int res = R + 1;
        while(l <= r){
            int mid = l+r>>1;
            if(arr[mid] > x){
                res = mid;
                r = mid -1;
            }
            else{
                l = mid +1;
            }
        }
        return res;
    }
}
class FastReader {
    BufferedReader br;
    StringTokenizer st;

    public FastReader() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    int[] nextIntArray() {
        String line = nextLine();
        String[] strNums = line.split("\\s+");
        int[] arr = new int[strNums.length];
        for (int i = 0; i < strNums.length; i++) {
            arr[i] = Integer.parseInt(strNums[i]);
        }
        return arr;
    }

    long[] nextLongArray() {
        String line = nextLine();
        String[] strNums = line.split("\\s+");
        long[] arr = new long[strNums.length];
        for (int i = 0; i < strNums.length; i++) {
            arr[i] = Long.parseLong(strNums[i]);
        }
        return arr;
    }

    char[] nextCharArray() {
        String line = nextLine();
        String[] strNums = line.split("\\s+");
        char[] arr = new char[strNums.length];
        for (int i = 0; i < strNums.length; i++) {
            arr[i] = strNums[i].charAt(0);
        }
        return arr;
    }

    char[] StringtoChar() {
        String line = nextLine();
        return line.toCharArray();
    }
}
class FastWriter {
    private final PrintWriter writer;

    public FastWriter() {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)), true);
    }

    public void print(Object object) {
        writer.print(object);
    }

    public void println(Object object) {
        writer.println(object);
    }

    public void flush() {
        writer.flush();
    }
}

import javax.swing.tree.TreeNode;
import java.io.*;
import java.util.*;

/**
 * @Author: _Djhhh
 * @Introduction：
 */

public class Main {
    static FastReader fr = new FastReader();
    static FastWriter fw = new FastWriter();

    public static void solve() {
        int n=fr.nextInt();
        int[] in = new int[n];
        ArrayList<ArrayList<Integer>> to = new ArrayList<>();
        for(int i=0;i<n;i++){
            to.add(new ArrayList<>());
        }
        for(int i=0;i<n-1;i++){
            int x=fr.nextInt()-1;
            int y=fr.nextInt()-1;
            in[x]++;
            in[y]++;
            to.get(x).add(y);
            to.get(y).add(x);
        }
        int mx=0;
        int id1=0;
        for(int i=0;i<n;i++){
            if(in[i]>=mx){
                mx=in[i];
                int cnt=0;
                for(var y:to.get(i)){
                    if(in[y]==mx)cnt++;
                }
                if(cnt>=2)continue;
                id1=i;
            }
        }
        for(var y:to.get(id1)){
            in[y]--;
        }
        in[id1]=0;
        int mn=0;
        for(int i=0;i<n;i++){
            if(in[i]>=mn&&i!=id1){
                mn=in[i];
            }
        }
        fw.println((mx+mn-1));
    }

    public static void main(String[] args) {
        int t = 1;
        t = fr.nextInt();
        while (t-- > 0) solve();
    }
}

class DSU {
    int n;
    int[] fa;
    int[] dep;
    int[] siz;
    int[] edges;
    boolean[] v;
    DSU(int n) {
        fa = new int[n];
        dep = new int[n];
        siz = new int[n];
        edges = new int[n];
        v = new boolean[n];
        for (int i = 0; i < n; i++) {
            fa[i] = i;
            dep[i] = 0;
            siz[i] = 1;
            edges[i] = 0;
            v[i]=false;
        }
    }
    int look(int x) {
        if (fa[x] == x) return x;
        else return fa[x] = look(fa[x]);
    }
    void merge(int x, int y) {
        v[x]=v[y]=true;
        int xx = look(x);
        int yy = look(y);
        if (xx == yy) return;
        edges[xx] += edges[yy] + 1;
        siz[xx] += siz[yy];
        if (dep[xx] < dep[yy]) {
            fa[xx] = yy;
        } else {
            fa[yy] = xx;
        }

        if (dep[xx] == dep[yy]) dep[xx]++;
    }
    boolean isMerge(int x, int y) {
        return look(x) == look(y);
    }
    int getSize(int x) {
        return siz[look(x)];
    }
    int getEdges(int x) {
        return edges[look(x)];
    }
}
class Pair<T1, T2> {
    private T1 first;
    private T2 second;

    public Pair(T1 first, T2 second) {
        this.first = first;
        this.second = second;
    }
    public void setFirst(T1 first) {
        this.first=first;
    }

    public void setSecond(T2 second) {
        this.second=second;
    }
    public T1 getFirst() {
        return first;
    }

    public T2 getSecond() {
        return second;
    }
}
class Algorithm {
    /**
     * 查找第一个大于等于 x 的位置
     * @param arr 查找数组
     * @param x 值
     * @param L 左边界
     * @param R 右边界
     * @return 第一个大于等于 x 的位置
     */
    public static int lowBs(int[] arr, long x, int L, int R){
        int l = L;
        int r = R;
        int res = R + 1;
        while(l <= r){
            int mid = l+r>>1;
            if(arr[mid] >= x){
                res = mid;
                r = mid - 1;
            }
            else{
                l = mid + 1;
            }
        }
        return res;
    }

    /**
     * 查找第一个大于 x 的位置
     * @param arr 查找数组
     * @param x 值
     * @param L 左边界
     * @param R 右边界
     * @return 第一个大于 x 的位置
     */
    public static int highBs(int[] arr, long x, int L, int R) {
        int l = L;
        int r = R;
        int res = R + 1;
        while(l <= r){
            int mid = l+r>>1;
            if(arr[mid] > x){
                res = mid;
                r = mid -1;
            }
            else{
                l = mid +1;
            }
        }
        return res;
    }
}
class FastReader {
    BufferedReader br;
    StringTokenizer st;

    public FastReader() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    int[] nextIntArray() {
        String line = nextLine();
        String[] strNums = line.split("\\s+");
        int[] arr = new int[strNums.length];
        for (int i = 0; i < strNums.length; i++) {
            arr[i] = Integer.parseInt(strNums[i]);
        }
        return arr;
    }

    long[] nextLongArray() {
        String line = nextLine();
        String[] strNums = line.split("\\s+");
        long[] arr = new long[strNums.length];
        for (int i = 0; i < strNums.length; i++) {
            arr[i] = Long.parseLong(strNums[i]);
        }
        return arr;
    }

    char[] nextCharArray() {
        String line = nextLine();
        String[] strNums = line.split("\\s+");
        char[] arr = new char[strNums.length];
        for (int i = 0; i < strNums.length; i++) {
            arr[i] = strNums[i].charAt(0);
        }
        return arr;
    }

    char[] StringtoChar() {
        String line = nextLine();
        return line.toCharArray();
    }
}
class FastWriter {
    private final PrintWriter writer;

    public FastWriter() {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)), true);
    }

    public void print(Object object) {
        writer.print(object);
    }

    public void println(Object object) {
        writer.println(object);
    }

    public void flush() {
        writer.flush();
    }
}

Answer: 2


#include <bits/stdc++.h>
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifndef LOCAL_STRESS_TEST
struct IOPre { static constexpr int TEN = 10, SZ = TEN * TEN * TEN * TEN; std::array<char, 4 * SZ> num; constexpr IOPre() : num{} { for (int i = 0; i < SZ; i++) { int n = i; for (int j = 3; j >= 0; j--) { num[i * 4 + j] = static_cast<char>(n % TEN + '0'); n /= TEN; } } } }; struct IO {
#if !HAVE_DECL_FREAD_UNLOCKED
#define fread_unlocked fread
#endif
#if !HAVE_DECL_FWRITE_UNLOCKED
#define fwrite_unlocked fwrite
#endif
    static constexpr int SZ = 1 << 17, LEN = 32, TEN = 10, HUNDRED = TEN * TEN, THOUSAND = HUNDRED * TEN, TENTHOUSAND = THOUSAND * TEN, MAGIC_MULTIPLY = 205, MAGIC_SHIFT = 11, MASK = 15, TWELVE = 12, SIXTEEN = 16; static constexpr IOPre io_pre = {}; std::array<char, SZ> input_buffer, output_buffer; int input_ptr_left, input_ptr_right, output_ptr_right; std::stringstream ss; IO() : input_buffer{}, output_buffer{}, input_ptr_left{}, input_ptr_right{}, output_ptr_right{} {} IO(const IO&) = delete; IO(IO&&) = delete; IO& operator=(const IO&) = delete; IO& operator=(IO&&) = delete; ~IO() { flush(); } template <class T> struct is_char { static constexpr bool value = std::is_same_v<T, char>; }; template <class T> struct is_bool { static constexpr bool value = std::is_same_v<T, bool>; }; template <class T> struct is_string { static constexpr bool value = std::is_same_v<T, std::string> || std::is_same_v<T, const char*> || std::is_same_v<T, char*>; }; template <class T, class D = void> struct is_custom { static constexpr bool value = false; }; template <class T> struct is_custom<T, std::void_t<typename T::internal_value_type>> { static constexpr bool value = true; }; template <class T> struct is_default { static constexpr bool value = is_char<T>::value || is_bool<T>::value || is_string<T>::value || std::is_integral_v<T>; }; template <class T, class D = void> struct is_iterable { static constexpr bool value = false; }; template <class T> struct is_iterable< T, typename std::void_t<decltype(std::begin(std::declval<T>()))>> { static constexpr bool value = true; }; template <class T, class D = void, class E = void> struct is_applyable { static constexpr bool value = false; }; template <class T> struct is_applyable<T, std::void_t<typename std::tuple_size<T>::type>, std::void_t<decltype(std::get<0>(std::declval<T>()))>> { static constexpr bool value = true; }; template <class T> static constexpr bool needs_newline = (is_iterable<T>::value || is_applyable<T>::value) && (!is_default<T>::value); template <typename T, typename U> struct any_needs_newline { static constexpr bool value = false; }; template <typename T> struct any_needs_newline<T, std::index_sequence<>> { static constexpr bool value = false; }; template <typename T, std::size_t I, std::size_t... Is> struct any_needs_newline<T, std::index_sequence<I, Is...>> { static constexpr bool value = needs_newline<decltype(std::get<I>(std::declval<T>()))> || any_needs_newline<T, std::index_sequence<Is...>>::value; }; inline void load() { memmove(std::begin(input_buffer), std::begin(input_buffer) + input_ptr_left, input_ptr_right - input_ptr_left); input_ptr_right = input_ptr_right - input_ptr_left + static_cast<int>(fread_unlocked(std::begin(input_buffer) + input_ptr_right - input_ptr_left, 1, SZ - input_ptr_right + input_ptr_left, stdin)); input_ptr_left = 0; } inline void read_char(char& c) { if (input_ptr_left + LEN > input_ptr_right) load(); c = input_buffer[input_ptr_left++]; } inline void read_string(std::string& x) { char c; while (read_char(c), c < '!') continue; x = c; while (read_char(c), c >= '!') x += c; } template <class T> inline std::enable_if_t<std::is_integral_v<T>, void> read_int(T& x) { if (input_ptr_left + LEN > input_ptr_right) load(); char c = 0; do c = input_buffer[input_ptr_left++]; while (c < '-'); [[maybe_unused]] bool minus = false; if constexpr (std::is_signed<T>::value == true) if (c == '-') minus = true, c = input_buffer[input_ptr_left++]; x = 0; while (c >= '0') x = x * TEN + (c & MASK), c = input_buffer[input_ptr_left++]; if constexpr (std::is_signed<T>::value == true) if (minus) x = -x; } inline void skip_space() { if (input_ptr_left + LEN > input_ptr_right) load(); while (input_buffer[input_ptr_left] <= ' ') input_ptr_left++; } inline void flush() { fwrite_unlocked(std::begin(output_buffer), 1, output_ptr_right, stdout); output_ptr_right = 0; } inline void write_char(char c) { if (output_ptr_right > SZ - LEN) flush(); output_buffer[output_ptr_right++] = c; } inline void write_bool(bool b) { if (output_ptr_right > SZ - LEN) flush(); output_buffer[output_ptr_right++] = b ? '1' : '0'; } inline void write_string(const std::string& s) { for (auto x : s) write_char(x); } inline void write_string(const char* s) { while (*s) write_char(*s++); } inline void write_string(char* s) { while (*s) write_char(*s++); } template <typename T> inline std::enable_if_t<std::is_integral_v<T>, void> write_int(T x) { if (output_ptr_right > SZ - LEN) flush(); if (!x) { output_buffer[output_ptr_right++] = '0'; return; } if constexpr (std::is_signed<T>::value == true) if (x < 0) output_buffer[output_ptr_right++] = '-', x = -x; int i = TWELVE; std::array<char, SIXTEEN> buf{}; while (x >= TENTHOUSAND) { memcpy(std::begin(buf) + i, std::begin(io_pre.num) + (x % TENTHOUSAND) * 4, 4); x /= TENTHOUSAND; i -= 4; } if (x < HUNDRED) { if (x < TEN) { output_buffer[output_ptr_right++] = static_cast<char>('0' + x); } else { std::uint32_t q = (static_cast<std::uint32_t>(x) * MAGIC_MULTIPLY) >> MAGIC_SHIFT; std::uint32_t r = static_cast<std::uint32_t>(x) - q * TEN; output_buffer[output_ptr_right] = static_cast<char>('0' + q); output_buffer[output_ptr_right + 1] = static_cast<char>('0' + r); output_ptr_right += 2; } } else { if (x < THOUSAND) { memcpy(std::begin(output_buffer) + output_ptr_right, std::begin(io_pre.num) + (x << 2) + 1, 3), output_ptr_right += 3; } else { memcpy(std::begin(output_buffer) + output_ptr_right, std::begin(io_pre.num) + (x << 2), 4), output_ptr_right += 4; } } memcpy(std::begin(output_buffer) + output_ptr_right, std::begin(buf) + i + 4, TWELVE - i); output_ptr_right += TWELVE - i; } inline IO& operator<<(std::ostream& (*pf)(std::ostream&)) { if (pf == static_cast<std::ostream & (*)(std::ostream&)>(std::endl)) write_char('\n'); return *this; } template <typename T_> IO& operator<<(T_&& x) { using T = typename std::remove_cv<typename std::remove_reference<T_>::type>::type; if constexpr (is_custom<T>::value) { write_int(x.get()); } else if constexpr (is_default<T>::value) { if constexpr (is_bool<T>::value) { write_bool(x); } else if constexpr (is_string<T>::value) { write_string(x); } else if constexpr (is_char<T>::value) { write_char(x); } else if constexpr (std::is_integral_v<T>) { write_int(x); } } else if constexpr (is_iterable<T>::value) { using E = decltype(*std::begin(x)); constexpr char sep = needs_newline<E> ? '\n' : ' '; int i = 0; for (const auto& y : x) { if (i++) write_char(sep); operator<<(y); } } else if constexpr (is_applyable<T>::value) { constexpr char sep = (any_needs_newline< T, std::make_index_sequence<std::tuple_size_v<T>>>::value) ? '\n' : ' '; int i = 0; std::apply([this, &sep, &i] (auto const &... y) { (((i++ ? write_char(sep) : void()), this->operator<<(y)), ...); }, x); } else { ss.str(""); ss << x; write_string(ss.str()); } return *this; } template <typename T> IO& operator>>(T& x) { static_assert(is_custom<T>::value or is_default<T>::value or is_iterable<T>::value or is_applyable<T>::value); static_assert(!is_bool<T>::value); if constexpr (is_custom<T>::value) { typename T::internal_value_type y; read_int(y); x = y; } else if constexpr (is_default<T>::value) { if constexpr (is_string<T>::value) { read_string(x); } else if constexpr (is_char<T>::value) { read_char(x); } else if constexpr (std::is_integral_v<T>) { read_int(x); } } else if constexpr (is_iterable<T>::value) { for (auto& y : x) operator>>(y); } else if constexpr (is_applyable<T>::value) { std::apply([this] (auto &... y) { ((this->operator>>(y)), ...); }, x); } return *this; } IO* tie(std::nullptr_t) { return this; } void sync_with_stdio(bool) {}
}; IO io;
#define cin io
#define cout io
#endif
#define int long long
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define FOR(...) GET_MACRO(__VA_ARGS__, _FOR3, _FOR2)(__VA_ARGS__)
#define _FOR2(i, n) for (int i = 0; i < (n); i++)
#define _FOR3(i, a, n) for (int i = (a); i < (n); i++)
#define ALL(arr) arr.begin(), arr.end()
#define SZ(arr) (int)arr.size()
using namespace std; template <typename T, size_t N> struct Arr : public array<T, N> { Arr() = default; Arr(const T& v) : array<T, N>{} { this->fill(v); } Arr(initializer_list<T> i) : array<T, N>{} { copy(i.begin(), i.end(), this->begin()); } template <typename... A, typename = enable_if_t<N == sizeof...(A)>> Arr(A&&... a) : array<T, N>{static_cast<T>(a)...} {} Arr& operator=(const T& v) { this->fill(v); return *this; } Arr& operator+=(const Arr& o) { FOR(i, N)(*this)[i] += o[i]; return *this; } Arr& operator-=(const Arr& o) { FOR(i, N)(*this)[i] -= o[i]; return *this; } Arr operator+(const Arr& o) const { Arr r = *this; r += o; return r; } Arr operator-(const Arr& o) const { Arr r = *this; r -= o; return r; } friend istream& operator>>(istream& in, Arr& a) { FOR(i, N) in >> a[i]; return in; } friend ostream& operator<<(ostream& out, const Arr& a) { FOR(i, N) out << a[i] << " \n"[i == N - 1]; return out; } }; namespace std { template <typename T, size_t N> struct tuple_size<Arr<T, N>> : integral_constant<size_t, N> {}; template <size_t I, typename T, size_t N> struct tuple_element<I, Arr<T, N>> { using type = T; }; template <size_t I, typename T, size_t N> T get(const Arr<T, N>& a) { return a[I]; } }; template <int D, typename T> struct MVec : vector<MVec<D - 1, T>> { MVec() : MVec(0) {} template <typename U, typename... Args> MVec(U n = U(), Args... args) : vector<MVec<D - 1, T>>(n, MVec<D - 1, T>(args...)) {} friend ostream& operator<<(ostream& s, const MVec& v) { for (auto& e : v) s << e; return s; } void Fill(const T& x) { for (auto& v : *this) v.Fill(x); } MVec& operator+=(const MVec& o) { FOR(i, this->size())(*this)[i] += o[i]; return *this; } MVec& operator-=(const MVec& o) { FOR(i, this->size())(*this)[i] -= o[i]; return *this; } MVec operator+(const MVec& o) const { MVec r(this->size()); FOR(i, this->size()) r[i] = (*this)[i] + o[i]; return r; } MVec operator-(const MVec& o) const { MVec r(this->size()); FOR(i, this->size()) r[i] = (*this)[i] - o[i]; return r; } friend istream& operator>>(istream& is, MVec& v) { for (auto& e : v) is >> e; return is; } }; template <typename T> using Vec = MVec<1, T>; template <typename T> ostream& operator<<(ostream& os, const MVec<1, T>& vec) noexcept { FOR(i, SZ(vec)) os << vec[i] << (i + 1 == SZ(vec) ? "\n" : " "); return os; } template <typename T, size_t N> ostream& operator<<(ostream& os, const MVec<1, Arr<T, N>>& vec) noexcept { for (auto& arr : vec) os << arr; return os; } template <typename T> struct MVec<1, T> : vector<T> { MVec() : MVec(0) {} using vector<T>::vector; MVec(initializer_list<T> l) : vector<T>(l) {} void Fill(const T& x) { fill(this->begin(), this->end(), x); } MVec operator+(const MVec& o) const { MVec r(this->size()); FOR(i, this->size()) r[i] = (*this)[i] + o[i]; return r; } MVec operator-(const MVec& o) const { MVec r(this->size()); FOR(i, this->size()) r[i] = (*this)[i] - o[i]; return r; } MVec& operator+=(const MVec& o) { FOR(i, this->size())(*this)[i] += o[i]; return *this; } MVec& operator-=(const MVec& o) { FOR(i, this->size())(*this)[i] -= o[i]; return *this; } friend istream& operator>>(istream& s, MVec& v) { for (auto& e : v) s >> e; return s; } }; template <typename Edge> struct Graph { struct OutgoingEdges { const Graph* g; int l, r; OutgoingEdges(const Graph* g, int l, int r) : g(g), l(l), r(r) {} const Edge* begin() const { return l == r ? nullptr : &g->prepared_edges[l]; } const Edge* end() const { return l == r ? nullptr : &g->prepared_edges[r]; } }; vector<Edge> prepared_edges; vector<pair<int, Edge>> edges; vector<int> start; int N; inline int size() { return N - 1; } Graph() {} Graph(int N) : N(N + 1), start(N + 2) {} void AddEdge(int from, const Edge& e) { edges.emplace_back(from, e); } void Prepare() { for (const auto& e : edges) ++start[e.first + 1]; for (int i = 1; i < N; ++i) start[i] += start[i - 1]; prepared_edges.resize(edges.size() + 1); auto counter = start; for (const auto& e : edges) prepared_edges[counter[e.first]++] = e.second; } OutgoingEdges operator[](int from) const { return (from < 0 || from + 1 >= start.size()) ? OutgoingEdges(this, 0, 0) : OutgoingEdges(this, start[from], start[from + 1]); } }; inline Graph<int> ReadGraph(int N, int M, bool undirected = true, bool one_indexed = true) { Graph<int> adj(N); FOR(i, M) { int a, b; cin >> a >> b; if (one_indexed) { a--; b--; } adj.AddEdge(a, b); if (undirected) { adj.AddEdge(b, a); } } adj.Prepare(); return adj; } inline Graph<Arr<int, 2>> ReadWeightedGraph(int N, int M, bool undirected = true, bool one_indexed = true) { Graph<Arr<int, 2>> adj(N); FOR(i, M) { int a, b, d; cin >> a >> b >> d; if (one_indexed) { a--; b--; } adj.AddEdge(a, { b, d }); if (undirected) { adj.AddEdge(b, { a, d }); } } adj.Prepare(); return adj; } template <class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } template <class T> bool ckmin(T& a, const T& b) { return a > b ? a = b, 1 : 0; }
const string YN[2] = { "NO\n", "YES\n" };
const int oo = 4000000002701507200LL;

struct Solution {
    const static bool kReadTestCases = 1;

    inline void Solve(int test_case = 0) {
        int N;cin >> N;
        Vec<set<int>> adj(N);
        FOR(i, N - 1) {
            int a, b;cin >> a >> b;a--;b--;
            adj[a].insert(b);
            adj[b].insert(a);
        }
        int comps = 1;
        FOR(iter, 2) {
            int best = -1;
            int best_node = -1;
            FOR(i, N) {
                if (SZ(adj[i]) > best) {
                    best = SZ(adj[i]);
                    best_node = i;
                }
            }
            comps--;
            comps += best;
            for (int x : adj[best_node]) {
                adj[x].erase(best_node);
            }
            adj[best_node].clear();
        }
        cout << comps << endl;
    }
    Solution() {

    }
    inline void Run() {
        cout << fixed << setprecision(20);
        int num_test_cases = 1;
        if (kReadTestCases) cin >> num_test_cases;
        FOR(test_case, 1, num_test_cases + 1) Solve(test_case);
    }
};
#ifndef LOCAL_STRESS_TEST
Solution solution;int32_t main() { solution.Run(); }
#else
#include "./_run_folder/_StressTester.h"
int32_t main() { StressTester stress_tester;stress_tester.Run(__FILE__); }
#endif

#include <bits/stdc++.h>
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifndef LOCAL_STRESS_TEST
struct IOPre { static constexpr int TEN = 10, SZ = TEN * TEN * TEN * TEN; std::array<char, 4 * SZ> num; constexpr IOPre() : num{} { for (int i = 0; i < SZ; i++) { int n = i; for (int j = 3; j >= 0; j--) { num[i * 4 + j] = static_cast<char>(n % TEN + '0'); n /= TEN; } } } }; struct IO {
#if !HAVE_DECL_FREAD_UNLOCKED
#define fread_unlocked fread
#endif
#if !HAVE_DECL_FWRITE_UNLOCKED
#define fwrite_unlocked fwrite
#endif
    static constexpr int SZ = 1 << 17, LEN = 32, TEN = 10, HUNDRED = TEN * TEN, THOUSAND = HUNDRED * TEN, TENTHOUSAND = THOUSAND * TEN, MAGIC_MULTIPLY = 205, MAGIC_SHIFT = 11, MASK = 15, TWELVE = 12, SIXTEEN = 16; static constexpr IOPre io_pre = {}; std::array<char, SZ> input_buffer, output_buffer; int input_ptr_left, input_ptr_right, output_ptr_right; std::stringstream ss; IO() : input_buffer{}, output_buffer{}, input_ptr_left{}, input_ptr_right{}, output_ptr_right{} {} IO(const IO&) = delete; IO(IO&&) = delete; IO& operator=(const IO&) = delete; IO& operator=(IO&&) = delete; ~IO() { flush(); } template <class T> struct is_char { static constexpr bool value = std::is_same_v<T, char>; }; template <class T> struct is_bool { static constexpr bool value = std::is_same_v<T, bool>; }; template <class T> struct is_string { static constexpr bool value = std::is_same_v<T, std::string> || std::is_same_v<T, const char*> || std::is_same_v<T, char*>; }; template <class T, class D = void> struct is_custom { static constexpr bool value = false; }; template <class T> struct is_custom<T, std::void_t<typename T::internal_value_type>> { static constexpr bool value = true; }; template <class T> struct is_default { static constexpr bool value = is_char<T>::value || is_bool<T>::value || is_string<T>::value || std::is_integral_v<T>; }; template <class T, class D = void> struct is_iterable { static constexpr bool value = false; }; template <class T> struct is_iterable< T, typename std::void_t<decltype(std::begin(std::declval<T>()))>> { static constexpr bool value = true; }; template <class T, class D = void, class E = void> struct is_applyable { static constexpr bool value = false; }; template <class T> struct is_applyable<T, std::void_t<typename std::tuple_size<T>::type>, std::void_t<decltype(std::get<0>(std::declval<T>()))>> { static constexpr bool value = true; }; template <class T> static constexpr bool needs_newline = (is_iterable<T>::value || is_applyable<T>::value) && (!is_default<T>::value); template <typename T, typename U> struct any_needs_newline { static constexpr bool value = false; }; template <typename T> struct any_needs_newline<T, std::index_sequence<>> { static constexpr bool value = false; }; template <typename T, std::size_t I, std::size_t... Is> struct any_needs_newline<T, std::index_sequence<I, Is...>> { static constexpr bool value = needs_newline<decltype(std::get<I>(std::declval<T>()))> || any_needs_newline<T, std::index_sequence<Is...>>::value; }; inline void load() { memmove(std::begin(input_buffer), std::begin(input_buffer) + input_ptr_left, input_ptr_right - input_ptr_left); input_ptr_right = input_ptr_right - input_ptr_left + static_cast<int>(fread_unlocked(std::begin(input_buffer) + input_ptr_right - input_ptr_left, 1, SZ - input_ptr_right + input_ptr_left, stdin)); input_ptr_left = 0; } inline void read_char(char& c) { if (input_ptr_left + LEN > input_ptr_right) load(); c = input_buffer[input_ptr_left++]; } inline void read_string(std::string& x) { char c; while (read_char(c), c < '!') continue; x = c; while (read_char(c), c >= '!') x += c; } template <class T> inline std::enable_if_t<std::is_integral_v<T>, void> read_int(T& x) { if (input_ptr_left + LEN > input_ptr_right) load(); char c = 0; do c = input_buffer[input_ptr_left++]; while (c < '-'); [[maybe_unused]] bool minus = false; if constexpr (std::is_signed<T>::value == true) if (c == '-') minus = true, c = input_buffer[input_ptr_left++]; x = 0; while (c >= '0') x = x * TEN + (c & MASK), c = input_buffer[input_ptr_left++]; if constexpr (std::is_signed<T>::value == true) if (minus) x = -x; } inline void skip_space() { if (input_ptr_left + LEN > input_ptr_right) load(); while (input_buffer[input_ptr_left] <= ' ') input_ptr_left++; } inline void flush() { fwrite_unlocked(std::begin(output_buffer), 1, output_ptr_right, stdout); output_ptr_right = 0; } inline void write_char(char c) { if (output_ptr_right > SZ - LEN) flush(); output_buffer[output_ptr_right++] = c; } inline void write_bool(bool b) { if (output_ptr_right > SZ - LEN) flush(); output_buffer[output_ptr_right++] = b ? '1' : '0'; } inline void write_string(const std::string& s) { for (auto x : s) write_char(x); } inline void write_string(const char* s) { while (*s) write_char(*s++); } inline void write_string(char* s) { while (*s) write_char(*s++); } template <typename T> inline std::enable_if_t<std::is_integral_v<T>, void> write_int(T x) { if (output_ptr_right > SZ - LEN) flush(); if (!x) { output_buffer[output_ptr_right++] = '0'; return; } if constexpr (std::is_signed<T>::value == true) if (x < 0) output_buffer[output_ptr_right++] = '-', x = -x; int i = TWELVE; std::array<char, SIXTEEN> buf{}; while (x >= TENTHOUSAND) { memcpy(std::begin(buf) + i, std::begin(io_pre.num) + (x % TENTHOUSAND) * 4, 4); x /= TENTHOUSAND; i -= 4; } if (x < HUNDRED) { if (x < TEN) { output_buffer[output_ptr_right++] = static_cast<char>('0' + x); } else { std::uint32_t q = (static_cast<std::uint32_t>(x) * MAGIC_MULTIPLY) >> MAGIC_SHIFT; std::uint32_t r = static_cast<std::uint32_t>(x) - q * TEN; output_buffer[output_ptr_right] = static_cast<char>('0' + q); output_buffer[output_ptr_right + 1] = static_cast<char>('0' + r); output_ptr_right += 2; } } else { if (x < THOUSAND) { memcpy(std::begin(output_buffer) + output_ptr_right, std::begin(io_pre.num) + (x << 2) + 1, 3), output_ptr_right += 3; } else { memcpy(std::begin(output_buffer) + output_ptr_right, std::begin(io_pre.num) + (x << 2), 4), output_ptr_right += 4; } } memcpy(std::begin(output_buffer) + output_ptr_right, std::begin(buf) + i + 4, TWELVE - i); output_ptr_right += TWELVE - i; } inline IO& operator<<(std::ostream& (*pf)(std::ostream&)) { if (pf == static_cast<std::ostream & (*)(std::ostream&)>(std::endl)) write_char('\n'); return *this; } template <typename T_> IO& operator<<(T_&& x) { using T = typename std::remove_cv<typename std::remove_reference<T_>::type>::type; if constexpr (is_custom<T>::value) { write_int(x.get()); } else if constexpr (is_default<T>::value) { if constexpr (is_bool<T>::value) { write_bool(x); } else if constexpr (is_string<T>::value) { write_string(x); } else if constexpr (is_char<T>::value) { write_char(x); } else if constexpr (std::is_integral_v<T>) { write_int(x); } } else if constexpr (is_iterable<T>::value) { using E = decltype(*std::begin(x)); constexpr char sep = needs_newline<E> ? '\n' : ' '; int i = 0; for (const auto& y : x) { if (i++) write_char(sep); operator<<(y); } } else if constexpr (is_applyable<T>::value) { constexpr char sep = (any_needs_newline< T, std::make_index_sequence<std::tuple_size_v<T>>>::value) ? '\n' : ' '; int i = 0; std::apply([this, &sep, &i] (auto const &... y) { (((i++ ? write_char(sep) : void()), this->operator<<(y)), ...); }, x); } else { ss.str(""); ss << x; write_string(ss.str()); } return *this; } template <typename T> IO& operator>>(T& x) { static_assert(is_custom<T>::value or is_default<T>::value or is_iterable<T>::value or is_applyable<T>::value); static_assert(!is_bool<T>::value); if constexpr (is_custom<T>::value) { typename T::internal_value_type y; read_int(y); x = y; } else if constexpr (is_default<T>::value) { if constexpr (is_string<T>::value) { read_string(x); } else if constexpr (is_char<T>::value) { read_char(x); } else if constexpr (std::is_integral_v<T>) { read_int(x); } } else if constexpr (is_iterable<T>::value) { for (auto& y : x) operator>>(y); } else if constexpr (is_applyable<T>::value) { std::apply([this] (auto &... y) { ((this->operator>>(y)), ...); }, x); } return *this; } IO* tie(std::nullptr_t) { return this; } void sync_with_stdio(bool) {}
}; IO io;
#define cin io
#define cout io
#endif
#define int long long
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define FOR(...) GET_MACRO(__VA_ARGS__, _FOR3, _FOR2)(__VA_ARGS__)
#define _FOR2(i, n) for (int i = 0; i < (n); i++)
#define _FOR3(i, a, n) for (int i = (a); i < (n); i++)
#define ALL(arr) arr.begin(), arr.end()
#define SZ(arr) (int)arr.size()
using namespace std; template <typename T, size_t N> struct Arr : public array<T, N> { Arr() = default; Arr(const T& v) : array<T, N>{} { this->fill(v); } Arr(initializer_list<T> i) : array<T, N>{} { copy(i.begin(), i.end(), this->begin()); } template <typename... A, typename = enable_if_t<N == sizeof...(A)>> Arr(A&&... a) : array<T, N>{static_cast<T>(a)...} {} Arr& operator=(const T& v) { this->fill(v); return *this; } Arr& operator+=(const Arr& o) { FOR(i, N)(*this)[i] += o[i]; return *this; } Arr& operator-=(const Arr& o) { FOR(i, N)(*this)[i] -= o[i]; return *this; } Arr operator+(const Arr& o) const { Arr r = *this; r += o; return r; } Arr operator-(const Arr& o) const { Arr r = *this; r -= o; return r; } friend istream& operator>>(istream& in, Arr& a) { FOR(i, N) in >> a[i]; return in; } friend ostream& operator<<(ostream& out, const Arr& a) { FOR(i, N) out << a[i] << " \n"[i == N - 1]; return out; } }; namespace std { template <typename T, size_t N> struct tuple_size<Arr<T, N>> : integral_constant<size_t, N> {}; template <size_t I, typename T, size_t N> struct tuple_element<I, Arr<T, N>> { using type = T; }; template <size_t I, typename T, size_t N> T get(const Arr<T, N>& a) { return a[I]; } }; template <int D, typename T> struct MVec : vector<MVec<D - 1, T>> { MVec() : MVec(0) {} template <typename U, typename... Args> MVec(U n = U(), Args... args) : vector<MVec<D - 1, T>>(n, MVec<D - 1, T>(args...)) {} friend ostream& operator<<(ostream& s, const MVec& v) { for (auto& e : v) s << e; return s; } void Fill(const T& x) { for (auto& v : *this) v.Fill(x); } MVec& operator+=(const MVec& o) { FOR(i, this->size())(*this)[i] += o[i]; return *this; } MVec& operator-=(const MVec& o) { FOR(i, this->size())(*this)[i] -= o[i]; return *this; } MVec operator+(const MVec& o) const { MVec r(this->size()); FOR(i, this->size()) r[i] = (*this)[i] + o[i]; return r; } MVec operator-(const MVec& o) const { MVec r(this->size()); FOR(i, this->size()) r[i] = (*this)[i] - o[i]; return r; } friend istream& operator>>(istream& is, MVec& v) { for (auto& e : v) is >> e; return is; } }; template <typename T> using Vec = MVec<1, T>; template <typename T> ostream& operator<<(ostream& os, const MVec<1, T>& vec) noexcept { FOR(i, SZ(vec)) os << vec[i] << (i + 1 == SZ(vec) ? "\n" : " "); return os; } template <typename T, size_t N> ostream& operator<<(ostream& os, const MVec<1, Arr<T, N>>& vec) noexcept { for (auto& arr : vec) os << arr; return os; } template <typename T> struct MVec<1, T> : vector<T> { MVec() : MVec(0) {} using vector<T>::vector; MVec(initializer_list<T> l) : vector<T>(l) {} void Fill(const T& x) { fill(this->begin(), this->end(), x); } MVec operator+(const MVec& o) const { MVec r(this->size()); FOR(i, this->size()) r[i] = (*this)[i] + o[i]; return r; } MVec operator-(const MVec& o) const { MVec r(this->size()); FOR(i, this->size()) r[i] = (*this)[i] - o[i]; return r; } MVec& operator+=(const MVec& o) { FOR(i, this->size())(*this)[i] += o[i]; return *this; } MVec& operator-=(const MVec& o) { FOR(i, this->size())(*this)[i] -= o[i]; return *this; } friend istream& operator>>(istream& s, MVec& v) { for (auto& e : v) s >> e; return s; } }; template <typename Edge> struct Graph { struct OutgoingEdges { const Graph* g; int l, r; OutgoingEdges(const Graph* g, int l, int r) : g(g), l(l), r(r) {} const Edge* begin() const { return l == r ? nullptr : &g->prepared_edges[l]; } const Edge* end() const { return l == r ? nullptr : &g->prepared_edges[r]; } }; vector<Edge> prepared_edges; vector<pair<int, Edge>> edges; vector<int> start; int N; inline int size() { return N - 1; } Graph() {} Graph(int N) : N(N + 1), start(N + 2) {} void AddEdge(int from, const Edge& e) { edges.emplace_back(from, e); } void Prepare() { for (const auto& e : edges) ++start[e.first + 1]; for (int i = 1; i < N; ++i) start[i] += start[i - 1]; prepared_edges.resize(edges.size() + 1); auto counter = start; for (const auto& e : edges) prepared_edges[counter[e.first]++] = e.second; } OutgoingEdges operator[](int from) const { return (from < 0 || from + 1 >= start.size()) ? OutgoingEdges(this, 0, 0) : OutgoingEdges(this, start[from], start[from + 1]); } }; inline Graph<int> ReadGraph(int N, int M, bool undirected = true, bool one_indexed = true) { Graph<int> adj(N); FOR(i, M) { int a, b; cin >> a >> b; if (one_indexed) { a--; b--; } adj.AddEdge(a, b); if (undirected) { adj.AddEdge(b, a); } } adj.Prepare(); return adj; } inline Graph<Arr<int, 2>> ReadWeightedGraph(int N, int M, bool undirected = true, bool one_indexed = true) { Graph<Arr<int, 2>> adj(N); FOR(i, M) { int a, b, d; cin >> a >> b >> d; if (one_indexed) { a--; b--; } adj.AddEdge(a, { b, d }); if (undirected) { adj.AddEdge(b, { a, d }); } } adj.Prepare(); return adj; } template <class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } template <class T> bool ckmin(T& a, const T& b) { return a > b ? a = b, 1 : 0; }
const string YN[2] = { "NO\n", "YES\n" };
const int oo = 4000000002701507200LL;

struct Solution {
    const static bool kReadTestCases = 1;

    inline void Solve(int test_case = 0) {
        int N;cin >> N;
        Vec<set<int>> adj(N);
        FOR(i, N - 1) {
            int a, b;cin >> a >> b;a--;b--;
            adj[a].insert(b);
            adj[b].insert(a);
        }
        multiset<int> sizes;
        int best = -oo;
        FOR(i, N) {
            sizes.insert(SZ(adj[i]));
        }
        FOR(i, N) {
            int ans = -1;
            ans += SZ(adj[i]);
            sizes.erase(sizes.find(SZ(adj[i])));
            for (int j : adj[i]) {
                sizes.erase(sizes.find(SZ(adj[j])));
                sizes.insert(SZ(adj[j]) - 1);
            }
            ans += *sizes.rbegin();
            sizes.insert(SZ(adj[i]));
            for (int j : adj[i]) {
                sizes.insert(SZ(adj[j]));
                sizes.erase(sizes.find(SZ(adj[j]) - 1));
            }
            ckmax(best, ans);
        }
        cout << best << endl;

    }
    Solution() {

    }
    inline void Run() {
        cout << fixed << setprecision(20);
        int num_test_cases = 1;
        if (kReadTestCases) cin >> num_test_cases;
        FOR(test_case, 1, num_test_cases + 1) Solve(test_case);
    }
};
#ifndef LOCAL_STRESS_TEST
Solution solution;int32_t main() { solution.Run(); }
#else
#include "./_run_folder/_StressTester.h"
int32_t main() { StressTester stress_tester;stress_tester.Run(__FILE__); }
#endif

Answer: 2


#include<bits/stdc++.h>
#define ll                long long
#define ld                long double
#define fi                first
#define se                second
#define pb                push_back
#define ppb               pop_back
#define pf                push_front
#define ppf               pop_front
#define nline             "\n"
#define all(x)            (x).begin(),(x).end()
#define uniq(v)           (v).erase(unique(all(v)),(v).end())
#define srt(x)            sort(all(x))
#define mem(a,val)        memset(a, val, sizeof(a))
#define Up(v,n)           upper_bound(v.begin(),v.end(),n)
#define Low(v,n)          lower_bound(v.begin(),v.end(),n)
#define PRE(x)            fixed << setprecision(x)
#define watch(x)          cout << (#x) << " is " << (x) << endl
using namespace std;

long long powM(long long a, long long b, long long m) {
    a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}

// GCD(A,B) = GCD(B,A-B) -> here A>=B or GCD(A,B) = GCD(B-A,A) -> here A<=B
ll gcd(ll a, ll b) { if (b == 0) {return a;} return gcd(b, a % b);}
ll modinv(ll a, ll m) { return powM(a, m - 2, m);}
ll mod_add(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a + b) % m) + m) % m;}
ll mod_mul(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a * b) % m) + m) % m;}
ll mod_sub(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a - b) % m) + m) % m;}
ll moddiv(ll a, ll b, ll m) {a = a % m; b = b % m;
return (mod_mul(a, modinv(b, m), m) + m) % m;}//m is prime

const long long INF=1e18;
const int32_t M=1e9+7;
const int32_t MM=998244353;

void solve(){
    int n; cin >> n;
    vector<int>a[n+1];
    priority_queue<pair<int,int>>pq;
    int ans = 0, maxi = 0, maxi_cnt = 0, tot = 0;

    for(int i=0;i<n-1;i++){
        int u,v; cin >> u >> v;
        a[u].push_back(v);  a[v].push_back(u);
    }
    for(int i=0;i<=n;i++) maxi = max(maxi, (int)a[i].size());
    for(int i=0;i<=n;i++) {
        if(a[i].size() == maxi) maxi_cnt++;
        pq.push({a[i].size(), i});
    }
    if(maxi_cnt > 2) {
        cout << pq.top().first*2-1 << '\n';
        return;
    }
    vector<int>vis(n+1,0);
    // removed one element
    ans = (pq.top().fi) - 1;
    for(auto e:a[pq.top().second]) vis[e]++;
    pq.pop();
    while(!pq.empty()) {
        int cnt = ans;
        pair<int,int>p = pq.top(); pq.pop();
        cnt = (cnt + (p.first) - vis[p.second]);
        tot = max(tot, cnt);
    }
    cout << tot << '\n';
}

signed main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(0);
    cout.precision(20), cout.setf(ios::fixed);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    cerr << setprecision(4) << fixed;
    cerr<<"Time taken : "<<(float)clock()/CLOCKS_PER_SEC<<" secs"<<endl;
    return 0;
}

// 1 2
// 3

#include<bits/stdc++.h>
#define ll                long long
#define ld                long double
#define fi                first
#define se                second
#define pb                push_back
#define ppb               pop_back
#define pf                push_front
#define ppf               pop_front
#define nline             "\n"
#define all(x)            (x).begin(),(x).end()
#define uniq(v)           (v).erase(unique(all(v)),(v).end())
#define srt(x)            sort(all(x))
#define mem(a,val)        memset(a, val, sizeof(a))
#define Up(v,n)           upper_bound(v.begin(),v.end(),n)
#define Low(v,n)          lower_bound(v.begin(),v.end(),n)
#define PRE(x)            fixed << setprecision(x)
#define watch(x)          cout << (#x) << " is " << (x) << endl
using namespace std;

long long powM(long long a, long long b, long long m) {
    a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}

// GCD(A,B) = GCD(B,A-B) -> here A>=B or GCD(A,B) = GCD(B-A,A) -> here A<=B
ll gcd(ll a, ll b) { if (b == 0) {return a;} return gcd(b, a % b);}
ll modinv(ll a, ll m) { return powM(a, m - 2, m);}
ll mod_add(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a + b) % m) + m) % m;}
ll mod_mul(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a * b) % m) + m) % m;}
ll mod_sub(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a - b) % m) + m) % m;}
ll moddiv(ll a, ll b, ll m) {a = a % m; b = b % m;
return (mod_mul(a, modinv(b, m), m) + m) % m;}//m is prime

const long long INF=1e18;
const int32_t M=1e9+7;
const int32_t MM=998244353;

void solve(){
    int n; cin >> n;
    vector<int>a[n+1];
    priority_queue<pair<int,int>>pq;
    int ans = 0, maxi = 0, maxi_cnt = 0, tot = 0;

    for(int i=0;i<n-1;i++){
        int u,v; cin >> u >> v;
        a[u].push_back(v);  a[v].push_back(u);
    }
    for(int i=0;i<=n;i++) maxi = max(maxi, (int)a[i].size());
    for(int i=0;i<=n;i++) {
        if(a[i].size() == maxi) maxi_cnt++;
        pq.push({a[i].size(), i});
    }
    if(maxi_cnt > 2) {
        cout << pq.top().first*2-1 << '\n';
        return;
    }
    vector<int>vis(n+1,0);
    // removed one element
    ans = (pq.top().fi) - 1;
    for(auto e:a[pq.top().second]) vis[e]++;
    pq.pop();
    while(!pq.empty()) {
        int cnt = ans;
        pair<int,int>p = pq.top(); pq.pop();
        cnt = (cnt + (p.first) - vis[p.second]);
        tot = max(tot, cnt);
    }
    cout << tot << '\n';
}

signed main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(0);
    cout.precision(20), cout.setf(ios::fixed);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    cerr << setprecision(4) << fixed;
    cerr<<"Time taken : "<<(float)clock()/CLOCKS_PER_SEC<<" secs"<<endl;
    return 0;
}

1 2
3

Answer: 1


#include <bits/stdc++.h>
#define FastIO ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define pii pair<int,int>
#define ll long long int
#define SIZE 200005
#define all(v) v.begin(), v.end()
#define pb push_back
#define MOD 1000000007
#define INF 1000000007
using namespace std;

int n , ma[SIZE] , val[SIZE] , ans;
vector<int> g[SIZE] , child[SIZE];

void init() {
    ans=0;
    for (int i = 1; i <= n; i++) {
        g[i].clear();
        child[i].clear();
        ma[i] = 0;
    }
}

void dfs(int here ,int pa) {
    val[here] = 1;
    for (auto t : g[here]) {
        if (t == pa) continue;
        val[here]++;
        child[here].pb(t);
        dfs(t , here);
    }
}

void solve(int here) {
    for (auto t : child[here]) solve(t);
    vector<int> tmp;
    for (auto t : child[here]) tmp.pb(ma[t]);
    sort(all(tmp));
    reverse(all(tmp));
    if (tmp.size() >= 2) ans = max(ans , tmp[0]+tmp[1]-1);
    for (auto t : child[here]) {
        ans = max(ans , ma[t]+val[here]-1-((here==1))-(child[t].size()==0));
    }
    ma[here] = max(val[here] , (tmp.size() > 0 ? tmp[0] : -1));
}

void solve() {
    cin >> n;
    for (int i = 1; i <= n-1; i++) {
        int u , v; cin >> u >> v;
        g[u].pb(v); g[v].pb(u);
    }

    if (n == 2) {
        cout << "0\n";
        return;
    }

    dfs(1 , -1);
    val[1]--;
    //for (int i = 1; i <= n; i++) printf("%d " , val[i]);
    //printf("\n");
    solve(1);

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

int main() {
    FastIO;

    int t; cin >> t;
    while(t--) {
        init();
        solve();
    }

    return 0;
}

#include <bits/stdc++.h>
#define FastIO ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define pii pair<int,int>
#define ll long long int
#define SIZE 200005
#define all(v) v.begin(), v.end()
#define pb push_back
#define MOD 1000000007
#define INF 1000000007
using namespace std;

int n , ma1[SIZE] , deg[SIZE] , ans , ma2[SIZE];
vector<int> g[SIZE] , child[SIZE];

void init() {
    ans=0;
    for (int i = 1; i <= n; i++) {
        g[i].clear();
        child[i].clear();
        ma1[i] = ma2[i] = deg[i] = 0;
    }
}

void dfs(int here ,int pa) {
    multiset<int> st1 , st2;
    for (auto t : g[here]) {
        if (t == pa) continue;
        ans = max(ans , deg[here]+deg[t]-2);
        dfs(t , here);
        ma2[here] = max(ma2[here] , ma1[t]);
        st1.insert(-ma1[t]);
        st2.insert(ma2[t]);
    }
    if (st2.size() > 0) ans = max(ans , deg[here]+(*st2.rbegin())-1);
    if (st1.size() >= 2) {
        int ret=0;
        auto it = st1.begin();
        ret += -(*it);
        it++;
        ret += -(*it); ret--;
        ans = max(ans , ret);
    }
    ma1[here] = max(deg[here] , ma2[here]);
}

void solve() {
    cin >> n;
    for (int i = 1; i <= n-1; i++) {
        int u , v; cin >> u >> v;
        g[u].pb(v); g[v].pb(u);
        deg[u]++; deg[v]++;
    }

    if (n == 2) {
        cout << "0\n";
        return;
    }

    dfs(1 , -1);

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

int main() {
    FastIO;

    int t; cin >> t;
    while(t--) {
        init();
        solve();
    }

    return 0;
}

Answer: 2


using namespace std;
#include <bits/stdc++.h>

#define all(A) A.begin(),A.end()
#define fori(i, k, n) for (int i = k; i < n; i++)
#define ln "\n"

vector<unordered_set<int> > adj;
vector<pair<int, int> > deg;
vector<bool> visited;
int n, ans;

void dfs(int u) {
    visited[u] = true;
    for (const auto &v: adj[u])
        if (!visited[v]) {
            ans = max(ans, deg[u].first + deg[v].first - 2);
            dfs(v);
        }
}

bool vecinos(int u, int v) {
    return adj[u].find(v) != adj[u].end();
}

void solve() {
    cin >> n;
    adj.assign(n, unordered_set<int>());
    deg.assign(n, {0, 0});
    visited.assign(n, false);
    fori(i, 0, n)
        deg[i].second = i;
    fori(i, 0, n-1) {
        int a, b;
        cin >> a >> b;
        a--;
        b--;
        adj[a].insert(b);
        adj[b].insert(a);
        deg[a].first++;
        deg[b].first++;
    }
    ans = 0;
    dfs(0);
    sort(all(deg), greater<pair<int, int> >());
    fori(i, 0, n) {
        fori(j, i+1, n) {
            if (vecinos(deg[i].second, deg[j].second))
                continue;
            ans = max(ans, deg[i].first + deg[j].first - 1);
            break;
        }
    }
    cout << ans << ln;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

using namespace std;
#include <bits/stdc++.h>

#define all(A) A.begin(),A.end()
#define fori(i, k, n) for (int i = k; i < n; i++)
#define ln "\n"

vector<vector<int> > adj;
vector<int> deg;
vector<bool> visited;
int n, U, V;

void removeVertex(int u) {
    deg[u] = 0;
    for (const auto &v: adj[u]) {
        adj[v].erase(remove(all(adj[v]), u), adj[v].end());
        deg[v]--;
    }
    adj[u].clear();
}

void dfs(int u) {
    visited[u] = true;
    for (const auto &v: adj[u])
        if (!visited[v])
            dfs(v);
}

void printGraph() {
    fori(u, 0, n) {
        cout << (u + 1) << "->";
        for (const auto &v: adj[u])
            cout << (v + 1) << ", ";
        cout << ln;
    }
}

void solve() {
    cin >> n;
    adj.assign(n, vector<int>());
    deg.assign(n, 0);
    fori(i, 0, n-1) {
        int a, b;
        cin >> a >> b;
        a--;
        b--;
        adj[a].push_back(b);
        adj[b].push_back(a);
        deg[a]++;
        deg[b]++;
    }
    set<pair<int, int> > tree;
    fori(u, 0, n)
        tree.insert({deg[u], u});
    auto first = prev(tree.end());
    tree.erase(first);
    U = first->second;
    removeVertex(U);
    tree.clear();
    fori(u, 0, n) {
        if (u == U)
            continue;
        tree.insert({deg[u], u});
    }
    V = prev(tree.end())->second;
    removeVertex(V);
    visited.assign(n, false);
    //   cout << "U: " << U + 1 << " V: " << V + 1 << ln;
    int ans = 0;
    fori(u, 0, n) {
        if (u != U && u != V && !visited[u]) {
            //cout << "u: " << u + 1 << ln;
            dfs(u);
            ans++;
        }
    }
    cout << ans << ln;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

Answer: 1


#include<bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL)
#define ll long long
#define all(v) (v).begin(),(v).end()
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define fi first
#define se second
#define pb push_back

/*------------- Hardwork beats Talent, when Talent doesn't work hard!! -------------*/
const ll infl = 1e17 + 7;
const int inf = 1e8 + 7;
const int mod = 1e9 + 7;

void Hrid_solve(){
    int n;
    cin >> n;
    vector<int> deg(n+1);
    set<pair<int,int>> st;
    for(int i=0; i<n-1; i++){
        int u,v;
        cin >> u >> v;
        deg[u]++;
        deg[v]++;
        if(u>v) swap(u,v);
        st.insert({u,v});
    }

    vector<pair<int,int>> vp;
    for(int i=1; i<=n; i++){
        vp.pb({deg[i],i});
    }
    sort(all(vp), greater<pair<int,int>>());

    int ans =-1;
    for(int i=0; i<n; i++){
        for(int j=i+1; j<n; j++){
            int u = vp[i].se, v = vp[j].se;
            if(u>v) swap(u,v);
            if(!st.count({u,v})){
                ans = max(ans, vp[i].fi+vp[j].fi-1);
                break;
            }
        }
    }
    for(auto [u,v]: st){
        ans = max(ans, deg[u]+deg[v]-2);
    }

    cout << ans << endl;

}

/*------------------ Today's decision might impact you Tomorrow !! ------------------*/

int32_t main(){
    fast_IO;
    // #ifndef ONLINE_JUDGE
    //     freopen("input.txt", "r", stdin);
    //     // freopen("output.txt", "w", stdout);
    // #endif

    int tc = 1;
    cin >> tc;
    for(int kase = 1; kase <= tc; kase++){
        // cout << "Case " << kase << ": \n";
        Hrid_solve();
    }

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL)
#define ll long long
#define all(v) (v).begin(),(v).end()
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define fi first
#define se second
#define pb push_back

/*------------- Hardwork beats Talent, when Talent doesn't work hard!! -------------*/
const ll infl = 1e17 + 7;
const int inf = 1e8 + 7;
const int mod = 1e9 + 7;

void Hrid_solve(){
    int n;
    cin >> n;
    vector<ll> deg(n+1);
    set<pair<ll,ll>> st;
    for(int i=0; i<n-1; i++){
        int u,v;
        cin >> u >> v;
        deg[u]++;
        deg[v]++;
        st.insert({u,v});
        st.insert({v,u});
    }

    vector<pair<ll,ll>> vp;
    for(int i=1; i<=n; i++){
        vp.pb({deg[i],i});
    }
    sort(all(vp), greater<pair<ll,ll>>());

    ll ans =0;
    for(int i=1; i<n; i++){
        if(!st.count({vp[i].se,vp[0].se})){
            ans = max(ans, vp[i].fi+vp[0].fi-1);
        }
        else{
            ans = max(ans, vp[i].fi+vp[0].fi-2);
        }
    }

    cout << ans << endl;

}

/*------------------ Today's decision might impact you Tomorrow !! ------------------*/

int32_t main(){
    fast_IO;
    // #ifndef ONLINE_JUDGE
    //     freopen("input.txt", "r", stdin);
    //     // freopen("output.txt", "w", stdout);
    // #endif

    int tc = 1;
    cin >> tc;
    for(int kase = 1; kase <= tc; kase++){
        // cout << "Case " << kase << ": \n";
        Hrid_solve();
    }

    return 0;
}

Answer: 1


 #pragma GCC optimize("O2")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const long double pi = 3.141592653589793238462643383279;
//#define max(a,b) (a>b?a:b)
//#define min(a,b) (a<b?a:b)
#define forb(i,a,b) for(ll i=a;i<b;i++)
#define fo(i,a) for(ll i=0;i<a;i++)
#define foa(i,a) for(auto i=a.begin();i!=a.end();i++)
#define rep(i,a) for(ll i=a;i>-1;i--)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define vi vector<int>
#define vll vector<ll>
#define vvi vector<vector<int>>
#define vvll vector<vector<ll> >
#define vb vector<bool>
#define vvb vector<vector<bool>>
#define vc vector<char>
#define vvc vector<vector<char>>
#define pb push_back
const ll mod= 1e9+7;

void _print(ll t) {cerr<< t;}
void _print(int t) {cerr << t;}
void _print(string t) {cerr << t;}
void _print(char t) {cerr << t;}
//void _print(lld t) {cerr << t;}
void _print(double t) {cerr << t;}
//void _print(ull t) {cerr << t;}
void printll(vector<ll> a){
    ll n=a.size();
    fo(i,n){
    cout<<a[i]<<" ";
        }
    cout<<'\n';
}

void printint(vector<int> a){
    ll n=a.size();
    fo(i,n) cout<<a[i]<<" ";
    cout<<'\n';
}

 ll gcd(ll a, ll b){
    //b = a*q1 + r1;
    //a = r1*q2 + r2;
    //do until r2=0
    if(a==0)return b;
    if(b==0)return a;
    if(a>b)swap(a,b);
    ll rem=b%a;
    while(rem){
        b=a;
        a=rem;
        rem=b%a;
    }
    return a;
}

ll lcm(ll a, ll b){
    return (a*b)/gcd(a,b);
}
ll power(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}
 ll factorial(ll n)
    {
        ll res = 1, i;

        for (i = 2; i <= n; i++)
            res = (res*1ll* i)%mod;
        return res;
    }

void solve() {
   ll n;
   cin>>n;
   vector<vll>adj(n+1);
   vll in(n+1,0);
 fo(i,n-1){
    ll a,b;
    cin>>a>>b;
    in[a]++;
    in[b]++;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  if(n==2){
    cout<<0<<endl;
    return;
  }
  ll mx=0;
  set<pair<ll,ll>>st;
  forb(i,1,n+1)
    {
    mx=max(mx,in[i]);
    st.insert({in[i],i});
    }

ll  ans=0;
  forb(i,1,n+1){
    if(in[i]==mx){
       st.erase({in[i],i});
     ll tmp=0;
       tmp+=in[i]-1;

        for(auto x:adj[i]){
            st.erase({in[x],x});
            in[x]--;
            st.insert({in[x],x});
        }
        tmp+=(*st.rbegin()).first;
       ans=max(ans,tmp);

       st.insert({in[i],i});
       for(auto x:adj[i]){
        st.erase({in[x],x});
        in[x]++;
        st.insert({in[x],x});
       }
    }
  }
  cout<<ans<<endl;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    ll t=1;
cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

 #pragma GCC optimize("O2")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const long double pi = 3.141592653589793238462643383279;
//#define max(a,b) (a>b?a:b)
//#define min(a,b) (a<b?a:b)
#define forb(i,a,b) for(ll i=a;i<b;i++)
#define fo(i,a) for(ll i=0;i<a;i++)
#define foa(i,a) for(auto i=a.begin();i!=a.end();i++)
#define rep(i,a) for(ll i=a;i>-1;i--)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define vi vector<int>
#define vll vector<ll>
#define vvi vector<vector<int>>
#define vvll vector<vector<ll> >
#define vb vector<bool>
#define vvb vector<vector<bool>>
#define vc vector<char>
#define vvc vector<vector<char>>
#define pb push_back
const ll mod= 1e9+7;

void _print(ll t) {cerr<< t;}
void _print(int t) {cerr << t;}
void _print(string t) {cerr << t;}
void _print(char t) {cerr << t;}
//void _print(lld t) {cerr << t;}
void _print(double t) {cerr << t;}
//void _print(ull t) {cerr << t;}
void printll(vector<ll> a){
    ll n=a.size();
    fo(i,n){
    cout<<a[i]<<" ";
        }
    cout<<'\n';
}

void printint(vector<int> a){
    ll n=a.size();
    fo(i,n) cout<<a[i]<<" ";
    cout<<'\n';
}

 ll gcd(ll a, ll b){
    //b = a*q1 + r1;
    //a = r1*q2 + r2;
    //do until r2=0
    if(a==0)return b;
    if(b==0)return a;
    if(a>b)swap(a,b);
    ll rem=b%a;
    while(rem){
        b=a;
        a=rem;
        rem=b%a;
    }
    return a;
}

ll lcm(ll a, ll b){
    return (a*b)/gcd(a,b);
}
ll power(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}
 ll factorial(ll n)
    {
        ll res = 1, i;

        for (i = 2; i <= n; i++)
            res = (res*1ll* i)%mod;
        return res;
    }

void solve() {
   ll n;
   cin>>n;
   vector<vll>adj(n);
   vll indeg(n,0);
   fo(i,n-1){
       ll u,v;
       cin>>u>>v;
       u--;v--;
       adj[u].pb(v);
       adj[v].pb(u);
       indeg[u]++;
       indeg[v]++;
   }
    ll ans=0;
   ll maxi=0,ind=0;
   fo(i,n){
       maxi=max(maxi,indeg[i]);
       if(maxi==indeg[i]){
           ind=i;
       }
   }
   indeg[ind]=0;
   ans+=maxi;
    for(auto it:adj[ind]){
        indeg[it]--;
    }
    sort(indeg.begin(),indeg.end());
    ans+=indeg.back();
    cout<<ans-1<<endl;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    ll t=1;
cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

Answer: 1


#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define ar array

const int mod = 1e9+7;

void solve(){
    int n;cin>>n;
    vector<int> adj[n];
    vector<int> degree(n,0);
    map<pair<int,int>,int> m;

    for(int i=0;i<n-1;i++){
        int x,y;cin>>x>>y;
        x--,y--;
        m[{x,y}]++;
        degree[x]++,degree[y]++;
    }
    map<pair<int,int>,int> m2;
    for(auto i: m){
       int x = degree[i.first.first], y = degree[i.first.second];
       if(x>y)swap(x,y);
       m2[{x,y}]++;
    }
    sort(degree.begin(),degree.end());
    int x = degree[n-1], y = degree[n-2];
    if(x == 1)cout<<"0\n";
    else if(x == y){
        ll freq = count(degree.begin(),degree.end(),x);
        ll num = m2[{y,x}];
        int ans = 2*x - 1;
        ll choice = (1LL*(freq)*(freq-1))/2;
        if(num>=choice) {
            ans--;
        }
        cout<<ans<<"\n";
    }
    else {
        int freq = count(degree.begin(),degree.end(),y);
        int num = m2[{y,x}];
        int ans = y + x -1;
        int choice = freq;
        if(num>=choice) ans--;
        cout<<ans<<"\n";
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int t;cin>>t;
    while(t--)
    solve();
        return 0;
}

// time-limit: 3000
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define ar array

const int mod = 1e9+7;

void solve(){
    int n;cin>>n;
    vector<int> adj[n];
    vector<int> degree(n,0);
    map<pair<int,int>,int> m;

    for(int i=0;i<n-1;i++){
        int x,y;cin>>x>>y;
        x--,y--;
        m[{x,y}]++;
        degree[x]++,degree[y]++;
    }
    map<pair<int,int>,int> m2;
    for(auto i: m){
       int x = degree[i.first.first], y = degree[i.first.second];
       if(x>y)swap(x,y);
       m2[{x,y}]++;
    }
    int idx = distance(degree.begin(),max_element(degree.begin(), degree.end()));
    vector<int> degree2 = degree;
    sort(degree.begin(),degree.end());
    int x = degree[n-1], y = degree[n-2];
    if(x == 1)cout<<"0\n";
    else if(x == y){
        int freq = count(degree.begin(),degree.end(),x);
        int num = m2[{y,x}];
        int ans = 2*x - 1;
        int choice = (1LL*(freq)*(freq-1))/2;
        if(num>=choice) {
            ans--;
        }
        cout<<ans<<"\n";
    }
    else {
        int ans = x + y -2;

        for(int i=0;i<n;i++){
            if(i==idx)continue;
            int res = degree2[i] + x -1 ;
            // cout<<i<<" "<<idx<<" "<<res<<"\n";
            if(m.find({min(i,idx),max(i,idx)})!=m.end()){
                res--;
            }
            ans=max(ans,res);
        }
        cout<<ans<<"\n";
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int t;cin>>t;
    while(t--)
    solve();
        return 0;
}

Answer: 1


#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define Yes cout<<"Yes"<<endl;
#define No cout<<"No"<<endl;
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define all(x) x.begin(),x.end()
#define All(x) x.begin()+1,x.end()
#define int long long
typedef unsigned long long ull;
typedef long long ll;
typedef __int128 i128;
typedef pair<int,int> pii;
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};

const int N=5e5+100;
vector<int>a[N];

void solve(){
    int n;
    cin>>n;
    vector<int>in(n+1);
    for(int i=1;i<=n;i++)a[i].clear();
    for(int i=1;i<n;i++){
        int u,v;

        cin>>u>>v;
        a[u].push_back(v);
        a[v].push_back(u);
        in[u]++,in[v]++;
    }
    int id=0;
    int mx=0;
    vector<array<int,4>>pos(n+1);
    for(int i=1;i<=n;i++){
        int x=0;
        int num=0;
        for(auto v:a[i]){
            int y=a[v].size();
            if(y>x){
                x=v;
                num=1;
            }
            else if(y==x){
                num++;
            }
        }
        pos[i]={(int)a[i].size(),x,num,i};
    }
    sort(All(pos),[&](array<int,4>x,array<int,4>y){
        if(x[0]!=y[0])return x[0]>y[0];
        if(x[1]!=y[1])return x[1]<y[1];
        if(x[2]!=y[2])return x[2]<y[2];
        return true;
    });
    // for(int i=1;i<=n;i++){
    //     for(int j=0;j<4;j++)cout<<pos[i][j]<<" ";cout<<endl;
    // }
    id=pos[1][3];
    mx=pos[1][0];
    int ans=mx;
    for(auto v:a[id]){
        in[v]--;
    }
    int res=-1e8;
    for(int i=1;i<=n;i++){
        if(i==id)continue;
        res=max(res,in[i]-1);
    }
    cout<<res+ans<<endl;
}

signed main(){
    ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--)solve();
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define Yes cout<<"Yes"<<endl;
#define No cout<<"No"<<endl;
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define all(x) x.begin(),x.end()
#define All(x) x.begin()+1,x.end()
#define int long long
typedef unsigned long long ull;
typedef long long ll;
typedef __int128 i128;
typedef pair<int,int> pii;
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};

const int N=5e5+100;
vector<int>a[N];

void solve(){
    int n;
    cin>>n;
    vector<int>in(n+1);
    for(int i=1;i<=n;i++)a[i].clear();

    for(int i=1;i<n;i++){
        int u,v;

        cin>>u>>v;
        a[u].push_back(v);
        a[v].push_back(u);
    }
    map<int,int>mp;
    for(int i=1;i<=n;i++){
        mp[a[i].size()]++;
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        mp[a[i].size()]--;
        if(mp[a[i].size()]==0)mp.erase(a[i].size());
        for(auto v:a[i]){
            mp[a[v].size()]--;
            mp[a[v].size()-1]++;
            if(mp[a[v].size()]==0)mp.erase(a[v].size());
        }

        auto [u,v]=*mp.rbegin();
        int now=a[i].size()+u-1;
        ans=max(ans,now);

        mp[a[i].size()]++;
        for(auto v:a[i]){
            mp[a[v].size()]++;
            mp[a[v].size()-1]--;
            if(mp[a[v].size()-1]==0)mp.erase(a[v].size()-1);
        }
    }
    cout<<ans<<endl;
}

signed main(){
    ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--)solve();
    return 0;
}

Answer: 2


#include <bits/stdc++.h>
#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define int long long
const int MOD = 1e9 + 7;
const int INF = LONG_MAX >> 1;
typedef pair<char, int> pchar;
typedef pair<int, int> pint;
typedef vector<int> v;
typedef vector<pint> vpint;
typedef vector<string> vs;
typedef unordered_map<int, int> ump;
typedef map<int, int> mp;
typedef tree<int, null_type, less<int>, rb_tree_tag,
            tree_order_statistics_node_update>
    ordered_set;
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define fl(i,n) for(int i=0;i<n;i++)
#define rl(i,m,n) for(int i=n;i>=m;i--)
#define py cout << "YES\n";
#define pn cout << "NO\n";
#define pimp cout << "IMPOSSIBLE\n";
#define vr(v) v.begin(), v.end()
#define rv(v) v.end(), v.begin()
#define debug(x) cerr << #x << " "; cerr << x << " "; cerr << endl;
int gcd(int a, int b) { if (b == 0) return a; return gcd(b, a % b); }
int lcm(int a, int b) { return (a / gcd(a, b) * b); }
int moduloMultiplication(int a, int b, int mod) { int res = 0; a %= mod; while (b) { if (b & 1) res = (res + a) % mod; b >>= 1; a = (a * 2) % mod; } return res; }
int powermod(int x, int y, int p) { int res = 1; x = x % p; if (x == 0) return 0; while (y > 0) { if (y & 1) res = (res * x) % p; y = y >> 1; x = (x * x) % p; } return res; }

// Utility functions
void pv(const vector<int>& v) { for(auto x: v) cout << x << " "; cout << "\n"; }
void pap(const pair<int,int> ap[],int n) { for(int i=0; i<n; i++) cout << ap[i].first << "->" << ap[i].second << "\n"; }
void pm(const map<int,int>& m) { for(auto x: m) cout << x.first << "->" << x.second << "\n"; }
void pa(const int a[], int n) { for (int i = 0; i < n; ++i) cout << a[i] << " "; cout << "\n"; }
bool sorta(const pair<int,int>& a, const pair<int,int>& b) { return (a.second < b.second); }
bool sortd(const pair<int,int>& a, const pair<int,int>& b) { return (a.second > b.second); }

// Bits
string decToBinary(int n) { string s=""; while (n > 0) { s = to_string(n % 2) + s; n = n / 2; } return s; }
int binaryToDecimal(const string& n) { int dec_value = 0; int base = 1; int len = n.length(); for(int i = len - 1; i >= 0; i--) { if (n[i] == '1') dec_value += base; base = base * 2; } return dec_value; }

// Check functions
bool isPrime(int n) { if (n <= 1) return false; if (n <= 3) return true; if (n % 2 == 0 || n % 3 == 0) return false; for(int i = 5; i * i <= n; i += 6) if (n % i == 0 || n % (i + 2) == 0) return false; return true; }
bool isPowerOfTwo(int n) { if (n == 0) return false; return (ceil(log2(n)) == floor(log2(n))); }
bool isPerfectSquare(int x) { if (x >= 0) { int sr = sqrt(x); return (sr * sr == x); } return false; }
void nl() { cout << "\n"; }
void yn(int x) { if (x == 1) cout << "YES" << "\n"; else cout << "NO" << "\n"; }
void yes() { cout << "YES" << "\n"; }
void no() { cout << "NO" << "\n"; }
void print(int x) { cout << x << "\n"; }
bool sortbysec(const pair<int,int>& a, const pair<int,int>& b) { return (a.second < b.second); }

class dsu{

    vector<int> parent,size;
  public:

    void make_set(int n){
       for (int i = 0; i <=n; ++i)
       {
         parent.push_back(i);
         size.push_back(1);
       }
    }

    int findPar(int node){
      if(parent[node]==node) return node;
      return parent[node]=findPar(parent[node]);//path compression
    }

    void union_sets(int a,int b){
      a=findPar(a);
      b=findPar(b);
      if(a!=b) parent[b]=a;
    }

    void unionSize(int u,int v){
      int pu=findPar(u);
      int pv=findPar(v);
      if(pu==pv) return;

      if(size[pu]<size[pv]){
        parent[pu]=pv;
        size[pv]+=size[pu];
      }else{
        parent[pv]=pu;
        size[pu]+=size[pv];
      }
    }

    void maximal(int a){
      int mx=a;
      while(parent[a]!=a){
          a=parent[a];
          mx=max(mx,a);
      }
      cout<<mx<<" ";
    }

   void minimal(int a){
      int mx=a;
      while(parent[a]!=a){
          a=parent[a];
          mx=min(mx,a);
      }
      cout<<mx<<" ";
    }

    void cnt(int a){
      int cnt=1;
      while(parent[a]!=a){
          a=parent[a];
          cnt++;
      }
      cout<<cnt<<" ";
    }

    void print(int a){
       if(a==parent[a]) return;
       cout<<a<<" ";
       print(parent[a]);
    }

};

int accurateFloor(int a, int b) {
  int val = a / b;
  while (val * b > a)
    val--;
  return val;
}

bool isSubSeqRec(const string& s1, const string& s2, int m, int n)
{
    // Base Cases
    if (m == 0)
        return true;
    if (n == 0)
        return false;

    // If last characters of two strings are matching
    if (s1[m - 1] == s2[n - 1])
        return isSubSeqRec(s1, s2, m - 1, n - 1);

    // If last characters are not matching
    return isSubSeqRec(s1, s2, m, n - 1);
}

// bool check(int n,int k,int sum,int a[]){

// }

void dfs(int u,map<int,set<int>> mp,set<int> &vis){
  vis.insert(u);
  for(auto x: mp[u]){
    if(vis.find(x)==vis.end()){
      dfs(x,mp,vis);
    }
  }
}
signed main()
 {
ios::sync_with_stdio(false);
cin.tie(NULL);

     int tc;
     cin>>tc;
     while(tc--){
       int n;
       cin>>n;
       map<int,set<int>> mp;
       for (int i = 1; i < n; ++i)
       {
            int a,b;
            cin>>a>>b;
            mp[a].insert(b);
            mp[b].insert(a);
       }

       int mxs=-1,u=0;
       for(auto x: mp){
          int sz=x.second.size();
          if(sz>mxs){
             u=x.first;
             mxs=x.second.size();
          }
       }
       set<int> st=mp[u];
       // cout<<u<<"->";
       for(auto x: st){
          mp[x].erase(u);
       }
       mp.erase(u);
       mxs=INT_MIN,u=0;

      for(auto x: mp){
        int sz=x.second.size();
          if(sz>mxs){
             u=x.first;
             mxs=x.second.size();
          }
       }
       st=mp[u];

       for(auto x: st){
          mp[x].erase(u);
       }
       set<int> vis;
       mp.erase(u);
       int cnt=0;

       for (auto x: mp)
       {

          int u=x.first;
          // cout<<u<<" "<<mp[u].size()<<"\n";
          if(vis.find(u)==vis.end()){
            cnt++;
            dfs(u,mp,vis);
          }
       }
       cout<<cnt<<"\n";

     }
   }

//0 0
//0 0

#include <bits/stdc++.h>
#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define int long long
const int MOD = 1e9 + 7;
const int INF = LONG_MAX >> 1;
typedef pair<char, int> pchar;
typedef pair<int, int> pint;
typedef vector<int> v;
typedef vector<pint> vpint;
typedef vector<string> vs;
typedef unordered_map<int, int> ump;
typedef map<int, int> mp;
typedef tree<int, null_type, less<int>, rb_tree_tag,
            tree_order_statistics_node_update>
    ordered_set;
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define fl(i,n) for(int i=0;i<n;i++)
#define rl(i,m,n) for(int i=n;i>=m;i--)
#define py cout << "YES\n";
#define pn cout << "NO\n";
#define pimp cout << "IMPOSSIBLE\n";
#define vr(v) v.begin(), v.end()
#define rv(v) v.end(), v.begin()
#define debug(x) cerr << #x << " "; cerr << x << " "; cerr << endl;
int gcd(int a, int b) { if (b == 0) return a; return gcd(b, a % b); }
int lcm(int a, int b) { return (a / gcd(a, b) * b); }
int moduloMultiplication(int a, int b, int mod) { int res = 0; a %= mod; while (b) { if (b & 1) res = (res + a) % mod; b >>= 1; a = (a * 2) % mod; } return res; }
int powermod(int x, int y, int p) { int res = 1; x = x % p; if (x == 0) return 0; while (y > 0) { if (y & 1) res = (res * x) % p; y = y >> 1; x = (x * x) % p; } return res; }

// Utility functions
void pv(const vector<int>& v) { for(auto x: v) cout << x << " "; cout << "\n"; }
void pap(const pair<int,int> ap[],int n) { for(int i=0; i<n; i++) cout << ap[i].first << "->" << ap[i].second << "\n"; }
void pm(const map<int,int>& m) { for(auto x: m) cout << x.first << "->" << x.second << "\n"; }
void pa(const int a[], int n) { for (int i = 0; i < n; ++i) cout << a[i] << " "; cout << "\n"; }
bool sorta(const pair<int,int>& a, const pair<int,int>& b) { return (a.second < b.second); }
bool sortd(const pair<int,int>& a, const pair<int,int>& b) { return (a.second > b.second); }

// Bits
string decToBinary(int n) { string s=""; while (n > 0) { s = to_string(n % 2) + s; n = n / 2; } return s; }
int binaryToDecimal(const string& n) { int dec_value = 0; int base = 1; int len = n.length(); for(int i = len - 1; i >= 0; i--) { if (n[i] == '1') dec_value += base; base = base * 2; } return dec_value; }

// Check functions
bool isPrime(int n) { if (n <= 1) return false; if (n <= 3) return true; if (n % 2 == 0 || n % 3 == 0) return false; for(int i = 5; i * i <= n; i += 6) if (n % i == 0 || n % (i + 2) == 0) return false; return true; }
bool isPowerOfTwo(int n) { if (n == 0) return false; return (ceil(log2(n)) == floor(log2(n))); }
bool isPerfectSquare(int x) { if (x >= 0) { int sr = sqrt(x); return (sr * sr == x); } return false; }
void nl() { cout << "\n"; }
void yn(int x) { if (x == 1) cout << "YES" << "\n"; else cout << "NO" << "\n"; }
void yes() { cout << "YES" << "\n"; }
void no() { cout << "NO" << "\n"; }
void print(int x) { cout << x << "\n"; }
bool sortbysec(const pair<int,int>& a, const pair<int,int>& b) { return (a.second < b.second); }

class dsu{

    vector<int> parent,size;
  public:

    void make_set(int n){
       for (int i = 0; i <=n; ++i)
       {
         parent.push_back(i);
         size.push_back(1);
       }
    }

    int findPar(int node){
      if(parent[node]==node) return node;
      return parent[node]=findPar(parent[node]);//path compression
    }

    void union_sets(int a,int b){
      a=findPar(a);
      b=findPar(b);
      if(a!=b) parent[b]=a;
    }

    void unionSize(int u,int v){
      int pu=findPar(u);
      int pv=findPar(v);
      if(pu==pv) return;

      if(size[pu]<size[pv]){
        parent[pu]=pv;
        size[pv]+=size[pu];
      }else{
        parent[pv]=pu;
        size[pu]+=size[pv];
      }
    }

    void maximal(int a){
      int mx=a;
      while(parent[a]!=a){
          a=parent[a];
          mx=max(mx,a);
      }
      cout<<mx<<" ";
    }

   void minimal(int a){
      int mx=a;
      while(parent[a]!=a){
          a=parent[a];
          mx=min(mx,a);
      }
      cout<<mx<<" ";
    }

    void cnt(int a){
      int cnt=1;
      while(parent[a]!=a){
          a=parent[a];
          cnt++;
      }
      cout<<cnt<<" ";
    }

    void print(int a){
       if(a==parent[a]) return;
       cout<<a<<" ";
       print(parent[a]);
    }

};

int accurateFloor(int a, int b) {
  int val = a / b;
  while (val * b > a)
    val--;
  return val;
}

bool isSubSeqRec(const string& s1, const string& s2, int m, int n)
{
    // Base Cases
    if (m == 0)
        return true;
    if (n == 0)
        return false;

    // If last characters of two strings are matching
    if (s1[m - 1] == s2[n - 1])
        return isSubSeqRec(s1, s2, m - 1, n - 1);

    // If last characters are not matching
    return isSubSeqRec(s1, s2, m, n - 1);
}

// bool check(int n,int k,int sum,int a[]){

// }

void dfs(int u,map<int,set<int>> mp,set<int> &vis){
  vis.insert(u);
  for(auto x: mp[u]){
    if(vis.find(x)==vis.end()){
      dfs(x,mp,vis);
    }
  }
}
signed main()
 {
ios::sync_with_stdio(false);
cin.tie(NULL);

     int tc;
     cin>>tc;
     while(tc--){
       int n;
       cin>>n;
       int cnt[n+1]{};
       map<int,set<int>> mp;
       set<pair<int,int>> st;
       for (int i = 1; i < n; ++i)
       {
            int a,b;
            cin>>a>>b;
            st.insert({a,b});
            st.insert({b,a});
            mp[a].insert(b);
            mp[b].insert(a);
            cnt[a]++,cnt[b]++;
       }

       vector<pair<int,int>> v;
       for (int i = 1; i <=n; ++i)
       {
         v.push_back({cnt[i],i});
       }

       sort(rbegin(v),rend(v));

       int ans=-1;
       for (int i = 0; i < v.size(); ++i)
       {
          for(int j=i+1; j<v.size(); ++j){
            if(mp[v[j].second].find(v[i].second)==mp[v[j].second].end()){
              ans=max(ans,v[j].first+v[i].first-1);
              break;
            }
          }
       }

      for(auto x: st){
        ans=max(ans,cnt[x.first]+cnt[x.second]-2);
      }

       cout<<ans<<"\n";

     }
   }

//0 0
//0 0

Answer: 2