#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <set>
#include <stack>
using namespace std;
#define MAXN 200005
struct nodeType{
vector<int> to;
int dep;
} node[MAXN];
void init_node(int n,bool clearljb){
for (int i = 1; i <= n; i++) {
if(clearljb) node[i].to.clear();
node[i].dep = 1;
}
}
vector<int> tdr;
int prevNode[MAXN];
bool vis[MAXN];
int bfs(int n,bool metaMode,int src,bool gentdr,int blocked){
//0 for meta 1 for tdim
//make blocked 0 if you do not want to split
init_node(n,false);
memset(vis, 0, sizeof(vis));
memset(prevNode, 0, sizeof(prevNode));
queue<int> q;
q.push(src);
int last = 0,maxdep = 0;
while (!q.empty()) {
nodeType &now = node[q.front()];
vis[q.front()] = true;
if (now.dep > maxdep) {
maxdep = now.dep;
last = q.front();
}
for (int i = 0; i < now.to.size(); i++) {
if (vis[now.to[i]] || now.to[i] == blocked) {
continue;
}
node[now.to[i]].dep = now.dep+1;
q.push(now.to[i]);
prevNode[now.to[i]] = q.front();
}
q.pop();
}
if (metaMode) {
return last;
}else {
if (gentdr) {
tdr.clear();
int tmp = last;
while (src != tmp) {
tdr.push_back(tmp);
tmp = prevNode[tmp];
}
tdr.push_back(src);
}
return maxdep;
}
}
int main(){
int casecnt;
cin >> casecnt;
while (casecnt--) {
int n;
cin >> n;
init_node(n,true);
for (int i = 1; i <= n-1; i++) {
int a = 0,b = 0;
scanf(" %d %d",&a,&b);
node[a].to.push_back(b);
node[b].to.push_back(a);
}
int seed = rand()%n+1;
int meta = bfs(n, true, seed,false,0);
int tdim = bfs(n, false, meta, true,0);
int lans = 0,rans = 0,dis = 0;
if (tdim % 2) {
vector<int> origtdr = tdr;
int center = (tdim-1)/2;
//odd situ1
int lmeta1 = bfs(n, true, origtdr[0], false, origtdr[center]);
int ltdim1 = bfs(n, false, lmeta1, true, origtdr[center]);
int lpos1 = tdr[ltdim1/2];
int rmeta1 = bfs(n, true, origtdr[tdim-1], false, origtdr[center-1]);
int rtdim1 = bfs(n, false, rmeta1, true, origtdr[center-1]);
int rpos1 = tdr[rtdim1/2];
int judge1 = max(ltdim1/2,rtdim1/2);
//odd situ2
int lmeta2 = bfs(n, true, origtdr[0], false, origtdr[center+1]);
int ltdim2 = bfs(n, false, lmeta2, true, origtdr[center+1]);
int lpos2 = tdr[ltdim2/2];
int rmeta2 = bfs(n, true, origtdr[tdim-1], false,origtdr[center]);
int rtdim2 = bfs(n, false, rmeta2, true, origtdr[center]);
int rpos2 = tdr[rtdim2/2];
int judge2 = max(ltdim2/2,rtdim2/2);
//judge
if (judge1 > judge2) {
//2 is good
lans = lpos2;
rans = rpos2;
dis = judge2;
}else{
//1 is good
lans = lpos1;
rans = rpos1;
dis = judge1;
}
}else{
//even situ
int lend = tdr[tdim/2-1];
int rend = tdr[tdim/2];
//run left
int lmeta = bfs(n, true, tdr[0], false,rend);
//run right
int rmeta = bfs(n, true, tdr[tdim-1], false, lend);
int ltdim = bfs(n, false, lmeta, true, rend);
lans = tdr[ltdim/2];
int rtdim = bfs(n, false, rmeta, true, lend);
rans = tdr[rtdim/2];
dis = max(ltdim/2,rtdim/2);
}
cout << dis << ' ' << lans << ' ' << rans << ' ' << endl;
}
return 0;
}