#include <iostream>
#include <math.h>
#include <cctype>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <list>
#include <fstream>
#include <iterator>
#include <iomanip>
#include <ctime>
#include <cstdlib>

using namespace std;

#define lli long long int
#define pb push_back
#define mp make_pair

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	int n, d;
	cin >> n >> d;
	vector<int> x(n);
	for (int i = 0; i < n; i++) cin >> x[i];
	sort(x.begin(), x.end());
	int s = 2;
	for (int i = 0; i < n - 1; i++)
	{
		if (x[i + 1] - x[i] == 2 * d) s++;
		else if (x[i + 1] - x[i] > 2*d) s += 2;
	}
	cout << s;
	//system("pause");
	return 0;
}


#include<iostream>
#include<vector>

using namespace std;

int main() {
	int n;
	int d;
	cin >> n >> d;
	int l = 2 * d;
	vector<int> pos;
	for (int i = 0; i < n; i++) {
		int k;
		cin >> k;
		pos.push_back(k);
	}
	int result=0;
	for (int i = 0; i < n-1; i++) {
		if (pos[i + 1] - pos[i] ==  l) {
			result += 1;
		}
		if (pos[i + 1] - pos[i] > l) {
			result += 2;
		}
	}
	result += 2;
	cout << result;

	return 0;
}


#include<iostream>
using namespace std;

int main()
{
	int n, num, d, D, DD;
	int h[100];
	cin >> n >> d;
	D = 2 * d;
	num = 2;
	for (int i = 0; i < n; i++)
		cin >> h[i];
	for (int i = 1; i < n; i++)
	{
		DD = h[i] - h[i - 1];
		if (DD > D)
			num += 2;
		else if (DD == D)
			num++;
	}
	cout << num << endl;
	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define pf push_front
#define popf pop_front
#define popb pop_back
#define mp make_pair
#define f first
#define s second

using namespace std;

const int MX = 100000 + 5;
int N,val[MX];
vector < int > cmp[2];

int main(){
	scanf("%d",&N);
	for( int i=1,u ; i <= N ; i++ ){
		scanf("%d%d",&u,&val[i]);
		cmp[u].pb(i);
	}
	int i=0,j=0 ;
	for( int k=1 ; k < N ; k++ ){
		int u = cmp[0][i] , b = cmp[1][j];
		int x = min( val[u] , val[b] );
		if( !val[u] && i+1 < (int)cmp[0].size() )
			i++;
		else
			j++;
		val[u] -= x;
		val[b] -= x;

		printf("%d %d %d\n",u,b,x);
	}

	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define pf push_front
#define popf pop_front
#define popb pop_back
#define mp make_pair
#define f first
#define s second

using namespace std;

const int MX = 100000 + 5;
int N,val[MX];
vector < int > cmp[2];

int main(){

	scanf("%d",&N);

	for( int i=1,u ; i <= N ; i++ ){
		scanf("%d%d",&u,&val[i]);
		cmp[u].pb(i);
	}
	int i=0,j=0 ;
	for( int k=1 ; k < N ; k++ ){
		int u = cmp[0][i] , b = cmp[1][j];
		int x = min( val[u] , val[b] );
		val[u] -= x;
		val[b] -= x;
		if( !val[u] && i+1 < (int)cmp[0].size() )
			i++;
		else
			j++;
		printf("%d %d %d\n",u,b,x);
	}

	return 0;
}


#include<iostream>

using namespace std;

#define MAXN 100000

int main() {
	int n;
	pair<int, long long int> a[MAXN];
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i].first>>a[i].second;
	int ptr_b=0, ptr_w=0;
	while(a[ptr_b].first!=1 && ptr_b<n)
		ptr_b++;
	while(a[ptr_w].first!=0 && ptr_w<n)
		ptr_w++;
	while(ptr_b<n && ptr_w<n) {
		long long int w=min(a[ptr_b].second, a[ptr_w].second);
		cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<w<<endl;

		a[ptr_b].second-=w;
		a[ptr_w].second-=w;

		int flag=0;
		if(!a[ptr_b].second && !a[ptr_w].second)
			flag=1;

		if(!a[ptr_b].second) {
			ptr_b++;
			while(a[ptr_b].first!=1 && ptr_b<n)
				ptr_b++;
		}

		if(flag && ptr_b<n)
			cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;

		if(!a[ptr_w].second) {
			ptr_w++;
			while(a[ptr_w].first!=0 && ptr_w<n)
				ptr_w++;
		}
	}
	if(ptr_b<n) {
		ptr_w=n-1;
		while(a[ptr_w].first!=0)
			ptr_w--;
		while(ptr_b<n) {
			if(a[ptr_b].first==1)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_b++;
		}
	}
	if(ptr_w<n) {
		ptr_b=n-1;
		while(a[ptr_b].first!=1)
			ptr_b--;
		while(ptr_w<n) {
			if(a[ptr_w].first==0)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_w++;
		}
	}
}


#include<iostream>

using namespace std;

#define MAXN 100000

int main() {
	int n;
	pair<int, long long int> a[MAXN];
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i].first>>a[i].second;
	int ptr_b=0, ptr_w=0;
	while(a[ptr_b].first!=1 && ptr_b<n)
		ptr_b++;
	while(a[ptr_w].first!=0 && ptr_w<n)
		ptr_w++;
	while(ptr_b<n && ptr_w<n) {
		long long int w=min(a[ptr_b].second, a[ptr_w].second);
		cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<w<<endl;

		a[ptr_b].second-=w;
		a[ptr_w].second-=w;
		if(!a[ptr_b].second) {
			ptr_b++;
			while(a[ptr_b].first!=1 && ptr_b<n)
				ptr_b++;
		}

		if(!a[ptr_w].second) {
			ptr_w++;
			while(a[ptr_w].first!=0 && ptr_w<n)
				ptr_w++;
		}
	}
	if(ptr_b<n) {
		ptr_w=n-1;
		while(a[ptr_w].first!=0)
			ptr_w--;
		while(ptr_b<n) {
			if(a[ptr_b].first==1)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_b++;
		}
	}
	if(ptr_w<n) {
		ptr_b=n-1;
		while(a[ptr_b].first!=1)
			ptr_b--;
		while(ptr_w<n) {
			if(a[ptr_w].first==0)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_w++;
		}
	}
}


#include<iostream>

using namespace std;

#define MAXN 100000

int main() {
	int n;
	pair<int, long long int> a[MAXN];
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i].first>>a[i].second;
	int ptr_b=0, ptr_w=0;
	while(ptr_b<n && a[ptr_b].first!=1)
		ptr_b++;
	while(ptr_w<n && a[ptr_w].first!=0)
		ptr_w++;
	while(ptr_b<n && ptr_w<n) {
		long long int w=min(a[ptr_b].second, a[ptr_w].second);
		cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<w<<endl;

		a[ptr_b].second-=w;
		a[ptr_w].second-=w;

		int flag=0;
		if(!a[ptr_w].second && !a[ptr_b].second)
			flag=1;

		if(!a[ptr_b].second) {
			ptr_b++;
			while(ptr_b<n && a[ptr_b].first!=1)
				ptr_b++;
		}

		if(flag && ptr_b<n)
			cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;

		if(!a[ptr_w].second) {
			ptr_w++;
			while(ptr_w<n && a[ptr_w].first!=0)
				ptr_w++;
		}
	}
	if(ptr_b<n) {
		ptr_w=n-1;
		while(a[ptr_w].first!=0)
			ptr_w--;
		while(ptr_b<n) {
			if(a[ptr_b].first==1)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_b++;
		}
	}
	else if(ptr_w<n) {
		ptr_b=n-1;
		while(a[ptr_b].first!=1)
			ptr_b--;
		while(ptr_w<n) {
			if(a[ptr_w].first==0)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_w++;
		}
	}
}


#include<iostream>

using namespace std;

#define MAXN 100000

int main() {
	int n;
	pair<int, long long int> a[MAXN];
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i].first>>a[i].second;
	int ptr_b=0, ptr_w=0;
	while(a[ptr_b].first!=1 && ptr_b<n)
		ptr_b++;
	while(a[ptr_w].first!=0 && ptr_w<n)
		ptr_w++;
	while(ptr_b<n && ptr_w<n) {
		int w=min(a[ptr_b].second, a[ptr_w].second);
		cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<w<<endl;

		a[ptr_b].second-=w;
		a[ptr_w].second-=w;
		if(!a[ptr_b].second) {
			ptr_b++;
			while(a[ptr_b].first!=1 && ptr_b<n)
				ptr_b++;
		}

		if(!a[ptr_w].second) {
			ptr_w++;
			while(a[ptr_w].first!=0 && ptr_w<n)
				ptr_w++;
		}
	}
	if(ptr_b<n) {
		ptr_w=n-1;
		while(a[ptr_w].first!=0)
			ptr_w--;
		while(ptr_b<n) {
			if(a[ptr_b].first==1)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_b++;
		}
	}
	if(ptr_w<n) {
		ptr_b=n-1;
		while(a[ptr_b].first!=1)
			ptr_b--;
		while(ptr_w<n) {
			if(a[ptr_w].first==0)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_w++;
		}
	}
}


#include<iostream>

using namespace std;

#define MAXN 100000

int main() {
	int n;
	pair<int, long long int> a[MAXN];
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i].first>>a[i].second;
	int ptr_b=0, ptr_w=0;
	while(a[ptr_b].first!=1 && ptr_b<n)
		ptr_b++;
	while(a[ptr_w].first!=0 && ptr_w<n)
		ptr_w++;
	while(ptr_b<n && ptr_w<n) {
		long long int w=min(a[ptr_b].second, a[ptr_w].second);
		cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<w<<endl;

		a[ptr_b].second-=w;
		a[ptr_w].second-=w;

		int flag=0;
		if(!a[ptr_w].second && !a[ptr_b].second)
			flag=1;

		if(!a[ptr_b].second) {
			ptr_b++;
			while(a[ptr_b].first!=1 && ptr_b<n)
				ptr_b++;
		}

		if(flag && ptr_b<n)
			cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;

		if(!a[ptr_w].second) {
			ptr_w++;
			while(a[ptr_w].first!=0 && ptr_w<n)
				ptr_w++;
		}
	}
	if(ptr_b<n) {
		ptr_w=n-1;
		while(a[ptr_w].first!=0)
			ptr_w--;
		while(ptr_b<n) {
			if(a[ptr_b].first==1)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_b++;
		}
	}
	else if(ptr_w<n) {
		ptr_b=n-1;
		while(a[ptr_b].first!=1)
			ptr_b--;
		while(ptr_w<n) {
			if(a[ptr_w].first==0)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_w++;
		}
	}
}


#include<iostream>

using namespace std;

#define MAXN 100000

int main() {
	int n;
	pair<int, long long int> a[MAXN];
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i].first>>a[i].second;
	int ptr_b=0, ptr_w=0;
	while(ptr_b<n && a[ptr_b].first!=1)
		ptr_b++;
	while(ptr_w<n && a[ptr_w].first!=0)
		ptr_w++;
	int flag;
	while(ptr_b<n && ptr_w<n) {
		long long int w=min(a[ptr_b].second, a[ptr_w].second);
		cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<w<<endl;

		a[ptr_b].second-=w;
		a[ptr_w].second-=w;

		flag=0;
		if(!a[ptr_w].second && !a[ptr_b].second)
			flag=1;

		if(!a[ptr_b].second) {
			ptr_b++;
			while(ptr_b<n && a[ptr_b].first!=1)
				ptr_b++;
		}

		if(flag && ptr_b<n)
			cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;

		if(!a[ptr_w].second) {
			ptr_w++;
			while(ptr_w<n && a[ptr_w].first!=0)
				ptr_w++;
		}
	}
	if(ptr_b<n) {
		if(flag) {
			ptr_b++;
			while(ptr_b<n && a[ptr_b].first!=1)
				ptr_b++;
		}
		ptr_w=n-1;
		while(a[ptr_w].first!=0)
			ptr_w--;
		while(ptr_b<n) {
			if(a[ptr_b].first==1)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_b++;
		}
	}
	else if(ptr_w<n) {
		ptr_b=n-1;
		while(a[ptr_b].first!=1)
			ptr_b--;
		while(ptr_w<n) {
			if(a[ptr_w].first==0)
				cout<<ptr_b+1<<" "<<ptr_w+1<<" "<<0<<endl;
			ptr_w++;
		}
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
    int num,v;
}b[100005],w[100005];
bool cmp(node a,node b)
{
    if(a.v<b.v)
    return true;
    else return false;
}
int main()
{
    int n,p,q;
    while(scanf("%d",&n)!=EOF)
    {
        int num1=0,num2=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&p,&q);
            if(p==1)
            {
                b[num1].v=q;
                b[num1++].num=i+1;
            }
            else
            {
                w[num2].v=q;
                w[num2++].num=i+1;
            }
        }
        sort(b,b+num1,cmp);
        sort(w,w+num2,cmp);
        int nowsite=0;
        for(int i=0;i<num1;i++)
        {
            for(int j=nowsite;j<num2-1;j++)
            {
                if(w[j].v<=b[i].v)
                {
                    b[i].v-=w[j].v;
                    printf("%d %d %d\n",b[i].num,w[j].num,w[j].v);
                }
                else
                {
                    nowsite=j;
                    break;
                }
            }
        }
        for(int i=0;i<num1;i++)
        {
            printf("%d %d %d\n",b[i].num,w[num2-1].num,b[i].v);
        }
    }
    return 0;
}


