#include<cstdio>
#include<iostream>
#include<string>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<limits.h>
#include<list>
#include<queue>
#include<map>
using namespace std;
typedef pair<int, int> ii;
#define MAX 100000
#define INF 2000000000
#define TRvi(c, it) \
for(vector<int>::iterator it = c.begin(); it != c.end(); it++)
int V, treeRoot;
vector<vector<int> > tree;
map<ii, int> dp;
map<ii, int> height;
vector<int> realTree;
vector<ii> EdgeList;
int diameter(int node, int parent)
{
if(dp[ii(node, parent)] != -1)
{
return dp[ii(node, parent)];
}
int res = -INF;
int maxHeight = 0;
TRvi(tree[node], v)
{
int child = *v;
if(child != parent)
{
res = max(res, diameter(child, node));
}
}
if(res == -INF) /* node is leaf */
{
height[ii(node, parent)] = 1;
return 0;
}
int max1 = -1;
int max2 = -1;
int dir;
TRvi(tree[node], v)
{
int child = *v;
if(child != parent)
{
maxHeight = max(maxHeight, height[ii(child, node)]);
int num = height[ii(child, node)];
if(num > max1)
{
max2 = max1;
max1 = num;
}
else if(num > max2)
{
max2 = num;
}
}
}
if(max1 != -1 && max2 != -1)
res = max(res, (max1 + max2));
else if(max1 != -1)
res = max1;
else
res = max2;
height[ii(node, parent)] = 1 + maxHeight;
return dp[ii(node, parent)] = res;
}
void dfs(int node, int parent)
{
realTree[node] = parent;
TRvi(tree[node], v)
{
int child = *v;
if(child != parent)
{
dfs(child, node);
}
}
}
int minimizeDiameter()
{
int res = INF;
for(int i = 0; i < EdgeList.size(); i++)
{
int d1, d2;
ii front = EdgeList[i];
int u = front.first;
int v = front.second;
d1 = diameter(u, v);
d2 = diameter(v, u);
int removeEdge = -1;
removeEdge = max(max(d1, d2), (d1+1)/2 + (d2+1)/2 + 1);
//printf("%d %d\n", u, v);
//printf("%d %d %d\n", d1, d2, removeEdge);
res = min(res, removeEdge);
}
res = min(res, diameter(treeRoot, -1));
return res;
}
int main()
{
FILE* fin = freopen("revolta.in", "r", stdin);
FILE* fout = freopen("revolta.out", "w", stdout);
int start, end;
int T; cin >> T;
while(T--) {
cin >> V;
tree.clear();
tree.resize(V);
dp.clear();
height.clear();
realTree.assign(V, -1);
EdgeList.clear();
//memset(dp, -1, sizeof(dp));
//memset(height, -1, sizeof(height));
for(int i = 0; i < (V-1); i++)
{
cin >> start >> end;
tree[start].push_back(end);
tree[end].push_back(start);
EdgeList.push_back(ii(start, end));
dp[ii(start, end)] = -1;
dp[ii(end, start)] = -1;
height[ii(start, end)] = -1;
height[ii(end, start)] = -1;
}
treeRoot = 0;
dfs(treeRoot, -1);
dp[ii(treeRoot, -1)] = -1;
height[ii(treeRoot, -1)] = -1;
cout << minimizeDiameter() << endl;
}
fclose(fin);
fclose(fout);
return 0;
}