#include <bits/stdc++.h>
using namespace std;
#define PI 3.14159265358979323846
#define E  2.71828182845904523536
#define pout(x) cout << fixed << setprecision(x)
#define INF INFINITY
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define siz(x) (ll)x.size()
#define all(x) x.begin(), x.end()
typedef long double ld;
typedef long long ll;
ll _, n, m, k, s, x, y, p;
ll a[1001][1001];
ll st[1001][1001];
ll fin[1001][1001];
void solve();
int main() {
    cin >> _;
    while(_--) solve();
}
void solve() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
            fin[i][j] = 0;
        }
    }
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            cin >> st[j][i];
        }
    }
    for(int i = 0; i < m; i++){
        for(int k = 0; k < m; k++){
            set<ll> sttt;
            for(int j = 0; j < n; j++){
                sttt.insert(a[j][i]);
                sttt.insert(st[j][k]);
            }
            if(siz(sttt) == n){
                for(int j = 0; j < n; j++){
                    fin[j][i] = st[j][k];
                }
            }
        }
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cout << fin[i][j] << " ";
        }
        cout << endl;
    }
}


#include <bits/stdc++.h>
#define union Union
#define rank rank228
#define tm tm228
#define hash hash228
#define matr vector < vector < int > >
#define int long long
#define pii pair < int, int >
#define papa pair < node*, node* >
#define all(v) v.begin(), v.end()
#define endl "\n"
#define pb push_back
#define PI 3.14159265358979323846
#define ff first
#define ss second

using namespace std;

const int inf = 1e9 + 7, maxn = 1e3 + 100;

int a[maxn][maxn], b[maxn][maxn], ans[maxn][maxn];

void solve(){
    int n, m, k = 0;
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
            cin >> a[i][j];
    }
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            cin >> b[i][j];
        }
    }
    vector < int > cntb(n * m + 1, 0);
    for (int i = 0; i < m; ++i)
    {
        cntb[b[i][0]]++;
    }
    for (int i = 0; i < n; ++i)
    {
        vector < int > cnta(n * m + 1, 0);
        for (int j = 0; j < m; ++j)
        {
            cnta[a[i][j]]++;
        }
        int ok = 1;
        for (int i = 0; i < m * n; ++i)
        {
            if (cnta[i] != cntb[i])
            {
                ok--;
                break;
            }
        }
        if (ok)
        {
            k = i;
            break;
        }
    }
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            if (a[k][i] == b[j][0])
            {
                for (int l = 0;l < n; ++l)
                {
                    ans[l][i] = b[j][l];
                }
            }
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            cout << ans[i][j] << ' ';
        }
        cout << endl;
    }
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    srand(100);
    cout << fixed << setprecision(10);
    int t = 1;
    #ifdef LOCAL
        freopen("task.in", "r", stdin);
    #endif
    cin >> t;
    while (t--)
    {
        solve();
        cout << endl;
    }
}
//i hate feminism


#include <bits/stdc++.h>
#define union Union
#define rank rank228
#define tm tm228
#define hash hash228
#define matr vector < vector < int > >
#define int long long
#define pii pair < int, int >
#define papa pair < node*, node* >
#define all(v) v.begin(), v.end()
#define endl "\n"
#define pb push_back
#define PI 3.14159265358979323846
#define ff first
#define ss second

using namespace std;

const int inf = 1e9 + 7, maxn = 1e3 + 100;

int a[maxn][maxn], b[maxn][maxn], ans[maxn][maxn];

void solve(){
    int n, m, k = 0;
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
            cin >> a[i][j];
    }
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            cin >> b[i][j];
        }
    }
    vector < int > cntb(n * m, 0);
    for (int i = 0; i < m; ++i)
    {
        cntb[b[i][0]]++;
    }
    for (int i = 0; i < n; ++i)
    {
        vector < int > cnta(n * m, 0);
        for (int j = 0; j < m; ++j)
        {
            cnta[a[i][j]]++;
        }
        int ok = 1;
        for (int i = 0; i < m * n; ++i)
        {
            if (cnta[i] != cntb[i])
            {
                ok--;
                break;
            }
        }
        if (ok)
        {
            k = i;
            break;
        }
    }
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            if (a[k][i] == b[j][0])
            {
                for (int l = 0;l < n; ++l)
                {
                    ans[l][i] = b[j][l];
                }
            }
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            cout << ans[i][j] << ' ';
        }
        cout << endl;
    }
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    srand(100);
    cout << fixed << setprecision(10);
    int t = 1;
    #ifdef LOCAL
        freopen("task.in", "r", stdin);
    #endif
    cin >> t;
    while (t--)
    {
        solve();
        cout << endl;
    }
}
//i hate feminism


#include <bits/stdc++.h>
#define union Union
#define rank rank228
#define tm tm228
#define hash hash228
#define matr vector < vector < int > >
#define int long long
#define pii pair < int, int >
#define papa pair < node*, node* >
#define all(v) v.begin(), v.end()
#define endl "\n"
#define pb push_back
#define PI 3.14159265358979323846
#define ff first
#define ss second

using namespace std;

const int inf = 1e9 + 7, maxn = 1e3 + 100;

int a[maxn][maxn], b[maxn][maxn], ans[maxn][maxn];

void solve(){
    int n, m, k = 0;
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
            cin >> a[i][j];
    }
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            cin >> b[i][j];
        }
    }
    vector < int > cntb(n * m + 1, 0);
    for (int j = 0; j < m; ++j)
    {
        cntb[b[j][0]]++;
    }
    for (int i = 0; i < n; ++i)
    {
        vector < int > cnta(n * m + 1, 0);
        for (int j = 0; j < m; ++j)
        {
            cnta[a[i][j]]++;
        }
        bool ok = true;
        for (int j = 1; j < n * m; ++j)
        {
            if (cnta[j] != cntb[j])
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            k = i;
            break;
        }
    }
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            if (a[k][i] == b[j][0])
            {
                for (int x = 0; x < n; ++x)
                {
                    ans[x][j] = b[j][x];
                }
                break;
            }
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
            cout << ans[i][j] << ' ';
        cout << endl;
    }
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    srand(100);
    cout << fixed << setprecision(10);
    int t = 1;
    #ifdef LOCAL
        freopen("task.in", "r", stdin);
    #endif
    cin >> t;
    while (t--)
    {
        solve();
        cout << endl;
    }
}
//i hate feminism


#include <bits/stdc++.h>
#define union Union
#define rank rank228
#define tm tm228
#define hash hash228
#define matr vector < vector < int > >
#define int long long
#define pii pair < int, int >
#define papa pair < node*, node* >
#define all(v) v.begin(), v.end()
#define endl "\n"
#define pb push_back
#define PI 3.14159265358979323846
#define ff first
#define ss second

using namespace std;

const int inf = 1e9 + 7, maxn = 1e3 + 100;

int a[maxn][maxn], b[maxn][maxn], ans[maxn][maxn];

void solve(){
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
            cin >> a[i][j];
    }
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            cin >> b[i][j];
        }
    }
    vector < int > cntb(n * m + 1, 0);
    for (int j = 0; j < m; ++j)
    {
        cntb[b[j][0]]++;
    }
    for (int i = 0; i < n; ++i)
    {
        vector < int > cnta(n * m + 1, 0);
        for (int j = 0; j < m; ++j)
        {
            cnta[a[i][j]]++;
        }
        bool ok = true;
        for (int j = 1; j < n * m; ++j)
        {
            if (cnta[j] != cntb[j])
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            vector < int > used(m, 0);
            for (int j = 0; j < m; ++j)
            {
                if (b[j][0] == a[i][j])
                {
                    used[j] = 1;
                    for (int k = 0; k < n; ++k)
                    {
                        ans[k][j] = b[j][k];
                    }
                }
            }
            for (int i = 0; i < n; ++i)
            {
                for (int j = 0; j < m; ++j)
                    cout << ans[i][j] <<' ';
                cout << endl;
            }
            return;
        }
    }
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    srand(100);
    cout << fixed << setprecision(10);
    int t = 1;
    #ifdef LOCAL
        freopen("task.in", "r", stdin);
    #endif
    cin >> t;
    while (t--)
    {
        solve();
        cout << endl;
    }
}
//i hate feminism


#include<bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
  #include "Mohit.h"
#endif

