#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int Max = 1e5;

struct PP{
	int num, f, pos;
};
PP a[Max + 5], b[Max + 5];
bool vis[Max + 5];

bool cmp(PP x, PP y) {
	return x.num < y.num ;
}
int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i++) {
		scanf("%d%d", &a[i].num, &a[i].f);
		a[i].pos = i;
	}
	sort(a + 1, a + m + 1, cmp);
	bool flag = 0;
	int x = 0, y = 1, fx = 1, fy = 3;
	int sum = 0, su = 0;
	for(int i = 1; i <= m; i++) {
		if(a[i].f == 0) {
			if(fx < 1) {
				fy++;
				fx = fy - 2;
			}
			if(fx < 1|| fy > y) flag = 1;
			b[a[i].pos].num = fx;
			b[a[i].pos].pos = fy;
			fy++;
		}
		else if(a[i].f == 1){
			b[a[i].pos].num = ++x;
			b[a[i].pos].pos = ++y;
			vis[x] = 1; vis[y] = 1;
			su++;
		}
	}
	for(int i = 1; i <= n; i++) if(vis[i]) sum++;
	if(sum != n || su != n - 1) flag = 1;
	if(flag == 1) printf("-1\n");
	else {
		for(int i = 1; i <= m; i++) printf("%d %d\n", b[i].num, b[i].pos);
	}
	return 0;
}
/*2018-03-10 16:06:39.257*/


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long LL;
//strattime:2017/10/9 21:00
//endtime:2017/10/9 21:07

struct point
{
	int x,y,value,flag,index;
}a[100005];
bool cmp(point x,point y)
{
	if(x.value == y.value)
		return x.flag>y.flag;
	else
		return x.value<y.value;
}
bool cmp1(point x,point y)
{
	return x.index<y.index;
}
int n,m,i,j,ans,x,y,sum;
int main()
{
	cin>>n>>m;
	for(i=1;i<=m;i++)
	{
		cin>>a[i].value>>a[i].flag;
		a[i].index=i;
	}
	sort(a+1,a+1+m,cmp);
	ans= 1;
	x = y =2;
	for(i=1;i<=m;i++)
	{
		if(a[i].flag)
		{
			a[i].x = 1;
			a[i].y = ++ans;
		}
		else
		{
				if(x<2)
				{
					y++;
					x=y-1;
					if(x<2||y>ans)
					{
						cout<<-1<<endl;
						return 0;
					}
					a[i].x = x--;
					a[i].y = y;
				}
				else
				{
					a[i].x = x--;
					a[i].y =y;
				}
		}
	}
	sort(a+1,a+1+m,cmp1);
	for(i=1;i<=m;i++)
	{
		cout<<a[i].x<<" "<<a[i].y<<endl;
	}
 return 0;
}/*2018-03-10 17:58:52.683*/


#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
int p[100010];
struct node{
	int x;
	int y;
	int a;
	int b;
	int c;
};
node a[100010];
bool cmp(node x, node y) {
	return x.x < y.x;
}
bool cmp2(node x, node y) {
	return x.a < y.a;
}
int n, m;
int main() {
	while (scanf("%d%d", &n, &m) == 2) {
		int k = 0;
		for (int i = 0; i < m; i++) {
			scanf("%d%d", &a[i].x, &a[i].y);
			a[i].a = i;
			k = k + a[i].y;
		}
		if (k != n-1) {
			printf("-1\n");
			continue;
		}
		sort(a, a+m, cmp);
		int u1 = 2;
		int u2 = 2;
		int kk = 0;
		k = 0;
		for (int i = 0; i < m; i++) {
			if (a[i].y == 1) {
				k++;
				a[i].b = 1;
				a[i].c = u1;
				u1++;
			}
			else {
				k--;
				if (k <= 0) {
					printf("-1\n");
					kk = 1;
					break;
				}
				a[i].b = 1;
				a[i].c = u2;
				u2++;
			}
		}
		if (kk == 0) {
			sort(a, a+m, cmp2);
			for (int i = 0; i < m; i++) {
				printf("%d %d\n", a[i].b, a[i].c);
			}
		}
	}
	return 0;
}/*2018-03-10 22:35:05.807*/


#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int Max = 1e5;

struct PP{
	int num, f, pos;
};
PP a[Max + 5], b[Max + 5];
bool vis[Max + 5];

bool cmp(PP x, PP y) {
	return x.num < y.num ;
}
int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i++) {
		scanf("%d%d", &a[i].num, &a[i].f);
		a[i].pos = i;
	}
	sort(a + 1, a + m + 1, cmp);
	bool flag = 0;
	int x = 0, y = 1, fx = 1, fy = 3;
	int sum = 0, su = 0;
	for(int i = 1; i <= m; i++) {
		if(a[i].f == 0) {
			if(fx < 1) {
				fy++;
				fx = fy - 2;
			}
			if(fx < 1|| fy > y) flag = 1;
			b[a[i].pos].num = fx;
			b[a[i].pos].pos = fy;
			fx--;
		}
		else if(a[i].f == 1){
			b[a[i].pos].num = ++x;
			b[a[i].pos].pos = ++y;
			vis[x] = 1; vis[y] = 1;
			su++;
		}
	}
	for(int i = 1; i <= n; i++) if(vis[i]) sum++;
	if(sum != n || su != n - 1) flag = 1;
	if(flag == 1) printf("-1\n");
	else {
		for(int i = 1; i <= m; i++) printf("%d %d\n", b[i].num, b[i].pos);
	}
	return 0;
}
/*2018-03-10 16:08:21.805*/


#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<utility>
using namespace std;

const int MaxN = 1e5 + 5;
int n, m; struct NODE{
    int cnt;
    int lev;
    int u, v;
    int pos;
}box[MaxN];
int len[MaxN];

bool cmp1(NODE x, NODE y){
    if(x.cnt == y.cnt) return x.lev > y.lev;
    return x.cnt < y.cnt;
}

bool cmp2(NODE x, NODE y){
    return x.pos < y.pos
    ;
}
bool solve(){
    int tot = 1;
    for(int i = 1; i <= n; i++) len[i] = i;
    for(int i = 1; i <= m; i++){
        if(box[i].lev == 1){
            len[tot]++;
            box[i].u = tot;
            box[i].v = ++tot;
        if(tot > n)
            return false;
        }
        else if(box[i].lev == 0){
            bool flag = false;
            for(int j = 1; j <= tot; j++){
                if(len[j] < tot){
                    box[i].u = j;
                    box[i].v = ++len[j];
                    flag = true;
                    break;
                }
            }
            if(!flag) return flag;
        }
    }
    return true;
}
            int main(){    while(~scanf("%d %d", &n, &m)){        for(int i = 1; i <= m; i++){            scanf("%d %d", &box[i].cnt, &box[i].lev);            box[i].pos = i;        }        sort(box + 1, box + 1 + m, cmp1);        bool flag = solve();        if(!flag) printf("-1\n");        else{            sort(box + 1, box + 1 + m, cmp2);            for(int i = 1; i <= m; i++)                printf("%d %d\n", box[i].u, box[i].v);        }    }    return 0; }
/*2018-03-11 21:05:59.71*/


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m;
struct PP{
	int num;
	bool vail;
	int pos;
	int x,y;
}T[100005];

int cmp(PP x, PP y){
	if(x.num == y.num) return x.vail > y.vail;
	else return x.num < y. num;
}

int cmp1( PP x, PP y){
	return x.pos < y.pos;
}

int main()
{
	scanf("%d %d",&n,&m);
	for(int i = 1; i <= m; i++){
		scanf("%d%d",&T[i].num,&T[i].vail);
		T[i].pos = i;
	}
	sort(T+ 1, T + m + 1,cmp);
	int tt = 1,t = 2,k = 3;
	for(int i = 1; i <= m; i++){
		if(T[i].vail){
			T[i].x = 1;
			T[i].y = ++tt;
		}
		else{
			if(t < 2){k++; t= k - 1;}
            if(k > tt){printf("-1\n"); return 0;}
			T[i].x = t;
			T[i].y = k;
			t--;
		}
	}
	sort(T+ 1, T + m + 1, cmp1);
	for(int i = 1; i <= m; i++){
		printf("%d %d\n",T[i].x, T[i].y);
	}

	return 0;
}

/*2018-03-10 16:47:58.443*/


#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#define N 1100
#define M 100010
using namespace std;

struct node
{
    int num,valid;
};
node a[M];
int valid[M];
int n,m;
int cmp(const node &a,const node &b)
{
    return a.num<b.num||(a.num==b.num&&a.valid>b.valid);
}
int main()
{
    while (~scanf("%d%d",&n,&m))
    {
        for (int i=0;i<m;++i)
        {
            scanf("%d%d",&a[i].num,&a[i].valid);
            valid[i]=a[i].valid;
        }
        sort(a,a+m,cmp);
        int cnt=0;
        for (int i=0;i<m;++i)
        {
            cnt+=a[i].valid;
        }
        if (cnt!=n-1||a[0].valid==0)
        {
            printf("-1\n");
            continue;
        }
        int cnt1=2;
        for (int i=0;i<m;++i)
        {
            if (valid[i])
            {
                printf("%d %d\n",1,cnt1++);
            }
            else
            {
                printf("%d %d\n",1,2);
            }
        }

    }

    return 0;
}
/*2018-03-10 14:26:03.797*/


#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int Max = 1e5;

struct PP{
	int num, f, pos;
};
PP a[Max + 5], b[Max + 5];
bool vis[Max + 5];

bool cmp(PP x, PP y) {
	return x.num < y.num || (x.num == y.num && x.pos < y.pos);
}
int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i++) {
		scanf("%d%d", &a[i].num, &a[i].f);
		a[i].pos = i;
	}
	sort(a + 1, a + m + 1, cmp);
	bool flag = 0;
	int x = 0, y = 1, fx = 1, fy = 3;
	int sum = 0, su = 0;
	for(int i = 1; i <= m; i++) {
		if(a[i].f == 0) {
			if(fy > y) {
				fx++;
				fy = fx + 2;
			}
			if(fx >= x || fy > y) flag = 1;
			b[a[i].pos].num = fx;
			b[a[i].pos].pos = fy;
			fy++;
		}
		else if(a[i].f == 1){
			b[a[i].pos].num = ++x;
			b[a[i].pos].pos = ++y;
			vis[x] = 1; vis[y] = 1;
			su++;
		}
	}
	for(int i = 1; i <= n; i++) if(vis[i]) sum++;
	if(sum != n || su != n - 1) flag = 1;
	if(flag == 1) printf("-1\n");
	else {
		for(int i = 1; i <= m; i++) printf("%d %d\n", b[i].num, b[i].pos);
	}
	return 0;
}
/*2018-03-10 15:45:38.874*/


#include<stdio.h>
#include<algorithm>
#include <vector>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
int vis[100100];
int num;
int n,m;
struct node2
{
  int id;
  int x;
};
vector<node2>q;
struct node
{
   int u;
   int v;
}edge[100100];
struct Node
{
    int id;
    int x;
}val[100100];

bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int main()
{
    ios::sync_with_stdio(false);
    int flag;
    while(cin>>n>>m)
    {
        num=0;
        if(n==1&&m>0)
        {
          cout<<"-1"<<endl;
          continue;
        }
        vector<node2>V;
     memset(vis,0,sizeof(vis));
    int cnt=1;
    int a,f;
    for(int i=1;i<=m;i++)
    {
      cin>>a>>f;
      if(f==1)
      {
         num++;
         val[cnt].x=a;
         val[cnt].id=cnt;
         edge[i].u=1;
         edge[i].v=cnt++;
      }
      else
      {
          node2 tmp;
          tmp.id=i;
          tmp.x=a;
          V.push_back(tmp);
      }
    }
     sort(val+1,val+cnt,cmp);

       for(int i=0;i<V.size();i++)
       {
           flag=0;
           for(int j=cnt-1;j>=1;j--)
           {
              if(val[j].x<=V[i].x&&vis[j]<j-1)
              {
                  vis[j]++;
                  edge[V[i].id].u=vis[j];
                  edge[V[i].id].v=j;
                  flag=1;
                  break;
              }
           }
           if(flag==0)
           break;
       }
       if(flag==0||num!=n-1)cout<<"-1"<<endl;
       else
       {
            for(int i=1;i<=m;i++)
            cout<<edge[i].u<<" "<<edge[i].v<<endl;
       }
    }
    return 0;
}
/*2018-03-10 17:20:55.155*/


