Lord Omkar would like to have a tree with n nodes (3 ≤ n ≤ 10^5) and has asked his disciples to construct the tree. However, Lord Omkar has created m (1 ≤ m < n) restrictions to ensure that the tree will be as heavenly as possible. 

A tree with n nodes is an connected undirected graph with n nodes and n-1 edges. Note that for any two nodes, there is exactly one simple path between them, where a simple path is a path between two nodes that does not contain any node more than once.

Here is an example of a tree: 

<image>

A restriction consists of 3 pairwise distinct integers, a, b, and c (1 ≤ a,b,c ≤ n). It signifies that node b cannot lie on the simple path between node a and node c. 

Can you help Lord Omkar and become his most trusted disciple? You will need to find heavenly trees for multiple sets of restrictions. It can be shown that a heavenly tree will always exist for any set of restrictions under the given constraints.

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1 ≤ t ≤ 10^4). Description of the test cases follows.

The first line of each test case contains two integers, n and m (3 ≤ n ≤ 10^5, 1 ≤ m < n), representing the size of the tree and the number of restrictions.

The i-th of the next m lines contains three integers a_i, b_i, c_i (1 ≤ a_i, b_i, c_i ≤ n, a, b, c are distinct), signifying that node b_i cannot lie on the simple path between nodes a_i and c_i. 

It is guaranteed that the sum of n across all test cases will not exceed 10^5.

Output

For each test case, output n-1 lines representing the n-1 edges in the tree. On each line, output two integers u and v (1 ≤ u, v ≤ n, u ≠ v) signifying that there is an edge between nodes u and v. Given edges have to form a tree that satisfies Omkar's restrictions.

Example

Input


2
7 4
1 2 3
3 4 5
5 6 7
6 5 4
5 3
1 2 3
2 3 4
3 4 5


Output


1 2
1 3
3 5
3 4
2 7
7 6
5 1
1 3
3 2
2 4

Note

The output of the first sample case corresponds to the following tree: 

<image> For the first restriction, the simple path between 1 and 3 is 1, 3, which doesn't contain 2. The simple path between 3 and 5 is 3, 5, which doesn't contain 4. The simple path between 5 and 7 is 5, 3, 1, 2, 7, which doesn't contain 6. The simple path between 6 and 4 is 6, 7, 2, 1, 3, 4, which doesn't contain 5. Thus, this tree meets all of the restrictions.

The output of the second sample case corresponds to the following tree: 

<image>
/*author : vidit shukla
           (valiant_vidit)*/
#pragma  GCC optimize("O3")
#include <bits/stdc++.h>
#define ll               long long int
#define bhaago           ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define loop(a,b,i)      for(ll i=a;i<b;i++)
#define loop1(a,b,i)     for(ll i=a;i>b;i--)
#define printclock       cerr<<"Time : "<<1000*(ld)clock()/(ld)CLOCKS_PER_SEC<<"ms\n";
#define endl              '\n'
#define Endl              '\n'
#define all(v)           (vector.begin(),vector.end())
#define az(i)            for(auto it:i)cout<<it<<" ";cout<<Endl;
#define mpaz(i)          for(auto it:i)cout<<it.first<<"->"<<it.second<<endl;cout<<Endl;
#define araz(arr,i)      loop(0,i,j)cout<<arr[j]<<" ";cout<<Endl;
#define setin(s,i)       for(auto it:i)s.insert(it);
#define mpin(mp,i)       for(auto it:i)mp[it]++;
#define yy               cout<<"YES"<<endl
#define nn               cout<<"NO"<<endl
#define prn1(tk,ans)      cout<<"Case #"<<tk<<": "<<ans<<endl
#define prn(tk)          cout<<"Case #"<<tk<<": "
#define init(dp,i)       memset(dp,i,sizeof dp)
#define fix(f,n) std::fixed<<std::setprecision(n)<<f
const double pi = std::acos(-1);
using namespace std;
const ll mod = 1000000000+7;
 
 
ll power(ll x,ll y,ll md)  
{ll res=1;x=x%md;if(x==0)return 0;while(y>0){if(y&1)res=(res*x)%md;y=y>>1;x=(x*x)%md;}return res;} 
 
ll m_mul(ll a, ll b){a=a%mod;b=b%mod;return (a*b+mod)%mod;}
ll m_add(ll a,ll b){a=a%mod; b=b%mod;return (a+b+mod)%mod;}
 
ll spf[(ll)1e7+2]={0};
 
