#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 2e5 + 5,inf=1e9+7;
// 全局变量说明:
// dist[i]:节点i到最近叶子节点的最短距离,初始为无穷大inf
// adj:树的邻接表,adj[u]存储与u直接相连的所有节点
// ans:存储最终答案(非叶子节点中距离叶子最远的节点)
// n:当前测试用例的树的节点总数
vector<ll>dist;
vector<vector<ll>>adj(N);
vector<ll>ans;
ll n;
// 算法核心:多源BFS(从所有叶子节点出发)
// 思想:树的叶子节点作为多个BFS起点,逐层更新非叶子节点到叶子的最短距离,
// 最终筛选出非叶子节点中距离最大值对应的所有节点
void bfs() {
// 1. 初始化BFS队列:存储待处理的节点编号
queue<ll>q;
// 2. 多源BFS起点初始化:找到所有叶子节点(度为1的节点)
// 叶子节点到自身的距离为0,加入队列作为BFS的初始起点
for (ll i = 1; i <= n; i++) {
if (adj[i].size() == 1) { // 度为1的节点是叶子节点
q.push(i);
dist[i]=0; // 叶子节点到最近叶子的距离为0
}
}
// m:记录当前找到的“非叶子节点到叶子的最大距离”
ll m=0;
// 3. 多源BFS核心遍历:逐层更新节点距离
while(!q.empty()){
// 取出队列头部的当前节点
ll t=q.front();
q.pop();
// 4. 答案筛选:仅统计非叶子节点的最大距离
// 若当前节点距离大于已知最大值:更新最大值,重置答案数组
if(dist[t]>m){
m=dist[t];
ans.clear();
if(adj[t].size() > 1) { // 仅非叶子节点加入答案
ans.emplace_back(t);
}
}
// 若当前节点距离等于已知最大值:将该非叶子节点加入答案
else if(dist[t]==m){
if(adj[t].size() > 1) { // 仅非叶子节点加入答案
ans.emplace_back(t);
}
}
// 5. 遍历当前节点的所有邻接节点,更新距离并入队
for(auto it:adj[t]){
// 仅处理:未更新过距离的非叶子节点(避免重复处理+符合题意)
if(dist[it]==inf && adj[it].size() > 1) {
dist[it]=dist[t]+1; // 邻接节点距离 = 当前节点距离 + 1(树的边权为1)
q.push(it); // 邻接节点入队,继续BFS
}
}
}
}
int main() {
// 加速输入输出:关闭同步,消除cin/cout的缓冲区开销
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
ll T;
cin >> T; // 读取测试用例数
// 处理多组测试用例
while (T--) {
// 1. 读取当前测试用例的树的节点总数
cin >> n;
// 2. 初始化距离数组:dist[1~n]设为无穷大(表示未访问)
dist.assign(n+1,inf);
// 3. 清空邻接表中当前用例用到的节点(避免上一轮数据残留)
for (ll i = 1; i <= n; i++) {
adj[i].clear();
}
// 4. 清空答案数组
ans.clear();
// 5. 读取n-1条边,构建树的邻接表(无向边)
for (ll i = 1; i <= n - 1; i++) {
ll u, v;
cin >> u >> v;
adj[u].emplace_back(v); // 无向边:u->v
adj[v].emplace_back(u); // 无向边:v->u
}
// 6. 执行多源BFS,计算并筛选答案
bfs();
// 7. 输出答案:先输出答案数量,再排序后输出节点编号
cout<<ans.size()<<'\n';
sort(ans.begin(),ans.end()); // 按题目要求排序答案
for(auto t:ans){
cout<<t<<' ';
}
cout<<'\n';
}
return 0;
}