#include <bits/stdc++.h>

#define rep(i,e) for(int i = 0; i < e; i++)
#define reps(i,s,e) for(ll i = s; i <= e; i++)
#define rev(i,s) for(ll i = s; ~i; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x.size())
#define pb push_back
#define ff first
#define ss second

using namespace std;
typedef long long ll;
const ll MOD=1000000007;

int n;
vector<set<int>> adj;
vector<pair<int, int>> broken, joined;
vector<bool> visited;

inline void brk(int u, int v){
    adj[u].erase(v);
    adj[v].erase(u);

    broken.pb({u+1, v+1});
}

void dfs1(int u, int par){
    auto it = adj[u].begin();
    while(it != adj[u].end()) {
        if(*it == par) it++;
        else dfs1(*it++, u);
    }

    if(sz(adj[u]) > 2 and u != par) brk(u, par);

    int cnt = 2;
    it = adj[u].begin();
    while(it != adj[u].end()){
        if(cnt) {cnt--; it++; continue;}
        else brk(*it++, u);  
    }
}

void dfs2(int u, vector<int>& ans){
    visited[u] = true;
    for(auto it : adj[u])
        if(!visited[it]) dfs2(it, ans);

    if(sz(adj[u]) == 1) ans.pb(u);
    if(sz(adj[u]) == 0) {ans.pb(u); ans.pb(u);}
}

void solve(){
    cin >> n;
    adj = vector<set<int>>(n);
    broken.clear(); joined.clear();

    rep(i, n-1){
        int u, v;
        cin >> u >> v;
        u--; v--;

        adj[u].insert(v);
        adj[v].insert(u);
    }

    dfs1(0, 0);

    visited = vector<bool>(n, false);
    int end = -1;
    rep(i, n){
        if(!visited[i]){
            vector<int> ends;
            dfs2(i, ends);

            if(end != -1) joined.pb({end+1, ends[0]+1});
            end = ends[1];
            ends.clear();
        }
    }

    cout << sz(broken) << '\n';
    // cout << sz(joined) << '\n';
    rep(i, sz(broken)) cout << broken[i].ff << ' ' << broken[i].ss << ' ' << joined[i].ff << ' ' << joined[i].ss << '\n';
}

int main(){
#ifdef k4droid3
    freopen("input.txt", "r", stdin);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

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