#include<cstdio>
#include<set>
#include<vector>
using namespace std;

long long tab[100005];
set< pair<int,int> > Q[2];
set<pair<int,int> >::iterator it;
bool usuniete[100005];
int main()
{
    int n,k,s;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&k,&s);
        Q[k].insert(make_pair(s,i));
    }
    for(int ile=0;ile<n-1;ile++)
    {
        pair<int,int> w,d;
        //printf("aa\n");
        if((*Q[0].begin()).first<(*Q[1].begin()).first)
        {
           // printf("jestem\n");
           w=*Q[0].begin();Q[0].erase(Q[0].begin());
           //it=Q[1].end();
           d=*Q[1].rbegin();//Q[1].erase(Q[1].rbegin().base());
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[1].insert(make_pair(d.first-w.first,d.second));
        }
        else
        {
           w=*Q[1].begin();Q[1].erase(Q[1].begin());
           //it=Q[0].end();
           d=*Q[0].rbegin();//Q[0].erase(Q[0].rbegin().base());
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[0].insert(make_pair(d.first-w.first,d.second));
        }
        //printf("mam %d %d\n",w.first,w.second);
    }
    return 0;
}


#include<cstdio>
#include<set>
using namespace std;

set< pair<int,int> > Q[2];
int main()
{
    int n,k,s;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&k,&s);
        Q[k].insert(make_pair(s,i));
    }
    for(int ile=0;ile<n-1;ile++)
    {
        pair<int,int> w,d;
        if((*Q[0].begin()).first<(*Q[1].begin()).first)
        {
           w=*Q[0].begin();Q[0].erase(Q[0].begin());
           d=*Q[1].rbegin();Q[1].erase(Q[1].find(d));
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[1].insert(make_pair(d.first-w.first,d.second));
        }
        else
        {
           w=*Q[1].begin();Q[1].erase(Q[1].begin());
           d=*Q[0].rbegin();Q[0].erase(Q[0].find(d));
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[0].insert(make_pair(d.first-w.first,d.second));
        }
    }
    return 0;
}


#include<cstdio>
#include<set>
using namespace std;

set< pair<int,int> > Q[2];
bool uzyte[100005];
int main()
{
    int n,k,s,zero,pierw;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&k,&s);
        if(k==0)zero=i;
        else pierw=i;
        Q[k].insert(make_pair(s,i));
    }
    pair<int,int> w,d;
    int ile=0;
    for(;ile<n-1;ile++)
    {
        if(Q[0].empty()||Q[1].empty())break;
        if((*Q[0].begin()).first<(*Q[1].begin()).first)
        {
           w=*Q[0].begin();Q[0].erase(Q[0].begin());
           d=*Q[1].rbegin();Q[1].erase(Q[1].find(d));
           uzyte[w.second]=true;
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[1].insert(make_pair(d.first-w.first,d.second));
        }
        else
        {
           w=*Q[1].begin();Q[1].erase(Q[1].begin());
           d=*Q[0].rbegin();Q[0].erase(Q[0].find(d));
           uzyte[w.second]=true;
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[0].insert(make_pair(d.first-w.first,d.second));
        }
    }
    if(Q[0].empty()&& !Q[1].empty())
        while(ile++<n-1)
        {
           w=*Q[1].begin();Q[1].erase(Q[1].begin());
           printf("%d %d 0\n",w.second+1,zero+1);
        }
    if(Q[1].empty()&& !Q[0].empty())
        while(ile++<n-1)
        {
           w=*Q[0].begin();Q[0].erase(Q[0].begin());
           printf("%d %d 0\n",w.second+1,pierw+1);
        }
    return 0;
}


#include<cstdio>
#include<set>
#include<vector>
using namespace std;

long long tab[100005];
set< pair<int,int> > Q[2];
bool usuniete[100005];
int main()
{
    int n,k,s;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&k,&s);
        Q[k].insert(make_pair(s,i));
    }
    for(int ile=0;ile<n-1;ile++)
    {
        pair<int,int> w,d;
        if((*Q[0].begin()).first>(*Q[1].begin()).first)
        {
           w=*Q[0].begin();Q[0].erase(Q[0].begin());
           d=*Q[1].rbegin();Q[1].erase(Q[1].end()--);
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[1].insert(make_pair(d.first-w.first,d.second));
        }
        else
        {
           w=*Q[1].begin();Q[1].erase(Q[1].begin());
           d=*Q[0].rbegin();Q[0].erase(Q[0].end()--);
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[0].insert(make_pair(d.first-w.first,d.second));
        }
        //printf("mam %d %d\n",w.first,w.second);
    }
    return 0;
}


#include<cstdio>
#include<queue>
#include<vector>
using namespace std;

long long tab[100005];
priority_queue< pair<int,int> > Q[2],QM[2];
bool usuniete[100005];
int main()
{
    int n,k,s;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&k,&s);
        Q[k].push(make_pair(-s,i));
        QM[k].push(make_pair(s,i));
    }
    for(int ile=0;ile<n-1;)
    {
        pair<int,int> w,d;
        if(Q[0].top().first>Q[1].top().first)
        {
           w=Q[0].top();Q[0].pop();
           if(usuniete[w.second])continue;
           do{d=QM[1].top();QM[1].pop();}
           while(usuniete[d.second]);
           usuniete[w.second]=true;
           printf("%d %d %d\n",w.second+1,d.second+1,-w.first);
           QM[1].push(make_pair(d.first+w.first,d.second));
           Q[1].push(make_pair(-d.first-w.first,d.second));
        }
        else
        {
           w=Q[1].top();Q[1].pop();
           if(usuniete[w.second])continue;
           do {d=QM[0].top();QM[0].pop();}
           while(usuniete[d.second]);
           usuniete[w.second]=true;
           printf("%d %d %d\n",w.second+1,d.second+1,-w.first);
           QM[0].push(make_pair(d.first+w.first,d.second));
           Q[0].push(make_pair(-d.first-w.first,d.second));
        }
        ile++;
        //printf("mam %d %d\n",w.first,w.second);
    }
    return 0;
}


#include<cstdio>
#include<set>
#include<vector>
using namespace std;

long long tab[100005];
set< pair<int,int> > Q[2];
set<pair<int,int> >::iterator it;
bool usuniete[100005];
int main()
{
    int n,k,s;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&k,&s);
        Q[k].insert(make_pair(s,i));
    }
    for(int ile=0;ile<n-1;ile++)
    {
        pair<int,int> w,d;
        if((*Q[0].begin()).first<(*Q[1].begin()).first)
        {
           w=*Q[0].begin();Q[0].erase(Q[0].begin());
           //it=Q[1].end();
           d=*Q[1].rbegin();Q[1].erase(Q[1].rbegin().base());
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[1].insert(make_pair(d.first-w.first,d.second));
        }
        else
        {
           w=*Q[1].begin();Q[1].erase(Q[1].begin());
           //it=Q[0].end();
           d=*Q[0].rbegin();Q[0].erase(Q[0].rbegin().base());
           printf("%d %d %d\n",w.second+1,d.second+1,w.first);
           Q[0].insert(make_pair(d.first-w.first,d.second));
        }
        printf("mam %d %d\n",w.first,w.second);
    }
    return 0;
}


#include<cstdio>
#include<queue>
#include<vector>
using namespace std;

long long tab[100005];
priority_queue< pair<int,int> > Q[2],QM[2];