typedef long long ll;
typedef long double ld;
#define endl '\n'
#define rep(i,n)  for(ll i = 0; i < (n); ++i)
#define repA(i, a, n)  for(ll i = a; i <= (n); ++i)
#define repD(i, a, n)  for(ll i = a; i >= (n); --i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define pb push_back
typedef vector<ll> vll;
typedef vector<pair<ll,ll>> vpl;
const ld PI = 4*atan((ld)1);
const ll INF = 1e18;
const ll mod = 1e9+7;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll tt=1;
        cin >> tt;
    repA(qq,1,tt){
        ll n,m; cin >> n>> m;
        vector<vll>a(n,vll(m));
        map<ll,vll> mp;
        rep(i,n){
            rep(j,m) cin >> a[i][j];
        }

        vll wanted;
        rep(i,m){
            vll temp;
            ll first = -1;
            rep(j,n) {
                ll x; cin >> x;
                if(!j){
                    first =x ;
                    wanted.pb(x);
                }
                temp.pb(x);
            }
            mp[first]=(temp);
        }
        ll sb = *min_element(all(wanted));

        rep(i,n){
            ll sa=*min_element(all(a[i]));
            vll ans;
            if(sa==sb){
                trav(x,wanted){
                    trav(y,mp[x]){
                        ans.pb(y);
                    }
                }

                ll i=0,j=0;
                ll nn = ans.size();
                // trav(x,ans){
                //     cout << x << " ";
                // }
                // cout << endl;

                rep(i,n){
                    ll j = i;
                    while(j<nn){
                        cout << ans[j] <<  " ";
                        j+=n;
                    }
                    cout << endl;
                }
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
  #include "Mohit.h"
#endif

typedef long long ll;
typedef long double ld;
#define endl '\n'
#define rep(i,n)  for(ll i = 0; i < (n); ++i)
#define repA(i, a, n)  for(ll i = a; i <= (n); ++i)
#define repD(i, a, n)  for(ll i = a; i >= (n); --i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define pb push_back
typedef vector<ll> vll;
typedef vector<pair<ll,ll>> vpl;
const ld PI = 4*atan((ld)1);
const ll INF = 1e18;
const ll mod = 1e9+7;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll tt=1;
        cin >> tt;
    repA(qq,1,tt){
        ll n,m; cin >> n>> m;
        vector<vll>a(n,vll(m));
        map<ll,vll> mp;
        ll sb=0;
        rep(i,n){
            rep(j,m) cin >> a[i][j];
        }

        vll wanted;
        rep(i,m){
            vll temp;
            ll first = -1;
            rep(j,n) {
                ll x; cin >> x;
                if(!j){
                    first =x ;
                    wanted.pb(x);
                    sb+=x;
                }
                temp.pb(x);
            }
            mp[first]=(temp);
        }

        rep(i,n){
            ll sa=0;
            trav(x,a[i]){
                sa +=x;
            }
            vll ans;
            if(sa==sb){
                trav(x,wanted){
                    trav(y,mp[x]){
                        ans.pb(y);
                    }
                }

                ll i=0,j=0;
                ll nn = ans.size();
                // trav(x,ans){
                //     cout << x << " ";
                // }
                // cout << endl;

                rep(i,n){
                    ll j = i;
                    while(j<nn){
                        cout << ans[j] <<  " ";
                        j+=n;
                    }
                    cout << endl;
                }
                cout << endl;
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
  #include "Mohit.h"
#endif

typedef long long ll;
typedef long double ld;
#define endl '\n'
#define rep(i,n)  for(ll i = 0; i < (n); ++i)
#define repA(i, a, n)  for(ll i = a; i <= (n); ++i)
#define repD(i, a, n)  for(ll i = a; i >= (n); --i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define pb push_back
typedef vector<ll> vll;
typedef vector<pair<ll,ll>> vpl;
const ld PI = 4*atan((ld)1);
const ll INF = 1e18;
const ll mod = 1e9+7;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll tt=1;
        cin >> tt;
    repA(qq,1,tt){
        ll n,m; cin >> n>> m;
        vector<vll>a(n,vll(m));
        vector<vll>b(m,vll(n));
        map<ll,vll> mp;
        ll sb=0;
        rep(i,n){
            rep(j,m) cin >> a[i][j];
        }
        vll wanted;
        rep(i,m){
            vll temp;
            rep(j,n) {
                cin >> b[i][j];
                if(!j){
                    wanted.pb(b[i][j]);
                    sb+=b[i][j];
                }
                temp.pb(b[i][j]);
            }
            mp[b[i][0]]=(temp);
        }

        rep(i,n){
            ll sa=0;
            trav(x,a[i]){
                sa +=x;
            }
            // cout << sa <<" " << sb << endl;
            vll ans;
            if(sa==sb){
                ll i=0,j=0;
                trav(x,wanted){
                    j=0;
                    trav(y,mp[x]){
                        ans.pb(y);
                        // cout << y << " ";
                    }
                    i++;
                    // cout << endl;
                }

                i=0,j=0;
                ll nn = ans.size();
                while(j<n){
                    i=j;
                    while(i<nn){
                        cout << ans[i] <<" ";
                        i+=n;
                    }
                    j++;
                    cout << endl;
                }
                break;
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
  #include "Mohit.h"
#endif

typedef long long ll;
typedef long double ld;
#define endl '\n'
#define rep(i,n)  for(ll i = 0; i < (n); ++i)
#define repA(i, a, n)  for(ll i = a; i <= (n); ++i)
#define repD(i, a, n)  for(ll i = a; i >= (n); --i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define pb push_back
typedef vector<ll> vll;
typedef vector<pair<ll,ll>> vpl;
const ld PI = 4*atan((ld)1);
const ll INF = 1e18;
const ll mod = 1e9+7;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll tt=1;
        cin >> tt;
    repA(qq,1,tt){
        ll n,m; cin >> n>> m;
        vector<vll>a(n,vll(m));
        map<ll,vll> mp;
        ll sb=0;
        rep(i,n){
            rep(j,m) cin >> a[i][j];
        }
        vll wanted;
        rep(i,m){
            vll temp;
            ll first = -1;
            rep(j,n) {
                ll x; cin >> x;
                if(!j){
                    first =x ;
                    wanted.pb(x);
                    sb+=x;
                }
                temp.pb(x);
            }
            mp[first]=(temp);
        }

        rep(i,n){
            ll sa=0;
            trav(x,a[i]){
                sa +=x;
            }
            // cout << sa <<" " << sb << endl;
            vll ans;
            if(sa==sb){
                ll i=0,j=0;
                trav(x,wanted){
                    j=0;
                    trav(y,mp[x]){
                        ans.pb(y);
                        // cout << y << " ";
                    }
                    i++;
                    // cout << endl;
                }

                i=0,j=0;
                ll nn = ans.size();
                while(j<n){
                    i=j;
                    while(i<nn){
                        cout << ans[i] <<" ";
                        i+=n;
                    }
                    j++;
                    cout << endl;
                }
                break;
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
  #include "Mohit.h"
#endif

typedef long long ll;
typedef long double ld;
#define endl '\n'
#define rep(i,n)  for(ll i = 0; i < (n); ++i)
#define repA(i, a, n)  for(ll i = a; i <= (n); ++i)
#define repD(i, a, n)  for(ll i = a; i >= (n); --i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define pb push_back
typedef vector<ll> vll;
typedef vector<pair<ll,ll>> vpl;
const ld PI = 4*atan((ld)1);
const ll INF = 1e18;
const ll mod = 1e9+7;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll tt=1;
        cin >> tt;
    repA(qq,1,tt){
        ll n,m; cin >> n>> m;
        vector<vll>a(n,vll(m));
        vector<vll>b(m,vll(n));
        map<ll,vll> mp;

        vll wanted;
        rep(i,n){
            rep(j,m){
                cin >> a[i][j];
                if(!j)wanted.pb(a[i][j]);
            }
            mp[a[i][0]] = a[i];
        }

        rep(i,m){
            rep(j,n){
                cin >> b[i][j];
            }
        }

        ll row = -1;
        rep(i,m){
            rep(j,n){
                if(b[i][j]==wanted[0]){
                    row = i;
                    break;
                }
            }
        }
        vll temp = b[row];
        // trav(x,temp)cout << x << " ";
        // cout << endl;
        trav(x,temp){
            trav(y,mp[x]){
                cout << y << " ";
            }
            cout << endl;
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
  #include "Mohit.h"
#endif

typedef long long ll;
typedef long double ld;
#define endl '\n'
#define rep(i,n)  for(ll i = 0; i < (n); ++i)
#define repA(i, a, n)  for(ll i = a; i <= (n); ++i)
#define repD(i, a, n)  for(ll i = a; i >= (n); --i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define pb push_back
typedef vector<ll> vll;
typedef vector<pair<ll,ll>> vpl;
const ld PI = 4*atan((ld)1);
const ll INF = 1e18;
const ll mod = 1e9+7;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll tt=1;
        cin >> tt;
    repA(qq,1,tt){
        ll n,m; cin >> n>> m;
        vector<vll>a(n,vll(m));
        map<ll,vll> mp;
        rep(i,n){
            rep(j,m) cin >> a[i][j];
        }

        vll wanted;
        rep(i,m){
            vll temp;
            ll first = -1;
            rep(j,n) {
                ll x; cin >> x;
                if(!j){
                    first =x ;
                    wanted.pb(x);
                }
                temp.pb(x);
            }
            mp[first]=(temp);
        }
        ll sb = *min_element(all(wanted));

        rep(i,n){
            ll sa=*min_element(all(a[i]));
            ll mx = max(m,n);
            vector<vll> ans(mx,vll(mx,-1));
            if(sa==sb){
                ll i=0;
                trav(x,wanted){
                    ll j=0;
                    trav(y,mp[x]){
                        ans[i][j++] = y;
                    }
                    i++;
                }

                rep(i,mx){
                    if(ans[0][i]==-1)break;
                    rep(j,mx){
                        if(ans[j][i]==-1)break;
                        cout << ans[j][i] <<" ";
                    }
                    cout << endl;
                }
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
  #include "Mohit.h"
#endif

typedef long long ll;
typedef long double ld;
#define endl '\n'
#define rep(i,n)  for(ll i = 0; i < (n); ++i)
#define repA(i, a, n)  for(ll i = a; i <= (n); ++i)
#define repD(i, a, n)  for(ll i = a; i >= (n); --i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define pb push_back
typedef vector<ll> vll;
typedef vector<pair<ll,ll>> vpl;
const ld PI = 4*atan((ld)1);
const ll INF = 1e18;
const ll mod = 1e9+7;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll tt=1;
        cin >> tt;
    repA(qq,1,tt){
        ll n,m; cin >> n>> m;
        vector<vll>a(n,vll(m));
        map<ll,vll> mp;
        ll sb=0;
        rep(i,n){
            rep(j,m) cin >> a[i][j];
        }

        vll wanted;
        rep(i,m){
            vll temp;
            ll first = -1;
            rep(j,n) {
                ll x; cin >> x;
                if(!j){
                    first =x ;
                    wanted.pb(x);
                    sb+=x;
                }
                temp.pb(x);
            }
            mp[first]=(temp);
        }

        rep(i,n){
            ll sa=0;
            trav(x,a[i]){
                sa +=x;
            }
            vll ans;
            if(sa==sb){
                trav(x,wanted){
                    trav(y,mp[x]){
                        ans.pb(y);
                    }
                }

                ll i=0,j=0;
                ll nn = ans.size();
                // trav(x,ans){
                //     cout << x << " ";
                // }
                // cout << endl;

                rep(i,n){
                    ll j = i;
                    while(j<nn){
                        cout << ans[j] <<  " ";
                        j+=n;
                    }
                    cout << endl;
                }
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
  #include "Mohit.h"
#endif

typedef long long ll;
typedef long double ld;
#define endl '\n'
#define rep(i,n)  for(ll i = 0; i < (n); ++i)
#define repA(i, a, n)  for(ll i = a; i <= (n); ++i)
#define repD(i, a, n)  for(ll i = a; i >= (n); --i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define pb push_back
typedef vector<ll> vll;
typedef vector<pair<ll,ll>> vpl;
const ld PI = 4*atan((ld)1);
const ll INF = 1e18;
const ll mod = 1e9+7;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll tt=1;
        cin >> tt;
    repA(qq,1,tt){
        ll n,m; cin >> n>> m;
        vector<vll>a(n,vll(m));
        vector<vll>b(m,vll(n));
        map<ll,vll> mp;
        ll sb=0;
        rep(i,n){
            rep(j,m) cin >> a[i][j];
        }
        vll wanted;
        rep(i,m){
            vll temp;
            rep(j,n) {
                cin >> b[i][j];
                if(!j){
                    wanted.pb(b[i][j]);
                    sb+=b[i][j];
                }
                temp.pb(b[i][j]);
            }
            mp[b[i][0]]=(temp);
        }

        rep(i,n){
            ll sa=0;
            trav(x,a[i]){
                sa +=x;
            }
            // cout << sa <<" " << sb << endl;
            vll ans;
            if(sa==sb){
                ll i=0,j=0;
                trav(x,wanted){
                    j=0;
                    trav(y,mp[x]){
                        ans.pb(y);
                        // cout << y << " ";
                    }
                    i++;
                    // cout << endl;
                }

                i=0,j=0;
                ll nn = ans.size();
                while(j<n){
                    i=j;
                    while(i<nn){
                        cout << ans[i] <<" ";
                        i+=n;
                    }
                    j++;
                    cout << endl;
                }
            }
        }
    }
}


#include<bits/stdc++.h>
#define ll long long int
using namespace std;
int main(){
	int t=1;
	cin>>t;
	while(t--){
		int a,b,c=0;cin>>a>>b;
		int ar[a][b],br[b][a];
		for(int i=0;i<a;i++){
            for(int j=0;j<b;j++){
                cin>>ar[i][j];
            }
		}
		for(int i=0;i<b;i++){
            for(int j=0;j<a;j++){
                cin>>br[i][j];
            }
		}
		for(int i=0;i<a;i++){
            for(int j=0;j<a;j++){
                if(br[0][i]==ar[j][0]){
                    for(int k=0;k<b;k++){
                        cout<<ar[j][k]<<" ";
                    }
                    break;
                }
            }
		cout<<endl;
		}
	}
}


#include<bits/stdc++.h>
#define ll long long int
using namespace std;
int main(){
	int t=1;
	cin>>t;
	while(t--){
		int a,b,c=0;cin>>a>>b;
		int ar[a][b],br[b][a];
		for(int i=0;i<a;i++){
            for(int j=0;j<b;j++){
                cin>>ar[i][j];
            }
		}
		for(int i=0;i<b;i++){
            for(int j=0;j<a;j++){
                cin>>br[i][j];
            }
		}
		int x=0;
		for(int i=0;i<a;i++){
            for(int j=0;j<b;j++){
                if(br[0][0]==ar[i][j]){
                    x=j;
                    break;
                }
            }
            if(x)break;
		}

		for(int i=0;i<a;i++){
            for(int j=0;j<a;j++){
                if(br[0][i]==ar[j][x]){
                    for(int k=0;k<b;k++){
                        cout<<ar[j][k]<<" ";
                    }
                    break;
                }
            }
		cout<<endl;
		}
	}
}


#include<bits/stdc++.h>
#define ll long long int
using namespace std;
int main(){
	int t=1;
	cin>>t;
	while(t--){
		int a,b,c=0;cin>>a>>b;
		int ar[a][b],br[b][a];
		for(int i=0;i<a;i++){
            for(int j=0;j<b;j++){
                cin>>ar[i][j];
            }
		}
		for(int i=0;i<b;i++){
            for(int j=0;j<a;j++){
                cin>>br[i][j];
            }
		}
		int x=0;
		for(int i=0;i<a;i++){
            for(int j=0;j<b;j++){
                if(br[0][0]==ar[i][j]){
                    x=j;
                    break;
                }
            }
            if(x)break;
		}
		for(int i=0;i<a;i++){
            for(int j=0;j<a;j++){
                if(br[x][i]==ar[j][x]){
                    for(int k=0;k<b;k++){
                        cout<<ar[j][k]<<" ";
                    }
                    break;
                }
            }
		cout<<endl;
		}
	}
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

int num[1000000];
void solve(){
    int n,i,j,k,ii,jj,m,nn;
    int stolb[1000][1000],matr[1000][1000],stroka[1000][1000];

    cin >> n >> m;
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cin >> stroka[i][j];
        }
        num[stroka[i][0]]=i;
        //cout << stroka[i][0] << ' ' << i << endl;
    }
    for (j=0;j<m;j++){
        for (i=0;i<n;i++){
            cin >> stolb[j][i];
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            if (stroka[i][0]==stolb[j][0]){
                ii=i;
                jj=j;
            }
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            matr[i][j]=stroka[num[stolb[jj][i]]][j];
            cout << matr[i][j] << ' ';
        }
        cout << endl;
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

void solve(){
    int n,i,j,k,ii,jj,m,nn;
    int stolb[1000][1000],matr[1000][1000],stroka[1000][1000];
    int num[100000]
    cin >> n >> m;
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cin >> stroka[i][j];
        }
        num[stroka[i][0]]=i;
    }
    for (j=0;j<m;j++){
        for (i=0;i<n;i++){
            cin >> stolb[j][i];
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            if (stroka[i][0]==stolb[j][0]){
                ii=i;
                jj=j;
                break;
            }
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cout << stroka[num[stolb[jj][i]]][j] << ' ';
        }
        cout << endl;
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}


#include <bits/stdc++.h>
#define int long
using namespace std;

void solve(){
    int n,i,j,k,ii,jj,m,nn;
    int stolb[600][600],stroka[600][600];
    int num[260000];
    cin >> n >> m;
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cin >> stroka[i][j];
        }
        num[stroka[i][0]]=i;
    }
    for (j=0;j<m;j++){
        cin >> stolb[j][0];
        if (stroka[0][0]==stolb[j][0]){
            ii=0;
            jj=j;
        }
        for (i=1;i<n;i++){
            cin >> stolb[j][i];
            if (stroka[i][0]==stolb[j][0]){
                ii=i;
                jj=j;
            }
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cout << stroka[num[stolb[jj][i]]][j] << ' ';
        }
        cout << "\n";
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

void solve(){
    int n,i,j,k,ii,jj,m;
    int stroka[1000][1000],stolb[1000][1000],matr[1000][1000];
    cin >> n >> m;
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cin >> stroka[i][j];
        }
    }
    for (j=0;j<m;j++){
        for (i=0;i<n;i++){
            cin >> stolb[j][i];
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            if (stroka[i][0]==stolb[j][0]){
                ii=i;
                jj=j;
                break;
            }
        }
    }
    for (i=0;i<n;i++){
        matr[i][0]=stolb[jj][i];
        for (j=0;j<n;j++)if (stroka[j][0]==matr[i][0]){
            for (k=0;k<m;k++)matr[i][k]=stroka[j][k];
            break;
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++)cout << matr[i][j] << ' ';
        cout << endl;
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

void solve(){
    int n,i,j,k,ii,jj,m,nn;
    int stolb[1000][1000],matr[1000][1000],stroka[1000][1000];
    int num[100000];
    cin >> n >> m;
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cin >> stroka[i][j];
        }
        num[stroka[i][0]]=i;
    }
    for (j=0;j<m;j++){
        for (i=0;i<n;i++){
            cin >> stolb[j][i];
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            if (stroka[i][0]==stolb[j][0]){
                ii=i;
                jj=j;
                break;
            }
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cout << stroka[num[stolb[jj][i]]][j] << ' ';
        }
        cout << endl;
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

int num[1000000];

bool f(vector<int>& a1, vector<int>& a2){
    return num[a1[0]]<num[a2[0]];
}

void solve(){
    int n,i,j,k,ii,jj,m,nn;
    int stolb[1000][1000],matr[1000][1000];

    cin >> n >> m;
    vector<vector<int>>stroka(n);
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            cin >> nn;
            stroka[i].push_back(nn);
        }
    }
    for (j=0;j<m;j++){
        for (i=0;i<n;i++){
            cin >> stolb[j][i];
        }
    }
    if (n==1){
        for (i=0;i<m;i++)cout << stroka[0][i] << ' ';
        cout << endl;
        return;
    }
    if (m==1){
        for (i=0;i<n;i++)cout << stolb[0][i] << endl;
        return;
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            if (stroka[i][0]==stolb[j][0]){
                ii=i;
                jj=j;
                break;
            }
        }
    }
    for (j=0;j<m;j++){
        num[stolb[jj][j]]=j;
    }

    sort(stroka.begin(),stroka.end(),f);
    for (i=0;i<n;i++){
        for (j=0;j<m;j++)cout << stroka[i][j] << ' ';
        cout << endl;
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector <ll> vec;
typedef vector <ld> vecd;
typedef vector <vector <ll>> matrix;

const ld PI = 3.141592653589793;
const ld eps = 1e-9;
const ll INF = 1e18;

#define pb push_back
#define all(v) v.begin(), v.end()
#define fast_io ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)

ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}

ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}

ll fpow(ll x, ll n) {
	ll ans = 1;
	while (n) {
		if (n & 1)
			ans *= x;
		x *= x;
		n >>= 1;
	}
	return ans;
}

ll fact(ll x) {
	ll res = 1;
	for (int i = 1; i <= x; ++i) {
		res *= i;
	}
	return res;
}

int main() {
	fast_io;
	ll t;
	cin >> t;
	for (int q = 0; q < t; ++q) {
		ll n, m;
		matrix k, r, ans;
		vec f;
		cin >> n >> m;
		k.resize(n);
		r.resize(m);
		for (int i = 0; i < n; ++i) {
			k[i].resize(m);
			for (int j = 0; j < m; ++j) {
				cin >> k[i][j];
			}
		}
		for (int i = 0; i < m; ++i) {
			r[i].resize(n);
			for (int j = 0; j < n; ++j) {
				cin >> r[i][j];
			}
		}
		if (n == 1) {
			for (int i = 0; i < n; ++i) {
				for (int j = 0; j < m; ++j) {
					cout << k[i][j] << ' ';
				}
				cout << "\n";
			}
			continue;
		}
		if (m == 1) {
			for (int i = 0; i < n; ++i) {
				for (int j = 0; j < m; ++j) {
					cout << r[j][i] << ' ';
				}
				cout << "\n";
			}
			continue;
		}
		for (int i = 0; i < m; ++i) {
			bool flag = 0;
			for (int j = 0; j < m; ++j) {
				if (r[i][0] == k[j][0]) {
					f = r[i];
					flag = 1;
					break;
				}
			}
			if (flag) {
				break;
			}
		}
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < n; ++j) {
				if (f[i] == k[j][0]) {
					ans.pb(k[j]);
				}
			}
		}
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				cout << ans[i][j] << ' ';
			}
			cout << "\n";
		}
	}
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector <ll> vec;
typedef vector <ld> vecd;
typedef vector <vector <ll>> matrix;

const ld PI = 3.141592653589793;
const ld eps = 1e-9;
const ll INF = 1e18;

#define pb push_back
#define all(v) v.begin(), v.end()
#define fast_io ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)

ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}

ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}

ll fpow(ll x, ll n) {
	ll ans = 1;
	while (n) {
		if (n & 1)
			ans *= x;
		x *= x;
		n >>= 1;
	}
	return ans;
}

ll fact(ll x) {
	ll res = 1;
	for (int i = 1; i <= x; ++i) {
		res *= i;
	}
	return res;
}

int main() {
	fast_io;
	ll t;
	cin >> t;
	for (int q = 0; q < t; ++q) {
		ll n, m;
		matrix k, r, ans;
		cin >> n >> m;
		k.resize(n);
		r.resize(m);
		for (int i = 0; i < n; ++i) {
			k[i].resize(m);
			for (int j = 0; j < m; ++j) {
				cin >> k[i][j];
			}
		}
		for (int i = 0; i < m; ++i) {
			r[i].resize(n);
			for (int j = 0; j < n; ++j) {
				cin >> r[i][j];
			}
		}
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < n; ++j) {
				if (r[0][i] == k[j][0]) {
					ans.pb(k[j]);
				}
			}
		}
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				cout << ans[i][j] << ' ';
			}
			cout << "\n";
		}
	}
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector <ll> vec;
typedef vector <ld> vecd;
typedef vector <vector <ll>> matrix;

const ld PI = 3.141592653589793;
const ld eps = 1e-9;
const ll INF = 1e18;

#define pb push_back
#define all(v) v.begin(), v.end()
#define fast_io ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)

ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}

ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}

ll fpow(ll x, ll n) {
	ll ans = 1;
	while (n) {
		if (n & 1)
			ans *= x;
		x *= x;
		n >>= 1;
	}
	return ans;
}

ll fact(ll x) {
	ll res = 1;
	for (int i = 1; i <= x; ++i) {
		res *= i;
	}
	return res;
}

int main() {
	fast_io;
	ll t;
	cin >> t;
	for (int q = 0; q < t; ++q) {
		ll n, m;
		matrix k, r, ans;
		vec f;
		cin >> n >> m;
		k.resize(n);
		r.resize(m);
		for (int i = 0; i < n; ++i) {
			k[i].resize(m);
			for (int j = 0; j < m; ++j) {
				cin >> k[i][j];
			}
		}
		for (int i = 0; i < m; ++i) {
			r[i].resize(n);
			for (int j = 0; j < n; ++j) {
				cin >> r[i][j];
			}
		}
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				cout << r[j][i] << ' ';
			}
			cout << "\n";
		}
	}
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector <ll> vec;
typedef vector <ld> vecd;
typedef vector <vector <ll>> matrix;

const ld PI = 3.141592653589793;
const ld eps = 1e-9;
const ll INF = 1e18;

#define pb push_back
#define all(v) v.begin(), v.end()
#define fast_io ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)

ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}

ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}

ll fpow(ll x, ll n) {
	ll ans = 1;
	while (n) {
		if (n & 1)
			ans *= x;
		x *= x;
		n >>= 1;
	}
	return ans;
}

ll fact(ll x) {
	ll res = 1;
	for (int i = 1; i <= x; ++i) {
		res *= i;
	}
	return res;
}

int main() {
	fast_io;
	ll t;
	cin >> t;
	for (int q = 0; q < t; ++q) {
		ll n, m;
		matrix k, r, ans;
		vec f;
		cin >> n >> m;
		k.resize(n);
		r.resize(m);
		for (int i = 0; i < n; ++i) {
			k[i].resize(m);
			for (int j = 0; j < m; ++j) {
				cin >> k[i][j];
			}
		}
		for (int i = 0; i < m; ++i) {
			r[i].resize(n);
			for (int j = 0; j < n; ++j) {
				cin >> r[i][j];
			}
		}
		for (int i = 0; i < n; ++i) {
			bool flag = 0;
			for (int j = 0; j < m; ++j) {
				if (r[j][0] == k[i][0]) {
					f = r[j];
					flag = 1;
					break;
				}
			}
			if (flag) {
				break;
			}
		}
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < n; ++j) {
				if (f[i] == k[j][0]) {
					ans.pb(k[j]);
				}
			}
		}
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				cout << ans[i][j] << ' ';
			}
			cout << "\n";
		}
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

//#define int long long

struct Edge
{
    int to;
    bool is_hor;

    Edge(int to, bool is_hor) : to(to), is_hor(is_hor) {}
};

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int t;
    cin >> t;
    for (; t > 0; --t)
    {
        int n, m;
        cin >> n >> m;
        vector<Edge>* graph = new vector<Edge>[n * m + 1];
        for (int i = 0; i < n; ++i)
        {
            int from = -1;
            for (int j = 0; j < m; ++j)
            {
                int to;
                cin >> to;
                if (from != -1)
                {
                    graph[from].push_back(Edge(to, true));
                }
                from = to;
            }
        }
        for (int i = 0; i < m; ++i)
        {
            int from = -1;
            for (int j = 0; j < n; ++j)
            {
                int to;
                cin >> to;
                if (from != -1)
                {
                    graph[from].push_back(Edge(to, false));
                }
                from = to;
            }
        }
        vector<char> has_edge(n * m + 1);
        for (int i = 1; i <= n * m; ++i)
        {
            for (Edge e : graph[i])
            {
                has_edge[e.to] = 1;
            }
        }
        int start = -1;
        for (int i = 1; i <= n * m; ++i)
        {
            if (!has_edge[i])
            {
                start = i;
                break;
            }
        }
        vector< vector<int> > matrix(m, vector<int>(n));
        queue< pair<int, pair<int, int> > > q;
        q.push({ start, {0, 0} });
        while (!q.empty())
        {
            int cur_elem = q.front().first;
            pair<int, int> cur_pos = q.front().second;
            q.pop();
            matrix[cur_pos.first][cur_pos.second] = cur_elem;
            for (Edge e : graph[cur_elem])
            {
                if (e.is_hor)
                {
                    q.push({ e.to, {cur_pos.first + 1, cur_pos.second} });
                }
                else
                {
                    q.push({ e.to, {cur_pos.first, cur_pos.second + 1} });
                }
            }
        }
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                cout << matrix[j][i] << ' ';
            }
            cout << '\n';
        }
    }

}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