#include<cstdio>
#include<algorithm>

using namespace std;

int n, m, a, ans[100005][2], l = 1, b[2];
bool imp;

struct edge {
    int w, i;
    bool mst;
} e[100005];

bool cmp(edge x, edge y) {
    if (x.w == y.w) {
        if (!x.mst && y.mst) return false;
        else return true;
    }
    return x.w < y.w;
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &e[i].w, &a);
        if(a) e[i].mst = true;
        else e[i].mst = false;
        e[i].i = i;
    }
    b[0] = 2;
    sort(e, e + m, cmp);
    for (int i = 0; i < m; i++) {
        if(e[i].mst) {
            ans[e[i].i][0] = l++;
            ans[e[i].i][1] = l;
        }
        else {
            b[1]++;
            if (b[1] == b[0] - 1) {
                b[0]++;
                b[1] = 1;
            }
            if (b[0] > l) {
                imp = true;
                break;
            }
            ans[e[i].i][0] = b[1];
            ans[e[i].i][1] = b[0];
        }
    }
    if (imp) printf("-1\n");
    else
        for (int i = 0; i < m; i++)
            printf("%d %d\n", ans[i][0], ans[i][1]);
    scanf("\n");
    return 0;
}


#include<cstdio>
#include<algorithm>

using namespace std;

int n, m, a, ans[100005][2], l = 1, b[2];
bool imp;

struct edge {
    int w, i;
    bool mst;
} e[100005];

bool cmp(edge x, edge y) {
    if (x.w == y.w) {
        if(x.mst == y.mst) return x.i < y.i;
        return x.mst;
    }
    return x.w < y.w;
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &e[i].w, &a);
        if(a) e[i].mst = true;
        else e[i].mst = false;
        e[i].i = i;
    }
    b[0] = 2;
    sort(e, e + m, cmp);
    for (int i = 0; i < m; i++) {
        if(e[i].mst) {
            ans[e[i].i][0] = l++;
            ans[e[i].i][1] = l;
        }
        else {
            b[1]++;
            if (b[1] == b[0] - 1) {
                b[0]++;
                b[1] = 1;
            }
            if (b[0] > l) {
                imp = true;
                break;
            }
            ans[e[i].i][0] = b[1];
            ans[e[i].i][1] = b[0];
        }
    }
    if (imp) printf("-1\n");
    else
        for (int i = 0; i < m; i++)
            printf("%d %d\n", ans[i][0], ans[i][1]);
    scanf("\n");
    return 0;
}


#include<cstdio>
#include<algorithm>

using namespace std;

int n, m, a, ans[100005][2], l = 1, b[2];
bool imp;

struct edge {
    int w, i;
    bool mst;
} e[100005];

bool cmp(edge x, edge y) {
    if (x.w == y.w) return x.mst;
    return x.w < y.w;
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &e[i].w, &a);
        if(a) e[i].mst = true;
        else e[i].mst = false;
        e[i].i = i;
    }
    b[0] = 2;
    sort(e, e + m, cmp);
    for (int i = 0; i < m; i++) {
        if(e[i].mst) {
            ans[e[i].i][0] = l++;
            ans[e[i].i][1] = l;
        }
        else {
            b[1]++;
            if (b[1] == b[0] - 1) {
                b[0]++;
                b[1] = 1;
            }
            if (b[0] > l) {
                imp = true;
                break;
            }
            ans[e[i].i][0] = b[0];
            ans[e[i].i][1] = b[1];
        }
    }
    if (imp) printf("-1\n");
    else
        for (int i = 0; i < m; i++)
            printf("%d %d\n", ans[i][0], ans[i][1]);
    scanf("\n");
    return 0;
}


#include<cstdio>
#include<algorithm>

using namespace std;

int n, m, a, ans[100005][2], l = 1, b[2];
bool imp;

struct edge {
    int w, i;
    bool mst;
} e[100005];

bool cmp(edge x, edge y) {
    if (x.w == y.w) {
        if(x.mst == y.mst) return x.i < y.i;
        return x.mst;
    }
    return x.w < y.w;
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        if(a) e[i].mst = true;
        else e[i].mst = false;
        e[i].i = i;
    }
    b[0] = 2;
    sort(e, e + m, cmp);
    for (int i = 0; i < m; i++) {
        if(e[i].mst) {
            ans[e[i].i][0] = l++;
            ans[e[i].i][1] = l;
        }
        else {
            b[1]++;
            if (b[1] == b[0] - 1) {
                b[0]++;
                b[1] = 1;
            }
            if (b[0] > l) {
                imp = true;
                break;
            }
            ans[e[i].i][0] = b[1];
            ans[e[i].i][1] = b[0];
        }
    }
    if (imp) printf("-1\n");
    else
        for (int i = 0; i < m; i++)
            printf("%d %d\n", ans[i][0], ans[i][1]);
    scanf("\n");
    return 0;
}


#include<cstdio>
#include<algorithm>

using namespace std;

int n, m, a, ans[100005][2], l = 1, b[2];
bool imp;

struct edge {
    int w, i;
    bool mst;
} e[100005];

bool cmp(edge x, edge y) {
    return x.w < y.w;
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &e[i].w, &a);
        if(a) e[i].mst = true;
        else e[i].mst = false;
        e[i].i = i;
    }
    b[0] = 2;
    sort(e, e + m, cmp);
    for (int i = 0; i < m; i++) {
        if(e[i].mst) {
            ans[e[i].i][0] = l++;
            ans[e[i].i][1] = l;
        }
        else {
            b[1]++;
            if (b[1] == b[0] - 1) {
                b[0]++;
                b[1] = 1;
            }
            if (b[0] > l) {
                imp = true;
                break;
            }
            ans[e[i].i][0] = b[0];
            ans[e[i].i][1] = b[1];
        }
    }
    if (imp) printf("-1\n");
    else
        for (int i = 0; i < m; i++)
            printf("%d %d\n", ans[i][0], ans[i][1]);
    scanf("\n");
    return 0;
}


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

#define ll long long

pair<int,int> a[100010];	//mst
pair<int,int> b[100010];	//not mst

int ansl[100010];
int ansr[100010];

int main(){
	int n,m;
	cin>>n>>m;
	int cnta=0;
	int cntb=0;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		if(y){
			a[cnta].second=i;
			a[cnta++].first=x;
		}else{
			b[cntb].second=i;
			b[cntb++].first=x;
		}
	}
	sort(a,a+cnta);
	sort(b,b+cntb);

	bool ok=1;
	int j=0;
	int k=1;
	for(int i=0;i<cntb;i++){
		int len=b[i].first;
		bool flag=0;
		for(;j<cnta;j++,k=j+1){
			for(;k<cnta;k++){
				if(a[j].first<=len && a[k].first<=len){
					flag=1;
					int id = b[i].second;
					ansl[id]=j+2;
					ansr[id]=k+2;
					k++;
					break;
				}else{
					break;
				}
			}
			if(flag)break;
		}
		if(!flag){
			ok=0;
		}
	}

	if(ok){
		for(int i=0;i<cnta;i++){
			ansl[a[i].second]=1;
			ansr[a[i].second]=i+2;
		}
		for(int i=1;i<=m;i++){
			printf("%d %d\n",ansl[i],ansr[i]);
		}
	}else{
		cout<<"-1"<<endl;
	}

	return 0;

}


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

#define ll long long

pair<int,int> a[100010];	//mst
pair<int,int> b[100010];	//not mst

int ansl[100010];
int ansr[100010];

int pos[100010];

int main(){
	int n,m;
	cin>>n>>m;
	int cnta=0;
	int cntb=0;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		if(y){
			a[cnta].second=i;
			a[cnta++].first=x;
		}else{
			b[cntb].second=i;
			b[cntb++].first=x;
		}
	}
	sort(a,a+cnta);
	sort(b,b+cntb);

	bool ok=1;

	for(int i=0;i<cntb;i++){
		int len=b[i].first;
		//cout<<"len is "<<len<<endl;
		bool flag=0;
		for(int j=0;j<cnta;j++){
			for(int k=pos[j];k<cnta;k++){
				if(pos[j]==0)k=j+1;
				if(a[j].first<=len && a[k].first<=len){
					flag=1;
					int id = b[i].second;
					ansl[id]=j+2;
					ansr[id]=k+2;
					k++;
					pos[j]=k;
					break;
				}else{
					break;
				}
			}
			if(flag)break;
		}
		if(!flag){
			ok=0;
		}
	}

	if(ok){
		for(int i=0;i<cnta;i++){
			ansl[a[i].second]=1;
			ansr[a[i].second]=i+2;
		}
		for(int i=1;i<=m;i++){
			printf("%d %d\n",ansl[i],ansr[i]);
		}
	}else{
		cout<<"-1"<<endl;
	}

	return 0;

}


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

#define ll long long

pair<int,int> a[100010];    //mst
pair<int,int> b[100010];    //not mst
/*int ida[100010];
int idb[100010];
*/
int ansl[100010];
int ansr[100010];

int main(){
    int n,m;
    cin>>n>>m;
    int cnta=0;
    int cntb=0;
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        if(y){
            a[cnta].second=i;
            a[cnta++].first=x;
        }else{
            b[cntb].second=i;
            b[cntb++].first=x;
        }
    }
    sort(a,a+cnta);
    sort(b,b+cntb);

    bool ok=1;
    int j=0;
    int k=1;
    for(int i=0;i<cntb;i++){
        int len=b[i].first;
        bool flag=0;
        for(;j<cnta;j++,k=j+1){
            for(;k<cnta;k++){
                if(a[j].first+a[k].first<=len){
                    flag=1;
                    int id = b[i].second;
                    ansl[id]=j+2;
                    ansr[id]=k+2;
                    k++;
                    break;
                }else{
                    break;
                }
            }
            if(flag)break;
        }
        if(!flag){
            ok=0;
        }
    }

    if(ok){
        for(int i=0;i<cnta;i++){
            ansl[a[i].second]=1;
            ansr[a[i].second]=i+2;
        }
        for(int i=1;i<=m;i++){
            printf("%d %d\n",ansl[i],ansr[i]);
        }
    }else{
        cout<<"-1"<<endl;
    }

    return 0;

}


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

#define ll long long

pair<int,int> a[100010];	//mst
pair<int,int> b[100010];	//not mst

int ansl[100010];
int ansr[100010];

int pos[100010];

int main(){
	int n,m;
	cin>>n>>m;
	int cnta=0;
	int cntb=0;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		if(y){
			a[cnta].second=i;
			a[cnta++].first=x;
		}else{
			b[cntb].second=i;
			b[cntb++].first=x;
		}
	}
	sort(a,a+cnta);
	sort(b,b+cntb);

	bool ok=1;

	for(int i=0;i<cntb;i++){
		int len=b[i].first;
		cout<<"len is "<<len<<endl;
		bool flag=0;
		for(int j=0;j<cnta;j++){
			for(int k=pos[j];k<cnta;k++){
				if(pos[j]==0)k=j+1;
				if(a[j].first<=len && a[k].first<=len){
					flag=1;
					int id = b[i].second;
					ansl[id]=j+2;
					ansr[id]=k+2;
					k++;
					pos[j]=k;
					break;
				}else{
					break;
				}
			}
			if(flag)break;
		}
		if(!flag){
			ok=0;
		}
	}

	if(ok){
		for(int i=0;i<cnta;i++){
			ansl[a[i].second]=1;
			ansr[a[i].second]=i+2;
		}
		for(int i=1;i<=m;i++){
			printf("%d %d\n",ansl[i],ansr[i]);
		}
	}else{
		cout<<"-1"<<endl;
	}

	return 0;

}


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

#define ll long long

pair<int,int> a[100010];	//mst
pair<int,int> b[100010];	//not mst
/*int ida[100010];
int idb[100010];
*/
int ansl[100010];
int ansr[100010];