int main()
{
    int n,k,s;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&k,&s);
        Q[k].push(make_pair(-s,i));
        QM[k].push(make_pair(s,i));
    }
    for(int ile=0;ile<n-1;ile++)
    {
        pair<int,int> w,d;
        if(Q[0].top().first>Q[1].top().first)
        {
           w=Q[0].top();Q[0].pop();
           d=QM[1].top();QM[1].pop();
           printf("%d %d %d\n",w.second+1,d.second+1,-w.first);
           QM[1].push(make_pair(d.first+w.first,d.second));
           Q[1].push(make_pair(-d.first-w.first,d.second));
        }
        else
        {
           w=Q[1].top();Q[1].pop();
           d=QM[0].top();QM[0].pop();
           printf("%d %d %d\n",w.second+1,d.second+1,-w.first);
           QM[0].push(make_pair(d.first+w.first,d.second));
           Q[0].push(make_pair(-d.first-w.first,d.second));
        }
        //printf("mam %d %d\n",w.first,w.second);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
#define A first
#define B second
#define mp make_pair
#define pii pair<int,int>
#define ins insert
#define pb push_back
typedef long long ll;
const int maxn=110000;
struct T1{
    int u,v,w;
}e[maxn];
struct T2{
    int c,s,n;
}a[maxn];
bool cmp(T2 a,T2 b){
    return a.s<b.s;
}
int n,tot;
int c[maxn],s[maxn];
int main(){
    //freopen("input.txt","r",stdin);
    scanf("%d",&n);
    for (int i=1; i<=n; i++){
        scanf("%d%d",&a[i].c,&a[i].s);
        a[i].n=i;
    }
    sort(a+1,a+1+n,cmp);
    for (int i=1; i<=n; i++)
        for (int j=i+1; j<=n; j++)
            if ((a[i].c^a[j].c&1==1)&&a[j].s>=a[i].s){
                a[j].s-=a[i].s;
                tot++;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=a[i].s;
                break;
            }
    for (int i=1; i<n; i++)
        printf("%d %d %d\n",e[i].u,e[i].v,e[i].w);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
#define A first
#define B second
#define mp make_pair
#define pii pair<int,int>
#define ins insert
#define pb push_back
typedef long long ll;
const int maxn=110000;
struct T1{
    int u,v,w;
}e[maxn];
struct T2{
    int c,s,n;
}a[maxn];
bool cmp(T2 a,T2 b){
    return a.s<b.s;
}
int n,tot;
int c[maxn],s[maxn];
int main(){
    //freopen("input.txt","r",stdin);
    scanf("%d",&n);
    for (int i=1; i<=n; i++){
        scanf("%d%d",&a[i].c,&a[i].s);
        a[i].n=i;
    }
    sort(a+1,a+1+n,cmp);
    for (int i=1; i<=n; i++)
        for (int j=i+1; j<=n; j++)
            if ((a[i].c^a[j].c&1==1)&&a[j].s>=a[i].s){
                a[j].s-=a[i].s;
                tot++;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=a[i].s;
                a[i].s=0;
                break;
            }
    for (int i=1; i<=n; i++)
        if (a[i].s>0)
            for (int j=i+1; j<=n; j++){
                int tt=min(a[i].s,a[j].s);
                a[i].s-=tt;
                a[j].s-=tt;
                tot++;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=tt;
                if (a[i].s==0) break;
            }
    for (int i=1; i<n; i++)
        printf("%d %d %d\n",e[i].u,e[i].v,e[i].w);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
#define A first
#define B second
#define mp make_pair
#define pii pair<int,int>
#define ins insert
#define pb push_back
typedef long long ll;
const int maxn=110000;
vector<pii> a,b;
int n;
int main(){
    //freopen("input.txt","r",stdin);
    scanf("%d",&n);
    for (int i=1; i<=n; i++){
        int c,s,num=i;
        scanf("%d%d",&c,&s);
        if (c) a.pb(mp(s,num)); else
           b.pb(mp(s,num));
    }
    sort(a.begin(),a.end());
    sort(b.begin(),b.end());
    for (int i=0,j=0,tot=1; tot<n; tot++){
        int tt=min(a[i].A,b[j].A);
        a[i].A-=tt;
        b[j].A-=tt;
        printf("%d %d %d\n",a[i].B,b[j].B,tt);
        if (a[i].A==0&&i+1<a.size()) i++; else  j++;
    }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
#define A first
#define B second
#define mp make_pair
#define pii pair<int,int>
#define ins insert
#define pb push_back
typedef long long ll;
const int maxn=110000;
struct T1{
    int u,v,w;
}e[maxn];
struct T2{
    int c,s,n;
}a[maxn];
bool cmp(T2 a,T2 b){
    return a.s<b.s;
}
int n,tot;
int c[maxn],s[maxn];
int main(){
    //freopen("input.txt","r",stdin);
    scanf("%d",&n);
    for (int i=1; i<=n; i++){
        scanf("%d%d",&a[i].c,&a[i].s);
        a[i].n=i;
    }
    sort(a+1,a+1+n,cmp);
    for (int i=1; i<=n; i++)
        for (int j=i+1; j<=n; j++)
            if ((a[i].c^a[j].c&1==1)&&a[j].s>=a[i].s){
                a[j].s-=a[i].s;
                tot++;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=a[i].s;
                a[i].s=0;
                break;
            }
    for (int i=1; i<=n; i++)
        if (a[i].s>0)
            for (int j=i+1; j<=n; j++)
                if ((a[i].c^a[j].c&1==1)&&a[j].s>0){
                int tt=min(a[i].s,a[j].s);
                a[i].s-=tt;
                a[j].s-=tt;
                tot++;
                //cout<<a[i].n<<' '<<a[j].n<<' '<<tt<<"   444"<<endl;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=tt;
                if (a[i].s==0) break;
            }
    for (int i=1; i<n; i++)
        printf("%d %d %d\n",e[i].u,e[i].v,e[i].w);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
#define A first
#define B second
#define mp make_pair
#define pii pair<int,int>
#define ins insert
#define pb push_back
typedef long long ll;
const int maxn=110000;
struct T1{
    int u,v,w;
}e[maxn];
struct T2{
    int c,s,n;
}a[maxn];
bool cmp(T2 a,T2 b){
    return a.s<b.s;
}
int n,tot;
int c[maxn],s[maxn];
int main(){
    //freopen("input.txt","r",stdin);
    scanf("%d",&n);
    for (int i=1; i<=n; i++){
        scanf("%d%d",&a[i].c,&a[i].s);
        a[i].n=i;
    }
    sort(a+1,a+1+n,cmp);
    for (int i=1; i<=n; i++)
        for (int j=i+1; j<=n; j++)
            if ((a[i].c^a[j].c&1==1)){
                int tt=min(a[i].s,a[j].s);
                a[j].s-=tt;
                a[i].s-=tt;
                tot++;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=tt;
                if (a[i].s==0) break;
            }
    for (int i=1; i<=n; i++)
    if (a[i].s>0) cout<<a[i].s<<endl;
    for (int i=1; i<n; i++)
        printf("%d %d %d\n",e[i].u,e[i].v,e[i].w);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
#define A first
#define B second
#define mp make_pair
#define pii pair<int,int>
#define ins insert
#define pb push_back
typedef long long ll;
const int maxn=110000;
struct T1{
    int u,v,w;
}e[maxn];
struct T2{
    int c,s,n;
}a[maxn];
bool cmp(T2 a,T2 b){
    return a.s<b.s;
}
int n,tot;
int c[maxn],s[maxn];
int b[maxn];
int main(){
    //freopen("input.txt","r",stdin);
    scanf("%d",&n);
    for (int i=1; i<=n; i++){
        scanf("%d%d",&a[i].c,&a[i].s);
        a[i].n=i;
    }
    sort(a+1,a+1+n,cmp);
    for (int i=1; i<=n; i++)
        for (int j=i+1; j<=n; j++)
            if ((a[i].c^a[j].c&1==1)&&a[j].s>=a[i].s){
                a[j].s-=a[i].s;
                tot++;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=a[i].s;
                a[i].s=0;
                b[a[i].n]=1;
                b[a[j].n]=1;
                break;
            }
    for (int i=1; i<=n; i++)
        if (a[i].s>0)
            for (int j=i+1; j<=n; j++)
                if ((a[i].c^a[j].c&1==1)&&a[j].s>0){
                int tt=min(a[i].s,a[j].s);
                a[i].s-=tt;
                a[j].s-=tt;
                tot++;
                //cout<<a[i].n<<' '<<a[j].n<<' '<<tt<<"   444"<<endl;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=tt;
                b[a[i].n]=1;
                b[a[j].n]=1;
                if (a[i].s==0) break;
            }
    for (int i=1; i<=n; i++)
        if (b[i]==0){
            tot++;
            e[tot].u=i;
            e[tot].v=1;
            e[tot].w=0;
        }
    for (int i=1; i<n; i++)
        printf("%d %d %d\n",e[i].u,e[i].v,e[i].w);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
#define A first
#define B second
#define mp make_pair
#define pii pair<int,int>
#define ins insert
#define pb push_back
typedef long long ll;
const int maxn=110000;
struct T1{
    int u,v,w;
}e[maxn];
struct T2{
    int c,s,n;
}a[maxn];
bool cmp(T2 a,T2 b){
    return a.s<b.s;
}
int n,tot;
int c[maxn],s[maxn];
int main(){
    //freopen("input.txt","r",stdin);
    scanf("%d",&n);
    for (int i=1; i<=n; i++){
        scanf("%d%d",&a[i].c,&a[i].s);
        a[i].n=i;
    }
    sort(a+1,a+1+n,cmp);
    for (int i=1; i<=n; i++)
        for (int j=i+1; j<=n; j++)
            if ((a[i].c^a[j].c&1)==1){
                a[j].s-=a[i].s;
                tot++;
                e[tot].u=a[i].n;
                e[tot].v=a[j].n;
                e[tot].w=a[i].s;
                break;
            }
    for (int i=1; i<n; i++)
        printf("%d %d %d\n",e[i].u,e[i].v,e[i].w);
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
using namespace std;
const int MAXN=100010;
const int INF=2000000010;
const long long INFLL=999999999999999999ll;
typedef long long lld;
struct Node
{
int idx, val;
bool operator <(const Node &e) const
{
return (val > e.val);
}
};
priority_queue<Node> nodes[2];
int black;
int white;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int type,v;
        scanf("%d%d",&type,&v);
        Node N;
        N.val=v;
        N.idx=i+1;
        nodes[type].push(N);
        if(!type) black=i+1;
        else white=i+1;
    }
    int added=1;
    while(added<n)
    {
        if(nodes[0].empty())
        {
            Node next=nodes[1].top();
            nodes[1].pop();
            printf("%d %d %d\n",black,next.idx,0);
            added++;
            continue;
        }
        if(nodes[1].empty())
        {
            Node next=nodes[0].top();
            nodes[0].pop();
            printf("%d %d %d\n",white,next.idx,0);
            added++;
            continue;
        }
        Node firstBlack=nodes[0].top();
        nodes[0].pop();
        Node firstWhite=nodes[1].top();
        nodes[1].pop();
        if(firstBlack.val<=firstWhite.val)
        {
            Node N;
            N.val=firstWhite.val-firstBlack.val;
            N.idx=firstWhite.idx;
            nodes[1].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstBlack.val);
            black=firstBlack.idx;
        }
        else
        {
            Node N;
            N.val=firstBlack.val-firstWhite.val;
            N.idx=firstBlack.idx;
            nodes[0].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstWhite.val);
            white=firstWhite.idx;
        }
        added++;
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
using namespace std;
const int MAXN=100010;
const int INF=2000000010;
const long long INFLL=999999999999999999ll;
typedef long long lld;
struct Node
{
int idx, val;
bool operator <(const Node &e) const
{
return (val > e.val);
}
};
priority_queue<Node> nodes[2];
int black;
int white;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int type,v;
        scanf("%d%d",&type,&v);
        Node N;
        N.val=v;
        N.idx=i+1;
        nodes[type].push(N);
        if(!type) black=i+1;
        else white=i+1;
    }
    int added=1;
    while(added<n)
    {
        if(nodes[0].empty())
        {
            Node next=nodes[1].top();
            nodes[1].pop();
            printf("%d %d %d\n",black,next.idx,0);
            added++;
            continue;
        }
        if(nodes[1].empty())
        {
            Node next=nodes[0].top();
            nodes[0].pop();
            printf("%d %d %d\n",white,next.idx,0);
            added++;
            continue;
        }
        Node firstBlack=nodes[0].top();
        nodes[0].pop();
        Node firstWhite=nodes[1].top();
        nodes[1].pop();
        if(firstBlack.val==firstWhite.val)
        {
            printf("%d %d %d\n",firstWhite.idx,firstBlack.idx,firstWhite.val);
            added+=2;
        }
        else
        if(firstBlack.val<firstWhite.val)
        {
            Node N;
            N.val=firstWhite.val-firstBlack.val;
            N.idx=firstWhite.idx;
            nodes[1].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstBlack.val);
            black=firstBlack.idx;
        }
        else
        {
            Node N;
            N.val=firstBlack.val-firstWhite.val;
            N.idx=firstBlack.idx;
            nodes[0].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstWhite.val);
            white=firstWhite.idx;
        }
        added++;
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
using namespace std;
const int MAXN=100010;
const int INF=2000000010;
const long long INFLL=999999999999999999ll;
typedef long long lld;
struct Node
{
int idx, val;
bool operator <(const Node &e) const
{
return (val > e.val);
}
};
priority_queue<Node> nodes[2];
int black;
int white;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int type,v;
        scanf("%d%d",&type,&v);
        Node N;
        N.val=v;
        N.idx=i+1;
        nodes[type].push(N);
        if(!type) black=i+1;
        else white=i+1;
    }
    int added=1;
    while(added<n)
    {
        if(nodes[0].empty())
        {
            Node next=nodes[1].top();
            nodes[1].pop();
            printf("%d %d %d\n",black,next.idx,0);
            added++;
            continue;
        }
        if(nodes[1].empty())
        {
            Node next=nodes[0].top();
            nodes[0].pop();
            printf("%d %d %d\n",white,next.idx,0);
            added++;
            continue;
        }
        Node firstBlack=nodes[0].top();
        nodes[0].pop();
        Node firstWhite=nodes[1].top();
        nodes[1].pop();
        if(firstBlack.val<firstWhite.val)
        {
            Node N;
            N.val=firstWhite.val-firstBlack.val;
            N.idx=firstWhite.idx;
            nodes[1].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstBlack.val);
        }
        else
        {
            Node N;
            N.val=firstBlack.val-firstWhite.val;
            N.idx=firstBlack.idx;
            nodes[0].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstWhite.val);
        }
        added++;
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
using namespace std;
const int MAXN=100010;
const int INF=2000000010;
const long long INFLL=999999999999999999ll;
typedef long long lld;
struct Node
{
int idx, val;
bool operator <(const Node &e) const
{
return (val > e.val);
}
};
priority_queue<Node> nodes[2];
int black;
int white;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int type,v;
        scanf("%d%d",&type,&v);
        Node N;
        N.val=v;
        N.idx=i+1;
        nodes[type].push(N);
        if(!type) black=i+1;
        else white=i+1;
    }
    int added=1;
    while(added<n)
    {
        if(nodes[0].empty())
        {
            Node next=nodes[1].top();
            nodes[1].pop();
            printf("%d %d %d\n",black,next.idx,0);
            added++;
            continue;
        }
        if(nodes[1].empty())
        {
            Node next=nodes[0].top();
            nodes[0].pop();
            printf("%d %d %d\n",white,next.idx,0);
            added++;
            continue;
        }
        Node firstBlack=nodes[0].top();
        nodes[0].pop();
        Node firstWhite=nodes[1].top();
        nodes[1].pop();
        if(firstBlack.val==firstWhite.val)
        {
            printf("%d %d %d\n",firstWhite.idx,firstBlack.idx,firstWhite.val);
            printf("%d %d %d\n",firstBlack.idx,white,0);
            added+=2;
        }
        else
        if(firstBlack.val<firstWhite.val)
        {
            Node N;
            N.val=firstWhite.val-firstBlack.val;
            N.idx=firstWhite.idx;
            nodes[1].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstBlack.val);
            black=firstBlack.idx;
        }
        else
        {
            Node N;
            N.val=firstBlack.val-firstWhite.val;
            N.idx=firstBlack.idx;
            nodes[0].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstWhite.val);
            white=firstWhite.idx;
        }
        added++;
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
using namespace std;
const int MAXN=100010;
const int INF=2000000010;
const long long INFLL=999999999999999999ll;
typedef long long lld;
struct Node
{
int idx, val;
bool operator <(const Node &e) const
{
return (val > e.val);
}
};
priority_queue<Node> nodes[2];
int black;
int white;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int type,v;
        scanf("%d%d",&type,&v);
        Node N;
        N.val=v;
        N.idx=i+1;
        nodes[type].push(N);
        if(!type) black=i+1;
        else white=i+1;
    }
    int added=1;
    while(added<n)
    {
        if(nodes[0].empty())
        {
            Node next=nodes[1].top();
            nodes[1].pop();
            printf("%d %d %d\n",black,next.idx,0);
            added++;
            continue;
        }
        if(nodes[1].empty())
        {
            Node next=nodes[0].top();
            nodes[0].pop();
            printf("%d %d %d\n",white,next.idx,0);
            added++;
            continue;
        }
        Node firstBlack=nodes[0].top();
        nodes[0].pop();
        Node firstWhite=nodes[1].top();
        nodes[1].pop();
        if(firstBlack.val==firstWhite.val)
        {
            printf("%d %d %d\n",firstWhite.idx,firstBlack.idx,firstWhite.val);
            ++added;
        }
        else
        if(firstBlack.val<firstWhite.val)
        {
            Node N;
            N.val=firstWhite.val-firstBlack.val;
            N.idx=firstWhite.idx;
            nodes[1].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstBlack.val);
            black=firstBlack.idx;
        }
        else
        {
            Node N;
            N.val=firstBlack.val-firstWhite.val;
            N.idx=firstBlack.idx;
            nodes[0].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstWhite.val);
            white=firstWhite.idx;
        }
        added++;
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
using namespace std;
const int MAXN=100010;
const int INF=2000000010;
const long long INFLL=999999999999999999ll;
typedef long long lld;
struct Node
{
int idx, val;
bool operator <(const Node &e) const
{
return (val > e.val);
}
};
priority_queue<Node> nodes[2];
int black;
int white;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int type,v;
        scanf("%d%d",&type,&v);
        Node N;
        N.val=v;
        N.idx=i+1;
        nodes[type].push(N);
        if(!type) black=i+1;
        else white=i+1;
    }
    int added=1;
    while(added<n)
    {
        if(nodes[0].empty())
        {
            Node next=nodes[1].top();
            nodes[1].pop();
            printf("%d %d %d\n",black,next.idx,0);
            added++;
            continue;
        }
        if(nodes[1].empty())
        {
            Node next=nodes[0].top();
            nodes[0].pop();
            printf("%d %d %d\n",white,next.idx,0);
            added++;
            continue;
        }
        Node firstBlack=nodes[0].top();
        nodes[0].pop();
        Node firstWhite=nodes[1].top();
        nodes[1].pop();
        if(firstBlack.val<firstWhite.val)
        {
            Node N;
            N.val=firstWhite.val-firstBlack.val;
            N.idx=firstWhite.idx;
            nodes[1].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstBlack.val);
            black=firstBlack.idx;
        }
        else
        {
            Node N;
            N.val=firstBlack.val-firstWhite.val;
            N.idx=firstBlack.idx;
            nodes[0].push(N);
            printf("%d %d %d\n",firstBlack.idx,firstWhite.idx,firstWhite.val);
            white=firstWhite.idx;
        }
        added++;
    }
    return 0;
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[MAXN][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return n.c-m.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);
	qsort(B , b , sizeof(mal) , so);
	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a  &&  !b)	break;

			if(!a)	{b--; continue;}
			if(!b)	{a--;continue;}
			ans[x][0] = B[b].id , ans[x][1] = A[a-1].id;
			a--; b--;
			ans[x++][2] = 0;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[100009][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return n.c-m.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);

	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a)	break;

			ans[x][0] = A[a].id;
			ans[x][1] = B[b-1].id;
			ans[x++][2] = 0;
			a--;	b--;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[100009][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return m.c-n.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);

	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a)	break;

			ans[x][0] = A[a].id;
			ans[x][1] = B[b-1].id;
			ans[x++][2] = 0;
			a--;	b--;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[100009][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return n.c-m.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);
	qsort(B , b , sizeof(mal) , so);
	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a)	break;

			ans[x][0] = A[a].id;
			ans[x][1] = B[b-1].id;
			ans[x++][2] = 0;
			a--;	b--;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[MAXN][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return n.c-m.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);
	qsort(B , b , sizeof(mal) , so);
	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a  &&  !a)	break;

			if(!a)	ans[x][0] = A[a].id , ans[x][1] = B[b-1].id , b--;
			else if(!b)	ans[x][0] = B[b].id , ans[x][1] = A[a-1].id , a--;
			else ans[x][0] = B[b].id , ans[x][1] = A[a-1].id , a-- , b--;
			ans[x++][2] = 0;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[100009][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return m.c-n.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);

	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a)	break;

			ans[x][0] = A[a].id;
			ans[x][1] = A[a-1].id;
			ans[x++][2] = 0;
			a--;	b--;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[100009][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return m.c-n.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);

	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a)	break;

			ans[x][0] = A[a].id;
			ans[x][1] = A[b-1].id;
			ans[x++][2] = 0;
			a--;	b--;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[100009][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return n.c-m.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);
	for(int h=0; h<a; h++)	printf("%d\n",A[h].c);
	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a)	break;

			ans[x][0] = A[a].id;
			ans[x][1] = B[b-1].id;
			ans[x++][2] = 0;
			a--;	b--;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