//#define int long long

struct Edge
{
    int to;
    bool is_hor;

    Edge(int to, bool is_hor) : to(to), is_hor(is_hor) {}
};

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int t;
    cin >> t;
    vector<Edge>* graph = new vector<Edge>[250001];
    vector<char> has_edge(250001);
    for (; t > 0; --t)
    {
        int n, m;
        cin >> n >> m;
        for (int i = 1; i <= n * m; ++i)
        {
            graph[i].clear();
            graph[i].reserve(2);
            has_edge[i] = 0;
        }
        for (int i = 0; i < n; ++i)
        {
            int from = -1;
            for (int j = 0; j < m; ++j)
            {
                int to;
                cin >> to;
                if (from != -1)
                {
                    graph[from].push_back(Edge(to, true));
                    has_edge[to] = 1;
                }
                from = to;
            }
        }
        for (int i = 0; i < m; ++i)
        {
            int from = -1;
            for (int j = 0; j < n; ++j)
            {
                int to;
                cin >> to;
                if (from != -1)
                {
                    graph[from].push_back(Edge(to, false));
                    has_edge[to] = 1;
                }
                from = to;
            }
        }
        int start = -1;
        for (int i = 1; i <= n * m; ++i)
        {
            if (!has_edge[i])
            {
                start = i;
                break;
            }
        }
        vector< vector<int> > matrix(m, vector<int>(n));
        queue< pair<int, pair<int, int> > > q;
        has_edge.assign(n * m + 1, 0);
        q.push({ start, {0, 0} });
        while (!q.empty())
        {
            int cur_elem = q.front().first;
            pair<int, int> cur_pos = q.front().second;
            q.pop();
            matrix[cur_pos.first][cur_pos.second] = cur_elem;
            for (Edge e : graph[cur_elem])
            {
                if (!has_edge[e.to])
                {
                    if (e.is_hor)
                    {
                        q.push({ e.to, {cur_pos.first + 1, cur_pos.second} });
                        has_edge[e.to] = 1;
                    }
                    else
                    {
                        q.push({ e.to, {cur_pos.first, cur_pos.second + 1} });
                        has_edge[e.to] = 1;
                    }
                }
            }
        }
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                cout << matrix[j][i] << ' ';
            }
            cout << '\n';
        }
    }

}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