struct dsu{
vector<ll>parent,rank;
dsu(ll n)
{parent.resize(n+2); for(ll i=0;i<=n;i++)parent[i]=i;rank.resize(n+2);}
ll fnd(ll i)
{if(parent[i]==i)return i;else return parent[i]=fnd(parent[i]);}
void unite(ll a,ll b)
{  a=fnd(a);b=fnd(b);if(rank[a]>rank[b])parent[b]=a;else if(rank[b]>rank[a])parent[a]=b;else{parent[a]=b;rank[b]++;}}
bool same(ll a,ll b)
{return fnd(a)==fnd(b);}
};
//------------------------------------------------------
struct sgtree
{
vector<ll> arr;vector<ll> tree, lazy;
 
sgtree(ll n, ll brr[])
{arr.resize(n);ll k = 2 * (ll)powl(2, log2l(n) + 1);tree.resize(k);lazy.resize(k);
loop(0, k, i) lazy[i] = -1;//here*//this is veryyy imp., here dummyy value is to be kept., then to change all conditions where dummy is checked.!!
loop(0, n, i)arr[i] = brr[i];}
 
void build(ll ind, ll left, ll right)
{if (left == right){tree[ind] = arr[left];return;}
ll mid = left + (right - left) / 2;
build(2 * ind + 1, left, mid);build(2 * ind + 2, mid + 1, right);
tree[ind] = tree[2 * ind + 1] + tree[2 * ind + 2];}
 
void updateSingle(ll ind, ll index, ll val, ll left, ll right) //after arr[index]=val
{if (left == right && left == index){tree[ind] =val;return;}
if (index > right || index < left)return;
ll mid = left + (right - left) / 2;
updateSingle(2 * ind + 1, index, val, left, mid);updateSingle(2 * ind + 2, index, val, mid + 1, right);
tree[ind] = tree[2 * ind + 1] + tree[2 * ind + 2];}
 
void updateLazy(ll ind, ll indexleft, ll indexright, ll val, ll left, ll right) //upadte value in a range
{if (lazy[ind] != -1)//here*
{tree[ind] =  (right-left+1)*lazy[ind]; //here you can make changes as req.
if (left != right){lazy[2 * ind + 1] = lazy[ind];lazy[2 * ind + 2] = lazy[ind];}
lazy[ind] = -1;//here*
}
if (indexleft > right || indexright < left)return;
if (indexleft <= left && right <= indexright)
{tree[ind] = (right-left+1)* val; //here you can make changes as req.
if (left != right)
{lazy[2 * ind + 1] = val;lazy[2 * ind + 2] = val;}return;}
ll mid = left + (right - left) / 2;
updateLazy(2 * ind + 1, indexleft, indexright, val, left, mid);
updateLazy(2 * ind + 2, indexleft, indexright, val, mid + 1, right);
tree[ind] = tree[2 * ind + 1] + tree[2 * ind + 2];
}
ll ans(ll ind, ll start, ll end, ll left, ll right) //start, end are query for l and r
{if (lazy[ind] != -1)//here*
{tree[ind]=(right-left+1)*lazy[ind]; //here you can make changes as req.
if (left!=right){lazy[2*ind+1]=lazy[ind];lazy[2*ind+2]=lazy[ind];}
 lazy[ind] = -1;//here*
}
if (left>end||start>right)return 0;
if (start<=left && right<=end)return tree[ind];
ll mid=left+(right-left)/2;
return ans(2*ind+1,start,end,left,mid)+ans(2*ind+2,start,end,mid+1,right);
}
};
//------------------------------------------------------
void siv()
{
spf[1]=1;
loop(1,1e7+2,i)spf[i]=i;
loop(2,1e7+2,i)spf[i]=2,i++;
for(ll i=3;i*i<(ll)1e7+2;i++)
{if( spf[i]==i)for(ll j=i*i;j<(ll)1e7+2;j=j+i)if(spf[j]==j)spf[j]=i;}
}
//---------------------------------------------------
 void dfs(vector<ll>v[],ll vis[],ll i)
 {
     vis[i] = 1;
     for(auto it:v[i])
     {
         if(vis[it]==0)
             dfs(v, vis, it);
     }
 }
 void dfsp(vector<ll>v[],ll vis[],ll i)
 {
     vis[i] = 1;
     //cout << "i==" << i << endl;
     for(auto it:v[i])
     {
     //    cout << "it==" << it << endl;
         if(vis[it]==0)
             {
                  cout << i << " " << it << endl;
                 dfsp(v, vis, it);
                 }
     }
 }
int main() {
//see if tcs are present or not.
      bhaago;
      // freopen("@iin.txt","r",stdin);
      // freopen("@output.txt","w",stdout);
    ll tc=1;
    cin>>tc;
    while(tc--)
    {
        ll n,m;
        
        cin>>n>>m; ll arr[n];
        vector<ll> v[n+1];
        ll vis[n + 1] = {0};
        ll preb = -1;
        loop(0,m,i)
        {
            ll a, b, c;
            cin>>a>>b>>c;
            if(preb!=-1)
            {
                v[preb].push_back(b);
                v[b].push_back(preb);
            }
            v[a].push_back(c);
            v[c].push_back(a);
            preb = b;

        }
        ll pre = -1;
        loop(1,n+1,i)
        {
            if(vis[i]==0)
                {
                  //  cout << "i==" << i << endl;
                    if(pre!=-1)
                    {
                        v[pre].push_back(i);
                        v[i].push_back(pre);
                      
                    }
                    dfs(v, vis, i);
                      pre = i;
                }
        }
        // for (int i = 1;i<=n;i++)
        // {
        //     cout << "i==" << i << "-->";
        //     for(auto it:v[i])
        //         cout << it << " ";
        //     cout << endl;
        // }
        ll vis2[n + 1] = {0};
        // for (int i = 0; i < n + 1; i++)
        //     vis[i] = 0;
        // for (int i = 1; i < n + 1;i++)
        //     cout << vis2[i] << " ";
        // cout << endl;
        dfsp(v, vis2, 1);
        // for (int i = 1; i < n + 1;i++)
        //     cout << vis2[i] << " ";
        // cout << endl;
        //cout<<n<<endl;
    }
	// your code goes here
	return 0;
}