# include <stdio.h>
# include <algorithm>
# include <vector>
# include <stdlib.h>

# define MAXN 100009
# define mi(x,y) (x<y ? x : y)

using namespace std;

struct mal
{
	int id,c;
};

int n,x,y,a,b;

mal A[MAXN];
mal B[MAXN];

int ans[MAXN][4];

int so(void const *x,void const *y)
{
	mal m = *(mal*)x;
	mal n = *(mal*)y;

	return n.c-m.c;
}

int main()
{
	scanf("%d",&n);

	for(int h=0; h<n; h++)
	{
		scanf("%d %d",&x,&y);
		if(x)	B[b].c = y , B[b++].id = h+1;
		else 	A[a].c = y , A[a++].id = h+1;
	}

	qsort(A , a , sizeof(mal) , so);
	qsort(B , b , sizeof(mal) , so);
	a--;	b--;

	x = 0;

	while(1)
	{
		if(A[a].c == B[b].c)
		{
			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = A[a].c;

			if(!a  &&  !b)	break;

			if(!a)	{b--; continue;}
			else if(!b)	{a--;continue;}
			else ans[x][0] = B[b].id , ans[x][1] = A[a-1].id , a-- , b--;
			ans[x++][2] = -9;
		}

		else
		{
			int k = mi(A[a].c,B[b].c);

			ans[x][0] = A[a].id;
			ans[x][1] = B[b].id;
			ans[x++][2] = k;

			if(A[a].c < B[b].c)	a-- , B[b].c -= k;
			else 	b-- , A[a].c -= k;
		}
	}

	for(int h=0; h<x; h++)	printf("%d %d %d\n",ans[h][0],ans[h][1],ans[h][2]);
}


#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <memory.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double,double> pdd;

typedef vector<int> vi;
typedef vector<pair<int, int > > vii;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<ld> vld;

typedef vector<vi> vvi;
typedef vector<vii> vvii;
typedef vector<vll> vvll;
typedef vector<vs> vvs;

typedef map<int, int> mii;
typedef map<int, string> mis;
typedef map<string, int> msi;
typedef map<string, string> mss;

#define sz(a) (int)((a).size())
#define len(a) (int)((a).length())

#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define Sort(x) sort(x.begin(),x.end())
#define Reverse(x) reverse(x.begin(),x.end())

#define forr(i,n) for (int i = 0; i < (n); ++i)
#define fori(n) forr(i,n)
#define forj(n) forr(j,n)
#define fork(n) forr(k,n)
#define forjn forj(n)
#define forjm forj(m)
#define forkm fork(m)
#define foria(a) fori(sz(a))
#define foriv foria(v)
#define foris fori(len(s))
#define forja(a) forj(sz(a))
#define forjv forj(v)
#define forjs forj(len(s))
#define FOREACH(it,x) for(__typeof((x).begin()) it=(x.begin()); it!=(x).end(); ++it)

#define MAX(a,b) (a>b?a:b)
#define MIN(a,b) (a<b?a:b)

#define read cin>>
#define write cout<<
#define writeln write endl

#define readt int aaa; read aaa;
#define gett (bbb+1)
#define fort forr(bbb,aaa)

#define issa(a,s) istringstream a(s);
#define iss(s) issa(ss,s);

ld dis(ld x, ld y) {return sqrt(x*x+y*y);}
const ld PI = acos(ld(0.0))*2;
const int INF = 1<<30;

bool is_palindrome(const string &s, int start, int end) {
  int siz = end - start + 1;
  if (siz % 2 == 0) {
    int middle = start + siz/2;
    int i;
    for (i = 0; middle - 1 - i >= 0 && middle+i <= end && s[middle-1-i] == s[middle+i]; i++);
    if (middle - i - 1 < 0 || middle+i > end)
      return true;
  } else {
    int middle = start + siz/2;
    int i;
    for (i = 1; middle - i >= 0 && middle+i <= end && s[middle-i]==s[middle+i]; i++);
    if (middle - i < 0 || middle+i > end)
      return true;
  }
  return false;
}
//Polya-Burnside theory : (n^6+3n^4+12n^3+8n^2)/24
int euclidd,euclidx,euclidy;
void extendedeuclid(int a,int b)
{
  if(b==0)
  {
    euclidd=a;
    euclidx=1;
    euclidy=0;
    return ;
  }
  extendedeuclid(b,a%b);
  int d1,x1,y1;
  d1=euclidd;
  x1=euclidx;
  y1=euclidy;
  euclidx=y1;
  euclidy=x1-((a/b)*y1);
}
double dist_2point(double x1,double y1,double x2,double y2)
{
  double d;
  d=sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
  return d;
}
int binary_search(int a[],int n,int l,int u)
{
  int mid;
  if(l>u)
    return 0;
  mid=floor(l+u)/2;
  if(a[mid]==n)
    return mid;
  else if(a[mid]>n)
    return binary_search(a,n,l,mid-1);
  else
    return binary_search(a,n,mid+1,u);
}
long gcd(long a,long b)
{
  while(b>0) {
    a=a%b;
    a=a^b;
    b=b^a;
    a=a^b;
  }
  return a;
}
long lcm(long a,long b)
{
  long x=(a*b)/gcd(a,b);
  return x;
}
long is_prime(long n)
{
  long ii;
  if (n == 1)
    return 0;
  if (n == 2)
    return 1;
  if (n%2 == 0)
    return 0;
  for (ii=3;ii*ii<=n;ii=ii+2)
    if (n%ii == 0)
      return 0;
  return 1;
}
long long bigmod(long long b,long long p,long long m)
{
  if(b==0) return 0;
  long long x,power;
  x=1;
  power=b%m;
  while(p)
  {
    if(p%2==1)
      x=(x*power)%m;
    power=(power*power)%m;
    p=p/2;
  }
  return x;
}
void assert(bool b)
{
  if (!b)
    throw 0;
}
template <int n>
struct nbest
{
  vector<pair<ll, int> > p;
  nbest():p(n+1)
  {
    foria(p) p[i].first = p[i].second = -1;
  }
  void add(ll value, int key)
  {
    p[n] = make_pair(value, key);
    sort(rall(p));
  }
  ll getValue(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].first;
  }
  int getKey(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second;
  }
  bool has(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second != -1;
  }
};