//#define int long long

struct Edge
{
    int to;
    bool is_hor;

    Edge(int to, bool is_hor) : to(to), is_hor(is_hor) {}
};

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int t;
    cin >> t;
    vector<Edge>* graph = new vector<Edge>[250001];
    vector<char> has_edge(250001);
    for (; t > 0; --t)
    {
        int n, m;
        cin >> n >> m;
        for (int i = 1; i <= n * m; ++i)
        {
            graph[i].clear();
            graph[i].reserve(2);
            has_edge[i] = 0;
        }
        for (int i = 0; i < n; ++i)
        {
            int from = -1;
            for (int j = 0; j < m; ++j)
            {
                int to;
                cin >> to;
                if (from != -1)
                {
                    graph[from].push_back(Edge(to, true));
                    has_edge[to] = 1;
                }
                from = to;
            }
        }
        for (int i = 0; i < m; ++i)
        {
            int from = -1;
            for (int j = 0; j < n; ++j)
            {
                int to;
                cin >> to;
                if (from != -1)
                {
                    graph[from].push_back(Edge(to, false));
                    has_edge[to] = 1;
                }
                from = to;
            }
        }
        int start = -1;
        for (int i = 1; i <= n * m; ++i)
        {
            if (!has_edge[i])
            {
                start = i;
                break;
            }
        }
        vector< vector<int> > matrix(m, vector<int>(n));
        queue< pair<int, pair<int, int> > > q;
        q.push({ start, {0, 0} });
        while (!q.empty())
        {
            int cur_elem = q.front().first;
            pair<int, int> cur_pos = q.front().second;
            q.pop();
            matrix[cur_pos.first][cur_pos.second] = cur_elem;
            for (Edge e : graph[cur_elem])
            {
                if (e.is_hor)
                {
                    q.push({ e.to, {cur_pos.first + 1, cur_pos.second} });
                }
                else
                {
                    q.push({ e.to, {cur_pos.first, cur_pos.second + 1} });
                }
            }
        }
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                cout << matrix[j][i] << ' ';
            }
            cout << '\n';
        }
    }

}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

#define int long long

struct Edge
{
    int to;
    bool is_hor;

    Edge(int to, bool is_hor) : to(to), is_hor(is_hor) {}
};

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int t;
    cin >> t;
    for (; t > 0; --t)
    {
        int n, m;
        cin >> n >> m;
        vector<Edge>* graph = new vector<Edge>[n * m + 1];
        for (int i = 0; i < n; ++i)
        {
            int from = -1;
            for (int j = 0; j < m; ++j)
            {
                int to;
                cin >> to;
                if (from != -1)
                {
                    graph[from].push_back(Edge(to, true));
                }
                from = to;
            }
        }
        for (int i = 0; i < m; ++i)
        {
            int from = -1;
            for (int j = 0; j < n; ++j)
            {
                int to;
                cin >> to;
                if (from != -1)
                {
                    graph[from].push_back(Edge(to, false));
                }
                from = to;
            }
        }
        vector<char> has_edge(n * m + 1);
        for (int i = 1; i <= n * m; ++i)
        {
            for (Edge e : graph[i])
            {
                has_edge[e.to] = 1;
            }
        }
        int start = -1;
        for (int i = 1; i <= n * m; ++i)
        {
            if (!has_edge[i])
            {
                start = i;
                break;
            }
        }
        vector< vector<int> > matrix(m, vector<int>(n));
        queue< pair<int, pair<int, int> > > q;
        q.push({ start, {0, 0} });
        while (!q.empty())
        {
            int cur_elem = q.front().first;
            pair<int, int> cur_pos = q.front().second;
            q.pop();
            matrix[cur_pos.first][cur_pos.second] = cur_elem;
            for (Edge e : graph[cur_elem])
            {
                if (e.is_hor)
                {
                    q.push({ e.to, {cur_pos.first + 1, cur_pos.second} });
                }
                else
                {
                    q.push({ e.to, {cur_pos.first, cur_pos.second + 1} });
                }
            }
        }
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                cout << matrix[j][i] << ' ';
            }
            cout << '\n';
        }
    }

}