int main(){
	int n,m;
	cin>>n>>m;
	int cnta=0;
	int cntb=0;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		if(y){
			a[cnta].second=i;
			a[cnta++].first=x;
		}else{
			b[cntb].second=i;
			b[cntb++].first=x;
		}
	}
	sort(a,a+cnta);
	sort(b,b+cntb);

	bool ok=1;
	int j=0;
	int k=1;
	for(int i=0;i<cntb;i++){
		int len=b[i].first;
		bool flag=0;
		for(;j<cnta;j++,k=j+1){
			for(;k<cnta;k++){
				if(a[j].first<=len){
					flag=1;
					int id = b[i].second;
					ansl[id]=j+2;
					ansr[id]=k+2;
					k++;
					break;
				}else{
					break;
				}
			}
			if(flag)break;
		}
		if(!flag){
			ok=0;
		}
	}

	if(ok){
		for(int i=0;i<cnta;i++){
			ansl[a[i].second]=1;
			ansr[a[i].second]=i+2;
		}
		for(int i=1;i<=m;i++){
			printf("%d %d\n",ansl[i],ansr[i]);
		}
	}else{
		cout<<"-1"<<endl;
	}

	return 0;

}


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

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return !( rhs.r->used==0 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;

    Verticles* getParent()
    {
        if ( parent==NULL )
            return this;

        parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

int canconnect[ maxs ][ 2 ];

bool answ;
int cnt2;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    int cc=0;
    int cnt = 1;
    cnt2 = 0;
    for ( int i=0; i<m && answ; i++ )
    {

        if ( sr[ i ].r->used == 1 )
        {
            cnt++;
            a = &v[ 1 ];
            b = &v[ cnt ];
            b->parent = a;

            sr[ i ].r->f = 1;
            sr[ i ].r->t = cnt;

            for ( int i=2; i<cnt && cnt2<=m; i++ )
            {
                canconnect[ cnt2 ][ 0 ] = i;
                canconnect[ cnt2 ][ 1 ] = cnt;
                cnt2++;
            }
        }
        else
        {
            if ( cc==cnt2 )
            {
                answ = false;
            }
            else
            {
                sr[ i ].r->f = canconnect[ cc ][ 0 ];
                sr[ i ].r->t = canconnect[ cc ][ 1 ];
                cc++;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = NULL;
    }

    Solve();

    if ( !answ )
    {
        printf("-1\n");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

    return 0;
}


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

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return ( r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;

    Verticles* getParent()
    {
        if ( parent==NULL )
            return this;

        parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

int canconnect[ maxs ][ 2 ];

bool answ;
int cnt2;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    int cc=0;
    int cnt = 1;
    cnt2 = 0;
    for ( int i=0; i<m && answ; i++ )
    {

        if ( sr[ i ].r->used == 1 )
        {
            cnt++;
            a = &v[ 1 ];
            b = &v[ cnt ];
            b->parent = a;

            sr[ i ].r->f = 1;
            sr[ i ].r->t = cnt;

            for ( int i=2; i<cnt && cnt2<=m; i++ )
            {
                canconnect[ cnt2 ][ 0 ] = i;
                canconnect[ cnt2 ][ 1 ] = cnt;
                cnt2++;
            }
        }
        else
        {
            if ( cc==cnt2 )
            {
                answ = false;
            }
            else
            {
                sr[ i ].r->f = canconnect[ cc ][ 0 ];
                sr[ i ].r->t = canconnect[ cc ][ 1 ];
                cc++;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = NULL;
    }

    Solve();

    if ( !answ )
    {
        printf("-1\n");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return ( r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;

    Verticles* getParent()
    {
        if ( parent==NULL )
            return this;

        parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

int cc;
int aa[ 100009 ][ 2 ];

bool answ;
int cnt2;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    cc = 0;
    int cnt = 1;
    cnt2 = 0;
    for ( int i=0; i<m && answ; i++ )
    {
        if ( sr[ i ].r->used == 1 )
        {
            cnt++;
            a = &v[ 1 ];
            b = &v[ cnt ];

            sr[ i ].r->f = 1;
            sr[ i ].r->t = cnt;

            for ( int i=2; i<cnt && cnt2<m; i++ )
            {
                cnt2++;
                aa[ cnt2 ][ 0 ] = i;
                aa[ cnt2 ][ 1 ] = cnt;
            }
        }
        else
        {
            if ( cc==cnt2 )
            {
                answ = false;
            }
            else
            {
                sr[ i ].r->f = aa[ cc ][ 0 ];
                sr[ i ].r->t = aa[ cc ][ 1 ];
                cc++;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = NULL;
    }

    Solve();

    if ( !answ )
    {
        printf("-1\n");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return ( r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;
    list< int > inside;

    Verticles* getParent()
    {
        if ( parent==NULL )
            return this;

        parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

list< Verticles* > vert;
queue< pair<int,int> > canconnect;

bool answ;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    list<int>::iterator ai, bi;

    //cout<<" - - - "<<endl;

    for ( int i=0; i<m && answ; i++ )
    {
        //cout<<sr[ i ].r->len<<" "<<sr[ i ].r->used<<endl;
        if ( vert.empty() )
        {
            answ =false;
            break;
        }

        if ( sr[ i ].r->used == 1 )
        {
            a = vert.front(), vert.erase(vert.begin());
            b = vert.front(), vert.erase(vert.begin());

            a = a->getParent();
            b = b->getParent();

            b->parent = a;
            sr[ i ].r->f = a->head;
            sr[ i ].r->t = b->head;

            for ( ai = a->inside.begin(); ai!=a->inside.end(); ai++ )
            {
                for ( bi = b->inside.begin(); (int)canconnect.size()<m && bi!=b->inside.end(); bi++ )
                {
                    if ( *ai != a->head || *bi != b->head )
                    {
                       //cout<<" - "<<*ai<<" "<<*bi<<endl;
                        canconnect.push( make_pair( *ai, *bi ) );
                    }
                }
            }

            a->inside.splice( a->inside.end(), b->inside );
            vert.insert( vert.begin(), a );
        }
        else
        {
            if ( canconnect.empty() )
            {
                answ = false;
            }
            else
            {
                tmp = canconnect.front(), canconnect.pop();
                sr[ i ].r->f = tmp.first;
                sr[ i ].r->t = tmp.second;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = NULL;
        v[ i ].inside.push_back( i );
        vert.push_back( &v[ i ]);
    }

    Solve();

    if ( !answ || vert.size()!=1 )
    {
        printf("-1\n");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return ( r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;
    list< int > inside;

    Verticles* getParent()
    {
        if ( parent!=this )
            parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

queue< Verticles* > vert;
queue< pair<int,int> > canconnect;

bool answ;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    list<int>::iterator ai, bi;

    //cout<<" - - - "<<endl;

    for ( int i=0; i<m && answ; i++ )
    {
        //cout<<sr[ i ].r->len<<" "<<sr[ i ].r->used<<endl;
        if ( sr[ i ].r->used == 1 )
        {
            a = vert.front(), vert.pop();
            if ( vert.empty() )
            {
                answ = false;
                break;
            }
            b = vert.front(), vert.pop();

            a = a->getParent();
            b = b->getParent();

            b->parent = a;
            sr[ i ].r->f = a->head;
            sr[ i ].r->t = b->head;

            for ( ai = a->inside.begin(); ai!=a->inside.end(); ai++ )
            {
                for ( bi = b->inside.begin(); (int)canconnect.size()<m && bi!=b->inside.end(); bi++ )
                {
                    if ( *ai != a->head || *bi != b->head )
                    {
                        canconnect.push( make_pair( *ai, *bi ) );
                    }
                }
            }

            a->inside.splice( a->inside.end(), b->inside );
            vert.push( a );
        }
        else
        {
            if ( canconnect.empty() )
            {
                answ = false;
            }
            else
            {
                tmp = canconnect.front(), canconnect.pop();
                sr[ i ].r->f = tmp.first;
                sr[ i ].r->t = tmp.second;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = &v[ i ];
        v[ i ].inside.push_back( i );
        vert.push( &v[ i ]);
    }

    Solve();

    if ( !answ || vert.size()!=1 )
    {
        printf("-1");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

}


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

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    int magic;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len && rhs.r->used == r->used ) return magic < rhs.magic;
        if ( r->len == rhs.r->len ) return !( rhs.r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;

    Verticles* getParent()
    {
        if ( parent==NULL )
            return this;

        parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

int canconnect[ maxs ][ 2 ];

bool answ;
int cnt2;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    int cc=0;
    int cnt = 1;
    cnt2 = 0;
    for ( int i=0; i<m && answ; i++ )
    {

        if ( sr[ i ].r->used == 1 )
        {
            cnt++;
            a = &v[ 1 ];
            b = &v[ cnt ];
            b->parent = a;

            sr[ i ].r->f = 1;
            sr[ i ].r->t = cnt;

            for ( int i=2; i<cnt && cnt2<=m; i++ )
            {
                canconnect[ cnt2 ][ 0 ] = i;
                canconnect[ cnt2 ][ 1 ] = cnt;
                cnt2++;
            }
        }
        else
        {
            if ( cc==cnt2 )
            {
                answ = false;
            }
            else
            {
                sr[ i ].r->f = canconnect[ cc ][ 0 ];
                sr[ i ].r->t = canconnect[ cc ][ 1 ];
                cc++;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
        sr[ i ].magic = i;
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = NULL;
    }

    Solve();

    if ( !answ )
    {
        printf("-1\n");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return ( r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;
    list< int > inside;

    Verticles* getParent()
    {
        if ( parent==NULL )
            return this;

        parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

queue< Verticles* > vert;
queue< pair<int,int> > canconnect;

bool answ;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    list<int>::iterator ai, bi;

    //cout<<" - - - "<<endl;

    for ( int i=0; i<m && answ; i++ )
    {
        //cout<<sr[ i ].r->len<<" "<<sr[ i ].r->used<<endl;
        if ( vert.empty() )
        {
            answ =false;
            break;
        }

        if ( sr[ i ].r->used == 1 )
        {
            a = vert.front(), vert.pop();
            if ( vert.empty() )
            {
                answ = false;
                break;
            }
            b = vert.front(), vert.pop();

            a = a->getParent();
            b = b->getParent();

            b->parent = a;
            sr[ i ].r->f = a->head;
            sr[ i ].r->t = b->head;

            for ( ai = a->inside.begin(); ai!=a->inside.end(); ai++ )
            {
                for ( bi = b->inside.begin(); (int)canconnect.size()<m && bi!=b->inside.end(); bi++ )
                {
                    if ( *ai != a->head || *bi != b->head )
                    {
                        canconnect.push( make_pair( *ai, *bi ) );
                    }
                }
            }

            a->inside.splice( a->inside.end(), b->inside );
            vert.push( a );
        }
        else
        {
            if ( canconnect.empty() )
            {
                answ = false;
            }
            else
            {
                tmp = canconnect.front(), canconnect.pop();
                sr[ i ].r->f = tmp.first;
                sr[ i ].r->t = tmp.second;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = NULL;
        v[ i ].inside.push_back( i );
        vert.push( &v[ i ]);
    }

    Solve();

    if ( !answ || vert.size()!=1 )
    {
        printf("-1\n");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

}


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

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return !( rhs.r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;

    Verticles* getParent()
    {
        if ( parent==NULL )
            return this;

        parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

int canconnect[ maxs ][ 2 ];

bool answ;
int cnt2;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    int cc=0;
    int cnt = 1;
    cnt2 = 0;
    for ( int i=0; i<m && answ; i++ )
    {

        if ( sr[ i ].r->used == 1 )
        {
            cnt++;
            a = &v[ 1 ];
            b = &v[ cnt ];
            b->parent = a;

            sr[ i ].r->f = 1;
            sr[ i ].r->t = cnt;

            for ( int i=2; i<cnt && cnt2<=m; i++ )
            {
                canconnect[ cnt2 ][ 0 ] = i;
                canconnect[ cnt2 ][ 1 ] = cnt;
                cnt2++;
            }
        }
        else
        {
            if ( cc==cnt2 )
            {
                answ = false;
            }
            else
            {
                sr[ i ].r->f = canconnect[ cc ][ 0 ];
                sr[ i ].r->t = canconnect[ cc ][ 1 ];
                cc++;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = NULL;
    }

    Solve();

    if ( !answ )
    {
        printf("-1\n");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return ( r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;
    list< int > inside;

    Verticles* getParent()
    {
        if ( parent!=this )
            parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

queue< Verticles* > vert;
queue< pair<int,int> > canconnect;

bool answ;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    list<int>::iterator ai, bi;

    //cout<<" - - - "<<endl;

    for ( int i=0; i<m && answ; i++ )
    {
        //cout<<sr[ i ].r->len<<" "<<sr[ i ].r->used<<endl;
        if ( sr[ i ].r->used == 1 )
        {
            a = vert.front(), vert.pop();
            if ( vert.empty() )
            {
                answ = false;
            }
            b = vert.front(), vert.pop();

            a = a->getParent();
            b = b->getParent();

            b->parent = a;
            sr[ i ].r->f = a->head;
            sr[ i ].r->t = b->head;

            for ( ai = a->inside.begin(); ai!=a->inside.end(); ai++ )
            {
                for ( bi = b->inside.begin(); (int)canconnect.size()<m && bi!=b->inside.end(); bi++ )
                {
                    if ( *ai != a->head || *bi != b->head )
                    {
                        canconnect.push( make_pair( *ai, *bi ) );
                    }
                }
            }

            a->inside.insert( a->inside.end(), b->inside.begin(), b->inside.end() );
            vert.push( a );
        }
        else
        {
            if ( canconnect.empty() )
            {
                answ = false;
            }
            else
            {
                tmp = canconnect.front(), canconnect.pop();
                sr[ i ].r->f = tmp.first;
                sr[ i ].r->t = tmp.second;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = &v[ i ];
        v[ i ].inside.push_back( i );
        vert.push( &v[ i ]);
    }

    Solve();

    if ( !answ )
    {
        printf("-1");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return ( r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;
    list< int > inside;

    Verticles* getParent()
    {
        if ( parent!=this )
            parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

queue< Verticles* > vert;
queue< pair<int,int> > canconnect;

bool answ;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    list<int>::iterator ai, bi;

    //cout<<" - - - "<<endl;

    for ( int i=0; i<m && answ; i++ )
    {
        //cout<<sr[ i ].r->len<<" "<<sr[ i ].r->used<<endl;
        if ( sr[ i ].r->used == 1 )
        {
            a = vert.front(), vert.pop();
            if ( vert.empty() )
            {
                answ = false;
            }
            b = vert.front(), vert.pop();

            a = a->getParent();
            b = b->getParent();

            b->parent = a;
            sr[ i ].r->f = a->head;
            sr[ i ].r->t = b->head;

            for ( ai = a->inside.begin(); ai!=a->inside.end(); ai++ )
            {
                for ( bi = b->inside.begin(); (int)canconnect.size()<m && bi!=b->inside.end(); bi++ )
                {
                    if ( *ai != a->head || *bi != b->head )
                    {
                        canconnect.push( make_pair( *ai, *bi ) );
                    }
                }
            }

            a->inside.insert( a->inside.end(), b->inside.begin(), b->inside.end() );
            vert.push( a );
        }
        else
        {
            if ( canconnect.empty() )
            {
                answ = false;
            }
            else
            {
                tmp = canconnect.front(), canconnect.pop();
                sr[ i ].r->f = tmp.first;
                sr[ i ].r->t = tmp.second;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = &v[ i ];
        v[ i ].inside.push_back( i );
        vert.push( &v[ i ]);
    }

    Solve();

    if ( !answ || vert.size()>1 )
    {
        printf("-1");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxs = 100009;

int n, m;

struct Road{
    int len, used;
    int f, t;
}r[ 100009 ];

struct sRoad{
    Road* r;
    bool operator<(const sRoad& rhs)const
    {
        if ( r->len == rhs.r->len ) return ( r->used==1 );
        return r->len < rhs.r->len;
    }
}sr[ 100009 ];

struct Verticles
{
    int head;
    Verticles* parent;

    Verticles* getParent()
    {
        if ( parent==NULL )
            return this;

        parent = parent->getParent();
        return parent;
    }
}v[ 100009 ];

queue< pair<int,int> > canconnect;

bool answ;
int cnt2;

void Solve()
{
    Verticles *a, *b;
    pair<int,int> tmp;

    int cnt = 1;
    cnt2 = 0;
    for ( int i=0; i<m && answ; i++ )
    {

        if ( sr[ i ].r->used == 1 )
        {
            cnt++;
            a = &v[ 1 ];
            b = &v[ cnt ];
            b->parent = a;

            sr[ i ].r->f = 1;
            sr[ i ].r->t = cnt;

            for ( int i=2; i<cnt && cnt2<m; i++ )
            {
                cnt2++;
                canconnect.push( make_pair( i, cnt ) );
            }
        }
        else
        {
            if ( canconnect.empty() )
            {
                answ = false;
            }
            else
            {
                tmp = canconnect.front(), canconnect.pop();
                sr[ i ].r->f = tmp.first;
                sr[ i ].r->t = tmp.second;
            }
        }
    }
}

int main()
{
    answ = true;
    scanf("%d %d", &n, &m );

    for ( int i=0; i<m; i++ )
    {
        scanf("%d %d", &r[ i ].len, &r[ i ].used );
        sr[ i ].r = &r[ i ];
    }

    sort( sr, sr+m );

    for ( int i=1; i<=n; i++ )
    {
        v[ i ].head = i;
        v[ i ].parent = NULL;
    }

    Solve();

    if ( !answ )
    {
        printf("-1\n");
        return 0;
    }

    for ( int i=0; i<m; i++)
        printf("%d %d\n", r[ i].f, r[ i].t );

    return 0;
}


//
//	ID: y0rkl1u
//	PROG: codeforces 605B. Lazy Student
//	LANG: C++
//	DATE: 12.18.2015
//	NOTE: MST
//

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

#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Cmax(a,b) ((a)<(b)?(a)=(b):1)
#define Cmin(a,b) ((a)>(b)?(a)=(b):1)
#define CLR(arr) memset(arr,0,sizeof(arr))
#define CLRS(arr,k) memset(arr,k,sizeof(arr))
#define elif else if
#define PB push_back
#define SZ(x) ((int)(x).size())
#define ft first
#define sc second
#define MP make_pair
#define Print(x) cerr<<#x<<" = "<<x<<endl
#define RETURN(x) do{cout<<x<<endl;return;}while(0)

typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;

struct Tedge{int w,pick,idx,u,v;};
bool ByWeight(const Tedge&a,const Tedge&b)
{return a.w<b.w||(a.w==b.w&&a.pick<b.pick);}
bool ByIdx(const Tedge&a,const Tedge&b)
{return a.idx<b.idx;}
const int MAX_E=100010;
int E,V;
VPII Rest;
Tedge Ed[MAX_E];
inline void Main()
{
	scanf("%d%d",&V,&E);
	for(int i=1;i<=E;i++){
		scanf("%d%d",&Ed[i].w,&Ed[i].pick);
		Ed[i].idx=i;
	}
	sort(Ed+1,Ed+1+E,ByWeight);
	int cur=1;
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		if(e.pick){
			e.u=cur;
			e.v=++cur;
			for(int u=1;u<=cur-2;u++)
				Rest.PB(MP(u,cur));
		}
		else{
			if(Rest.size()){
				PII r=Rest.back();Rest.pop_back();
				e.u=r.ft,e.v=r.sc;
			}
			else RETURN(-1);
		}
	}
	sort(Ed+1,Ed+1+E,ByIdx);
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		printf("%d %d\n",e.u,e.v);
	}
}
int main(){Main();return 0;}


//
//	ID: y0rkl1u
//	PROG: codeforces 605B. Lazy Student
//	LANG: C++
//	DATE: 12.18.2015
//	NOTE: MST
//

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

#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Cmax(a,b) ((a)<(b)?(a)=(b):1)
#define Cmin(a,b) ((a)>(b)?(a)=(b):1)
#define CLR(arr) memset(arr,0,sizeof(arr))
#define CLRS(arr,k) memset(arr,k,sizeof(arr))
#define elif else if
#define PB push_back
#define SZ(x) ((int)(x).size())
#define ft first
#define sc second
#define MP make_pair
#define Print(x) cerr<<#x<<" = "<<x<<endl
#define RETURN(x) do{cout<<x<<endl;return;}while(0)

typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;

struct Tedge{int w,pick,idx,u,v;};
bool ByWeight(const Tedge&a,const Tedge&b)
{return a.w<b.w||(a.w==b.w&&a.pick>b.pick);}
bool ByIdx(const Tedge&a,const Tedge&b)
{return a.idx<b.idx;}
const int MAX_E=100010;
int E,V;
VPII Rest;
Tedge Ed[MAX_E];
inline void Main()
{
	scanf("%d%d",&V,&E);
	for(int i=1;i<=E;i++){
		scanf("%d%d",&Ed[i].w,&Ed[i].pick);
		Ed[i].idx=i;
	}
	sort(Ed+1,Ed+1+E,ByWeight);
	int cur=1;
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		if(e.pick){
			e.u=cur;
			e.v=++cur;
			for(int u=1;u<=cur-2;u++)
				Rest.PB(MP(u,cur));
		}
		else{
			if(Rest.size()){
				PII r=Rest.back();Rest.pop_back();
				e.u=r.ft,e.v=r.sc;
			}
			else RETURN(-1);
		}
	}
	sort(Ed+1,Ed+1+E,ByIdx);
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		printf("%d %d\n",e.u,e.v);
	}
}
int main(){Main();return 0;}


//
//	ID: y0rkl1u
//	PROG: codeforces 605B. Lazy Student
//	LANG: C++
//	DATE: 12.18.2015
//	NOTE: MST
//

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

#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Cmax(a,b) ((a)<(b)?(a)=(b):1)
#define Cmin(a,b) ((a)>(b)?(a)=(b):1)
#define CLR(arr) memset(arr,0,sizeof(arr))
#define CLRS(arr,k) memset(arr,k,sizeof(arr))
#define elif else if
#define PB push_back
#define SZ(x) ((int)(x).size())
#define ft first
#define sc second
#define MP make_pair
#define Print(x) cerr<<#x<<" = "<<x<<endl
#define RETURN(x) do{cout<<x<<endl;return;}while(0)

typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;

struct Tedge{int w,pick,idx,u,v;};
bool ByWeight(const Tedge&a,const Tedge&b)
{return a.w<b.w||(a.w==b.w&&a.pick>b.pick);}
bool ByIdx(const Tedge&a,const Tedge&b)
{return a.idx<b.idx;}
const int MAX_E=100010;
int E,V;
VPII Rest;
Tedge Ed[MAX_E];
inline void Main()
{
	scanf("%d%d",&V,&E);
	for(int i=1;i<=E;i++){
		scanf("%d%d",&Ed[i].w,&Ed[i].pick);
		Ed[i].idx=i;
	}
	sort(Ed+1,Ed+1+E,ByWeight);
	int cur=1;
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		if(e.pick){
			e.u=cur;
			e.v=++cur;
			for(int u=1;u<=cur-2;u++)
				if(SZ(Rest)<=2*V)
					Rest.PB(MP(u,cur));
				else break;
		}
		else{
			if(Rest.size()){
				PII r=Rest.back();Rest.pop_back();
				e.u=r.ft,e.v=r.sc;
			}
			else RETURN(-1);
		}
	}
	sort(Ed+1,Ed+1+E,ByIdx);
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		printf("%d %d\n",e.u,e.v);
	}
}
int main(){Main();return 0;}


//
//	ID: y0rkl1u
//	PROG: codeforces 605B. Lazy Student
//	LANG: C++
//	DATE: 12.18.2015
//	NOTE: MST
//

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

#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Cmax(a,b) ((a)<(b)?(a)=(b):1)
#define Cmin(a,b) ((a)>(b)?(a)=(b):1)
#define CLR(arr) memset(arr,0,sizeof(arr))
#define CLRS(arr,k) memset(arr,k,sizeof(arr))
#define elif else if
#define PB push_back
#define SZ(x) ((int)(x).size())
#define ft first
#define sc second
#define MP make_pair
#define Print(x) cerr<<#x<<" = "<<x<<endl
#define RETURN(x) do{cout<<x<<endl;return;}while(0)

typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;

struct Tedge{int w,pick,idx,u,v;};
bool ByWeight(const Tedge&a,const Tedge&b)
{return a.w<b.w||(a.w==b.w&&a.pick>b.pick);}
bool ByIdx(const Tedge&a,const Tedge&b)
{return a.idx<b.idx;}
const int MAX_E=100010;
int E,V;
VPII Rest;
Tedge Ed[MAX_E];
inline void Main()
{
	scanf("%d%d",&V,&E);
	for(int i=1;i<=E;i++){
		scanf("%d%d",&Ed[i].w,&Ed[i].pick);
		Ed[i].idx=i;
	}
	sort(Ed+1,Ed+1+E,ByWeight);
	int cur=1;
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		if(e.pick){
			e.u=cur;
			e.v=++cur;
			for(int u=1;u<=cur-2;u++)
				if(SZ(Rest)<=2*V)
					Rest.PB(MP(u,cur));
		}
		else{
			if(Rest.size()){
				PII r=Rest.back();Rest.pop_back();
				e.u=r.ft,e.v=r.sc;
			}
			else RETURN(-1);
		}
	}
	sort(Ed+1,Ed+1+E,ByIdx);
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		printf("%d %d\n",e.u,e.v);
	}
}
int main(){Main();return 0;}


//
//	ID: y0rkl1u
//	PROG: codeforces 605B. Lazy Student
//	LANG: C++
//	DATE: 12.18.2015
//	NOTE: MST
//

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

#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Cmax(a,b) ((a)<(b)?(a)=(b):1)
#define Cmin(a,b) ((a)>(b)?(a)=(b):1)
#define CLR(arr) memset(arr,0,sizeof(arr))
#define CLRS(arr,k) memset(arr,k,sizeof(arr))
#define elif else if
#define PB push_back
#define SZ(x) ((int)(x).size())
#define ft first
#define sc second
#define MP make_pair
#define Print(x) cerr<<#x<<" = "<<x<<endl
#define RETURN(x) do{cout<<x<<endl;return;}while(0)

typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;

struct Tedge{int w,pick,idx,u,v;};
bool ByWeight(const Tedge&a,const Tedge&b)
{return a.w<b.w||(a.w==b.w&&a.pick>b.pick);}
bool ByIdx(const Tedge&a,const Tedge&b)
{return a.idx<b.idx;}
const int MAX_E=100010;
int E,V;
VPII Rest;
Tedge Ed[MAX_E];
inline void Main()
{
	scanf("%d%d",&V,&E);
	for(int i=1;i<=E;i++){
		scanf("%d%d",&Ed[i].w,&Ed[i].pick);
		Ed[i].idx=i;
	}
	sort(Ed+1,Ed+1+E,ByWeight);
	int cur=1;
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		if(e.pick){
			e.u=cur;
			e.v=++cur;
			for(int u=1;u<=cur-2;u++){
				if(SZ(Rest)<=2*E)
					Rest.PB(MP(u,cur));
				else break;
			}
		}
		else{
			if(Rest.size()){
				PII r=Rest.back();Rest.pop_back();
				e.u=r.ft,e.v=r.sc;
			}
			else RETURN(-1);
		}
	}
	sort(Ed+1,Ed+1+E,ByIdx);
	for(int i=1;i<=E;i++){
		Tedge&e=Ed[i];
		printf("%d %d\n",e.u,e.v);
	}
}
int main(){Main();return 0;}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <utility>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <ctime>
#define ll long long
#define maxn 100010
#define inf 0x7fffffff
#define eps 1e-7
#define imax(x,y)(x>y)?x:y
#define imin(x,y)(x<y)?x:y

using namespace std;

struct edge
{
    int w,b,id,u,v;
}e[maxn*2];

vector<int>u,v;
vector<int>::iterator it;

bool cmp(edge a,edge b)
{
    if (a.w<b.w)return 1;
    if (a.w==b.w&&a.b>b.b)return 1;
    return 0;
}

bool cmp2(edge a,edge b)
{
    if (a.id<b.id)return 1;
    return 0;
}

int n,m,w[100010],b[100010];
int main()
{
    scanf("%d %d",&n,&m);
    for (int i=0;i<m;i++)
    {
    e[i].id=i;
    scanf("%d%d",&e[i].w,&e[i].b);
    }
    sort(e,e+m,cmp);
    int now=1,count=0;
    for (int i=0;i<m;i++)
    {
    if (e[i].b)
    {
        e[i].u=now;
        e[i].v=now+1;
        count+=now;
        for (int i=1;i<now;i++)
        {
        u.push_back(i);
        v.push_back(now+1);
        }
        count--;
        now++;
    }
    else
    {
        if (!count)
        {
        printf("-1");
        return 0;
        }
        it=u.end();it--;
        e[i].u=*it;
        it=v.end();it--;
        e[i].v=*it;
        count--;
    }
    }
    sort(e,e+m,cmp2);
    for (int i=0;i<m;i++)
    printf("%d %d\n",e[i].u,e[i].v);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <utility>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <ctime>
#define ll long long
#define maxn 100010
#define inf 0x7fffffff
#define eps 1e-7
#define imax(x,y)(x>y)?x:y
#define imin(x,y)(x<y)?x:y

using namespace std;

struct edge
{
    int w,b,id,u,v;
}e[maxn*2];

vector<int>u,v;
vector<int>::iterator it;

bool cmp(edge a,edge b)
{
    if (a.w<b.w)return 1;
    if (a.w==b.w&&a.b>b.b)return 1;
    return 0;
}

bool cmp2(edge a,edge b)
{
    if (a.id<b.id)return 1;
    return 0;
}

int n,m;
int main()
{
    scanf("%d %d",&n,&m);
    for (int i=0;i<m;i++)
    {
    e[i].id=i;
    scanf("%d%d",&e[i].w,&e[i].b);
    }
    sort(e,e+m,cmp);
    int now=1,count=0,cct=0;
    for (int i=0;i<m;i++)
    {
    if (e[i].b)
    {
        e[i].u=now;
        e[i].v=now+1;
        count+=now;
        for (int i=1;i<now;i++)
        if (cct<m)
        {
        u.push_back(i);
        v.push_back(now+1);
        cct++;
        }
        else break;
        count--;
        now++;
    }
    else
    {
        if (!count)
        {
        printf("-1");
        return 0;
        }
        it=u.end();it--;
        e[i].u=*it;
        u.pop_back();
        it=v.end();it--;
        e[i].v=*it;
        count--;
        v.pop_back();
    }
    }
    sort(e,e+m,cmp2);
    for (int i=0;i<m;i++)
    printf("%d %d\n",e[i].u,e[i].v);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <utility>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <ctime>
#define ll long long
#define maxn 100010
#define inf 0x7fffffff
#define eps 1e-7
#define imax(x,y)(x>y)?x:y
#define imin(x,y)(x<y)?x:y

using namespace std;

struct edge
{
    int w,b,id,u,v;
}e[maxn*2];

vector<int>u,v;
vector<int>::iterator it;

bool cmp(edge a,edge b)
{
    if (a.w<b.w)return 1;
    if (a.w==b.w&&a.b>b.b)return 1;
    return 0;
}

bool cmp2(edge a,edge b)
{
    if (a.id<b.id)return 1;
    return 0;
}

int n,m,w[100010],b[100010];
int main()
{
    scanf("%d %d",&n,&m);
    for (int i=0;i<m;i++)
    {
    e[i].id=i;
    scanf("%d%d",&e[i].w,&e[i].b);
    }
    sort(e,e+m,cmp);
    int now=1,count=0;
    for (int i=0;i<m;i++)
    {
    if (e[i].b)
    {
        e[i].u=now;
        e[i].v=now+1;
        count+=now;
        for (int i=1;i<now;i++)
        {
        u.push_back(i);
        v.push_back(now+1);
        }
        count--;
        now++;
    }
    else
    {
        if (!count)
        {
        printf("-1");
        return 0;
        }
        it=u.end();it--;
        e[i].u=*it;
        u.pop_back();
        it=v.end();it--;
        e[i].v=*it;
        count--;
        v.pop_back();
    }
    }
    sort(e,e+m,cmp2);
    for (int i=0;i<m;i++)
    printf("%d %d\n",e[i].u,e[i].v);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <utility>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <ctime>
#define ll long long
#define maxn 100010
#define inf 0x7fffffff
#define eps 1e-7
#define imax(x,y)(x>y)?x:y
#define imin(x,y)(x<y)?x:y

using namespace std;

struct edge
{
    int w,b,id,u,v;
}e[maxn*2];

vector<int>u,v;
vector<int>::iterator it;

bool cmp(edge a,edge b)
{
    if (a.w<b.w)return 1;
    if (a.w==b.w&&a.b>b.b)return 1;
    return 0;
}

bool cmp2(edge a,edge b)
{
    if (a.id<b.id)return 1;
    return 0;
}

int n,m;
int main()
{
    scanf("%d %d",&n,&m);
    for (int i=0;i<m;i++)
    {
    e[i].id=i;
    scanf("%d%d",&e[i].w,&e[i].b);
    }
    sort(e,e+m,cmp);
    int now=1,count=0;
    for (int i=0;i<m;i++)
    {
    if (e[i].b)
    {
        e[i].u=now;
        e[i].v=now+1;
        count+=now;
        for (int i=1;i<now;i++)
        {
        u.push_back(i);
        v.push_back(now+1);
        }
        count--;
        now++;
    }
    else
    {
        if (!count)
        {
        printf("-1");
        return 0;
        }
        it=u.end();it--;
        e[i].u=*it;
        u.pop_back();
        it=v.end();it--;
        e[i].v=*it;
        count--;
        v.pop_back();
    }
    }
    sort(e,e+m,cmp2);
    for (int i=0;i<m;i++)
    printf("%d %d\n",e[i].u,e[i].v);
    return 0;
}


#include <bits/stdc++.h>
#define INF 0x7fffffff
#define maxn 100010
#define eps 1e-6
#define pi acos(-1.0)
#define e 2.718281828459
#define mod (int)1e9 + 7
using namespace std;
typedef long long ll;
struct node
{
  int w, flag, id;
  friend bool operator<(node a, node b)
  {
    if (a.w == b.w)
      return a.flag > b.flag;
    return a.w < b.w;
  }
} a[maxn];
struct edge
{
  int u, v;
} p[maxn];
int main()
{
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
  long _begin_time = clock();
#endif
  int n, m;
  while (scanf("%d%d", &n, &m) != EOF)
  {
    for (int i = 0; i < m; i++)
    {
      scanf("%d%d", &a[i].w, &a[i].flag);
      a[i].id = i;
    }
    sort(a, a + m);
    int flag = 1, cnt = 1, pre = 2, cur = 3;
    for (int i = 0; i < m; i++)
    {
      int x = a[i].id;
      if (a[i].flag)
      {
        p[x].u = 1;
        p[x].v = ++cnt;
      }
      else
      {
        if (pre <= 1)
        {
          cur++;
          pre = cur - 1;
        }
        if (cur > cnt)
        {
          flag = 0;
          break;
        }
        p[x].u = cur;
        p[x].v = pre;
        pre--;
      }
    }
    if (flag)
      for (int i = 0; i < m; i++)
        printf("%d %d\n", p[i].u, p[i].v);
    else
      puts("-1");
  }

#ifndef ONLINE_JUDGE
  long _end_time = clock();
  printf("time = %ld ms.", _end_time - _begin_time);
#endif
  return 0;
}


#include <bits/stdc++.h>
#define INF 0x7fffffff
#define maxn 100010
#define eps 1e-6
#define pi acos(-1.0)
#define e 2.718281828459
#define mod (int)1e9 + 7
using namespace std;
typedef long long ll;
struct node
{
  int w, flag, id;
  friend bool operator<(node a, node b)
  {
    if (a.w == b.w)
      return a.id > b.id;
    return a.w < b.w;
  }
} a[maxn];
struct edge
{
  int u, v;
} p[maxn];
int main()
{
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
  long _begin_time = clock();
#endif
  int n, m;
  while (scanf("%d%d", &n, &m) != EOF)
  {
    for (int i = 0; i < m; i++)
    {
      scanf("%d%d", &a[i].w, &a[i].flag);
      a[i].id = i;
    }
    sort(a, a + m);
    int flag = 1, cnt = 1, pre = 2, cur = 3;
    for (int i = 0; i < m; i++)
    {
      int x = a[i].id;
      if (a[i].flag)
      {
        p[x].u = 1;
        p[x].v = ++cnt;
      }
      else
      {
        if (pre <= 1)
        {
          cur++;
          pre = cur - 1;
        }
        if (cur > cnt)
        {
          flag = 0;
          break;
        }
        p[x].u = pre;
        p[x].v = cur;
        pre--;
      }
    }
    if (flag)
      for (int i = 0; i < m; i++)
        printf("%d %d\n", p[i].u, p[i].v);
    else
      puts("-1");
  }

#ifndef ONLINE_JUDGE
  long _end_time = clock();
  printf("time = %ld ms.", _end_time - _begin_time);
#endif
  return 0;
}


#include <bits/stdc++.h>
#define INF 0x7fffffff
#define maxn 100010
#define eps 1e-6
#define pi acos(-1.0)
#define e 2.718281828459
#define mod (int)1e9 + 7
using namespace std;
typedef long long ll;
struct node
{
  int w, flag, id;
  friend bool operator<(node a, node b)
  {
    if (a.w == b.w)
      return a.id > b.id;
    return a.w < b.w;
  }
} a[maxn];
struct edge
{
  int u, v;
} p[maxn];
int main()
{
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
  long _begin_time = clock();
#endif
  int n, m;
  while (scanf("%d%d", &n, &m) != EOF)
  {
    for (int i = 0; i < m; i++)
    {
      scanf("%d%d", &a[i].w, &a[i].flag);
      a[i].id = i;
    }
    sort(a, a + m);
    int flag = 1, cnt = 1, pre = 2, cur = 3;
    for (int i = 0; i < m; i++)
    {
      int x = a[i].id;
      if (a[i].flag)
      {
        p[x].u = 1;
        p[x].v = ++cnt;
      }
      else
      {
        if (pre <= 1)
        {
          cur++;
          pre = cur - 1;
        }
        if (cur > cnt)
        {
          flag = 0;
          break;
        }
        p[x].u = cur;
        p[x].v = pre;
        pre--;
      }
    }
    if (flag)
      for (int i = 0; i < m; i++)
        printf("%d %d\n", p[i].u, p[i].v);
    else
      puts("-1");
  }

#ifndef ONLINE_JUDGE
  long _end_time = clock();
  printf("time = %ld ms.", _end_time - _begin_time);
#endif
  return 0;
}


#include <bits/stdc++.h>
#define INF 0x7fffffff
#define maxn 100010
#define eps 1e-6
#define pi acos(-1.0)
#define e 2.718281828459
#define mod (int)1e9 + 7
using namespace std;
typedef long long ll;
struct node
{
  int w, flag, id;
  friend bool operator<(node a, node b)
  {
    if (a.w == b.w)
      return a.id > b.id;
    return a.w < b.w;
  }
} a[maxn];
struct edge
{
  int u, v;
} p[maxn];
int main()
{
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
  long _begin_time = clock();
#endif
  int n, m;
  while (scanf("%d%d", &n, &m) != EOF)
  {
    for (int i = 0; i < m; i++)
    {
      scanf("%d%d", &a[i].w, &a[i].flag);
      a[i].id = i;
    }
    sort(a, a + m);
    int flag = 1, cnt = 2, pre = 2, cur = 3;
    for (int i = 0; i < m; i++)
    {
      int x = a[i].id;
      if (a[i].flag)
      {
        p[x].u = 1;
        p[x].v = cnt++;
      }
      else
      {
        if (pre <= 1)
        {
          cur++;
          pre = cur - 1;
        }
        if (cur > cnt)
        {
          flag = 0;
          break;
        }
        p[x].u = pre;
        p[x].v = cur;
        pre--;
      }
    }
    if (flag)
      for (int i = 0; i < m; i++)
        printf("%d %d\n", p[i].u, p[i].v);
    else
      puts("-1");
  }

#ifndef ONLINE_JUDGE
  long _end_time = clock();
  printf("time = %ld ms.", _end_time - _begin_time);
#endif
  return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
typedef __int64 LL;
int n,m,tt=1;
struct edge{
	int a,b,w,id,used;
}e[100010];
int cmp(edge x,edge y){
	return x.w<y.w;
}
int cmp2(edge x,edge y){
	return x.id<y.id;
}
LL dis[100010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int aa,bb;scanf("%d%d",&aa,&bb);
		e[i].w=aa;e[i].id=i;e[i].used=bb;
	}
	sort(e+1,e+1+m,cmp);
	int ll=2,rr=3;
	for(int i=1;i<=m;i++){
		if(e[i].used){
			tt++;
			e[i].a=1;e[i].b=tt;
		}
		else{
			bool fail=true;
			for(;ll<tt;ll++){
				for(;rr<=tt;rr++){
					e[i].a=ll;e[i].b=rr;
					rr++;fail=false;break;
				}
				if(!fail)break;
				rr=ll+2;
			}
			if(fail){
				printf("-1\n");
				return 0;
			}
		}
	}
	sort(e+1,e+1+m,cmp2);
	for(int i=1;i<=m;i++)printf("%d %d\n",e[i].a,e[i].b);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
typedef __int64 LL;
int n,m,tt=1;
struct edge{
	int a,b,w,id,used;
}e[100010];
int cmp(edge x,edge y){
	if(x.w==y.w)return x.used>y.used;
	return x.w<y.w;
}
int cmp2(edge x,edge y){
	return x.id<y.id;
}
LL dis[100010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int aa,bb;scanf("%d%d",&aa,&bb);
		e[i].w=aa;e[i].id=i;e[i].used=bb;
	}
	sort(e+1,e+1+m,cmp);
	int ll=2,rr=3;
	for(int i=1;i<=m;i++){
		if(e[i].used){
			tt++;
			e[i].a=1;e[i].b=tt;
		}
		else{
			bool fail=true;
			for(;rr<=tt;rr++){
				for(;ll<tt;ll++){
					e[i].a=ll;e[i].b=rr;
					ll++;fail=false;break;
				}
				if(!fail)break;
				ll=2;
			}
			if(fail){
				printf("-1\n");
				return 0;
			}
		}
	}
	sort(e+1,e+1+m,cmp2);
	for(int i=1;i<=m;i++)printf("%d %d\n",e[i].a,e[i].b);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
typedef __int64 LL;
int n,m,tt=1;
struct edge{
	int a,b,w,id,used;
}e[100010];
int cmp(edge x,edge y){
	return x.w<y.w;
}
int cmp2(edge x,edge y){
	return x.id<y.id;
}
LL dis[100010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int aa,bb;scanf("%d%d",&aa,&bb);
		e[i].w=aa;e[i].id=i;e[i].used=bb;
	}
	sort(e+1,e+1+m,cmp);
	int ll=1,rr=3;
	for(int i=1;i<=m;i++){
		if(e[i].used){
			tt++;
			e[i].a=tt-1;e[i].b=tt;
			dis[tt]=dis[tt-1]+(LL)e[i].w;
		}
		else{
			bool fail=true;
			for(;ll<tt;ll++){
				for(;rr<=tt;rr++){
					if(dis[rr]-dis[ll]<(LL)e[i].w){
						e[i].a=ll;e[i].b=rr;
						fail=false;break;
					}
				}
				if(!fail)break;
				rr=ll+3;
			}
			if(fail){
				printf("-1\n");
				return 0;
			}
		}
	}
	sort(e+1,e+1+m,cmp2);
	for(int i=1;i<=m;i++)printf("%d %d %d\n",e[i].a,e[i].b,e[i].w);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
typedef __int64 LL;
int n,m,tt=1;
struct edge{
	int a,b,w,id,used;
}e[100010];
int cmp(edge x,edge y){
	if(x.w==y.w)return x.used>y.used;
	return x.w<y.w;
}
int cmp2(edge x,edge y){
	return x.id<y.id;
}
LL dis[100010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int aa,bb;scanf("%d%d",&aa,&bb);
		e[i].w=aa;e[i].id=i;e[i].used=bb;
	}
	sort(e+1,e+1+m,cmp);
	int ll=2,rr=3;
	for(int i=1;i<=m;i++){
		if(e[i].used){
			tt++;
			e[i].a=1;e[i].b=tt;
		}
		else{
			bool fail=true;
			for(;ll<tt;ll++){
				for(;rr<=tt;rr++){
					e[i].a=ll;e[i].b=rr;
					rr++;fail=false;break;
				}
				if(!fail)break;
				rr=ll+2;
			}
			if(fail){
				printf("-1\n");
				return 0;
			}
		}
	}
	sort(e+1,e+1+m,cmp2);
	for(int i=1;i<=m;i++)printf("%d %d\n",e[i].a,e[i].b);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
typedef __int64 LL;
int n,m,tt=1;
struct edge{
	int a,b,w,id,used;
}e[100010];
int cmp(edge x,edge y){
	if(x.w==y.w)return x.used>y.used;
	return x.w<y.w;
}
int cmp2(edge x,edge y){
	return x.id<y.id;
}
LL dis[100010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int aa,bb;scanf("%d%d",&aa,&bb);
		e[i].w=aa;e[i].id=i;e[i].used=bb;
	}
	sort(e+1,e+1+m,cmp);
	int ll=2,rr=3;
	for(int i=1;i<=m;i++){
		if(e[i].used){
			tt++;
			e[i].a=1;e[i].b=tt;
		}
		else{
			bool fail=true;
			for(;rr<=tt;rr++){
				for(;ll<rr;ll++){
					e[i].a=ll;e[i].b=rr;
					ll++;fail=false;break;
				}
				if(!fail)break;
				ll=2;
			}
			if(fail){
				printf("-1\n");
				return 0;
			}
		}
	}
	sort(e+1,e+1+m,cmp2);
	for(int i=1;i<=m;i++)printf("%d %d\n",e[i].a,e[i].b);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
typedef __int64 LL;
int n,m,tt=1;
struct edge{
	int a,b,w,id,used;
}e[100010];
int cmp(edge x,edge y){
	if(x.w==y.w)return x.used>y.used;
	return x.w<y.w;
}
int cmp2(edge x,edge y){
	return x.id<y.id;
}
LL dis[100010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int aa,bb;scanf("%d%d",&aa,&bb);
		e[i].w=aa;e[i].id=i;e[i].used=bb;
	}
	sort(e+1,e+1+m,cmp);
	int ll=2,rr=3;
	for(int i=1;i<=m;i++){
		if(e[i].used){
			tt++;
			e[i].a=1;e[i].b=tt;
		}
		else{
			bool fail=true;
			for(;ll<n;ll++){
				for(;rr<=n;rr++){
					e[i].a=ll;e[i].b=rr;
					rr++;fail=false;break;
				}
				if(!fail)break;
				rr=ll+2;
			}
			if(fail){
				printf("-1\n");
				return 0;
			}
		}
	}
	sort(e+1,e+1+m,cmp2);
	for(int i=1;i<=m;i++)printf("%d %d\n",e[i].a,e[i].b);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
typedef __int64 LL;
int n,m,tt=1;
struct edge{
	int a,b,w,id,used;
}e[100010];
int cmp(edge x,edge y){
	return x.w<y.w;
}
int cmp2(edge x,edge y){
	return x.id<y.id;
}
LL dis[100010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int aa,bb;scanf("%d%d",&aa,&bb);
		e[i].w=aa;e[i].id=i;e[i].used=bb;
	}
	sort(e+1,e+1+m,cmp);
	int ll=1,rr=3;
	for(int i=1;i<=m;i++){
		if(e[i].used){
			tt++;
			e[i].a=tt-1;e[i].b=tt;
			dis[tt]=dis[tt-1]+(LL)e[i].w;
		}
		else{
			bool fail=true;
			for(;ll<tt;ll++){
				for(;rr<=tt;rr++){
					if(dis[rr]-dis[ll]<(LL)e[i].w){
						e[i].a=ll;e[i].b=rr;
						fail=false;break;
					}
				}
				if(!fail)break;
				rr=ll+3;
			}
			if(fail){
				printf("-1\n");
				return 0;
			}
		}
	}
	sort(e+1,e+1+m,cmp2);
	for(int i=1;i<=m;i++)printf("%d %d\n",e[i].a,e[i].b);
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b, idx, x, y;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<Edge> edges2;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    t.idx = i;
    edges.push_back(t);
    edges2.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i);
  }
  for (int i = 0; i < n - 1; ++i) {
    edges2[edges[mst[i]].idx].x = 1, edges2[edges[mst[i]].idx].y = i+2;
  }
  bool can = true;
  int u = 3, v = 2;
  for (int i = 0; can && i < m; ++i) {
    if (edges[i].b)
      continue;
    if (v == u)
      ++u, v = 2;
    can = (edges[i].w >= edges[mst[u-2]].w);
    edges2[edges[i].idx].x = v++, edges2[edges[i].idx].y = u;
  }
  if (can) {
    for (int i = 0; i < m; ++i)
      cout << edges2[i].x << " " << edges2[i].y << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b, idx, x, y;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<Edge> edges2;
  vector<int> mst;
  vector<int> minr;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  minr.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    t.idx = i;
    edges.push_back(t);
    edges2.push_back(t);
  }
  sort(edges.begin(), edges.end());
  int rank = 0, rc = 0;
  for (int i = 0; i < m; ++i) {
    if (i > 0 && edges[i].w == edges[i-1].w)
      ++rc;
    else
      ++rank, rc = 1;
    if (edges[i].b) {
      mst.push_back(i + 1);
      minr.push_back(rank);
    }
    // cout << edges[i].w << "\t" << edges[i].b << endl;
  }
  bool can = (mst[0] == 1);
  for (int i = 2; can && i < n; ++i) {
    // cout << mst[i-1] << "\t" << (i - 1) * i / 2 << endl;
    if (minr[i-1] > i * (i - 1) / 2 + 1)
      can = false;
  }
  if (can) {
    int u = 2, v = 2, c = 1, idx = 0;
    edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
    for (int i = 1; i < n - 1; ++i) {
      for (int j = mst[i-1]+1; j < mst[i]; ++j) {
        if (v == u)
          ++u, v = 2;
        edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
      }
      edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
    }
    for (int j = mst[n-2]+1; j <= m; ++j) {
      if (v == u)
        ++u, v = 2;
        edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
    }
    for (int i = 0; i < m; ++i)
      cout << edges2[i].x << " " << edges2[i].y << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    edges.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i + 1);
    // cout << edges[i].w << "\t" << edges[i].b << endl;
  }
  bool can = (mst[0] == 1);
  for (int i = 2; can && i < n; ++i) {
    // cout << mst[i-1] << "\t" << (i + 1) * i / 2 << endl;
    if (mst[i-1] > i * (i + 1) / 2)
      can = false;
  }
  if (can) {
    int u = 1, v = 1, c = 0;
    cout << 0 << " " << ++c << endl;
    for (int i = 1; i < n - 1; ++i) {
      for (int j = mst[i-1]+1; j < mst[i]; ++j) {
        if (v == u)
          ++u, v = 1;
        cout << v++ << " " << u << endl;
      }
      cout << 0 << " " << ++c << endl;
    }
    for (int j = mst[n-2]+1; j <= m; ++j) {
      if (v == u)
        ++u, v = 1;
      cout << v++ << " " << u << endl;
    }
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    edges.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i + 1);
    // cout << edges[i].w << "\t" << edges[i].b << endl;
  }
  bool can = (mst[0] == 1);
  for (int i = 2; can && i < n; ++i) {
    // cout << mst[i-1] << "\t" << (i + 1) * i / 2 << endl;
    if (mst[i-1] > i * (i + 1) / 2)
      can = false;
  }
  if (can) {
    int u = 2, v = 2, c = 1;
    cout << 1 << " " << ++c << endl;
    for (int i = 1; i < n - 1; ++i) {
      for (int j = mst[i-1]+1; j < mst[i]; ++j) {
        if (v == u)
          ++u, v = 2;
        cout << v++ << " " << u << endl;
      }
      cout << 1 << " " << ++c << endl;
    }
    for (int j = mst[n-2]+1; j <= m; ++j) {
      if (v == u)
        ++u, v = 2;
      cout << v++ << " " << u << endl;
    }
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b, idx, x, y;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<Edge> edges2;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    t.idx = i;
    edges.push_back(t);
    edges2.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i + 1);
    // cout << edges[i].w << "\t" << edges[i].b << endl;
  }
  bool can = (mst[0] == 1);
  for (int i = 2; can && i < n; ++i) {
    // cout << mst[i-1] << "\t" << (i - 1) * i / 2 << endl;
    if (mst[i-1] > i * (i - 1) / 2 + 1)
      can = false;
  }
  if (can) {
    int u = 2, v = 2, c = 1, idx = 0;
    edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
    for (int i = 1; i < n - 1; ++i) {
      for (int j = mst[i-1]+1; j < mst[i]; ++j) {
        if (v == u)
          ++u, v = 2;
        edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
      }
      edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
    }
    for (int j = mst[n-2]+1; j <= m; ++j) {
      if (v == u)
        ++u, v = 2;
        edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
    }
    for (int i = 0; i < m; ++i)
      cout << edges2[i].x << " " << edges2[i].y << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b, idx, x, y;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<Edge> edges2;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    t.idx = i;
    edges.push_back(t);
    edges2.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i + 1);
  }
  bool can = (mst[0] == 1);
  int u = 2, v = 2, c = 1, idx = 0;
  edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
  for (int i = 1; i < n - 1; ++i) {
    for (int j = mst[i-1]+1; can && j < mst[i]; ++j) {
      if (v == u)
        ++u, v = 2;
      can = edges[idx].w < edges[mst[i]].w;
      edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
    }
    if (!can) break;
    can = edges[idx].w < edges[mst[i]].w;
    edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
  }
  for (int j = mst[n-2]+1; can && j <= m; ++j) {
    if (v == u)
      ++u, v = 2;
      edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
  }
  if (can) {
    for (int i = 0; i < m; ++i)
      cout << edges2[i].x << " " << edges2[i].y << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b, idx, x, y;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<Edge> edges2;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    t.idx = i;
    edges.push_back(t);
    edges2.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i);
  }
  for (int i = 0; i < n - 1; ++i) {
    edges2[edges[mst[i]].idx].x = 1, edges2[edges[mst[i]].idx].y = i+2;
  }
  bool can = true;
  int u = 3, v = 2;
  for (int i = 0; can && i < m; ++i) {
    if (i == mst[u-3] || (n > 2 && i == mst[u-2]) || (n > 3 && i == mst[u-1]) || (n > 4 && i == mst[u]))
      continue;
    if (v == u)
      ++u, v = 2;
    can = (edges[i].w >= edges[mst[u-2]].w);
    edges2[edges[i].idx].x = v++, edges2[edges[i].idx].y = u;
  }
  if (can) {
    for (int i = 0; i < m; ++i)
      cout << edges2[i].x << " " << edges2[i].y << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b, idx, x, y;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<Edge> edges2;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    t.idx = i;
    edges.push_back(t);
    edges2.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i);
  }
  for (int i = 0; i < n - 1; ++i) {
    edges2[edges[mst[i]].idx].x = 1, edges2[edges[mst[i]].idx].y = i+2;
  }
  bool can = true;
  int u = 3, v = 2;
  for (int i = 0; can && i < m; ++i) {
    if (edges2[i].b)
      continue;
    if (v == u)
      ++u, v = 2;
    can = (edges[i].w >= edges[mst[u-2]].w);
    edges2[edges[i].idx].x = v++, edges2[edges[i].idx].y = u;
  }
  if (can) {
    for (int i = 0; i < m; ++i)
      cout << edges2[i].x << " " << edges2[i].y << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b, idx, x, y;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<Edge> edges2;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    t.idx = i;
    edges.push_back(t);
    edges2.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i + 1);
    // cout << edges[i].w << "\t" << edges[i].b << endl;
  }
  bool can = (mst[0] == 1);
  for (int i = 2; can && i < n; ++i) {
    // cout << mst[i-1] << "\t" << (i + 1) * i / 2 << endl;
    if (mst[i-1] > i * (i + 1) / 2)
      can = false;
  }
  if (can) {
    int u = 2, v = 2, c = 1, idx = 0;
    edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
    for (int i = 1; i < n - 1; ++i) {
      for (int j = mst[i-1]+1; j < mst[i]; ++j) {
        if (v == u)
          ++u, v = 2;
        edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
      }
      edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
    }
    for (int j = mst[n-2]+1; j <= m; ++j) {
      if (v == u)
        ++u, v = 2;
        edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
    }
    for (int i = 0; i < m; ++i)
      cout << edges2[i].x << " " << edges2[i].y << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Edge {
  int w, b, idx, x, y;
};

bool operator<(const Edge& a, const Edge& b) {
  return a.w < b.w;
}

int main() {
  int n, m, t1, t2;
  vector<Edge> edges;
  vector<Edge> edges2;
  vector<int> mst;
  cin >> n >> m;
  edges.reserve(m);
  mst.reserve(n-1);
  Edge t;
  for (int i = 0; i < m; ++i) {
    cin >> t.w >> t.b;
    t.idx = i;
    edges.push_back(t);
    edges2.push_back(t);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; ++i) {
    if (edges[i].b)
      mst.push_back(i+1);
  }
  bool can = (mst[0] == 1);
  int u = 2, v = 2, c = 1, idx = 0;
  edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
  for (int i = 1; can && i < n - 1; ++i) {
    for (int j = mst[i-1]+1; can && j < mst[i]; ++j) {
      if (v == u)
        ++u, v = 2;
      can = (edges[idx].w <= edges[mst[u-1]].w);
      edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
    }
    edges2[edges[idx].idx].x = 1, edges2[edges[idx++].idx].y = ++c;
  }
  for (int j = mst[n-2]+1; can && j <= m; ++j) {
    if (v == u)
      ++u, v = 2;
      edges2[edges[idx].idx].x = v++, edges2[edges[idx++].idx].y = u;
  }
  if (can) {
    for (int i = 0; i < m; ++i)
      cout << edges2[i].x << " " << edges2[i].y << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int M = 1000100;
struct node
{
	int w,flag;
	int a,b;
	int id;
	int num;
}a[M];
int n,pos[M],m,s[M];
bool cmp(const node &x,const node &y)
{
	if(x.w==y.w)
		return x.flag>y.flag;
	return x.w<y.w;
}
int fa[M];
bool cmp1(const node &x,const node &y)
{
	return x.id<y.id;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i].w,&a[i].flag);
		a[i].id=i;
	}
	sort(a+1,a+1+m,cmp);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	int k=1;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
		{
			a[i].a=k;
			pos[k]=i;
			a[i].num=(k-1)*k/2+1;
			a[i].b=++k;
		}
	bool flag=0;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
			if(a[i].num<i)
			{
				flag=1;
				break;
			}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	pos[n]=m+1;
	for(int i=1;i<n-1;i++)
	{
		int x=0;
		for(int j=pos[i]+1;j<pos[i+1];j++)
		{
			x++;
			a[j].a=x;
			a[j].b=i+1;
		}
		s[i+1]=x+1;
	}
	s[n]=1;
	for(int i=pos[n-1]+1;i<pos[n];)
	{
		for(int j=3;j<=n&&i<pos[n];j++)
		{
			for(int k=s[j];k<j-1;k++)
			{
				a[i].a=k;
				a[i].b=j;
				i++;
				if(i==pos[n])
					break;
			}
		}
	}
	sort(a+1,a+1+m,cmp1);
	for(int i=1;i<=m;i++)
		printf("%d %d\n",a[i].a,a[i].b);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int M = 1000100;
struct node
{
	int w,flag;
	int a,b;
	int id;
	int num;
}a[M];
int n,pos[M],m,s[M];
bool cmp(const node &x,const node &y)
{
	if(x.w==y.w)
		return x.flag>y.flag;
	return x.w<y.w;
}
int fa[M];
bool cmp1(const node &x,const node &y)
{
	return x.id<y.id;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i].w,&a[i].flag);
		a[i].id=i;
	}
	sort(a+1,a+1+m,cmp);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	int k=1;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
		{
			a[i].a=k;
			pos[k]=i;
			a[i].num=(k-1)*k/2+1;
			a[i].b=++k;
		}
	bool flag=0;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
			if(a[i].num<i)
			{
				flag=1;
				break;
			}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	pos[n]=m+1;
	for(int i=3;i<=n;i++)
		s[i]=1;
	int h=3,s=1;
	for(int i=1;i<n;i++)
	{
		for(int j=pos[i]+1;j<pos[i+1];)
		{
			while(1)
			{
				a[j].a=s;
				a[j].b=h;
				s++;
				if(s==h-1)
				{
					s=1;
					h++;
				}
				j++;
				if(j==pos[i+1])
					break;
			}
		}
	}
	sort(a+1,a+1+m,cmp1);
	for(int i=1;i<=m;i++)
		printf("%d %d\n",a[i].a,a[i].b);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int M = 1000100;
struct node
{
	int w,flag;
	int a,b;
	int id;
	int num;
}a[M];
int n,pos[M],m,s[M];
bool cmp(const node &x,const node &y)
{
	if(x.w==y.w)
		return x.flag>y.flag;
	return x.w<y.w;
}
int fa[M];
bool cmp1(const node &x,const node &y)
{
	return x.id<y.id;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i].w,&a[i].flag);
		a[i].id=i;
	}
	sort(a+1,a+1+m,cmp);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	int k=1;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
		{
			a[i].a=k;
			pos[k]=i;
			a[i].num=(k-1)*k/2+1;
			a[i].b=++k;
		}
	bool flag=0;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
			if(a[i].num<i)
			{
				flag=1;
				break;
			}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	pos[n]=m+1;
	int h=3,s1=1;
	for(int i=1;i<n;i++)
	{
		for(int j=pos[i]+1;j<pos[i+1];)
		{
			a[j].a=s1;
			a[j].b=h;
			s1++;
			if(s1==h-1)
			{
				s1=1;
				h++;
			}
			/*if(h>i&&s!=1)
			{
				flag=1;
				break;
			}*/
			j++;
		}
		/*if(flag)
			break;*/
	}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	sort(a+1,a+1+m,cmp1);
	for(int i=1;i<=m;i++)
		printf("%d %d\n",a[i].a,a[i].b);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int M = 1000100;
struct node
{
	int w,flag;
	int a,b;
	int id;
	int num;
}a[M];
int n,pos[M],m,s[M];
bool cmp(const node &x,const node &y)
{
	if(x.w==y.w)
		return x.flag>y.flag;
	return x.w<y.w;
}
int fa[M];
int find_fa(int x)
{
	if(x==fa[x])
		return x;
	return fa[x]=find_fa(fa[x]);
}
bool cmp1(const node &x,const node &y)
{
	return x.id<y.id;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i].w,&a[i].flag);
		a[i].id=i;
	}
	sort(a+1,a+1+m,cmp);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	int k=1;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
		{
			a[i].a=k;
			pos[k]=i;
			a[i].b=++k;
			a[i].num=(k-1)*k/2-k+2;
		}
	bool flag=0;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
			if(a[i].num<i)
			{
				flag=1;
				break;
			}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	pos[n]=m+1;
	for(int i=1;i<n-1;i++)
	{
		int x=0;
		for(int j=pos[i]+1;j<pos[i+1];j++)
		{
			x++;
			a[j].a=x;
			a[j].b=i+1;
		}
		s[i+1]=x+1;
	}
	s[n]=1;
	for(int i=pos[n-1]+1;i<pos[n];)
	{
		for(int j=1;j<=n&&i<pos[n];j++)
		{
			for(int k=s[j];k<j-1;k++)
			{
				a[i].a=k;
				a[i].b=j;
				i++;
				if(i==pos[n])
					break;
			}
		}
	}
	sort(a+1,a+1+m,cmp1);
	for(int i=1;i<=m;i++)
		printf("%d %d\n",a[i].a,a[i].b);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int M = 1000100;
struct node
{
	int w,flag;
	int a,b;
	int id;
	int num;
}a[M];
int n,pos[M],m,s[M];
bool cmp(const node &x,const node &y)
{
	if(x.w==y.w)
		return x.flag>y.flag;
	return x.w<y.w;
}
int fa[M];
int find_fa(int x)
{
	if(x==fa[x])
		return x;
	return fa[x]=find_fa(fa[x]);
}
bool cmp1(const node &x,const node &y)
{
	return x.id<y.id;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i].w,&a[i].flag);
		a[i].id=i;
	}
	sort(a+1,a+1+m,cmp);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	int k=1;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
		{
			a[i].a=k;
			pos[k]=i;
			a[i].b=++k;
			a[i].num=(k-1)*k/2-k+2;
		}
	bool flag=0;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
			if(a[i].num<i)
			{
				flag=1;
				break;
			}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	pos[n]=m+1;
	for(int i=1;i<n-1;i++)
	{
		int x=0;
		for(int j=pos[i]+1;j<pos[i+1];j++)
		{
			x++;
			a[j].a=x;
			a[j].b=i;
		}
		s[i]=x+1;
	}
	s[n-1]=1;
	s[n]=1;
	for(int i=pos[n-1]+1;i<pos[n];)
	{
		for(int j=1;j<=n&&i<pos[n];j++)
		{
			for(int k=s[j];k<j-1;k++)
			{
				a[i].a=k;
				a[i].b=j;
				i++;
				if(i==pos[n])
					break;
			}
		}
	}
	sort(a+1,a+1+m,cmp1);
	for(int i=1;i<=m;i++)
		printf("%d %d\n",a[i].a,a[i].b);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int M = 1000100;
struct node
{
	int w,flag;
	int a,b;
	int id;
	long long num;
}a[M];
int n,pos[M],m,s[M];
bool cmp(const node &x,const node &y)
{
	if(x.w==y.w)
		return x.flag>y.flag;
	return x.w<y.w;
}
int fa[M];
bool cmp1(const node &x,const node &y)
{
	return x.id<y.id;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i].w,&a[i].flag);
		a[i].id=i;
	}
	sort(a+1,a+1+m,cmp);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	int k=1;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
		{
			a[i].a=k;
			pos[k]=i;
			a[i].num=(long long)(k-1)*k/2+1;
			a[i].b=++k;
		}
	bool flag=0;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
			if(a[i].num<(long long)i)
			{
				flag=1;
				break;
			}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	pos[n]=m+1;
	int h=3,s1=1;
	for(int i=1;i<n;i++)
	{
		for(int j=pos[i]+1;j<pos[i+1];)
		{
			a[j].a=s1;
			a[j].b=h;
			s1++;
			if(s1==h-1)
			{
				s1=1;
				h++;
			}
			/*if(h>i&&s!=1)
			{
				flag=1;
				break;
			}*/
			j++;
		}
		/*if(flag)
			break;*/
	}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	sort(a+1,a+1+m,cmp1);
	for(int i=1;i<=m;i++)
		printf("%d %d\n",a[i].a,a[i].b);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int M = 1000100;
struct node
{
	int w,flag;
	int a,b;
	int id;
	int num;
}a[M];
int n,pos[M],m,s[M];
bool cmp(const node &x,const node &y)
{
	if(x.w==y.w)
		return x.flag>y.flag;
	return x.w<y.w;
}
int fa[M];
bool cmp1(const node &x,const node &y)
{
	return x.id<y.id;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i].w,&a[i].flag);
		a[i].id=i;
	}
	sort(a+1,a+1+m,cmp);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	int k=1;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
		{
			a[i].a=k;
			pos[k]=i;
			a[i].num=(k-1)*k/2+1;
			a[i].b=++k;
		}
	bool flag=0;
	for(int i=1;i<=m;i++)
		if(a[i].flag)
			if(a[i].num<i)
			{
				flag=1;
				break;
			}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	pos[n]=m+1;
	for(int i=3;i<=n;i++)
		s[i]=1;
	int h=3,s=1;
	for(int i=1;i<n;i++)
	{
		for(int j=pos[i]+1;j<pos[i+1];)
		{
			a[j].a=s;
			a[j].b=h;
			s++;
			if(s==h-1)
			{
				s=1;
				h++;
			}
			if(h>=i)
			{
				flag=1;
				break;
			}
			j++;
		}
		if(flag)
			break;
	}
	if(flag)
	{
		printf("-1\n");
		return 0;
	}
	sort(a+1,a+1+m,cmp1);
	for(int i=1;i<=m;i++)
		printf("%d %d\n",a[i].a,a[i].b);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n, m;
vector <pair <pair <int, int>, int> > a;
pair <int, int> ans[int(1e6)];

main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; ++i) {
		int cost, w; cin >> cost >> w;
		a.push_back(make_pair(make_pair(cost, -w), i));
	}
	sort(a.begin(), a.end());
	int from = 2, to = 3, cur = 2;
	for (int i = 0; i < (int)(a.size()); ++i) {
		if (a[i].first.second == -1) {
			ans[a[i].second] = make_pair(1, cur);
			cur++;
		} else {
			if (to >= cur) return cout << -1, 0;
			ans[a[i].second] = make_pair(from, to);
			from++;
			if (from == to) to++, from = 2;
		}
	}
	for (int i = 1; i <= m; ++i) cout << ans[i].first << ' ' << ans[i].second << endl;
}


#include <bits/stdc++.h>

using namespace std;
int n, m;
vector <pair <pair <int, int>, int> > a;
pair <int, int> ans[int(1e6)];

main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; ++i) {
		int cost, w; cin >> cost >> w;
		a.push_back(make_pair(make_pair(cost, -w), i));
	}
	sort(a.begin(), a.end());
	for (int i = 0; i < n - 1; ++i) if (a[i].first.second == 0) return cout << -1, 0;
	int prev = 1;
	for (int i = 0; i < n - 1; ++i) {
		ans[a[i].second] = make_pair(prev, prev + 1);
		prev++;
	}
	int cur = 1, now = 2;
	for (int i = n - 1; i < (int)(a.size()); ++i) {
		ans[a[i].second] = make_pair(cur, cur + now);
		now++;
		if (cur + now > n) cur++, now = 2;
	}
	for (int i = 1; i <= m; ++i) cout << ans[i].first << ' ' << ans[i].second << endl;
}


#include <bits/stdc++.h>

using namespace std;
int n, m;
vector <pair <pair <int, int>, int> > a;
pair <int, int> ans[int(1e6)];

main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; ++i) {
		int cost, w; cin >> cost >> w;
		a.push_back(make_pair(make_pair(cost, -w), i));
	}
	sort(a.begin(), a.end());
	for (int i = 0; i < n - 1; ++i) {
		int j = 1;
		while (a[i + j].first.first == a[i].first.first && a[i + j].first.second == 0) j++;
		if (a[i].first.second == 0) return cout << -1, 0;
		i = i + j - 1;
	}
	int prev = 1;
	for (int i = 0; i < n - 1; ++i) {
		ans[a[i].second] = make_pair(prev, prev + 1);
		prev++;
	}
	int cur = 1, now = 2;
	for (int i = n - 1; i < (int)(a.size()); ++i) {
		ans[a[i].second] = make_pair(cur, cur + now);
		now++;
		if (cur + now > n) cur++, now = 2;
	}
	for (int i = 1; i <= m; ++i) cout << ans[i].first << ' ' << ans[i].second << endl;
}


#include <bits/stdc++.h>

using namespace std;
int n, m;
vector <pair <pair <int, int>, int> > a;
pair <int, int> ans[int(1e6)];

main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; ++i) {
		int cost, w; cin >> cost >> w;
		a.push_back(make_pair(make_pair(cost, -w), i));
	}
	sort(a.begin(), a.end());
	for (int i = 0; i < n - 1; ++i) {
		int j = 1;
		while (a[i + j].first.first == a[i].first.first && a[i + j].first.second == 0) j++;
		if (a[i].first.second == 0) return cout << -1, 0;
		i = i + j - 1;
	}
	int prev = 1;
	for (int i = 0; i < n - 1; ++i) {
		ans[a[i].second] = make_pair(prev, prev + 1);
		prev++;
	}
	int cur = 1, now = 2;
	for (int i = 0; i < (int)(a.size()); ++i) {
		if (a[i].first.second == 1) continue;
		ans[a[i].second] = make_pair(cur, cur + now);
		now++;
		if (cur + now > n) cur++, now = 2;
	}
	for (int i = 1; i <= m; ++i) cout << ans[i].first << ' ' << ans[i].second << endl;
}