template <typename T>
void dumpContents(const vector<T>& v,
                  const string& msg="")
{
  cerr << "### " << msg << " ###\n";
  if (v.empty())
    return;

  for (typename vector<T>::const_iterator it=v.begin();
       it != v.end(); ++it) {
    cerr << *it << " ";
  }
  cerr << endl;
}

void printBit(ull S, int n=64){
  for(int i=n-1; i>=0; i--){
    if(S>>i & 1) cout << 1;
    else cout << 0;
  }
  cout << endl;
}

void subsetCombination(int n, int k){
  ull S = (1ULL << k) - 1ULL;
  ull E = ~((1ULL << n) - 1ULL);
  while(!(S & E)){
    printBit(S, n);
    ull smallest = S & -S;
    ull ripple = S + smallest;
    ull nsmallest = ripple & -ripple;
    S = ripple | (((nsmallest / smallest) >> 1) - 1);
  }
}

void grayCode(int n){
  int N = 1 << n;
  ull G = 0;
  for(int i=0; i<N; i++){
    G = i ^ (i >> 1ULL);
    printBit(G, n);
  }
}

int bitCount(ull n)
{
  int cnt = 0;
  while(n != 0) {
    cnt += 1;
    n &= (n-1); // the lowest 1 is turned to 0.
  }
  return cnt;
}

// ========== end of template ==========

// === global variables

const int WHITE = 0;
const int BLACK = 1;
const int EMPTY = 2;

int n;
vi node_colors;
vll node_values;
vi black_nodes;
vi white_nodes;

int black_remains = 0;
int white_remains = 0;
std::stack<std::string> results;

// === functions

void output();

void initialize()
{
  // count black and white nodes
  for (int i=0; i<n; ++i) {
    if (node_colors[i] == BLACK)
      black_remains += 1;
    else if (node_colors[i] == WHITE)
      white_remains += 1;
  }
}

void solve()
{
  // the smaller group should have a leaf
  int leaf_color = EMPTY;
  if (black_remains < white_remains)
    leaf_color = WHITE;
  else if (white_remains < black_remains)
    leaf_color = BLACK;

  for (int v=0; v<n; ++v) {
    const int color = node_colors[v];
    if (color == EMPTY) continue;
    if (leaf_color != EMPTY && leaf_color != color) continue;
    const ll  value = node_values[v];

    // check finish
    if (value == 0 &&
        (black_remains + white_remains) == 1) {
      output();
      exit(0);
    }

    // try one of the next node candidates
    for (int c=0; c<n; ++c) {
      if (c==v ||
          node_colors[c] == EMPTY ||
          node_colors[c] == color ||
          node_values[c] < value) {
        continue;
      }

      // push the next node
      node_colors[v] = EMPTY;
      node_values[c] -= value;
      if (color == BLACK)
        black_remains -= 1;
      else
        white_remains -= 1;
      ostringstream out;
      out << v+1 << " " << c+1 << " " << value;
      results.push(out.str());

      solve();

      // pop the next node
      node_colors[v] = color;
      node_values[c] += value;
      if (color == BLACK)
        black_remains += 1;
      else
        white_remains += 1;
      results.pop();
    }
  }
}

void output()
{
  while (!results.empty()) {
    std::cout << results.top() << "\n";
    results.pop();
  }
}

int main(int argc, char** argv)
{
  ios::sync_with_stdio(false);
  //string line;

  // the first line
  {
    read n;
    node_colors.resize(n);
    node_values.resize(n);
    for (int i=0; i<n; ++i) {
      cin.ignore(); // skip carriage return
      int color;
      ll  value;
      read color;
      read value;
      node_colors[i] = color;
      node_values[i] = value;
      if (color == BLACK)
        black_nodes.push_back(i);
      else
        white_nodes.push_back(i);
    }
  }

  initialize();
  solve();

  return 0;
}


#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <memory.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double,double> pdd;

typedef vector<int> vi;
typedef vector<pair<int, int > > vii;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<ld> vld;

typedef vector<vi> vvi;
typedef vector<vii> vvii;
typedef vector<vll> vvll;
typedef vector<vs> vvs;

typedef map<int, int> mii;
typedef map<int, string> mis;
typedef map<string, int> msi;
typedef map<string, string> mss;

#define sz(a) (int)((a).size())
#define len(a) (int)((a).length())

#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define Sort(x) sort(x.begin(),x.end())
#define Reverse(x) reverse(x.begin(),x.end())

#define forr(i,n) for (int i = 0; i < (n); ++i)
#define fori(n) forr(i,n)
#define forj(n) forr(j,n)
#define fork(n) forr(k,n)
#define forjn forj(n)
#define forjm forj(m)
#define forkm fork(m)
#define foria(a) fori(sz(a))
#define foriv foria(v)
#define foris fori(len(s))
#define forja(a) forj(sz(a))
#define forjv forj(v)
#define forjs forj(len(s))
#define FOREACH(it,x) for(__typeof((x).begin()) it=(x.begin()); it!=(x).end(); ++it)

#define MAX(a,b) (a>b?a:b)
#define MIN(a,b) (a<b?a:b)

#define read cin>>
#define write cout<<
#define writeln write endl

#define readt int aaa; read aaa;
#define gett (bbb+1)
#define fort forr(bbb,aaa)

#define issa(a,s) istringstream a(s);
#define iss(s) issa(ss,s);

ld dis(ld x, ld y) {return sqrt(x*x+y*y);}
const ld PI = acos(ld(0.0))*2;
const int INF = 1<<30;

bool is_palindrome(const string &s, int start, int end) {
  int siz = end - start + 1;
  if (siz % 2 == 0) {
    int middle = start + siz/2;
    int i;
    for (i = 0; middle - 1 - i >= 0 && middle+i <= end && s[middle-1-i] == s[middle+i]; i++);
    if (middle - i - 1 < 0 || middle+i > end)
      return true;
  } else {
    int middle = start + siz/2;
    int i;
    for (i = 1; middle - i >= 0 && middle+i <= end && s[middle-i]==s[middle+i]; i++);
    if (middle - i < 0 || middle+i > end)
      return true;
  }
  return false;
}
//Polya-Burnside theory : (n^6+3n^4+12n^3+8n^2)/24
int euclidd,euclidx,euclidy;
void extendedeuclid(int a,int b)
{
  if(b==0)
  {
    euclidd=a;
    euclidx=1;
    euclidy=0;
    return ;
  }
  extendedeuclid(b,a%b);
  int d1,x1,y1;
  d1=euclidd;
  x1=euclidx;
  y1=euclidy;
  euclidx=y1;
  euclidy=x1-((a/b)*y1);
}
double dist_2point(double x1,double y1,double x2,double y2)
{
  double d;
  d=sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
  return d;
}
int binary_search(int a[],int n,int l,int u)
{
  int mid;
  if(l>u)
    return 0;
  mid=floor(l+u)/2;
  if(a[mid]==n)
    return mid;
  else if(a[mid]>n)
    return binary_search(a,n,l,mid-1);
  else
    return binary_search(a,n,mid+1,u);
}
long gcd(long a,long b)
{
  while(b>0) {
    a=a%b;
    a=a^b;
    b=b^a;
    a=a^b;
  }
  return a;
}
long lcm(long a,long b)
{
  long x=(a*b)/gcd(a,b);
  return x;
}
long is_prime(long n)
{
  long ii;
  if (n == 1)
    return 0;
  if (n == 2)
    return 1;
  if (n%2 == 0)
    return 0;
  for (ii=3;ii*ii<=n;ii=ii+2)
    if (n%ii == 0)
      return 0;
  return 1;
}
long long bigmod(long long b,long long p,long long m)
{
  if(b==0) return 0;
  long long x,power;
  x=1;
  power=b%m;
  while(p)
  {
    if(p%2==1)
      x=(x*power)%m;
    power=(power*power)%m;
    p=p/2;
  }
  return x;
}
void assert(bool b)
{
  if (!b)
    throw 0;
}
template <int n>
struct nbest
{
  vector<pair<ll, int> > p;
  nbest():p(n+1)
  {
    foria(p) p[i].first = p[i].second = -1;
  }
  void add(ll value, int key)
  {
    p[n] = make_pair(value, key);
    sort(rall(p));
  }
  ll getValue(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].first;
  }
  int getKey(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second;
  }
  bool has(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second != -1;
  }
};

template <typename T>
void dumpContents(const vector<T>& v,
                  const string& msg="")
{
  cerr << "### " << msg << " ###\n";
  if (v.empty())
    return;

  for (typename vector<T>::const_iterator it=v.begin();
       it != v.end(); ++it) {
    cerr << *it << " ";
  }
  cerr << endl;
}

void printBit(ull S, int n=64){
  for(int i=n-1; i>=0; i--){
    if(S>>i & 1) cout << 1;
    else cout << 0;
  }
  cout << endl;
}

void subsetCombination(int n, int k){
  ull S = (1ULL << k) - 1ULL;
  ull E = ~((1ULL << n) - 1ULL);
  while(!(S & E)){
    printBit(S, n);
    ull smallest = S & -S;
    ull ripple = S + smallest;
    ull nsmallest = ripple & -ripple;
    S = ripple | (((nsmallest / smallest) >> 1) - 1);
  }
}

void grayCode(int n){
  int N = 1 << n;
  ull G = 0;
  for(int i=0; i<N; i++){
    G = i ^ (i >> 1ULL);
    printBit(G, n);
  }
}

int bitCount(ull n)
{
  int cnt = 0;
  while(n != 0) {
    cnt += 1;
    n &= (n-1); // the lowest 1 is turned to 0.
  }
  return cnt;
}

// ========== end of template ==========

// === global variables

const int WHITE = 0;
const int BLACK = 1;
const int EMPTY = 2;

int n;
vi node_colors;
vll node_values;
typedef std::multimap<ll,int> nodes_t;
nodes_t black_nodes;
nodes_t white_nodes;

int black_remains = 0;
int white_remains = 0;
std::stack<std::string> results;

// === functions

void output();

void initialize()
{
  // count black and white nodes
  for (int i=0; i<n; ++i) {
    if (node_colors[i] == BLACK)
      black_remains += 1;
    else if (node_colors[i] == WHITE)
      white_remains += 1;
  }
}

void solve()
{
  // the smaller group should have a leaf
  int leaf_color = EMPTY;
  if (black_remains < white_remains)
    leaf_color = WHITE;
  else if (white_remains < black_remains)
    leaf_color = BLACK;

  for (int v=0; v<n; ++v) {
    const int color = node_colors[v];
    if (color == EMPTY) continue;
    if (leaf_color != EMPTY && leaf_color != color) continue;
    const ll  value = node_values[v];

    // check finish
    if (value == 0 &&
        (black_remains + white_remains) == 1) {
      output();
      exit(0);
    }

    // try one of the next node candidates
    for (int c=0; c<n; ++c) {
      if (c==v ||
          node_colors[c] == EMPTY ||
          node_colors[c] == color ||
          node_values[c] < value) {
        continue;
      }

      // push the next node
      node_colors[v] = EMPTY;
      node_values[c] -= value;
      if (color == BLACK)
        black_remains -= 1;
      else
        white_remains -= 1;
      ostringstream out;
      out << v+1 << " " << c+1 << " " << value;
      results.push(out.str());

      solve();

      // pop the next node
      node_colors[v] = color;
      node_values[c] += value;
      if (color == BLACK)
        black_remains += 1;
      else
        white_remains += 1;
      results.pop();
    }
  }
}

void output()
{
  while (!results.empty()) {
    std::cout << results.top() << "\n";
    results.pop();
  }
}

void select_black()
{
  nodes_t::iterator smallest = black_nodes.begin();
  const ll black_smallest = smallest->first;
  const int black_node    = smallest->second;
  black_nodes.erase(smallest);

  nodes_t::iterator largest = --white_nodes.end();
  const ll value     = largest->first;
  const int node     = largest->second;
//std::cerr << black_node << "[" << black_smallest << "] - " <<
//             node       << "[" << value          << "]\n";
  assert(value >= black_smallest);
  const ll new_value = value - black_smallest;
  white_nodes.erase(largest);
  white_nodes.insert(make_pair(new_value, node));

  ostringstream out;
  out << black_node+1 << " " << node+1 << " " << black_smallest;
  results.push(out.str());
}