#include<bits/stdc++.h>
using namespace std;
int main(){
	long long t, n, m;
	cin >> t;
	while (t){
        cin >> n >> m;
        long long str[n][m], stlb[m][n];
        long long sortedStr[n][m];
        for (long long i = 0 ; i < n; i++){
            for (long long j = 0; j < m; j++){
                cin >> str[i][j];
                sortedStr[i][j] = str[i][j];
            }
        }
        for (long long i = 0 ; i < n; i++){
            sort(sortedStr[i], sortedStr[i] + m);
        }
//        for (long long i = 0 ; i < n; i++){
//            for (long long j = 0; j < m; j++){
//                cout << sortedStr[i][j] << " ";
//            }
//            cout << endl;
//        }
        long long firstStr[m];
        for (long long i = 0 ; i < m; i++){
            for (long long j = 0; j < n; j++){
                cin >> stlb[i][j];
                if (j == 0)
                    firstStr[i] = stlb[i][j];
            }
        }

        sort (firstStr, firstStr + m);
        long long flag = -1;

        for (long long i = 0 ; i< n; i++){
            for (long long j = 0 ; j < m; j++){
                if (sortedStr[i][j] != firstStr[j]){
                    flag = 99;
                    break;
                }
            }
            if (flag != 99){
                flag = i;
                break;
            }
            flag = -1;
        }

//        cout << "flag = " << flag << endl << endl;

        for (long long i = 0 ; i < m; i++){
            if (str[flag][i] != stlb[i][0]){
                long long searchInd = -1;
                for (long long j = i + 1; j < m; j++){
                    if (stlb[j][0] == str[flag][i]){
                        searchInd = j;
                        break;
                    }
                }
//                cout << "swap indexes: " << i << " " << searchInd << endl;
//                swap (stlb[i], stlb[searchInd]);
                for (int w = 0; w < n; w++){
                    swap (stlb[i][w], stlb[searchInd][w]);
                }
            }
        }

//        cout << endl;
        for (long long i = 0; i < n; i++){
            for (long long j = 0; j < m; j++){
                cout << stlb[j][i] << " ";
            }
            cout << endl;
        }

        t--;
	}
    return 0;
}
/*

2
2 3
6 5 4
1 2 3
1 6
2 5
3 4
*/
/*

1
5 3
13 14 15
7 8 9
1 2 3
4 5 6
10 11 12

2 5 8 11 14
1 4 7 10 13
3 6 9 12 15

*/


#include<bits/stdc++.h>
using namespace std;
int main(){
	long long t, n, m;
	cin >> t;
	while (t){
        cin >> n >> m;
        long long str[n][m], stlb[m][n];
        long long sortedStr[n][m];
        for (long long i = 0 ; i < n; i++){
            for (long long j = 0; j < m; j++){
                cin >> str[i][j];
                sortedStr[i][j] = str[i][j];
            }
        }
        for (long long i = 0 ; i < n; i++){
            sort(sortedStr[i], sortedStr[i] + m);
        }
//        for (long long i = 0 ; i < n; i++){
//            for (long long j = 0; j < m; j++){
//                cout << sortedStr[i][j] << " ";
//            }
//            cout << endl;
//        }
        long long firstStr[m];
        for (long long i = 0 ; i < m; i++){
            for (long long j = 0; j < n; j++){
                cin >> stlb[i][j];
                if (j == 0)
                    firstStr[i] = stlb[i][j];
            }
        }

        sort (firstStr, firstStr + m);
        long long flag = -1;

        for (long long i = 0 ; i< n; i++){
            for (long long j = 0 ; j < m; j++){
                if (sortedStr[i][j] != firstStr[j]){
                    flag = 99;
                    break;
                }
            }
            if (flag != 99){
                flag = i;
                break;
            }
            flag = -1;
        }

//        cout << flag;

        for (long long i = 0 ; i < m; i++){
            if (str[flag][i] != stlb[i][0]){
                long long searchInd = -1;
                for (long long j = i + 1; j < m; j++){
                    if (stlb[j][0] == str[flag][i]){
                        searchInd = j;
                        break;
                    }
                }
                //swap (stlb[i], stlb[searchInd]);
                long long *left = stlb[i];
                long long *right = stlb[searchInd];

                long long * swapp = left;
                left = right;
                right = swapp;
            }
        }

//        cout << endl;
        for (long long i = 0; i < n; i++){
            for (long long j = 0; j < m; j++){
                cout << stlb[j][i] << " ";
            }
            cout << endl;
        }

        t--;
	}
    return 0;
}
/*

2
2 3
6 5 4
1 2 3
1 6
2 5
3 4
*/


#include<bits/stdc++.h>
using namespace std;
int main(){
	int t, n, m;
	cin >> t;
	while (t){
        cin >> n >> m;
        int str[n][m], stlb[m][n];
        int sortedStr[n][m];
        for (int i = 0 ; i < n; i++){
            for (int j = 0; j < m; j++){
                cin >> str[i][j];
                sortedStr[i][j] = str[i][j];
            }
        }
        for (int i = 0 ; i < n; i++){
            sort(sortedStr[i], sortedStr[i] + m);
        }
//        for (int i = 0 ; i < n; i++){
//            for (int j = 0; j < m; j++){
//                cout << sortedStr[i][j] << " ";
//            }
//            cout << endl;
//        }
        int firstStr[m];
        for (int i = 0 ; i < m; i++){
            for (int j = 0; j < n; j++){
                cin >> stlb[i][j];
                if (j == 0)
                    firstStr[i] = stlb[i][j];
            }
        }

        sort (firstStr, firstStr + m);
        int flag = -1;

        for (int i = 0 ; i< n; i++){
            for (int j = 0 ; j < m; j++){
                if (sortedStr[i][j] != firstStr[j]){
                    flag = 99;
                    break;
                }
            }
            if (flag != 99){
                flag = i;
                break;
            }
            flag = -1;
        }

//        cout << flag;

        for (int i = 0 ; i < m; i++){
            if (str[flag][i] != stlb[i][0]){
                int searchInd = -1;
                for (int j = i + 1; j < m; j++){
                    if (stlb[j][0] == str[flag][i]){
                        searchInd = j;
                        break;
                    }
                }
                //swap (stlb[i], stlb[searchInd]);
                int *left = stlb[i];
                int *right = stlb[searchInd];

                int * swapp = left;
                left = right;
                right = swapp;
            }
        }

//        cout << endl;
        for (int i = 0; i < n; i++){
            for (int j = 0; j < m; j++){
                cout << stlb[j][i] << " ";
            }
            cout << endl;
        }

        t--;
	}
    return 0;
}
/*

2
2 3
6 5 4
1 2 3
1 6
2 5
3 4
*/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

typedef long long LL;

const int MAXN = 100005;
const LL MOD = 99990001;

struct NODE
{
	int col, id;
	int sum;
	NODE() {}
	NODE(int _col, int _id, int _sum):col(_col), id(_id), sum(_sum) {}
};

bool operator < (const NODE &a, const NODE &b)
{
	return a.sum > b.sum;
}

int pre[MAXN];
int val[MAXN];
int n, x, y;

priority_queue<NODE> q;
priority_queue<NODE> q0, q1;

