#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;
ifstream fin("revolta.in");
ofstream fout("revolta.out");
#define MAX 100010
typedef vector <int> :: iterator iter;
vector <int> G[MAX];
#define cout fout
int rmq[20][2 * MAX];
int lvl[MAX], f[MAX];
int dr;
int doi[2 * MAX];
void df(int nod, int dad)
{
// cout << nod << " ";
lvl[nod] = lvl[dad] + 1;
rmq[0][++dr] = nod;
f[nod] = dr;
for(iter it = G[nod].begin() ; it != G[nod].end() ; it++)
{
if(*it == dad)
continue;
df(*it, nod);
rmq[0][++dr] = nod;
}
}
int n;
void build_rmq()
{
int k, i;
for(k = 1 ; (1<<k) <= dr ; k++)
{
for(i = 1 ; i + (1<<k) - 1 <= dr ; i++)
{
if(lvl[rmq[k - 1][i]] < lvl[rmq[k - 1][i + (1<<(k - 1))]])
rmq[k][i] = rmq[k - 1][i];
else
rmq[k][i] = rmq[k - 1][i + (1<<(k - 1))];
}
}
doi[1] = 0;
for(i = 2 ; i <= dr ; i++)
doi[i] = doi[i / 2] + 1;
}
int lca(int x, int y)
{
x = f[x];
y = f[y];
if(x > y)
swap(x, y);
int lg = doi[(y - x + 1)];
if(lvl[rmq[lg][x]] < lvl[rmq[lg][y - (1<<lg) + 1]])
return rmq[lg][x];
return rmq[lg][y - (1<<lg) + 1];
}
int lvl2[MAX], nnext[MAX];
void init()
{
for(int i = 1 ; i <= n ; i++)
G[i].clear();
memset(rmq,0, sizeof rmq);
memset(lvl,0,sizeof lvl);
memset(lvl2,0,sizeof lvl2);
dr = 0;
}
int dist(int x, int y)
{
return lvl[x] + lvl[y] - 2 * lvl[lca(x, y)] + 1;
}
int tata[MAX];
void diam(int nod, int dad)
{
lvl2[nod] =lvl2[dad] + 1;
tata[nod] = dad;
for(auto it : G[nod])
{
if(it == dad)
continue;
diam(it, nod);
}
}
pair<int, int> find_diametru(pair<int, int> a, pair<int, int> b)
{
int mxdist = max(max(dist(a.first, a.second), dist(a.first, b.first)),
max(max(dist(a.first, b.second), dist(a.second, b.first)),
max(dist(a.second, b.second), dist(b.first, b.second))));
if(dist(a.first, a.second) == mxdist)
return a;
if(dist(a.first, b.first) == mxdist)
return make_pair(a.first, b.first);
if(dist(a.first, b.second) == mxdist)
return make_pair(a.first, b.second);
if(dist(a.second, b.first) == mxdist)
return make_pair(a.second, b.first);
if(dist(a.second, b.second) == mxdist)
return make_pair(a.second, b.second);
return b;
}
pair<int, int> diametru[MAX];
bool special[MAX];
void build(int nod, int dad)
{
diametru[nod] = make_pair(nod, nod);
for(auto it : G[nod])
{
if(it == dad || special[it])
continue;
build(it, nod);
diametru[nod] = find_diametru(diametru[nod], diametru[it]);
}
}
pair<int, int> dp1[MAX], dp2[MAX];
int main()
{
int t, i, x, y, nod, nod2;
fin >> t;
while(t--)
{
fin >> n;
init();
for(i = 1 ; i < n ; i++)
{
fin >> x >> y;
x++;
y++;
/// [RPSTI;L SCOATE AS;DLFKJAS;LKDHFALKJHFBGKJADFK;G'JL
G[x].push_back(y);
G[y].push_back(x);
}
df(1, 0); ///vezi boule baga din 1
build_rmq();
nod = 1;
for(i = 1 ; i <= n ; i++)
if(lvl[i] > lvl[nod])
nod = i;
diam(nod, 0);
nod2 = 1;
for(i = 1 ; i <= n ; i++)
if(lvl2[i] > lvl2[nod2])
nod2 = i;
// cout << nod << "! " << nod2 << "\n";
for(i = nod2 ; i != 0 ; i = tata[i])
{
special[i] = 1;
nnext[tata[i]] = i;
}
for(i = nod2 ; i != 0 ; i = tata[i])
{
build(i, 0);
// cout << i << " " << diametru[i].first << " " << diametru[i].second << "\n";
}
dp1[nod2] = diametru[nod2];
for(i = tata[nod2] ; i != 0 ; i = tata[i])
{
dp1[i] = find_diametru(dp1[nnext[i]], diametru[i]);
}
dp2[nod] = diametru[nod];
nnext[nod2]=0;
for(i = nnext[nod] ; i != 0 ; i = nnext[i])
{
dp2[i] = find_diametru(diametru[i],dp2[tata[i]]);
}
int d1, d2;
int ans = n + 4;
for(i = nod; i != nod2 ; i = nnext[i])
{
d1 = dist(dp2[i].first, dp2[i].second);
d2 = dist(dp1[nnext[i]].first, dp1[nnext[i]].second);
ans = min(d1/ 2 +1 + d2 / 2+1, ans);
/*pair<int, int> aux = find_diametru(dp2[i], dp1[nnext[i]]);
ans = min(ans, dist(aux.first, aux.second));*/
}
cout << ans - 1 << "\n";
}
}