void select_white()
{
  nodes_t::iterator smallest = white_nodes.begin();
  const ll white_smallest = smallest->first;
  const int white_node    = smallest->second;
  white_nodes.erase(smallest);

  nodes_t::iterator largest = --black_nodes.end();
  const ll value = largest->first;
  const int node = largest->second;
//std::cerr << white_node << "[" << white_smallest << "] - " <<
//             node       << "[" << value          << "]\n";
  assert(value >= white_smallest);
  const ll new_value = value - white_smallest;
  black_nodes.erase(largest);
  black_nodes.insert(make_pair(new_value,node));

  ostringstream out;
  out << white_node+1 << " " << node+1 << " " << white_smallest;
  results.push(out.str());
}

void solve2()
{
  // check finish
  if ((black_nodes.empty() && white_nodes.size()==1) ||
      (white_nodes.empty() && black_nodes.size()==1)) {
    output();
    return;
  }

  // select the smaller group
  if (black_nodes.size() < white_nodes.size())
    select_white();
  else if (white_nodes.size() < black_nodes.size())
    select_black();
  else if (black_nodes.begin()->first < white_nodes.begin()->first)
    select_black();
  else
    select_white();

  solve2();
}

int main(int argc, char** argv)
{
  ios::sync_with_stdio(false);
  //string line;

  // the first line
  {
    read n;
    node_colors.resize(n);
    node_values.resize(n);
    for (int i=0; i<n; ++i) {
      cin.ignore(); // skip carriage return
      int color;
      ll  value;
      read color;
      read value;
      node_colors[i] = color;
      node_values[i] = value;
      if (color == BLACK)
        black_nodes.insert(make_pair(value, i));
      else
        white_nodes.insert(make_pair(value, i));
    }
  }

  initialize();
  solve2();

  return 0;
}


#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <memory.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double,double> pdd;

typedef vector<int> vi;
typedef vector<pair<int, int > > vii;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<ld> vld;

typedef vector<vi> vvi;
typedef vector<vii> vvii;
typedef vector<vll> vvll;
typedef vector<vs> vvs;

typedef map<int, int> mii;
typedef map<int, string> mis;
typedef map<string, int> msi;
typedef map<string, string> mss;

#define sz(a) (int)((a).size())
#define len(a) (int)((a).length())

#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define Sort(x) sort(x.begin(),x.end())
#define Reverse(x) reverse(x.begin(),x.end())

#define forr(i,n) for (int i = 0; i < (n); ++i)
#define fori(n) forr(i,n)
#define forj(n) forr(j,n)
#define fork(n) forr(k,n)
#define forjn forj(n)
#define forjm forj(m)
#define forkm fork(m)
#define foria(a) fori(sz(a))
#define foriv foria(v)
#define foris fori(len(s))
#define forja(a) forj(sz(a))
#define forjv forj(v)
#define forjs forj(len(s))
#define FOREACH(it,x) for(__typeof((x).begin()) it=(x.begin()); it!=(x).end(); ++it)

#define MAX(a,b) (a>b?a:b)
#define MIN(a,b) (a<b?a:b)

#define read cin>>
#define write cout<<
#define writeln write endl

#define readt int aaa; read aaa;
#define gett (bbb+1)
#define fort forr(bbb,aaa)

#define issa(a,s) istringstream a(s);
#define iss(s) issa(ss,s);

ld dis(ld x, ld y) {return sqrt(x*x+y*y);}
const ld PI = acos(ld(0.0))*2;
const int INF = 1<<30;

bool is_palindrome(const string &s, int start, int end) {
  int siz = end - start + 1;
  if (siz % 2 == 0) {
    int middle = start + siz/2;
    int i;
    for (i = 0; middle - 1 - i >= 0 && middle+i <= end && s[middle-1-i] == s[middle+i]; i++);
    if (middle - i - 1 < 0 || middle+i > end)
      return true;
  } else {
    int middle = start + siz/2;
    int i;
    for (i = 1; middle - i >= 0 && middle+i <= end && s[middle-i]==s[middle+i]; i++);
    if (middle - i < 0 || middle+i > end)
      return true;
  }
  return false;
}
//Polya-Burnside theory : (n^6+3n^4+12n^3+8n^2)/24
int euclidd,euclidx,euclidy;
void extendedeuclid(int a,int b)
{
  if(b==0)
  {
    euclidd=a;
    euclidx=1;
    euclidy=0;
    return ;
  }
  extendedeuclid(b,a%b);
  int d1,x1,y1;
  d1=euclidd;
  x1=euclidx;
  y1=euclidy;
  euclidx=y1;
  euclidy=x1-((a/b)*y1);
}
double dist_2point(double x1,double y1,double x2,double y2)
{
  double d;
  d=sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
  return d;
}
int binary_search(int a[],int n,int l,int u)
{
  int mid;
  if(l>u)
    return 0;
  mid=floor(l+u)/2;
  if(a[mid]==n)
    return mid;
  else if(a[mid]>n)
    return binary_search(a,n,l,mid-1);
  else
    return binary_search(a,n,mid+1,u);
}
long gcd(long a,long b)
{
  while(b>0) {
    a=a%b;
    a=a^b;
    b=b^a;
    a=a^b;
  }
  return a;
}
long lcm(long a,long b)
{
  long x=(a*b)/gcd(a,b);
  return x;
}
long is_prime(long n)
{
  long ii;
  if (n == 1)
    return 0;
  if (n == 2)
    return 1;
  if (n%2 == 0)
    return 0;
  for (ii=3;ii*ii<=n;ii=ii+2)
    if (n%ii == 0)
      return 0;
  return 1;
}
long long bigmod(long long b,long long p,long long m)
{
  if(b==0) return 0;
  long long x,power;
  x=1;
  power=b%m;
  while(p)
  {
    if(p%2==1)
      x=(x*power)%m;
    power=(power*power)%m;
    p=p/2;
  }
  return x;
}
void assert(bool b)
{
  if (!b)
    throw 0;
}
template <int n>
struct nbest
{
  vector<pair<ll, int> > p;
  nbest():p(n+1)
  {
    foria(p) p[i].first = p[i].second = -1;
  }
  void add(ll value, int key)
  {
    p[n] = make_pair(value, key);
    sort(rall(p));
  }
  ll getValue(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].first;
  }
  int getKey(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second;
  }
  bool has(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second != -1;
  }
};

template <typename T>
void dumpContents(const vector<T>& v,
                  const string& msg="")
{
  cerr << "### " << msg << " ###\n";
  if (v.empty())
    return;

  for (typename vector<T>::const_iterator it=v.begin();
       it != v.end(); ++it) {
    cerr << *it << " ";
  }
  cerr << endl;
}

void printBit(ull S, int n=64){
  for(int i=n-1; i>=0; i--){
    if(S>>i & 1) cout << 1;
    else cout << 0;
  }
  cout << endl;
}

void subsetCombination(int n, int k){
  ull S = (1ULL << k) - 1ULL;
  ull E = ~((1ULL << n) - 1ULL);
  while(!(S & E)){
    printBit(S, n);
    ull smallest = S & -S;
    ull ripple = S + smallest;
    ull nsmallest = ripple & -ripple;
    S = ripple | (((nsmallest / smallest) >> 1) - 1);
  }
}

void grayCode(int n){
  int N = 1 << n;
  ull G = 0;
  for(int i=0; i<N; i++){
    G = i ^ (i >> 1ULL);
    printBit(G, n);
  }
}

int bitCount(ull n)
{
  int cnt = 0;
  while(n != 0) {
    cnt += 1;
    n &= (n-1); // the lowest 1 is turned to 0.
  }
  return cnt;
}

// ========== end of template ==========

// === global variables

const int WHITE = 0;
const int BLACK = 1;
const int EMPTY = 2;

int n;
vi node_colors;
vll node_values;
vi black_nodes;
vi white_nodes;

int remains;
std::stack<std::string> results;

// === functions

void output();

void initialize()
{
  remains = n;
}

void solve()
{
  // count black nodes
  int black_remains = 0;
  FOREACH(it, black_nodes) {
    if (node_colors[*it] == BLACK) // not empty
      black_remains += 1;
  }
  // count white nodes
  int white_remains = 0;
  FOREACH(it, white_nodes) {
    if (node_colors[*it] == WHITE) { // not empty
      white_remains += 1;
    }
  }

  // the smaller group should have a leaf
  int leaf_color = EMPTY;
  if (black_remains < white_remains)
    leaf_color = WHITE;
  else if (white_remains < black_remains)
    leaf_color = BLACK;

  for (int v=0; v<n; ++v) {
    const int color = node_colors[v];
    if (color == EMPTY) continue;
    if (leaf_color != EMPTY && leaf_color != color) continue;
    const ll  value = node_values[v];

    // check finish
    if (value == 0 && remains == 1) {
      output();
      exit(0);
    }

    // try one of the next node candidates
    for (int c=0; c<n; ++c) {
      if (c==v ||
          node_colors[c] == EMPTY ||
          node_colors[c] == color ||
          node_values[c] < value) {
        continue;
      }

      // push the next node
      node_colors[v] = EMPTY;
      node_values[c] -= value;
      remains -= 1;
      ostringstream out;
      out << v+1 << " " << c+1 << " " << value;
      results.push(out.str());

      solve();

      // pop the next node
      node_colors[v] = color;
      node_values[c] += value;
      remains += 1;
      results.pop();
    }
  }
}

void output()
{
  while (!results.empty()) {
    std::cout << results.top() << "\n";
    results.pop();
  }
}

int main(int argc, char** argv)
{
  ios::sync_with_stdio(false);
  //string line;

  // the first line
  {
    read n;
    node_colors.resize(n);
    node_values.resize(n);
    for (int i=0; i<n; ++i) {
      cin.ignore(); // skip carriage return
      int color;
      ll  value;
      read color;
      read value;
      node_colors[i] = color;
      node_values[i] = value;
      if (color == BLACK)
        black_nodes.push_back(i);
      else
        white_nodes.push_back(i);
    }
  }

  initialize();
  solve();

  return 0;
}


#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <memory.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double,double> pdd;

typedef vector<int> vi;
typedef vector<pair<int, int > > vii;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<ld> vld;

typedef vector<vi> vvi;
typedef vector<vii> vvii;
typedef vector<vll> vvll;
typedef vector<vs> vvs;

typedef map<int, int> mii;
typedef map<int, string> mis;
typedef map<string, int> msi;
typedef map<string, string> mss;

#define sz(a) (int)((a).size())
#define len(a) (int)((a).length())

#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define Sort(x) sort(x.begin(),x.end())
#define Reverse(x) reverse(x.begin(),x.end())

#define forr(i,n) for (int i = 0; i < (n); ++i)
#define fori(n) forr(i,n)
#define forj(n) forr(j,n)
#define fork(n) forr(k,n)
#define forjn forj(n)
#define forjm forj(m)
#define forkm fork(m)
#define foria(a) fori(sz(a))
#define foriv foria(v)
#define foris fori(len(s))
#define forja(a) forj(sz(a))
#define forjv forj(v)
#define forjs forj(len(s))
#define FOREACH(it,x) for(__typeof((x).begin()) it=(x.begin()); it!=(x).end(); ++it)

#define MAX(a,b) (a>b?a:b)
#define MIN(a,b) (a<b?a:b)

#define read cin>>
#define write cout<<
#define writeln write endl

#define readt int aaa; read aaa;
#define gett (bbb+1)
#define fort forr(bbb,aaa)

#define issa(a,s) istringstream a(s);
#define iss(s) issa(ss,s);

ld dis(ld x, ld y) {return sqrt(x*x+y*y);}
const ld PI = acos(ld(0.0))*2;
const int INF = 1<<30;