void solved(int cas)
{
	scanf ("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf ("%d %d", &x, &y);
		q.push(NODE(x, i, y));
	}
	while (!q.empty())
	{
		NODE temp = q.top();
		q.pop();
		if (temp.col)
		{
			if (q0.empty())
				q1.push(temp);
			else
			{
				NODE t = q0.top();
				if (t.sum <= temp.sum)
				{
					q0.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q1.push(temp);
			}
		}
		else
		{
			if (q1.empty())
				q0.push(temp);
			else
			{
				NODE t = q1.top();
				if (t.sum <= temp.sum)
				{
					q1.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q0.push(temp);
			}
		}
	}
	while (!q0.empty() && !q1.empty())
	{
		NODE t0 = q0.top();
		q0.pop();
		NODE t1 = q1.top();
		q1.pop();
		if (t0.sum <= t1.sum)
		{
			pre[t0.id] = t1.id;
			val[t0.id] = t0.sum;
			q1.push(NODE(t1.col, t1.id, t1.sum - t0.sum));
		}
		else
		{
			pre[t1.id] = t0.id;
			val[t1.id] = t1.sum;
			q0.push(NODE(t0.col, t0.id, t0.sum - t1.sum));
		}
	}
	int root;
	if (q0.empty())
		root = q1.top().id;
	else
		root = q0.top().id;
	for (int i = 1; i <= n; i++)
	{
		if (i != root)
			printf ("%d %d %d\n", i, pre[i], val[i]);
	}
}

int main() {
	//freopen("input.txt","r",stdin);
	int T = 1;
	//scanf("%d", &T);
	for (int i = 1; i <= T; i ++)
		solved(i);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

typedef long long LL;

const int MAXN = 100005;
const LL MOD = 99990001;

struct NODE
{
	int col, id;
	int sum;
	NODE() {}
	NODE(int _col, int _id, int _sum):col(_col), id(_id), sum(_sum) {}
};

bool operator < (const NODE &a, const NODE &b)
{
	return a.sum > b.sum;
}

int pre[MAXN];
int val[MAXN];
int col[MAXN];
int n, x, y;
int flag[2];
int cnt[2];

priority_queue<NODE> q;
priority_queue<NODE> q0, q1;

void solved(int cas)
{
	scanf ("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf ("%d %d", &x, &y);
		col[i] = x;
		flag[x] = i;
		cnt[x]++;
		q.push(NODE(x, i, y));
	}
	while (!q.empty())
	{
		NODE temp = q.top();
		q.pop();
		if (temp.col)
		{
			if (q0.empty())
				q1.push(temp);
			else
			{
				NODE t = q0.top();
				if (t.sum <= temp.sum)
				{
					q0.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q1.push(temp);
			}
		}
		else
		{
			if (q1.empty())
				q0.push(temp);
			else
			{
				NODE t = q1.top();
				if (t.sum <= temp.sum)
				{
					q1.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q0.push(temp);
			}
		}
	}
	while (!q0.empty() && !q1.empty())
	{
		NODE t0 = q0.top();
		q0.pop();
		NODE t1 = q1.top();
		q1.pop();
		if (t0.sum <= t1.sum)
		{
			pre[t0.id] = t1.id;
			val[t0.id] = t0.sum;
			q1.push(NODE(t1.col, t1.id, t1.sum - t0.sum));
		}
		else
		{
			pre[t1.id] = t0.id;
			val[t1.id] = t1.sum;
			q0.push(NODE(t0.col, t0.id, t0.sum - t1.sum));
		}
	}
	int root;

	if (q0.empty())
		root = q1.top().id;
	else
		root = q0.top().id;

	int temp = flag[col[root]^1];

	for (int i = 1; i <= n; i++)
	{
		if (i != root && pre[i] == 0)
		{
			for (int k = 0; k < 2; k++)
			{
				if (cnt[k] == 1)
				{
					int j;
					for (j = 1; j <= n; j++)
						if (col[j] == k)
							break;
					for (int l = 1; l <= n; l++)
						if (l != j)
							printf ("%d %d %d\n", l, j, 0);
					return;
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
	{
		if (i != root && pre[i] == root)
			temp = i;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i != root)
		{
			if (pre[i] == 0)
				pre[i] = temp;
			printf ("%d %d %d\n", i, pre[i], val[i]);
		}
	}
}

int main() {
	//freopen("input.txt","r",stdin);
	int T = 1;
	//scanf("%d", &T);
	for (int i = 1; i <= T; i ++)
		solved(i);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

typedef long long LL;

const int MAXN = 100005;
const LL MOD = 99990001;

struct NODE
{
	int col, id;
	int sum;
	NODE() {}
	NODE(int _col, int _id, int _sum):col(_col), id(_id), sum(_sum) {}
};

bool operator < (const NODE &a, const NODE &b)
{
	return a.sum > b.sum;
}

int pre[MAXN];
int val[MAXN];
int n, x, y;

priority_queue<NODE> q;
priority_queue<NODE> q0, q1;

void solved(int cas)
{
	scanf ("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf ("%d %d", &x, &y);
		q.push(NODE(x, i, y));
	}
	while (!q.empty())
	{
		NODE temp = q.top();
		q.pop();
		if (temp.col)
		{
			if (q0.empty())
				q1.push(temp);
			else
			{
				NODE t = q0.top();
				if (t.sum <= temp.sum)
				{
					q0.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q1.push(temp);
			}
		}
		else
		{
			if (q1.empty())
				q0.push(temp);
			else
			{
				NODE t = q1.top();
				if (t.sum <= temp.sum)
				{
					q1.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q0.push(temp);
			}
		}
	}
	while (!q0.empty() && !q1.empty())
	{
		NODE t0 = q0.top();
		q0.pop();
		NODE t1 = q1.top();
		q1.pop();
		if (t0.sum <= t1.sum)
		{
			pre[t0.id] = t1.id;
			val[t0.id] = t0.sum;
			q1.push(NODE(t1.col, t1.id, t1.sum - t0.sum));
		}
		else
		{
			pre[t1.id] = t0.id;
			val[t1.id] = t1.sum;
			q0.push(NODE(t0.col, t0.id, t0.sum - t1.sum));
		}
	}
	int root;
	if (q0.empty())
		root = q1.top().id;
	else
		root = q0.top().id;
	int flag;
	for (int i = 1; i <= n; i++)
	{
		if (i != root && pre[i] == root)
			flag = i;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i != root)
		{
			if (pre[i] == 0)
				pre[i] = flag;
			printf ("%d %d %d\n", i, pre[i], val[i]);
		}
	}
}

int main() {
	//freopen("input.txt","r",stdin);
	int T = 1;
	//scanf("%d", &T);
	for (int i = 1; i <= T; i ++)
		solved(i);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

typedef long long LL;

const int MAXN = 100005;
const LL MOD = 99990001;

struct NODE
{
	int col, id;
	int sum;
	NODE() {}
	NODE(int _col, int _id, int _sum):col(_col), id(_id), sum(_sum) {}
};

bool operator < (const NODE &a, const NODE &b)
{
	return a.sum > b.sum;
}

int pre[MAXN];
int val[MAXN];
int col[MAXN];
int n, x, y;
int flag[2];

priority_queue<NODE> q;
priority_queue<NODE> q0, q1;

void solved(int cas)
{
	scanf ("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf ("%d %d", &x, &y);
		col[i] = x;
		flag[x] = i;
		q.push(NODE(x, i, y));
	}
	while (!q.empty())
	{
		NODE temp = q.top();
		q.pop();
		if (temp.col)
		{
			if (q0.empty())
				q1.push(temp);
			else
			{
				NODE t = q0.top();
				if (t.sum <= temp.sum)
				{
					q0.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q1.push(temp);
			}
		}
		else
		{
			if (q1.empty())
				q0.push(temp);
			else
			{
				NODE t = q1.top();
				if (t.sum <= temp.sum)
				{
					q1.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q0.push(temp);
			}
		}
	}
	while (!q0.empty() && !q1.empty())
	{
		NODE t0 = q0.top();
		q0.pop();
		NODE t1 = q1.top();
		q1.pop();
		if (t0.sum <= t1.sum)
		{
			pre[t0.id] = t1.id;
			val[t0.id] = t0.sum;
			q1.push(NODE(t1.col, t1.id, t1.sum - t0.sum));
		}
		else
		{
			pre[t1.id] = t0.id;
			val[t1.id] = t1.sum;
			q0.push(NODE(t0.col, t0.id, t0.sum - t1.sum));
		}
	}
	int root;

	if (q0.empty())
		root = q1.top().id;
	else
		root = q0.top().id;

	int temp = flag[col[root]^1];

	for (int i = 1; i <= n; i++)
	{
		if (i != root && pre[i] == root)
			temp = i;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i != root)
		{
			if (pre[i] == 0)
				pre[i] = temp;
			printf ("%d %d %d\n", i, pre[i], val[i]);
		}
	}
}

int main() {
	//freopen("input.txt","r",stdin);
	int T = 1;
	//scanf("%d", &T);
	for (int i = 1; i <= T; i ++)
		solved(i);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

typedef long long LL;

const int MAXN = 100005;
const LL MOD = 99990001;

struct NODE
{
	int col, id;
	int sum;
	NODE() {}
	NODE(int _col, int _id, int _sum):col(_col), id(_id), sum(_sum) {}
};

bool operator < (const NODE &a, const NODE &b)
{
	return a.sum > b.sum;
}

int pre[MAXN];
int val[MAXN];
int n, x, y;
int col[MAXN];
int flag[2];

priority_queue<NODE> q;
priority_queue<NODE> q0, q1;

void solved(int cas)
{
	scanf ("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf ("%d %d", &x, &y);
		flag[x] = i;
		col[i] = x;
		q.push(NODE(x, i, y));
	}
	while (!q.empty())
	{
		NODE temp = q.top();
		q.pop();
		if (temp.col)
		{
			if (q0.empty())
				q1.push(temp);
			else
			{
				NODE t = q0.top();
				if (t.sum <= temp.sum)
				{
					q0.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q1.push(temp);
			}
		}
		else
		{
			if (q1.empty())
				q0.push(temp);
			else
			{
				NODE t = q1.top();
				if (t.sum <= temp.sum)
				{
					q1.pop();
					pre[t.id] = temp.id;
					val[t.id] = t.sum;
					q.push(NODE(temp.col, temp.id, temp.sum - t.sum));
				}
				else
					q0.push(temp);
			}
		}
	}
	while (!q0.empty() && !q1.empty())
	{
		NODE t0 = q0.top();
		q0.pop();
		NODE t1 = q1.top();
		q1.pop();
		if (t0.sum <= t1.sum)
		{
			pre[t0.id] = t1.id;
			val[t0.id] = t0.sum;
			q1.push(NODE(t1.col, t1.id, t1.sum - t0.sum));
		}
		else
		{
			pre[t1.id] = t0.id;
			val[t1.id] = t1.sum;
			q0.push(NODE(t0.col, t0.id, t0.sum - t1.sum));
		}
	}
	int root;
	if (q0.empty())
		root = q1.top().id;
	else
		root = q0.top().id;
	for (int i = 1; i <= n; i++)
	{
		if (i != root)
		{
			if (pre[i] == 0)
				pre[i] = flag[col[i]^1];
			printf ("%d %d %d\n", i, pre[i], val[i]);
		}
	}
}

int main() {
	//freopen("input.txt","r",stdin);
	int T = 1;
	//scanf("%d", &T);
	for (int i = 1; i <= T; i ++)
		solved(i);
	return 0;
}


#include <cstdio>
#include <cstdlib>

typedef struct {
	int id;
	int col;
	int vl;
}nodes;
nodes nds[100002];
int cmp(const void *ka,const void *kb) {
	nodes *a=(nodes *)ka;
	nodes *b=(nodes *)kb;
	if(a->col!=b->col) return a->col-b->col;
	return a->vl-b->vl;
}
int n;
int main() {
	scanf("%d",&n);
	int all0=0;
	for(int i=0;i<n;i++) {
		scanf("%d%d",&nds[i].col,&nds[i].vl);
		nds[i].id=i+1;
		if(nds[i].col<1) all0++;
	}
	qsort(nds,n,sizeof(nodes),cmp);
	if(nds[n-1].vl>0) {
		int v0=0; int v1=all0;
		while(v0<all0) {
			if(nds[v0].vl>nds[v1].vl) {
				printf("%d %d %d\n",nds[v0].id,nds[v1].id,nds[v1].vl);
				nds[v0].vl-=nds[v1].vl;
				v1++;
			} else {
				printf("%d %d %d\n",nds[v0].id,nds[v1].id,nds[v0].vl);
				nds[v1].vl-=nds[v0].vl;
				v0++;
			}
		}
	} else {
		for(int i=all0;i<n;i++) printf("%d %d 0\n",nds[0].id,nds[i].id);
		for(int i=1;i<all0;i++) printf("%d %d 0\n",nds[all0].id,nds[i].id);
	}
	return 0;
}


#include <cstdio>
#include <queue>

using namespace std;
priority_queue< pair<int,int> > edgew;
priority_queue< pair<int,int> > edgeb;
int n;
int uf[100001];
int col[100001];
int getpa(int a) {
	if(uf[a]==a) return a;
	uf[a]=getpa(uf[a]);
	return uf[a];
}
int main() {
	scanf("%d",&n);
	int exw=-1;
	int exb=-1;
	for(int i=1;i<=n;i++) {
		int ka,kb;
		scanf("%d%d",&ka,&kb);
		col[i]=ka;
		uf[i]=i;
		if(ka) {
			edgeb.push(make_pair(kb,i));
			exb=i;
		} else {
			edgew.push(make_pair(kb,i));
			exw=i;
		}
	}
	while(edgeb.size()&&edgew.size()>1) {
		int dtb=edgeb.top().second;
		int dtw=edgew.top().second;
		int csb=edgeb.top().first;
		int csw=edgew.top().first;
		if(csb==0) break;
		edgeb.pop();
		edgew.pop();
		uf[getpa(dtb)]=getpa(dtw);
		if(csw<csb) {
			printf("%d %d %d\n",dtb,dtw,csw);
			edgeb.push(make_pair(csb-csw,dtb));
		} else {
			printf("%d %d %d\n",dtb,dtw,csb);
			edgew.push(make_pair(csw-csb,dtw));
		}
	}
	for(int i=1;i<=n;i++) {
		if(col[i]) {
			if(getpa(i)!=getpa(exw)) {
				printf("%d %d 0\n",i,exw);
				uf[getpa(i)]=getpa(exw);
			}
		} else {
			if(getpa(i)!=getpa(exb)) {
				printf("%d %d 0\n",i,exb);
				uf[getpa(i)]=getpa(exb);
			}
		}
	}
	return 0;
}


#include <cstdio>
#include <queue>

using namespace std;
priority_queue< pair<int,int> > edgew;
priority_queue< pair<int,int> > edgeb;
int n;
int main() {
	scanf("%d",&n);
	int exw=-1;
	int exb=-1;
	for(int i=1;i<=n;i++) {
		int ka,kb;
		scanf("%d%d",&ka,&kb);
		if(ka) {
			edgeb.push(make_pair(kb,i));
			exb=i;
		} else {
			edgew.push(make_pair(kb,i));
			exw=i;
		}
	}
	while(edgeb.size()+edgew.size()>1) {
		if(edgeb.size()==0) {
			int dtw=edgew.top().second;
			printf("%d %d 0\n",exb,dtw,0);
			edgew.pop();
		} else if(edgew.size()==0) {
			int dtb=edgeb.top().second;
			printf("%d %d 0\n",dtb,exw,0);
			edgeb.pop();
		} else {
			int dtb=edgeb.top().second;
			int dtw=edgew.top().second;
			int csb=edgeb.top().first;
			int csw=edgew.top().first;
			edgeb.pop();
			edgew.pop();
			if(csw<csb) {
				printf("%d %d %d\n",dtb,dtw,csw);
				edgeb.push(make_pair(csb-csw,dtb));
			} else {
				printf("%d %d %d\n",dtb,dtw,csb);
				edgew.push(make_pair(csw-csb,dtw));
			}
		}
	}
	return 0;
}


#include <cstdio>
#include <queue>

using namespace std;
priority_queue< pair<int,int> > edgew;
priority_queue< pair<int,int> > edgeb;
int n;
int uf[100001];
int col[100001];
int getpa(int a) {
	if(uf[a]==a) return a;
	uf[a]=getpa(uf[a]);
	return uf[a];
}
int main() {
	scanf("%d",&n);
	int exw=-1;
	int exb=-1;
	for(int i=1;i<=n;i++) {
		int ka,kb;
		scanf("%d%d",&ka,&kb);
		col[i]=ka;
		uf[i]=i;
		if(ka) {
			edgeb.push(make_pair(kb,i));
			exb=i;
		} else {
			edgew.push(make_pair(kb,i));
			exw=i;
		}
	}
	while(edgeb.size()+edgew.size()>1) {
		int dtb=edgeb.top().second;
		int dtw=edgew.top().second;
		int csb=edgeb.top().first;
		int csw=edgew.top().first;
		if(csb==0) break;
		edgeb.pop();
		edgew.pop();
		uf[getpa(dtb)]=getpa(dtw);
		if(csw<csb) {
			printf("%d %d %d\n",dtb,dtw,csw);
			edgeb.push(make_pair(csb-csw,dtb));
		} else {
			printf("%d %d %d\n",dtb,dtw,csb);
			edgew.push(make_pair(csw-csb,dtw));
		}
	}
	for(int i=1;i<=n;i++) {
		if(col[i]) {
			if(getpa(i)!=getpa(exw)) {
				printf("%d %d 0\n",i,exw);
				uf[getpa(i)]=getpa(exw);
			}
		} else {
			if(getpa(i)!=getpa(exb)) {
				printf("%d %d 0\n",i,exb);
				uf[getpa(i)]=getpa(exb);
			}
		}
	}
	return 0;
}


#include <set>
#include <iostream>
#include <cassert>

using namespace std;

const int max_v = 1e5 + 15;

int V, x, y, boja[max_v];
set<pair<int, int> > s, wb[2];

int main()
{
  cin >> V;
  for (int i = 0; i < V; i++)
  {
    cin >> x >> y;
    boja[i] = x;
    wb[x].insert(make_pair(-y, i));
    s.insert(make_pair(y, i));
  }
  while (s.size() > 1)
  {
    pair<int, int> u = *s.begin();
    int clr = boja[u.second];
    s.erase(s.begin());
    wb[clr].erase(make_pair(-u.first, u.second));
    wb[clr].insert(make_pair(0, u.second));
    clr ^= 1;
    pair<int, int> v = *wb[clr].begin();
    wb[clr].erase(wb[clr].begin());
    cout << u.second + 1 << " " << v.second + 1 << " " << u.first << endl;
    if (s.find(make_pair(-v.first, v.second)) != s.end())
    {
      s.erase(make_pair(-v.first, v.second));
      s.insert(make_pair(-v.first - u.first, v.second));
    }
    v.first += u.first;
    wb[clr].insert(v);
  }
  return 0;
}


#include <set>
#include <iostream>
#include <cassert>

using namespace std;

const int max_v = 1e5 + 15;

int V, x, y, boja[max_v];
set<pair<int, int> > s, wb[2];

int main()
{
  cin >> V;
  for (int i = 0; i < V; i++)
  {
    cin >> x >> y;
    boja[i] = x;
    wb[x].insert(make_pair(-y, i));
    s.insert(make_pair(y, i));
  }
  while (s.size() > 1)
  {
    pair<int, int> u = *s.begin();
    int clr = boja[u.second];
    s.erase(s.begin());
    wb[clr].erase(make_pair(-u.first, u.second));
    clr ^= 1;
    pair<int, int> v = *wb[clr].begin();
    wb[clr].erase(wb[clr].begin());
    cout << u.second + 1 << " " << v.second + 1 << " " << u.first << endl;
    if (s.find(make_pair(-v.first, v.second)) != s.end())
    {
      s.erase(make_pair(-v.first, v.second));
      s.insert(make_pair(-v.first - u.first, v.second));
    }
    v.first += u.first;
    wb[clr].insert(v);
  }
  return 0;
}


#include <set>
#include <iostream>

using namespace std;

const int max_v = 1e5 + 15;

int V, x, y, boja[max_v];
set<pair<int, int> > s, wb[2];

int main()
{
  cin >> V;
  for (int i = 0; i < V; i++)
  {
    cin >> x >> y;
    boja[i] = x;
    wb[x].insert(make_pair(-y, i));
    s.insert(make_pair(y, i));
  }
  while (s.size() > 1)
  {
    pair<int, int> u = *s.begin();
    int clr = boja[u.second];
    s.erase(s.begin());
    wb[clr].erase(make_pair(-u.first, u.second));
    wb[clr].insert(make_pair(0, u.second));
    clr ^= 1;
    pair<int, int> v = *wb[clr].begin();
    cout << u.second + 1 << " " << v.second + 1 << " " << u.first << endl;
    wb[clr].erase(wb[clr].begin());
    s.erase(make_pair(-v.first, v.second));
    v.first += u.first;
    s.insert(make_pair(-v.first, v.second));
    wb[clr].insert(v);
  }
  return 0;
}


#include <set>
#include <iostream>

#define ff first
#define ss second

using namespace std;

int V, x, y;
set<pair<int, int> > w, b;

int main()
{
  cin >> V;
  for (int i = 1; i <= V; i++)
  {
    cin >> x >> y;
    (x ? b : w).insert(make_pair(y, i));
  }
  for (; !b.empty(); b.erase(b.begin()))
  {
    if (make_pair(w.begin()->ff, -(int)w.size()) < make_pair(b.begin()->ff, -(int)b.size())) b.swap(w);
    cout << b.begin()->ss << " " << w.begin()->ss << " " << b.begin()->ff << endl;
    pair<int, int> t = *w.begin();
    w.erase(*w.begin());
    t.ff -= b.begin()->ff;
    w.insert(t);
  }
  return 0;
}


#include <set>
#include <iostream>

using namespace std;

const int max_v = 1e5 + 15;

int V, x, y, boja[max_v];
set<pair<int, int> > s, wb[2];

int main()
{
  cin >> V;
  for (int i = 0; i < V; i++)
  {
    cin >> x >> y;
    boja[i] = x;
    wb[x].insert(make_pair(-y, i));
    s.insert(make_pair(y, i));
  }
  while (s.size() > 1)
  {
    pair<int, int> u = *s.begin();
    s.erase(s.begin());
    int clr = 1 ^ boja[u.second];
    pair<int, int> v = *wb[clr].begin();
    wb[clr].erase(wb[clr].begin());
    cout << u.second + 1 << " " << v.second + 1 << " " << u.first << endl;
    v.first += u.first;
    wb[clr].insert(v);
  }
  return 0;
}


#include <set>
#include <iostream>
#include <cassert>

using namespace std;

const int max_v = 1e5 + 15;

int V, x, y, boja[max_v];
set<pair<int, int> > s, wb[2];

int main()
{
  cin >> V;
  for (int i = 0; i < V; i++)
  {
    cin >> x >> y;
    boja[i] = x;
    wb[x].insert(make_pair(-y, i));
    s.insert(make_pair(y, i));
  }
  while (s.size() > 1)
  {
    pair<int, int> u = *s.begin();
    int clr = boja[u.second];
    s.erase(*s.begin());
    wb[clr].erase(make_pair(-u.first, u.second));
    wb[clr].insert(make_pair(0, u.second));
    clr ^= 1;
    pair<int, int> v = *wb[clr].begin();
    wb[clr].erase(wb[clr].begin());
    cout << u.second + 1 << " " << v.second + 1 << " " << u.first << endl;
    if (s.find(make_pair(-v.first, v.second)) != s.end())
    {
      s.erase(make_pair(-v.first, v.second));
      s.insert(make_pair(-v.first + u.first, v.second));
    }
    v.first += u.first;
    wb[clr].insert(v);
  }
  return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std;
#define SZ(v) ((int)(v).size())
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPF(i, a, b) for (int i = (a); i <= (b); ++i)
#define REPD(i, a, b) for (int i = (a); i >= (b); --i)
const int maxint = -1u>>1;
struct point {
        int a, b;
}       x[100010], y[100010];
int n, a, b, l1, l2, la;
bool cmp(point p1, point p2) {
        return p1.a < p2.a;
}
int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i ++) {
                scanf("%d%d", &a, &b);
                if (a) {
                        l1 ++;
                        x[l1].a = b;
                        x[l1].b = i;
                } else {
                        l2 ++;
                        y[l2].a = b;
                        y[l2].b = i;
                }
        }
        sort(x + 1, x + l1 + 1, cmp);
        sort(y + 1, y + l2 + 1, cmp);

        la = l1;
        l1 = 1, l2 = 1;
        for (int i = 1; i < n; i ++) {
                if (x[l1].a <= y[l2].a && l1 <= la) {
                        printf("%d %d %d\n", x[l1].b, y[l2].b, x[l1].a);
                        y[l2].a -= x[l1].a;
                        l1 ++;
                } else {
                        printf("%d %d %d\n", x[l1].b, y[l2].b, y[l2].a);
                        x[l1].a -= y[l2].a;
                        l2 ++;
                }
        }

        return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std;
#define SZ(v) ((int)(v).size())
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPF(i, a, b) for (int i = (a); i <= (b); ++i)
#define REPD(i, a, b) for (int i = (a); i >= (b); --i)
const int maxint = -1u>>1;
struct point {
        int a, b;
}       x[100010], y[100010];
int n, a, b, l1, l2;
bool cmp(point p1, point p2) {
        return p1.a < p2.a;
}
int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i ++) {
                scanf("%d%d", &a, &b);
                if (a) {
                        l1 ++;
                        x[l1].a = b;
                        x[l1].b = i;
                } else {
                        l2 ++;
                        y[l2].a = b;
                        y[l2].b = i;
                }
        }
        sort(x, x + l1, cmp);
        sort(y, y + l2, cmp);

        l1 = 1, l2 = 1;
        for (int i = 1; i < n; i ++) {
                if (x[l1].a < y[l2].a) {
                        printf("%d %d %d\n", x[l1].b, y[l2].b, x[l1].a);
                        y[l2].a -= x[l1].a;
                        l1 ++;
                } else {
                        printf("%d %d %d\n", x[l1].b, y[l2].b, y[l2].a);
                        x[l1].a -= y[l2].a;
                        l2 ++;
                }
        }

        return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std;
#define SZ(v) ((int)(v).size())
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPF(i, a, b) for (int i = (a); i <= (b); ++i)
#define REPD(i, a, b) for (int i = (a); i >= (b); --i)
const int maxint = -1u>>1;
struct point {
        int a, b;
}       x[100010], y[100010];
int n, a, b, l1, l2;
bool cmp(point p1, point p2) {
        return p1.a < p2.a;
}
int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i ++) {
                scanf("%d%d", &a, &b);
                if (a) {
                        l1 ++;
                        x[l1].a = b;
                        x[l1].b = i;
                } else {
                        l2 ++;
                        y[l2].a = b;
                        y[l2].b = i;
                }
        }
        sort(x + 1, x + l1 + 1, cmp);
        sort(y + 1, y + l2 + 1, cmp);

        l1 = 1, l2 = 1;
        for (int i = 1; i < n; i ++) {
                if (x[l1].a < y[l2].a) {
                        printf("%d %d %d\n", x[l1].b, y[l2].b, x[l1].a);
                        y[l2].a -= x[l1].a;
                        l1 ++;
                } else {
                        printf("%d %d %d\n", x[l1].b, y[l2].b, y[l2].a);
                        x[l1].a -= y[l2].a;
                        l2 ++;
                }
        }

        return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std;
#define SZ(v) ((int)(v).size())
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPF(i, a, b) for (int i = (a); i <= (b); ++i)
#define REPD(i, a, b) for (int i = (a); i >= (b); --i)
const int maxint = -1u>>1;
struct point {
        int a, b;
}       x[100010], y[100010];
int n, a, b, l1, l2, la;
bool cmp(point p1, point p2) {
        return p1.a < p2.a;
}
int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i ++) {
                scanf("%d%d", &a, &b);
                if (a) {
                        l1 ++;
                        x[l1].a = b;
                        x[l1].b = i;
                } else {
                        l2 ++;
                        y[l2].a = b;
                        y[l2].b = i;
                }
        }
        sort(x + 1, x + l1 + 1, cmp);
        sort(y + 1, y + l2 + 1, cmp);

        la = l1;
        l1 = 1, l2 = 1;
        for (int i = 1; i < n; i ++) {
                if (x[l1].a <= y[l2].a && l1 < la) {
                        printf("%d %d %d\n", x[l1].b, y[l2].b, x[l1].a);
                        y[l2].a -= x[l1].a;
                        l1 ++;
                } else {
                        printf("%d %d %d\n", x[l1].b, y[l2].b, y[l2].a);
                        x[l1].a -= y[l2].a;
                        l2 ++;
                }
        }

        return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n;
priority_queue < PII > w,b;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
			w.push( MP(s[i],i) );
		else
			b.push( MP(s[i],i) );
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		cout<<bb.S+1<<" "<<ww.S+1<<" "<<t<<endl;
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				cout<<bb.S+1<<" "<<w.top().S+1<<" "<<0<<endl;
		}
		else
			w.push(ww);
	}
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n,iff=0;
priority_queue < PII > w,b,x,y;
vector < pair < PII , ll > > v;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
		{
			if(s[i]==0)
				x.push( MP(s[i],i) );
			else
				w.push( MP(s[i],i) );
		}
		else
		{
			if(s[i]==0)
				y.push( MP(s[i],i) );
			else
				b.push( MP(s[i],i) );
		}
	}
	while(x.size()>0){if(b.size()>0){v.PB(MP(MP(x.top().S+1,b.top().S+1),0));x.pop();}else break;}
	while(y.size()>0){if(w.size()>0){v.PB(MP(MP(y.top().S+1,w.top().S+1),0));y.pop();}else break;}
	if(x.size()>0)
	{
		PII xx,yy;
		xx.F=x.top().F;xx.S=x.top().S;
		yy.F=y.top().F;yy.S=y.top().S;
		x.pop();y.pop();
		while(x.size()>0)
		{
			v.PB(MP(MP(yy.S+1,x.top().S+1),0));
			x.pop();
		}
		while(y.size()>0)
		{
			v.PB(MP(MP(xx.S+1,y.top().S+1),0));
			b.pop();
		}
		v.PB(MP(MP(xx.S+1,yy.S+1),0));
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		v.PB( MP ( MP(bb.S+1,ww.S+1) , t ) );
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				v.PB( MP ( MP(bb.S+1,w.top().S+1) , 0 ) );
			else if(b.size()>0)
				v.PB( MP ( MP(ww.S+1,b.top().S+1) , 0 ) );
		}
		else
			w.push(ww);
	}
	if(v.size()!=n-1){cout<<v.size()<<endl;return 0;}
	for(ll i=0;i<n-1;i++)
		cout<<v[i].F.F<<" "<<v[i].F.S<<" "<<v[i].S<<endl;
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n,iff=0;
priority_queue < PII > w,b,x,y;
vector < pair < PII , ll > > v;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
		{
			if(s[i]==0)
				x.push( MP(s[i],i) );
			else
				w.push( MP(s[i],i) );
		}
		else
		{
			if(s[i]==0)
				y.push( MP(s[i],i) );
			else
				b.push( MP(s[i],i) );
		}
	}
	while(x.size()>0){if(b.size()>0){v.PB(MP(MP(x.top().S+1,b.top().S+1),0));x.pop();}}
	while(y.size()>0){if(w.size()>0){v.PB(MP(MP(y.top().S+1,w.top().S+1),0));y.pop();}}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		v.PB( MP ( MP(bb.S+1,ww.S+1) , t ) );
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				v.PB( MP ( MP(bb.S+1,w.top().S+1) , 0 ) );
			else if(b.size()>0)
				v.PB( MP ( MP(ww.S+1,b.top().S+1) , 0 ) );
		}
		else
			w.push(ww);
	}
	if(v.size()!=n-1){cout<<v.size()<<endl;return 0;}
	for(ll i=0;i<n-1;i++)
		cout<<v[i].F.F<<" "<<v[i].F.S<<" "<<v[i].S<<endl;
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n;
priority_queue < PII > w,b;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
			w.push( MP(s[i],i) );
		else
			b.push( MP(s[i],i) );
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		cout<<bb.S+1<<" "<<ww.S+1<<" "<<t<<endl;
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				cout<<bb.S+1<<" "<<w.top().S+1<<" "<<0<<endl;
			else if(b.size()>0)
				cout<<ww.S+1<<" "<<b.top().S+1<<" "<<0<<endl;
		}
		else
			w.push(ww);
	}
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n;
priority_queue < PII > w,b;
vector < pair < PII , int > > v;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
			w.push( MP(s[i],i) );
		else
			b.push( MP(s[i],i) );
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		v.PB( MP ( MP(bb.S+1,ww.S+1) , t ) );
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				v.PB( MP ( MP(bb.S+1,w.top().S+1) , 0 ) );
			else if(b.size()>0)
				v.PB( MP ( MP(ww.S+1,b.top().S+1) , 0 ) );
		}
		else
			w.push(ww);
	}
	if(v.size()!=n-1){cout<<"SHIT"<<endl;return 0;}
	for(int i=0;i<n-1;i++)
		cout<<v[i].F.F<<" "<<v[i].F.S<<" "<<v[i].S<<endl;
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <int,int>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > point;

const int maxn=100*1000+100;

int n;
priority_queue < PII > w,b;
int c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
			w.push( MP(s[i],i) );
		else
			b.push( MP(s[i],i) );
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		int t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		cout<<bb.S+1<<" "<<ww.S+1<<" "<<t<<endl;
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				cout<<bb.S+1<<" "<<w.top().S+1<<" "<<0<<endl;
		}
		else
			w.push(ww);
	}
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n;
priority_queue < PII > w,b;
vector < pair < PII , ll > > v;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
			w.push( MP(s[i],i) );
		else
			b.push( MP(s[i],i) );
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		v.PB( MP ( MP(bb.S+1,ww.S+1) , t ) );
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				v.PB( MP ( MP(bb.S+1,w.top().S+1) , 0 ) );
			else if(b.size()>0)
				v.PB( MP ( MP(ww.S+1,b.top().S+1) , 0 ) );
		}
		else
			w.push(ww);
	}
	//if(v.size()!=n-1){cout<<v.size()<<endl;return 0;}
	for(ll i=0;i<n-1;i++)
		cout<<v[i].F.F<<" "<<v[i].F.S<<" "<<v[i].S<<endl;
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n;
priority_queue < PII > w,b;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
			w.push( MP(s[i],i) );
		else
			b.push( MP(s[i],i) );
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		cout<<bb.S+1<<" "<<ww.S+1<<" "<<t<<endl;
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				cout<<bb.S+1<<" "<<w.top().S+1<<" "<<0<<endl;
			else if(b.size()>0)
				cout<<ww.S+1<<" "<<b.top().S+1<<" "<<0<<endl;
		}
		else
			w.push(ww);
	}
	if(b.size()>0)
		cout<<"SHIT"<<endl;
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n,iff=0;
priority_queue < PII > w,b,x,y;
vector < pair < PII , ll > > v;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
		{
			if(s[i]==0)
				x.push( MP(s[i],i) );
			else
				w.push( MP(s[i],i) );
		}
		else
		{
			if(s[i]==0)
				y.push( MP(s[i],i) );
			else
				b.push( MP(s[i],i) );
		}
	}
	while(x.size()>0){if(b.size()>0){v.PB(MP(MP(x.top().S+1,b.top().S+1),0));x.pop();}else break;}
	while(y.size()>0){if(w.size()>0){v.PB(MP(MP(y.top().S+1,w.top().S+1),0));y.pop();}else break;}
	if(x.size()>0)
	{
		PII xx,yy;
		xx.F=x.top().F;xx.S=x.top().S;
		yy.F=y.top().F;yy.S=y.top().S;
		x.pop();y.pop();
		while(x.size()>0)
		{
			v.PB(MP(MP(yy.S+1,x.top().S+1),0));
			x.pop();
		}
		while(y.size()>0)
		{
			v.PB(MP(MP(xx.S+1,y.top().S+1),0));
			y.pop();
		}
		v.PB(MP(MP(xx.S+1,yy.S+1),0));
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		v.PB( MP ( MP(bb.S+1,ww.S+1) , t ) );
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				v.PB( MP ( MP(bb.S+1,w.top().S+1) , 0 ) );
			else if(b.size()>0)
				v.PB( MP ( MP(ww.S+1,b.top().S+1) , 0 ) );
		}
		else
			w.push(ww);
	}
	for(ll i=0;i<n-1;i++)
		cout<<v[i].F.F<<" "<<v[i].F.S<<" "<<v[i].S<<endl;
	return 0;
}