bool is_palindrome(const string &s, int start, int end) {
  int siz = end - start + 1;
  if (siz % 2 == 0) {
    int middle = start + siz/2;
    int i;
    for (i = 0; middle - 1 - i >= 0 && middle+i <= end && s[middle-1-i] == s[middle+i]; i++);
    if (middle - i - 1 < 0 || middle+i > end)
      return true;
  } else {
    int middle = start + siz/2;
    int i;
    for (i = 1; middle - i >= 0 && middle+i <= end && s[middle-i]==s[middle+i]; i++);
    if (middle - i < 0 || middle+i > end)
      return true;
  }
  return false;
}
//Polya-Burnside theory : (n^6+3n^4+12n^3+8n^2)/24
int euclidd,euclidx,euclidy;
void extendedeuclid(int a,int b)
{
  if(b==0)
  {
    euclidd=a;
    euclidx=1;
    euclidy=0;
    return ;
  }
  extendedeuclid(b,a%b);
  int d1,x1,y1;
  d1=euclidd;
  x1=euclidx;
  y1=euclidy;
  euclidx=y1;
  euclidy=x1-((a/b)*y1);
}
double dist_2point(double x1,double y1,double x2,double y2)
{
  double d;
  d=sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
  return d;
}
int binary_search(int a[],int n,int l,int u)
{
  int mid;
  if(l>u)
    return 0;
  mid=floor(l+u)/2;
  if(a[mid]==n)
    return mid;
  else if(a[mid]>n)
    return binary_search(a,n,l,mid-1);
  else
    return binary_search(a,n,mid+1,u);
}
long gcd(long a,long b)
{
  while(b>0) {
    a=a%b;
    a=a^b;
    b=b^a;
    a=a^b;
  }
  return a;
}
long lcm(long a,long b)
{
  long x=(a*b)/gcd(a,b);
  return x;
}
long is_prime(long n)
{
  long ii;
  if (n == 1)
    return 0;
  if (n == 2)
    return 1;
  if (n%2 == 0)
    return 0;
  for (ii=3;ii*ii<=n;ii=ii+2)
    if (n%ii == 0)
      return 0;
  return 1;
}
long long bigmod(long long b,long long p,long long m)
{
  if(b==0) return 0;
  long long x,power;
  x=1;
  power=b%m;
  while(p)
  {
    if(p%2==1)
      x=(x*power)%m;
    power=(power*power)%m;
    p=p/2;
  }
  return x;
}
void assert(bool b)
{
  if (!b)
    throw 0;
}
template <int n>
struct nbest
{
  vector<pair<ll, int> > p;
  nbest():p(n+1)
  {
    foria(p) p[i].first = p[i].second = -1;
  }
  void add(ll value, int key)
  {
    p[n] = make_pair(value, key);
    sort(rall(p));
  }
  ll getValue(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].first;
  }
  int getKey(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second;
  }
  bool has(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second != -1;
  }
};

template <typename T>
void dumpContents(const vector<T>& v,
                  const string& msg="")
{
  cerr << "### " << msg << " ###\n";
  if (v.empty())
    return;

  for (typename vector<T>::const_iterator it=v.begin();
       it != v.end(); ++it) {
    cerr << *it << " ";
  }
  cerr << endl;
}

void printBit(ull S, int n=64){
  for(int i=n-1; i>=0; i--){
    if(S>>i & 1) cout << 1;
    else cout << 0;
  }
  cout << endl;
}

void subsetCombination(int n, int k){
  ull S = (1ULL << k) - 1ULL;
  ull E = ~((1ULL << n) - 1ULL);
  while(!(S & E)){
    printBit(S, n);
    ull smallest = S & -S;
    ull ripple = S + smallest;
    ull nsmallest = ripple & -ripple;
    S = ripple | (((nsmallest / smallest) >> 1) - 1);
  }
}

void grayCode(int n){
  int N = 1 << n;
  ull G = 0;
  for(int i=0; i<N; i++){
    G = i ^ (i >> 1ULL);
    printBit(G, n);
  }
}

int bitCount(ull n)
{
  int cnt = 0;
  while(n != 0) {
    cnt += 1;
    n &= (n-1); // the lowest 1 is turned to 0.
  }
  return cnt;
}

// ========== end of template ==========

// === global variables

const int WHITE = 0;
const int BLACk = 1;
const int EMPTY = 2;

int n;
vi node_colors;
vll node_values;
bool finish;
std::stack<std::string> results;

// === functions

void output();

void initialize()
{
  finish = false;
}

void solve()
{
  if (finish)
    return;

  for (int v=0; v<n; ++v) {
    const int color = node_colors[v];
    if (color == EMPTY) continue;
    const ll  value = node_values[v];

    // check exit
    if (value == 0) {
      bool all_empty = true;
      for (int i=0; i<n; ++i) {
        if (i==v) continue;
        if (node_colors[i] != EMPTY) {
          all_empty = false;
          break;
        }
      }
      if (all_empty)
        finish = true;
    }
    if (finish) {
      output();
      return;
    }

    // try one of the next node candidates
    for (int c=0; c<n; ++c) {
      if (c==v ||
          node_colors[c] == EMPTY ||
          node_colors[c] == color ||
          node_values[c] < value) {
        continue;
      }

      // push the next node
      node_colors[v] = EMPTY;
      node_values[c] -= value;
      ostringstream out;
      out << v+1 << " " << c+1 << " " << value;
      results.push(out.str());

      solve();
      if (finish)
        return;

      // pop the next node
      node_colors[v] = color;
      node_values[c] += value;
      results.pop();
    }
  }
}

void output()
{
  while (!results.empty()) {
    std::cout << results.top() << "\n";
    results.pop();
  }
}

int main(int argc, char** argv)
{
  ios::sync_with_stdio(false);
  //string line;

  // the first line
  {
    read n;
    node_colors.resize(n);
    node_values.resize(n);
    for (int i=0; i<n; ++i) {
      cin.ignore(); // skip carriage return
      int color;
      ll  value;
      read color;
      read value;
      node_colors[i] = color;
      node_values[i] = value;
    }
  }

  initialize();
  solve();

  return 0;
}


#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <memory.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double,double> pdd;

typedef vector<int> vi;
typedef vector<pair<int, int > > vii;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<ld> vld;

typedef vector<vi> vvi;
typedef vector<vii> vvii;
typedef vector<vll> vvll;
typedef vector<vs> vvs;

typedef map<int, int> mii;
typedef map<int, string> mis;
typedef map<string, int> msi;
typedef map<string, string> mss;

#define sz(a) (int)((a).size())
#define len(a) (int)((a).length())

#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define Sort(x) sort(x.begin(),x.end())
#define Reverse(x) reverse(x.begin(),x.end())

#define forr(i,n) for (int i = 0; i < (n); ++i)
#define fori(n) forr(i,n)
#define forj(n) forr(j,n)
#define fork(n) forr(k,n)
#define forjn forj(n)
#define forjm forj(m)
#define forkm fork(m)
#define foria(a) fori(sz(a))
#define foriv foria(v)
#define foris fori(len(s))
#define forja(a) forj(sz(a))
#define forjv forj(v)
#define forjs forj(len(s))
#define FOREACH(it,x) for(__typeof((x).begin()) it=(x.begin()); it!=(x).end(); ++it)

#define MAX(a,b) (a>b?a:b)
#define MIN(a,b) (a<b?a:b)

#define read cin>>
#define write cout<<
#define writeln write endl

#define readt int aaa; read aaa;
#define gett (bbb+1)
#define fort forr(bbb,aaa)

#define issa(a,s) istringstream a(s);
#define iss(s) issa(ss,s);

ld dis(ld x, ld y) {return sqrt(x*x+y*y);}
const ld PI = acos(ld(0.0))*2;
const int INF = 1<<30;

bool is_palindrome(const string &s, int start, int end) {
  int siz = end - start + 1;
  if (siz % 2 == 0) {
    int middle = start + siz/2;
    int i;
    for (i = 0; middle - 1 - i >= 0 && middle+i <= end && s[middle-1-i] == s[middle+i]; i++);
    if (middle - i - 1 < 0 || middle+i > end)
      return true;
  } else {
    int middle = start + siz/2;
    int i;
    for (i = 1; middle - i >= 0 && middle+i <= end && s[middle-i]==s[middle+i]; i++);
    if (middle - i < 0 || middle+i > end)
      return true;
  }
  return false;
}
//Polya-Burnside theory : (n^6+3n^4+12n^3+8n^2)/24
int euclidd,euclidx,euclidy;
void extendedeuclid(int a,int b)
{
  if(b==0)
  {
    euclidd=a;
    euclidx=1;
    euclidy=0;
    return ;
  }
  extendedeuclid(b,a%b);
  int d1,x1,y1;
  d1=euclidd;
  x1=euclidx;
  y1=euclidy;
  euclidx=y1;
  euclidy=x1-((a/b)*y1);
}
double dist_2point(double x1,double y1,double x2,double y2)
{
  double d;
  d=sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
  return d;
}
int binary_search(int a[],int n,int l,int u)
{
  int mid;
  if(l>u)
    return 0;
  mid=floor(l+u)/2;
  if(a[mid]==n)
    return mid;
  else if(a[mid]>n)
    return binary_search(a,n,l,mid-1);
  else
    return binary_search(a,n,mid+1,u);
}
long gcd(long a,long b)
{
  while(b>0) {
    a=a%b;
    a=a^b;
    b=b^a;
    a=a^b;
  }
  return a;
}
long lcm(long a,long b)
{
  long x=(a*b)/gcd(a,b);
  return x;
}
long is_prime(long n)
{
  long ii;
  if (n == 1)
    return 0;
  if (n == 2)
    return 1;
  if (n%2 == 0)
    return 0;
  for (ii=3;ii*ii<=n;ii=ii+2)
    if (n%ii == 0)
      return 0;
  return 1;
}
long long bigmod(long long b,long long p,long long m)
{
  if(b==0) return 0;
  long long x,power;
  x=1;
  power=b%m;
  while(p)
  {
    if(p%2==1)
      x=(x*power)%m;
    power=(power*power)%m;
    p=p/2;
  }
  return x;
}
void assert(bool b)
{
  if (!b)
    throw 0;
}
template <int n>
struct nbest
{
  vector<pair<ll, int> > p;
  nbest():p(n+1)
  {
    foria(p) p[i].first = p[i].second = -1;
  }
  void add(ll value, int key)
  {
    p[n] = make_pair(value, key);
    sort(rall(p));
  }
  ll getValue(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].first;
  }
  int getKey(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second;
  }
  bool has(int pos, int exceptKey = -2)
  {
    if (exceptKey == -1)
      exceptKey = -2;
    if (p[pos].second == exceptKey)
      ++pos;
    return p[pos].second != -1;
  }
};

template <typename T>
void dumpContents(const vector<T>& v,
                  const string& msg="")
{
  cerr << "### " << msg << " ###\n";
  if (v.empty())
    return;

  for (typename vector<T>::const_iterator it=v.begin();
       it != v.end(); ++it) {
    cerr << *it << " ";
  }
  cerr << endl;
}

void printBit(ull S, int n=64){
  for(int i=n-1; i>=0; i--){
    if(S>>i & 1) cout << 1;
    else cout << 0;
  }
  cout << endl;
}

void subsetCombination(int n, int k){
  ull S = (1ULL << k) - 1ULL;
  ull E = ~((1ULL << n) - 1ULL);
  while(!(S & E)){
    printBit(S, n);
    ull smallest = S & -S;
    ull ripple = S + smallest;
    ull nsmallest = ripple & -ripple;
    S = ripple | (((nsmallest / smallest) >> 1) - 1);
  }
}

void grayCode(int n){
  int N = 1 << n;
  ull G = 0;
  for(int i=0; i<N; i++){
    G = i ^ (i >> 1ULL);
    printBit(G, n);
  }
}

int bitCount(ull n)
{
  int cnt = 0;
  while(n != 0) {
    cnt += 1;
    n &= (n-1); // the lowest 1 is turned to 0.
  }
  return cnt;
}

// ========== end of template ==========

// === global variables

const int WHITE = 0;
const int BLACk = 1;
const int EMPTY = 2;

int n;
vi node_colors;
vll node_values;

int remains;
bool finish;
std::stack<std::string> results;

// === functions

void output();

void initialize()
{
  finish = false;
  remains = n;
}