//In The Name Of God.
//CodeBreaker!

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<utility>
#include<list>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>

using namespace std;

#define PB push_back
#define PII pair <ll,ll>
#define PDD pair <double,double>
#define MP make_pair
#define X real()
#define Y imag()
#define F first
#define S second
#define ll long long

typedef complex < double > poll;

const ll maxn=100*1000+100;

ll n;
priority_queue < PII > w,b;
vector < pair < PII , int > > v;
ll c[maxn],s[maxn];

int main()
{
	cin>>n;
	for(ll i=0;i<n;i++)
	{
		cin>>c[i]>>s[i];
		if(c[i]==0)
			w.push( MP(s[i],i) );
		else
			b.push( MP(s[i],i) );
	}
	while(w.size()>0)
	{
		PII ww,bb;
		bb.F=b.top().F;bb.S=b.top().S;
		ww.F=w.top().F;ww.S=w.top().S;
		b.pop();w.pop();
		ll t=min(bb.F,ww.F);
		bb.F-=t;ww.F-=t;
		v.PB( MP ( MP(bb.S+1,ww.S+1) , t ) );
		if(ww.F==0)
		{
			if(bb.F>0)
				b.push(bb);
			else if(w.size()>0)
				v.PB( MP ( MP(bb.S+1,w.top().S+1) , 0 ) );
			else if(b.size()>0)
				v.PB( MP ( MP(ww.S+1,b.top().S+1) , 0 ) );
		}
		else
			w.push(ww);
	}
	if(v.size()!=n-1){cout<<v.size()<<endl;return 0;}
	for(int i=0;i<n-1;i++)
		cout<<v[i].F.F<<" "<<v[i].F.S<<" "<<v[i].S<<endl;
	return 0;
}