void solve()
{
  if (finish)
    return;

  for (int v=0; v<n; ++v) {
    const int color = node_colors[v];
    if (color == EMPTY) continue;
    const ll  value = node_values[v];

    // check exit
    if (value == 0 && remains == 1)
      finish = true;

    if (finish) {
      output();
      return;
    }

    // try one of the next node candidates
    for (int c=0; c<n; ++c) {
      if (c==v ||
          node_colors[c] == EMPTY ||
          node_colors[c] == color ||
          node_values[c] < value) {
        continue;
      }

      // push the next node
      node_colors[v] = EMPTY;
      node_values[c] -= value;
      remains -= 1;
      ostringstream out;
      out << v+1 << " " << c+1 << " " << value;
      results.push(out.str());

      solve();
      if (finish)
        return;

      // pop the next node
      node_colors[v] = color;
      node_values[c] += value;
      remains += 1;
      results.pop();
    }
  }
}

void output()
{
  while (!results.empty()) {
    std::cout << results.top() << "\n";
    results.pop();
  }
}

int main(int argc, char** argv)
{
  ios::sync_with_stdio(false);
  //string line;

  // the first line
  {
    read n;
    node_colors.resize(n);
    node_values.resize(n);
    for (int i=0; i<n; ++i) {
      cin.ignore(); // skip carriage return
      int color;
      ll  value;
      read color;
      read value;
      node_colors[i] = color;
      node_values[i] = value;
    }
  }

  initialize();
  solve();

  return 0;
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define pb push_back
#define mp make_pair
#define ff first
#define ss second

using namespace std ;

int main () {

    int n ;
    cin >> n ;
    vector <int> g[100005] ;
    priority_queue < pair<int,int> > w , b ;
    rep(i,n) {
        int col , s ;
        cin >> col >> s ;
        if (col==0) {
            w.push(mp(-s,i+1)) ;
        }
        else {
            b.push(mp(-s,i+1)) ;
        }
    }

    while(!w.empty() && !b.empty()) {
        pair <int,int> black = b.top() ;
        pair <int,int> white = w.top() ;

        if (-black.first >= -white.first) {
            w.pop() ;
            b.pop() ;
            black.first = black.first - (white.first) ;
            g[black.ss].pb(white.ss) ;
            g[black.ss].pb(-white.ff) ;
            b.push(black) ;
        }
        else if (-white.first >= -black.first) {
            w.pop() ;
            b.pop() ;
            white.first = white.first - (black.first) ;
            g[white.ss].pb(black.ss) ;
            g[white.ss].pb(-black.ff) ;
            w.push(white) ;
        }
    }

    for(int i = 1 ; i <= n; i++) {
        for (int j = 0 ; j < g[i].size() ; j+=2) {
            cout << i << " " << g[i][j] << " " << g[i][j+1] << endl ;
        }
    }

}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define pb push_back
#define mp make_pair
#define ff first
#define ss second

using namespace std ;

int main () {

    int n ;
    cin >> n ;
    vector <int> g[10005] ;
    priority_queue < pair<int,int> > w , b ;
    rep(i,n) {
        int col , s ;
        cin >> col >> s ;
        if (col==0) {
            w.push(mp(-s,i+1)) ;
        }
        else {
            b.push(mp(-s,i+1)) ;
        }
    }

    while(true) {
        if (w.empty() || b.empty()) break ;
        pair <int,int> black = b.top() ;
        pair <int,int> white = w.top() ;

        if (-black.first >= -white.first) {
            w.pop() ;
            b.pop() ;
            black.first = black.first - (white.first) ;
            g[black.ss].pb(white.ss) ;
            g[black.ss].pb(-white.ff) ;
            b.push(black) ;
        }
        if (w.empty() or b.empty()) break ;

        black = b.top() ;
        white  = w.top() ;
        if (-white.first >= -black.first) {
            w.pop() ;
            b.pop() ;
            white.first = white.first - (black.first) ;
            g[white.ss].pb(black.ss) ;
            g[white.ss].pb(-black.ff) ;
            w.push(white) ;
        }
    }

    for(int i = 1 ; i <= n; i++) {
        for (int j = 0 ; j < g[i].size() ; j+=2) {
            cout << i << " " << g[i][j] << " " << g[i][j+1] << endl ;
        }
    }

}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define pb push_back
#define mp make_pair
#define ff first
#define ss second

using namespace std ;

int main () {

    int n ;
    cin >> n ;
    vector <int> g[100005] ;
    int vis[100005] ;
    memset (vis , 0 , sizeof vis) ;
    priority_queue < pair<int,int> > w , b ;
    int B , W ;
    rep(i,n) {
        int col , s ;
        cin >> col >> s ;
        if (col==0) {
            w.push(mp(-s,i+1)) ;
            W = i+1 ;
        }
        else {
            b.push(mp(-s,i+1)) ;
            B = i+1 ;
        }
    }

    while(true) {
        if (w.empty() || b.empty()) break ;
        pair <int,int> black = b.top() ;
        pair <int,int> white = w.top() ;

        if (-black.first >= -white.first ) {
            w.pop() ;
            b.pop() ;
            black.first = black.first - (white.first) ;
            g[black.ss].pb(white.ss) ;
            g[black.ss].pb(-white.ff) ;
            b.push(black) ;
            vis[black.ss] = 1 ;
            vis[white.ss] = 1 ;
        }
        if (w.empty() or b.empty()) break ;

        black = b.top() ;
        white  = w.top() ;
        if (-white.first >= -black.first) {
            w.pop() ;
            b.pop() ;
            white.first = white.first - (black.first) ;
            g[white.ss].pb(black.ss) ;
            g[white.ss].pb(-black.ff) ;
            w.push(white) ;
            vis[black.ss] = 1 ;
            vis[white.ss] = 1 ;
        }
    }
    while (!b.empty()) {
        int id = b.top().ss ;
        b.pop();
        if (vis[id]==0) {
            vis[id] = 1 ;
            g[W].pb(id) ;
            g[W].pb(0) ;
        }

    }

    while (!w.empty()) {
        int id = w.top().ss ;
        w.pop() ;
        if (vis[id]==0) {
            vis[id] = 1 ;
            g[B].pb(id) ;
            g[B].pb(0) ;
        }

    }

    for(int i = 1 ; i <= n; i++) {
        for (int j = 0 ; j < g[i].size() ; j+=2) {
            cout << i << " " << g[i][j] << " " << g[i][j+1] << endl ;
        }
    }

}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define pb push_back
#define mp make_pair
#define ff first
#define ss second

using namespace std ;

int main () {

    int n ;
    cin >> n ;
    vector <int> g[100005] ;
    priority_queue < pair<int,int> > w , b ;
    rep(i,n) {
        int col , s ;
        cin >> col >> s ;
        if (col==0) {
            w.push(mp(-s,i+1)) ;
        }
        else {
            b.push(mp(-s,i+1)) ;
        }
    }

    while(true) {
        if (w.empty() || b.empty()) break ;
        pair <int,int> black = b.top() ;
        pair <int,int> white = w.top() ;

        if (-black.first >= -white.first) {
            w.pop() ;
            b.pop() ;
            black.first = black.first - (white.first) ;
            g[black.ss].pb(white.ss) ;
            g[black.ss].pb(-white.ff) ;
            b.push(black) ;
        }
        if (w.empty() or b.empty()) break ;

        black = b.top() ;
        white  = w.top() ;
        if (-white.first >= -black.first) {
            w.pop() ;
            b.pop() ;
            white.first = white.first - (black.first) ;
            g[white.ss].pb(black.ss) ;
            g[white.ss].pb(-black.ff) ;
            w.push(white) ;
        }
    }

    for(int i = 1 ; i <= n; i++) {
        for (int j = 0 ; j < g[i].size() ; j+=2) {
            cout << i << " " << g[i][j] << " " << g[i][j+1] << endl ;
        }
    }

}


#include<vector>
#include<queue>
#include<cstdio>
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
#define Queue priority_queue
#define ll long long
using namespace std;
struct node{
	int u;
	ll s;
	friend bool operator < (node a,node b){
		return a.s > b.s;
	}
};
const int Maxn=300000;
Queue<node> Q[2];
int n;
void Init(){
//	freopen("in.txt","r",stdin);
	scanf("%d",&n);
	node t[2];
	rep(i,n){
		int c;
		node p;p.u=i;
		scanf("%d%I64d",&c,&p.s);
		t[c].u=p.u;
//		if (B==NULL&&c==0) B=&p;
//		if (W==NULL&&c==1) W=&p;
		Q[c].push(p);
	}
	rep(i,2) {t[i].s=1000000000;t[i].s*=200000;Q[i].push(t[i]);}
	/*
	rep(i,2){
		printf("--------\n");
		while(!Q[i].empty()){
			printf("%d %I64d\n",Q[i].top().u,Q[i].top().s);Q[i].pop();
		}
	}*/

}
void Work(){
	while((Q[0].size()+Q[1].size())>2){
		node p=Q[0].top(),q=Q[1].top();
		Q[0].pop();Q[1].pop();
		node e;
		if (p<q){
			e.s=q.s;p.s-=q.s;Q[0].push(p);
		}else{
			e.s=p.s;q.s-=p.s;Q[1].push(q);
		}
		if ((Q[0].size()+Q[1].size())>2) printf("%d %d %I64d\n",p.u+1,q.u+1,e.s);
	}
}
int main(){
	Init();
	Work();
	//for(;;);
}


#include<vector>
#include<queue>
#include<cstdio>
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
#define Queue priority_queue
#define ll long long
using namespace std;
struct node{
	int u;
	ll s;
	friend bool operator < (node a,node b){
		return a.s > b.s;
	}
};
const int Maxn=300000;
Queue<node> Q[2];
int n;
void Init(){
//	freopen("in.txt","r",stdin);
	scanf("%d",&n);
	node t[2];
	rep(i,n){
		int c;
		node p;p.u=i;
		scanf("%d%I64d",&c,&p.s);
		t[c].u=p.u;
//		if (B==NULL&&c==0) B=&p;
//		if (W==NULL&&c==1) W=&p;
		Q[c].push(p);
	}
	rep(i,2) {t[i].s=1000000000;t[i].s*=2000;Q[i].push(t[i]);}
	/*
	rep(i,2){
		printf("--------\n");
		while(!Q[i].empty()){
			printf("%d %I64d\n",Q[i].top().u,Q[i].top().s);Q[i].pop();
		}
	}*/

}
void Work(){
	while((Q[0].size()+Q[1].size())>2){
		node p=Q[0].top(),q=Q[1].top();
		Q[0].pop();Q[1].pop();
		node e;
		if (p<q){
			e.s=q.s;p.s-=q.s;Q[0].push(p);
		}else{
			e.s=p.s;q.s-=p.s;Q[1].push(q);
		}
		if ((Q[0].size()+Q[1].size())>2) printf("%d %d %I64d\n",p.u+1,q.u+1,e.s);
	}
}
int main(){
	Init();
	Work();
	//for(;;);
}


#include<vector>
#include<queue>
#include<cstdio>
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
#define Queue priority_queue
#define ll long long
using namespace std;
struct node{
	int u;
	ll s;
	friend bool operator < (node a,node b){
		return a.s > b.s;
	}
};
const int Maxn=300000;
Queue<node> Q[2];
int n;
void Init(){
	freopen("in.txt","r",stdin);
	scanf("%d",&n);
	node t[2];
	rep(i,n){
		int c;
		node p;p.u=i;
		scanf("%d%I64d",&c,&p.s);
		t[c].u=p.u;
//		if (B==NULL&&c==0) B=&p;
//		if (W==NULL&&c==1) W=&p;
		Q[c].push(p);
	}
	rep(i,2) {t[i].s=1000000000;t[i].s*=2000;Q[i].push(t[i]);}
	/*
	rep(i,2){
		printf("--------\n");
		while(!Q[i].empty()){
			printf("%d %I64d\n",Q[i].top().u,Q[i].top().s);Q[i].pop();
		}
	}*/

}
void Work(){
	while((Q[0].size()+Q[1].size())>2){
		node p=Q[0].top(),q=Q[1].top();
		Q[0].pop();Q[1].pop();
		node e;
		if (p<q){
			e.s=q.s;p.s-=q.s;Q[0].push(p);
		}else{
			e.s=p.s;q.s-=p.s;Q[1].push(q);
		}
		if ((Q[0].size()+Q[1].size())>2) printf("%d %d %I64d\n",p.u+1,q.u+1,e.s);
	}
}
int main(){
	Init();
	Work();
	for(;;);
}