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

#define rep(i,a,b) for(i=(a);i<=(b);++i)
#define rev(i,a,b) for(i=(a);i>=(b);--i)
#define max2(a,b)  ((a)>(b)?(a):(b))
#define min2(a,b)  ((a)<(b)?(a):(b))
#define all(x) x.begin(),x.end()
#define sz(x) (long long)x.size()
#define fi first
#define se second
#define pb emplace_back // push_back
#define mp make_pair
#define endl '\n'

#ifdef Wild4Stone
template<typename T>
void __p(T a) { cout << a << " "; }
template<typename T, typename F>
void __p(pair<T, F> a) { cout << "{ "; __p(a.fi); __p(a.se); cout << "}"; }
template<typename T>
void __f(const char* s, T t) { cout << s << " : "; __p(t); }
template<typename T>
void __t(const char* s, const T &x) { cout << s << " : { "; for (auto it : x) __p(it); cout << "} ";}
template<typename T, typename ... F>
void __f(const char* s, T t, F ... f) {
	int i = 0; for (;; ++i) if (s[i] == ',') break;
	cout.write(s, i) << " : "; __p(t); cout << " | "; __f(s + i + 1, f...);
}
#define trace(...) { cout<<"LINE: "<<__LINE__<<" || "; __f(#__VA_ARGS__,__VA_ARGS__); cout<<"\n\n"; }
#define autra(...) { cout<<"LINE: "<<__LINE__<<" || "; __t(#__VA_ARGS__,__VA_ARGS__); cout<<"\n\n"; }
#else
#define trace(...) {}
#define autra(...) {}
#endif

typedef long long int ll;
typedef pair<ll, ll> pll;

const ll mod = 1000000007;  //998244353;
const ll inf = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-9;
const double PI = acos(-1);

ll i, j, k;
void solve(void);
inline bool equal(double a, double b) { return fabs(a - b) < eps; }
// inline ll gcd(ll a, ll b) { a=abs(a); b=abs(b); while(a>0 && b>0) (a>b?a%=b:b%=a); return (a==0?b:a); }
// inline ll power(ll x, ll n, ll m = LLONG_MAX)
//        {  ll res=1; x = (x%m + m)%m;
//             while(n) { if(n&1) res=(res*x)%m;  x=(x*x)%m;  n >>= 1; }  return res;
//        }

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0);
	cout << fixed << setprecision(10);
	int t = 1;
	// cin>>t;
	while (t--)  solve();
	return 0;
}

//***************** Code Starts Here *******************//

void solve()
{
	int n; cin >> n;
	int p[n + 1] = {0};

	if (n == 1)
	{
		cout << "1\n";
		return;
	}

	if (n == 2 || n == 3)
	{
		cout << "-1\n";
		return;
	}

	rep(i, 1, n) p[i] = i;
	rep(i, 1, n / 2 - 1) p[i] = i + 1;
	p[n / 2] = 1;

	rep(i, 1, n / 2) p[n + 1 - i] = n + 1 - p[i];
	rep(i, 1, n) cout << p[i] << " "; cout << endl;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e5 + 10;
int a[N];
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n;
	cin >> n;
	if (n %4 == 2 || n %4 == 3)
	{
		cout << -1 << endl;
		return 0;
	}
	for(int i = 2; i <= n; i+=2)
	{
		if (a[i]) continue;
		int o = 4;
		int cur = i;
		a[cur] = n-i+2;
		while (o--)
		{
			a[a[cur]] = n - cur + 1;
			cur = a[cur];
		}
	}
	if (n & 1) a[n / 2 + 1] = n / 2 + 1;
	for (int i = 1; i <= n; i++) cout << a[i] << ' ';
	return 0;
}


#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(...) ;
#else
#define debug(...) cerr << __LINE__ << " : " << #__VA_ARGS__ << " = " << _tostr(__VA_ARGS__) << endl;

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}

void _tostr_rec(ostringstream &oss) {
  oss << "\b\b \b";
}

template<typename Head, typename... Tail>
void _tostr_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << head << ", ";
  _tostr_rec(oss, forward<Tail>(tail)...);
}

template<typename... T>
string _tostr(T &&... args) {
  ostringstream oss;
  int size = sizeof...(args);
  if (size > 1) oss << "{";
  _tostr_rec(oss, forward<T>(args)...);
  if (size > 1) oss << "}";
  return oss.str();
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

int main() {
  int N;

  cin >> N;

  if (N / 2 * 2 % 4 != 0) {
    puts("-1");
    return 0;
  }

  int ans[SIZE];

  if (N % 2 == 1) ans[N / 2] = N / 2;

  for (int i = 0; i < N / 2; i += 2) {
    int a = i, b = i + 1, c = N - i - 1, d = N - i - 2;

    ans[a] = b;
    ans[b] = c;
    ans[c] = d;
    ans[d] = a;
  }

  for (int i = 0; i < N; i++) {
    printf("%d%c", ans[i] + 1, " \n"[N - 1 == i]);
  }

  return 0;
}


//In the name of ALLAH
#include <bits/stdc++.h>
#define pb push_back
#define X first
#define Y second
const bool DEBUG = false;
#define cerr if(DEBUG)cerr
using namespace std;

typedef long double ld;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;

const long long maxn = 2e5 + 5;
const long long INF = 1e18 + 1;
const long long M = 1e9 + 7;
const int lg = 21;

int n, p[maxn], l, r;

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n;
	if(n == 1)
		return cout << 1 << endl, 0;
	if(n % 2 == 1){
		p[n >> 1] = n / 2 + 1;
		if((n - 1) % 4 != 0)
			return cout << -1 << endl, 0;
	}
	if(n % 2 == 0 and n % 4 != 0)
		return cout << -1 << endl, 0;
	l = 0, r = n - 1;
	for(int i = 1; i <= n / 2; i += 2){
		p[l] = i + 1;
		p[l + 1] = n - i + 1;
		p[r] = n - i;
		p[r - 1] = i;
		r -= 2, l -= 2;
	}
	for(int i = 0; i < n; i++)
		cout << p[i] << " ";
	return 0;
}


//In the name of ALLAH
#include <bits/stdc++.h>
#define pb push_back
#define X first
#define Y second
const bool DEBUG = false;
#define cerr if(DEBUG)cerr
using namespace std;

typedef long double ld;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;

const long long maxn = 2e5 + 5;
const long long INF = 1e18 + 1;
const long long M = 1e9 + 7;
const int lg = 21;

int n, p[maxn], l, r;

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n;
	if(n == 1)
		return cout << 1 << endl, 0;
	if(n % 2 == 1){
		p[n >> 1] = n / 2 + 1;
		if((n - 1) % 4 != 0)
			return cout << -1 << endl, 0;
	}
	if(n % 2 == 0 and n % 4 != 0)
		return cout << -1 << endl, 0;
	l = 0, r = n - 1;
	for(int i = 1; i <= n / 2; i += 2){
		p[l] = i + 1;
		p[l + 1] = n - i + 1;
		p[r] = n - i;
		p[r - 1] = i;
		r -= 2, l += 2;
	}
	for(int i = 0; i < n; i++)
		cout << p[i] << " ";
	return 0;
}


#include<bits/stdc++.h>
#pragma GCC optimize ("-ffloat-store")
#define ll long long
#define For(i,a,b) for(ll i=a;i<=b;i++)
#define maxn 200002
#define pb push_back
#define X first
#define Y second
#define mod 1000000007
#define base 17
#define vc 1e9
using namespace std;
int n;
int f[maxn];
main(){
	ios_base::sync_with_stdio(0);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n;
	if(n%4!=0&&n%4!=1){
		cout << -1;
	}	else if(n%4==0){
		for(int i=1;i<n/2;i+=2){
			int num11 = i;
			int num12 = n+1-num11;
			int num21 = i+1;
			int num22 = n+1-num21;
			f[num11] = num21;
			f[num21] = num12;
			f[num12] = num22;
			f[num22] = num11;
		}
		For(i,1,n){
			cout << f[i] << " ";
		}
	} else{
		f[n/2+1] = n/2+1;
		for(int i=1;i<n/2;i+=2){
			int num11 = i;
			int num12 = n+1-num11;
			int num21 = i+1;
			int num22 = n+1-num21;
			f[num11] = num21;
			f[num21] = num12;
			f[num12] = num22;
			f[num22] = num11;
		}
		For(i,1,n){
			cout << f[i] << " ";
		}
	}
}


#include<bits/stdc++.h>

using namespace std;

#define pb push_back
#define mp make_pair
#define lli long long int
#define F first
#define S second
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define MAX1 998244353
#define MAX2 1000000007
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    std::cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');std::cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#define input(data,n,command) for(lli i=0;i<n;i++){lli tmp;cin>>tmp;data.pb(tmp);command}
#define sort(a) sort(a.begin(),a.end());
#define display(a) for(lli i = 0 ;i<a.size();i++){cout<<a[i]<<" ";} cout<<endl;
#define rep(i,n,p) for(lli i = 0;i<n;i= i +p)
#define endl "\n"

//Written By GHATAK...
/*--------------------------------------------------------------------*/
//vector<pair<lli,lli>>adj[300010];
lli n;
lli val[100010] = {0};

lli solve()
{
    //start from here
    cin>>n;
    rep(i,n+1,1)
    {
        val[i] = 0;
    }
    if((n%4 == 2)||(n%4 == 3))
    {
        cout<<"-1\n";
        return 0;
    }
    if(n == 1)
    {
        cout<<"1";
        return 0;
    }
    val[1] = 2;
    val[2] = n;
    val[n] = n-1;
    val[n-1] = 1;
    lli start = 3;
    lli end = n-2;
    while(start < end)
    {
        val[start] = val[start-2]  + 2;
        start++;
        val[start] = val[start-2] - 2;
        start++;
        val[end] = val[end+2]  - 2;
        end--;
        val[end] = val[end+2] + 2;
        end--;
    }
    if(start == end)
    {
        val[start] = start;
    }
    for(lli i = 1;i<=n;i++)
    {
        cout<<val[i]<<" ";
    }
    return 0;
}

int main()
{
    ios
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    lli T=1;
    //cin>>T;
    while(T--)
    {
        solve();
    }
    return 0;
}
/*-----------------------------------------------------------------------*/
/*
--->  reverse(vec.begin(),vec().end());
*/


#include<bits/stdc++.h>
#define ll             long long
#define pb             push_back
#define mp             make_pair
#define pii            pair<int,int>
#define pll            pair<long,long>
#define vi             vector<int>
//vector< vector<int> > Matrix(N, vector<int>(M, -1)); N*M
#define all(a)         (a).begin(),(a).end()
#define F              first
#define S              second
#define sz(x)          (int)x.size()
#define hell           1000000007
#define endl           '\n'
#define loop(i,a,b)	   for(long long i=a;i<b;i++)
#define dec(i,a,b)     for(long long i=a;i>=b;i--)
#define PI 			   3.141592653589793l
#define vl             vector<long>
#define inf            10000000000
#define tr(c,i)        for(typeof((c).begin() i = (c).begin(); i != (c).end(); i++)
#define present(c,x)   ((c).find(x) != (c).end())
#define cpresent(c,x)  (find(all(c),x) != (c).end())
#define fill(a,b)     memset(a,b,sizeof(a))
using namespace std;
long long min(long long a,long long b){
	if(a<b)
	 return a;
	 else
	 return b;
}
long long lcm(long long a, long long b)
{
    long long temp = __gcd(a, b);

    return temp ? (a / temp * b) : 0;
}
/*long long bin(int n, int k)
{
    long long res = 1;

    // Since C(n, k) = C(n, n-k)
    if ( k > n - k )
        k = n - k;

    // Calculate value of [n * (n-1) *---* (n-k+1)] / [k * (k-1) *----* 1]
    for (int i = 0; i < k; ++i)
    {
        res *= (n - i);
        res /= (i + 1);
    }
    return res;
}
typedef unsigned long long uint64;

uint64 PowMod(uint64 x, uint64 e, uint64 mod)
{
  uint64 res;

  if (e == 0)
  {
    res = 1;
  }
  else if (e == 1)
  {
    res = x;
  }
  else
  {
    res = PowMod(x, e / 2, mod);
    res = res * res % mod;
    if (e % 2)
      res = res * x % mod;
  }

  return res;
}*/
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("C-small-1-attempt0 (1).txt","r",stdin);
    //freopen("cheating.txt","w",stdout);
    int n;cin>>n;
    if(n%4==2 || n%4==3){
      cout<<"-1\n";
      return 0;
    }
    int k=n/4;
    std::vector<int> ans(n+1);
    loop(i,0,k){
      ans[2*i+1]=2*i+2;
      ans[2*i+2]=n-(2*i+1)+1;
      ans[n-(2*i+1)+1]=n-(2*i+2)+1;
      ans[n-(2*i+2)+1]=n-(n-(2*i+1)+1)+1;
    }
    if(n%4==1){
      ans[(n+1)/2]=(n+1)/2;
    }
    loop(i,1,n+1){
      cout<<ans[i]<<" ";
    }
    cout<<endl;
    return 0;
}


#include <bits/stdc++.h>

#pragma GCC optimize("O3")
using namespace std;
#define ll long long
#define ull unsigned long long
#define rep(i,n,N) for(int i=n;i<=N;++i)
#define rap(i,n,N) for(int i=n;i>=N;--i)
#define mp make_pair
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define fi first
#define se second
#define ff fi.fi
#define fs fi.se
#define sf se.fi
#define ss se.se
#define lc (id<<1)
#define rc ((id<<1)|1)
#define db(x) cerr << ">>>>>> " << #x << " -> " << x << endl
#define nani(x) cerr <<  "Line " << __LINE__ << ": " << #x << " is " << x << endl
#define all(x) x.begin(),x.end()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define plll pair<ll,pll>
#define pllll pair<pll,pll>
#define piii pair<int,pii>
#define piiii pair<pii,pii>
#define psi pair<string,int>
#define endl '\n'
const int MAX = 1e5+5;
const ll MAX2 = 11;
const ll MOD = 998244353;
const ll MOD2 = 1000005329;
const ll INF = 2e18;
const int dr[]={1,0,-1,0,1,1,-1,-1,0};
const int dc[]={0,1,0,-1,1,-1,1,-1,0};
const double pi = acos(-1);
const double EPS = 1e-9;
const int block = 2000;

int n,x[MAX],nw;

int main(){
//	cout<<fixed<<setprecision(10);
//    freopen("input.txt", "r", stdin);
//	freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n;
    if(n%4>1)return cout<<"-1\n",0;
    if(n&1)x[n/2+1] = n/2+1;
    rep(i,1,n/4){
    	x[i*2-1] = i*2, nw = i*2-1;
    	rep(k,1,3)x[x[nw]] = n-nw+1, nw = x[nw];
	}
    rep(i,1,n)cout<<x[i]<<' ';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define fi first
#define se second
#define MOD(n,k) ( ( ((n) % (k)) + (k) ) % (k))
#define forn(i,n) for (int i = 0; i < n; i++)
#define ALL(v) v.begin(), v.end()
#define find(v,x) (lower_bound(ALL(v), x) - v.begin())

typedef long long ll;
typedef long double ld;
typedef pair<ll, int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<ii> vii;

int n, a[100005];

int main () {
	ios_base::sync_with_stdio(0); cin.tie(0);

	cin >> n;

	if (n % 4 >= 2) {
		cout << -1 << endl;
		return 0;
	}

	for (int i = 0, j = 2; j <= n / 2; i+=2, j += 2)
		a[i] = j;
	for (int i = 1, j = n; j > n / 2; i+=2, j -= 2)
		a[i] = j;
	for (int i = n-1, j = n-1; j > n / 2; i-=2, j -= 2)
		a[i] = j;
	for (int i = n-2, j = 1; j < n / 2; i-=2, j += 2)
		a[i] = j;

	if (n & 1) a[n/2]=n/2+1;
	for (int i = 0; i < n; i++) cout << a[i] << " ";
	cout << endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int > pii;
typedef pair<int,pii > piii;
typedef vector<int>     VI;

#define sc1(x) scanf("%d",&x);
#define sc2(x,y) scanf("%d%d",&x,&y);
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z);
/*
#define sc1(x) scanf("%lld",&x);
#define sc2(x,y) scanf("%lld%lld",&x,&y);
#define sc3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z);
*/
#define pb push_back
#define mp make_pair
#define ini(x,val) memset(x,val,sizeof(x));
#define fs first
#define sc second
#define MOD 1000000007
#define inf 999999999
#define linf 99999999999999999ll	//long long inf
#define PI 3.1415926535897932384626
const double eps=0.000000000000001 ;

#define tr(container, it)  for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define PrintCont(cont) {cout<<("\n----------------\n");\
for(typeof(cont.begin()) it = cont.begin();it!=cont.end();++it) cout<<*it<<" ";cout<<("\n----------------\n");}
#define all(v) v.begin(),v.end()
string convertstring(ll n) { stringstream ss; ss << n ; return ss.str(); }

#define debug(x) cerr<<#x<<" :: "<<x<<"\n";
#define debug2(x,y) cerr<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\n";
#define debug3(x,y,z) cerr<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<"\n";
#define debug4(x,y,z,a) cerr<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<"\t"<<#a<<" :: "<<a<<"\n";
#define debugarr(a,st,en) {cerr<<"\n"<<#a<<" :: ";for(int i=st;i<=en;++i)cerr<<a[i]<<" ";cerr<<"\n";}

#define LIM 100005

int a[LIM];
int main()
{
	int n,i;
	sc1(n);
	if((n%4)>=2)
	{
		printf("-1\n");return 0;
	}
	if(n%4) a[(n+1)/2] = (n+1)/2;
	for(i=1;i<=n;++i)
	{
		if(a[i]==0)
		{
			int x = i+1;
			a[i] = x;
			a[n-x+1] = i;
			a[n-i+1] = n-x+1;
			a[x] = n-i+1;
		}
	}
	for(i=1;i<=n;++i)
		printf("%d ",a[i]);
	return 0;
}


#include<bits/stdc++.h>
#include<ext/numeric>

using namespace std;
using namespace __gnu_cxx;

#define CLR(a,v) sizeof(a,v,sizeof(a))

const int MAX = 1e5 + 5;

bool can[MAX];
int n, out[MAX];

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	can[0] = can[1] = 1;
	for (int i = 4; i < MAX; ++i)
		can[i] = can[i - 4];
	CLR(out, -1);
	cin >> n;
	if (!can[n])
		return puts("-1");
	int numFilled = 0;
	set<int> freeIndices, freeNumbers;
	for (int i = 1; i <= n; ++i)
		freeIndices.insert(i), freeNumbers.insert(i);
	while (numFilled < n) {
		if (numFilled + 1 == n) {
			++numFilled;
			out[*(freeIndices.begin())] = *(freeNumbers.begin());
		} else {
			numFilled += 4;
			int x = *(freeIndices.begin());
			int y;
			for (auto z : freeNumbers)
				if (z != x && z != n - x + 1) {
					y = z;
					break;
				}
			out[x] = y;
			out[y] = n - x + 1;
			out[n - x + 1] = n - y + 1;
			out[n - y + 1] = x;
			freeIndices.erase(x);
			freeIndices.erase(y);
			freeIndices.erase(n - x + 1);
			freeIndices.erase(n - y + 1);
			freeNumbers.erase(y);
			freeNumbers.erase(n - x + 1);
			freeNumbers.erase(n - y + 1);
			freeNumbers.erase(x);
		}
	}
	for (int i = 1; i <= n; ++i)
		printf("%d ", out[i]);
}


// You can win if you want
#include <bits/stdc++.h>
using namespace std;
# define ll long long
# define endl "\n"
# define pi 3.14159265359
# define str string
# define vll vector<ll>
# define pb push_back
# define mll map<ll,ll>
# define vp vector< pair<ll,ll> >
# define mp make_pair
# define ff first
# define ss second
# define pll pair<ll,ll>
# define f(x,y) for(int x=0;x<y;x++)
int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    ll x;
    cin>>x;
    if(x==2){
        cout<<-1;
    }
    else{
        vll v;
        v.resize(x,0);
        ll k=1;
        for(ll i=0;i<v.size();i++){
            v[i]=k;
            k++;
        }
        f(i,v.size()){
            cout<<v[i]<<" ";
        }
    }
    return 0;
}


// You can win if you want
#include <bits/stdc++.h>
using namespace std;
# define ll long long
# define endl "\n"
# define pi 3.14159265359
# define str string
# define vll vector<ll>
# define pb push_back
# define mll map<ll,ll>
# define vp vector< pair<ll,ll> >
# define mp make_pair
# define ff first
# define ss second
# define pll pair<ll,ll>
# define f(x,y) for(int x=0;x<y;x++)
int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    ll x;
    cin>>x;
    if(x%4==2 || x%4==3){
        cout<<-1;
    }
    else{
        vll v;
        v.resize(x,0);
        ll k=2;
        ll m=2+x;
        for(ll i=0;i<v.size()/2;i++){
            v[i]=k;
            v[i+1]=m-k;
            k+=2;
            i++;
        }
        m=x-1;
         k=1;
        for(ll i=v.size()-1;i>v.size()/2;i--){
            v[i]=m;
            v[i-1]=k;
            m-=2;
            k+=2;
            i--;
        }
        if(x%4==1){
            v[v.size()/2]=x/2 +1;
        }
        for(ll i=0;i<v.size();i++){
            cout<<v[i]<<" ";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int               long long
#define pb                push_back
#define ppb               pop_back
#define pf                push_front
#define ppf               pop_front
#define all(x)            (x).begin(),(x).end()
#define uniq(v)           (v).erase(unique(all(v)),(v).end())
#define sz(x)             (int)((x).size())
#define fr                first
#define sc                second
#define pii               pair<int,int>
#define loop(i,a,b)        for(int i=a;i<b;i++)
#define mem1(a)           memset(a,-1,sizeof(a))
#define mem0(a)           memset(a,0,sizeof(a))
#define ppc               __builtin_popcount
#define ppcll             __builtin_popcountll
#define br                break
#define con               continue

template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.fr>>a.sc;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.fr<<" "<<a.sc;return out;}
template<typename T,typename T1>T amax(T &a,T1 b){if(b>a)a=b;return a;}
template<typename T,typename T1>T amin(T &a,T1 b){if(b<a)a=b;return a;}

const long long INF=1e18;
const int32_t M=1e9+7;
const int32_t MM=998244353;

priority_queue<pii, vector<pii>, greater<pii> >q;

#include<bits/stdc++.h>
using namespace std;
signed main(){
	#ifndef ONLINE_JUDGE
	freopen("input.txt","r",stdin);
	freopen("output1.txt","w",stdout);
	#endif
    ios_base::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);

	int n;
	cin>>n;
	int a[n+1];
	if(n%4>=2){
		cout<<-1<<endl;
		return 0;
	}
	for(int i=1;i<=n/2;i+=2){
		a[i]= i+1;
		a[i+1]= n-i+1;
		a[n-i+1]= n-i;
		a[n-i]= i;
	}
    if(n%2)a[n/2 +1]= n/2+1;

    loop(i,1,n+1)
    cout<<a[i]<<" ";

}


#include <iostream>
using namespace std;
const int N = 1e5+5;
int v[N];
int main()
{
    int n;
    cin >> n;
    if (n == 1)
        cout << 1;
    else if (n<=3)
        cout << -1;
    else
    {
        v[1] = 2;
        int st = 2, dr = n, k = n;
        while (k)
        {
            if (k == 2)
                k--;
            v[st++] = k--;
            if (!k)
                break;
            if (k == 2)
                k--;
            v[dr--] = k--;
        }
        for (int i = 1; i<=n; i++)
            cout << v[i] << " ";
    }
}


#include <cstdio>
using namespace std;

const int N = 100500;
int A[N];

int main()
{
    int n;
    scanf("%d", &n);
    if (n % 4 == 2 || n % 4 == 3)
    {
        printf("-1\n");
        return 0;
    }
    for (int i = 0; i < n; i++)
        A[i] = i;
    for (int i = 0; i < n / 2; i += 2)
    {
        A[i] = i + 1;
        A[i + 1] = n - i - 1;
        A[n - i - 1] = n - i - 2;
        A[n - i - 2] = i;
    }
    for (int i = 0; i < n; i++)
        printf("%d%c", A[i] + 1, " \n"[i == n - 1]);
    return 0;
}


#include<bits/stdc++.h>
#define FIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define sort(a) sort(a.begin(),a.end());
#define sc(a) cin>>a;

using namespace std;
map<long long int,long long int  >ma,mb;

deque<long long int >de;
long long int a[200005],a1[200005];
bool p[1000006];

/*void seive()
{ memset(p,true,sizeof(p));
    long long int i,j;
    for(i=2; i*i<=1000000; i++)
    {
        if(p[i]==true )
        {
            for(j=i*i; j<=1000000; j+=i)
            {
                p[j]=false;
            }
        }
    }
    v.push_back(2);
    for(i=3; i<=1000000; i+=2)
    {
        if(p[i]==true)
        {
            v.push_back(i);
        }
    }
}*/
//long long int big_mod(long long int b,long long int p,long long int m ){long long int res=1;while(p!=0){if(p&1)res=(res*b)%m;b=(b*b)%m;p=p>>1;}res=(res-1+m)%m;return res;}

int main()
{
//     seive();
    FIO;
    long long int n,d=0,k=0,l=0,mid,x=0,i=0,m,f=0,j=0,c=0,j1=0,sum=0,s=0,mx1=-2000000000,mxa=-2000000000,d1,mx=2000000000,mx11=2000000000;

//" "n
//cin>>
//(v.begin(),v.end());
//cout<<endl;
//break

    vector <long long int>v,v1,v2,v4;

    cin>>m;

//" ";
    if(m%4!=0 && m%4!=1)
    {
        cout<<"-1";
        return 0;
    }

    for(i=1,k=2; i<=m/2; i+=2,k+=2)
    {
        l=k;
        a[i]=l;
        d=i;
        //cout<<d<<k;
        while(a[l]==0)
        {
            a[l]=m-d+1;
            d=l;
            l=a[l];
        }
    }
    if(m%4==1)
    {
        a[(m+1)/2]=(m+1)/2;
    }
    for(i=1; i<=m; i++)
    {
        cout<<a[i] <<" ";
    }

    cout<<endl;
//cout<<endl;

    return 0;
}


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

#define ll long long int

int main() {

	int n;	cin >> n;
	if (n % 4 == 2 || n % 4 == 3) {
		cout << "-1\n";
		return 0;
	}

	vector<int> v(n+1, 0);
	int skip = n + 3;
	if (n % 4 == 1)
		skip = n/2 + 1;

	for (int i = 1; i <= n; i += 2) {
		if (i >= skip)
			break;
		else if (v[i] > 0)
			break;
		v[i+1] = i;
		v[i] = n - i;
		v[n-i] = n - i + 1;
		v[n-i+1] = i + 1;
	}

	if (skip <= n)
		v[skip] = skip;

	for (int i = 1; i <= n; i += 1)
		cout << v[i] << ' ';
	cout << '\n';

	return 0;
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Codeforces335_D
{
	class ContestIO : StreamWriter
	{
		public ContestIO() : base(Console.OpenStandardOutput(8192), Encoding.ASCII, 8192) { }
		//d.ToString("N12", CultureInfo.InvariantCulture).Replace(",", "")
		public StreamReader Reader = new StreamReader(Console.OpenStandardInput(8192), Encoding.ASCII, false, 8192);
		bool IsDigit(int c) { return c >= '0' && c <= '9'; }

		public int Read()
		{
			int c1 = 0, c;
			while (!IsDigit(c = Reader.Read())) { c1 = c; }
			int r = c - '0';
			while (IsDigit(c = Reader.Read()))
				r = r * 10 + c - '0';
			return c1 == '-' ? -r : r;
		}
		public int[] ReadArray(int size) { return Enumerable.Range(0, size).Select(v => Read()).ToArray(); }
	}

	class Edge
	{
		public int Weight;
		public bool IsOstov;
		public int Pos;
		public int V1;
		public int V2;
	}

	class Program
	{
		static void Main(string[] args)
		{
			using (var io = new ContestIO())
			{
				var n = io.Read();
				var m = io.Read();

				List<Edge> edges = new List<Edge>();
				for (var i = 0; i < m; i++)
				{
					var w = io.Read();
					var o = io.Read();
					edges.Add(new Edge()
					{
						Weight = w,
						IsOstov = o == 1,
						Pos = i
					});
				}

				edges.Sort((e1, e2) => {
					var c1 = e1.Weight.CompareTo(e2.Weight);
					if (c1 != 0)
						return c1;
					c1 = e2.IsOstov.CompareTo(e1.IsOstov);
					if (c1 != 0)
						return c1;
					c1 = e1.Pos.CompareTo(e2.Pos);
					return c1;
				});

				if (n == 2)
				{
					if (edges[0].IsOstov)
						io.WriteLine("1 2");
					else
						io.WriteLine("-1");
				}
				else
				{
					if (!edges[0].IsOstov || !edges[1].IsOstov)
					{
						io.WriteLine("-1");
					}
					else
					{
						edges[0].V1 = 0;
						edges[0].V2 = 1;
						edges[1].V1 = 1;
						edges[1].V2 = 2;

						var nextV1 = 2;
						var nextV2 = 0;
						var lastO = 2;
						bool nope = false;

						for (var i = 2; i < edges.Count; i++)
						{
							if (edges[i].IsOstov)
							{
								edges[i].V1 = lastO;
								edges[i].V2 = ++lastO;
							}
							else
							{
								if (nextV1 > lastO)
								{
									nope = true;
									break;
								}

								edges[i].V1 = nextV1;
								edges[i].V2 = nextV2;
								nextV2++;
								if (nextV2 == (nextV1 - 1))
								{
									nextV1++;
									nextV2 = 0;
								}
							}
						}

						if (nope)
						{
							io.WriteLine("-1");
						}
						else
						{
							edges.Sort((e1, e2) => e1.Pos.CompareTo(e2.Pos));
							foreach (var e in edges)
							{
								io.WriteLine((e.V1 + 1).ToString() + " " + (e.V2 + 1).ToString());
							}
						}
					}
				}
			}

			Console.ReadLine();
		}
	}
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Lazy_Student
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            int n = Next();
            int m = Next();

            var nn = new Edge[m];
            for (int i = 0; i < m; i++)
            {
                nn[i] = new Edge(Next(), Next(), i);
            }
            Array.Sort(nn);

            int index = 2;
            var q = new Queue<Tuple<int, int>>();
            foreach (Edge edge in nn)
            {
                if (edge.b == 1)
                {
                    edge.u = 1;
                    edge.v = index;

                    if (q.Count < m)
                    {
                        for (int i = 2; i < index; i++)
                        {
                            q.Enqueue(new Tuple<int, int>(i, index));
                        }
                    }

                    index++;
                }
                else
                {
                    if (q.Count > 0)
                    {
                        Tuple<int, int> t = q.Dequeue();
                        edge.u = t.Item1;
                        edge.v = t.Item2;
                    }
                    else
                    {
                        writer.WriteLine("-1");
                        writer.Flush();
                        return;
                    }
                }
            }

            Array.Sort(nn, nn[0]);

            foreach (Edge edge in nn)
            {
                writer.Write(edge.u);
                writer.Write(' ');
                writer.WriteLine(edge.v);
            }

            writer.Flush();
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }

        #region Nested type: Edge

        private class Edge : IComparable<Edge>, IComparer<Edge>
        {
            public readonly int a;
            public readonly int b;
            public readonly int index;
            public int u, v;

            public Edge(int a, int b, int index)
            {
                this.a = a;
                this.b = b;
                this.index = index;
            }

            #region IComparable<Edge> Members

            public int CompareTo(Edge other)
            {
                int c = a.CompareTo(other.a);
                if (c == 0)
                    c = other.b.CompareTo(b);

                return c;
            }

            #endregion

            #region IComparer<Edge> Members

            public int Compare(Edge x, Edge y)
            {
                return x.index.CompareTo(y.index);
            }

            #endregion
        }

        #endregion
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){

		Array.Sort(P,(x,y)=>x.W>y.W?1:x.W<y.W?-1:x.Used>y.Used?-1:x.Used<y.Used?1:0);
		int cnt=0;
		for(int i=0;i<M;i++){
			if(P[i].Used==1)cnt++;
		}
		if(cnt!=N-1){
			Console.WriteLine(-1);
			return;
		}

		int now=0;
		int added=0;
		int[] from=new int[M];
		int[] to=new int[M];
		int[] thresh=new int[N];
		int tail=0;
		for(int i=0;i<N;i++)thresh[i]=i+1;
		for(int i=0;i<M;i++){
			if(P[i].Used==1){
				now++;
				from[P[i].Idx]=now-1;
				to[P[i].Idx]=now;
				tail=0;
			}else{
				long mar=(long)now*(long)(now-1)/2;
				if(added+1>mar){
					Console.WriteLine(-1);
					return;
				}
				for(int j=tail;j<N;j++){
					if(thresh[j]+1>now)continue;
					from[P[i].Idx]=j;
					to[P[i].Idx]=thresh[j]+1;
					thresh[j]++;
					if(thresh[j]==now)tail++;
					break;
				}
				added++;
			}
		}

		for(int i=0;i<M;i++){
			Console.WriteLine("{0} {1}",from[i]+1,to[i]+1);
		}

	}
	int N,M;
	Pair[] P;
	public Sol(){
		var d=ria();
		N=d[0];M=d[1];
		P=new Pair[M];
		for(int i=0;i<M;i++){
			P[i]=new Pair(ria(),i);
		}
	}
	class Pair{
		public int W,Used,Idx;
		public Pair(int[] d,int idx){
			W=d[0];Used=d[1];Idx=idx;
		}
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(){return Console.ReadLine().Split(' ');}
	static int[] ria(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>int.Parse(e));}
	static long[] rla(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>long.Parse(e));}
	static double[] rda(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>double.Parse(e));}
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoTraining.Codeforces.D_s
{

    public class FastScanner : StreamReader
    {
        private string[] _line;
        private int _iterator;

        public FastScanner(Stream stream) : base(stream)
        {
            _line = null;
            _iterator = 0;
        }
        public int NextInt()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt32(_line[_iterator++]);
        }
        public long NextLong()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt64(_line[_iterator++]);
        }
    }
    class LazyStudent335
    {
        public static void Main(string[] args)
        {
            using (FastScanner fs = new FastScanner(new BufferedStream(Console.OpenStandardInput())))
            using (StreamWriter writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput())))
            {
                int n = fs.NextInt();
                int m = fs.NextInt();
                Edge[] edges = new Edge[m];
                string[] ans = new string[m];
                for (int i = 0; i < m; i++)
                {
                    edges[i] = new Edge { Id = i, Weight = fs.NextInt(), IsInMST = fs.NextInt() == 1 };
                }
                edges = edges.OrderBy(e => e.Weight).ToArray();

                long inMst = 0;
                long notInMst = 0;
                foreach (Edge e in edges)
                {
                    if (e.IsInMST)
                    {
                        ans[e.Id] = (inMst + 1) + " " + (inMst + 2);
                        inMst++;
                    }
                    else
                    {
                        notInMst++;
                        if (notInMst > (inMst * (inMst - 1)) / 2)
                        {
                            writer.WriteLine(-1);
                            return;
                        }
                    }
                }
                int k = 0;
                for (int i = 1; i <= n && notInMst > 0; i++)
                {
                    for (int j = i + 2; j <= n && notInMst > 0; j++)
                    {
                        while (ans[k] != null && k < m) k++;
                        ans[k] = i + " " + j;
                        notInMst--;
                    }
                }
                for (int i = 0; i < m; i++)
                {
                    writer.WriteLine(ans[i]);
                }
            }
        }
    }
    class Edge
    {
        public int Id;
        public int Weight;
        public bool IsInMST;
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoTraining.Codeforces.D_s
{

    public class FastScanner : StreamReader
    {
        private string[] _line;
        private int _iterator;

        public FastScanner(Stream stream) : base(stream)
        {
            _line = null;
            _iterator = 0;
        }
        public int NextInt()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt32(_line[_iterator++]);
        }
        public long NextLong()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt64(_line[_iterator++]);
        }
    }
    class LazyStudent335
    {
        public static void Main(string[] args)
        {
            using (FastScanner fs = new FastScanner(new BufferedStream(Console.OpenStandardInput())))
            using (StreamWriter writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput())))
            {
                int n = fs.NextInt();
                int m = fs.NextInt();
                Edge[] edges = new Edge[m];
                string[] ans = new string[m];
                for (int i = 0; i < m; i++)
                {
                    edges[i] = new Edge { Id = i, Weight = fs.NextInt(), IsInMST = fs.NextInt() == 1 };
                }
                edges = edges.OrderBy(e => e.Weight).ThenByDescending(e => e.IsInMST).ToArray();

                long inMst = 0;
                long notInMst = 0;
                List<EdgeOcc> edgeOccs = new List<EdgeOcc>();
                foreach (Edge e in edges)
                {
                    if (e.IsInMST)
                    {
                        ans[e.Id] = (inMst + 1) + " " + (inMst + 2);
                        inMst++;
                    }
                    else
                    {
                        notInMst++;
                        if (notInMst > (inMst * (inMst - 1)) / 2)
                        {
                            writer.WriteLine(-1);
                            return;
                        }
                        else
                        {
                            edgeOccs.Add(new EdgeOcc { VertexCount = inMst + 1, Edge = e });
                        }
                    }
                }
                long p = inMst + 1;
                long q = p - 2;
                for (int i = edgeOccs.Count - 1; i >= 0; i--)
                {
                    while (edgeOccs[i].VertexCount < p)
                    {
                        p--;
                        q = p - 2;
                    }
                    ans[edgeOccs[i].Edge.Id] = q + " " + p;
                    q--;
                    if (q <= 0)
                    {
                        p--;
                        q = p - 2;
                    }
                }
                for (int i = 0; i < m; i++)
                {
                    writer.WriteLine(ans[i]);
                }
            }
        }
    }
    class EdgeOcc
    {
        public long VertexCount;
        public Edge Edge;
    }
    class Edge
    {
        public int Id;
        public int Weight;
        public bool IsInMST;
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoTraining.Codeforces.D_s
{

    public class FastScanner : StreamReader
    {
        private string[] _line;
        private int _iterator;

        public FastScanner(Stream stream) : base(stream)
        {
            _line = null;
            _iterator = 0;
        }
        public int NextInt()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt32(_line[_iterator++]);
        }
        public long NextLong()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt64(_line[_iterator++]);
        }
    }
    class LazyStudent335
    {
        public static void Main(string[] args)
        {
            using (FastScanner fs = new FastScanner(new BufferedStream(Console.OpenStandardInput())))
            using (StreamWriter writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput())))
            {
                int n = fs.NextInt();
                int m = fs.NextInt();
                Edge[] edges = new Edge[m];
                for (int i = 0; i < m; i++)
                {
                    edges[i] = new Edge { Weight = fs.NextInt(), IsInMST = fs.NextInt() == 1 };
                }
                edges = edges.OrderBy(e => e.Weight).ToArray();

                long inMst = 0, notInMst = 0, totalNotInMst = 0;
                StringBuilder sb = new StringBuilder();
                foreach (Edge e in edges)
                {
                    if (e.IsInMST)
                    {
                        if (notInMst > 0)
                        {
                            if (notInMst > (inMst * (inMst - 1)) / 2 - totalNotInMst)
                            {
                                writer.WriteLine(-1);
                                return;
                            }
                            else
                            {
                                totalNotInMst += notInMst;
                                notInMst = 0;
                            }
                        }
                        sb.Append((inMst + 1) + " " + (inMst + 2) + "\n");
                        inMst++;
                    }
                    else
                    {
                        notInMst++;
                    }
                }
                if (notInMst > 0)
                {
                    if (notInMst > (inMst * (inMst - 1)) / 2 - totalNotInMst)
                    {
                        writer.WriteLine(-1);
                        return;
                    }
                    else
                    {
                        totalNotInMst += notInMst;
                        notInMst = 0;
                    }
                }
                for (int i = 1; i <= n && totalNotInMst > 0; i++)
                {
                    for (int j = i + 2; j <= n && totalNotInMst > 0; j++)
                    {
                        sb.Append(i + " " + j + "\n");
                        totalNotInMst--;
                    }
                }
                writer.WriteLine(sb);
            }
        }
    }
    class Edge
    {
        public int Weight;
        public bool IsInMST;
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoTraining.Codeforces.D_s
{

    public class FastScanner : StreamReader
    {
        private string[] _line;
        private int _iterator;

        public FastScanner(Stream stream) : base(stream)
        {
            _line = null;
            _iterator = 0;
        }
        public int NextInt()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt32(_line[_iterator++]);
        }
        public long NextLong()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt64(_line[_iterator++]);
        }
    }
    class LazyStudent335
    {
        public static void Main(string[] args)
        {
            using (FastScanner fs = new FastScanner(new BufferedStream(Console.OpenStandardInput())))
            using (StreamWriter writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput())))
            {
                int n = fs.NextInt();
                int m = fs.NextInt();
                Edge[] edges = new Edge[m];
                for (int i = 0; i < m; i++)
                {
                    edges[i] = new Edge { Weight = fs.NextInt(), IsInMST = fs.NextInt() == 1 };
                }
                edges = edges.OrderBy(e => e.Weight).ToArray();

                long inMst = 0, notInMst = 0;
                StringBuilder sb = new StringBuilder();
                foreach (Edge e in edges)
                {
                    if (e.IsInMST)
                    {
                        sb.Append((inMst + 1) + " " + (inMst + 2) + "\n");
                        inMst++;
                    }
                    else
                    {
                        notInMst++;
                        if (notInMst > (inMst * (inMst - 1)) / 2)
                        {
                            writer.WriteLine(-1);
                            return;
                        }
                    }
                }
                for (int i = 1; i <= n && notInMst > 0; i++)
                {
                    for (int j = i + 2; j <= n && notInMst > 0; j++)
                    {
                        sb.Append(i + " " + j + "\n");
                        notInMst--;
                    }
                }
                writer.WriteLine(sb);
            }
        }
    }
    class Edge
    {
        public int Weight;
        public bool IsInMST;
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoTraining.Codeforces.D_s
{

    public class FastScanner : StreamReader
    {
        private string[] _line;
        private int _iterator;

        public FastScanner(Stream stream) : base(stream)
        {
            _line = null;
            _iterator = 0;
        }
        public int NextInt()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt32(_line[_iterator++]);
        }
        public long NextLong()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt64(_line[_iterator++]);
        }
    }
    class LazyStudent335
    {
        public static void Main(string[] args)
        {
            using (FastScanner fs = new FastScanner(new BufferedStream(Console.OpenStandardInput())))
            using (StreamWriter writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput())))
            {
                int n = fs.NextInt();
                int m = fs.NextInt();
                Edge[] edges = new Edge[m];
                string[] ans = new string[m];
                for (int i = 0; i < m; i++)
                {
                    edges[i] = new Edge { Id = i, Weight = fs.NextInt(), IsInMST = fs.NextInt() == 1 };
                }
                edges = edges.OrderBy(e => e.Weight).ThenByDescending(e => e.IsInMST).ToArray();

                long inMst = 0;
                long notInMst = 0;
                foreach (Edge e in edges)
                {
                    if (e.IsInMST)
                    {
                        ans[e.Id] = (inMst + 1) + " " + (inMst + 2);
                        inMst++;
                    }
                    else
                    {
                        notInMst++;
                        if (notInMst > (inMst * (inMst - 1)) / 2)
                        {
                            writer.WriteLine(-1);
                            return;
                        }
                    }
                }
                int k = 0;
                for (int i = 1; i <= n && notInMst > 0; i++)
                {
                    for (int j = i + 2; j <= n && notInMst > 0; j++)
                    {
                        while (ans[k] != null && k < m) k++;
                        ans[k] = i + " " + j;
                        notInMst--;
                    }
                }
                for (int i = 0; i < m; i++)
                {
                    writer.WriteLine(ans[i]);
                }
            }
        }
    }
    class Edge
    {
        public int Id;
        public int Weight;
        public bool IsInMST;
    }
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    public void Solve()
    {
        int n = ReadInt();
        int m = ReadInt();

        var a = new List<Tuple<int, int>>();
        var b = new List<Tuple<int, int>>();
        var ans = new int[m][];
        for (int i = 0; i < m; i++)
        {
            int w = ReadInt();
            if (ReadInt() == 1)
                a.Add(Tuple.Create(w, i));
            else
                b.Add(Tuple.Create(w, i));
        }

        a.Sort((a1, a2) => a1.Item1.CompareTo(a2.Item1));
        b.Sort((a1, a2) => a1.Item1.CompareTo(a2.Item1));

        for (int i = 0; i < n - 1; i++)
            ans[a[i].Item2] = new[] { 1, i + 2 };

        int l = 0, r = 1;
        foreach (var t in b)
        {
            if (a[r].Item1 > t.Item1)
            {
                Write(-1);
                return;
            }
            ans[t.Item2] = new[] { l + 2, r + 2 };
            if (--l == -1)
            {
                r++;
                l = r - 1;
            }
        }

        foreach (var aa in ans)
            WriteArray(aa);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("nand.in");
        //writer = new StreamWriter("nand.out");
#endif
        try
        {
            //var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
            //thread.Start();
            //thread.Join();
            new Solver().Solve();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
#if DEBUG
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
    #endregion
}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100005

typedef struct POINT{
    int number;
    int w;
    int f;
    int left;
    int right;
}P;

int comp1(const void *a,const void *b)
{
    int i;
    i=(*(P*)a).w-(*(P*)b).w;
    if(i==0)
        i=(*(P*)b).f-(*(P*)a).f;
    return i;
}

int comp2(const void *a,const void *b)
{
    return (*(P*)a).number-(*(P*)b).number;
}

int main()
{
    int n,m,i,j,t1,t2,temp,now;
    P* p;
    scanf("%d %d",&n,&m);
    p=(P*)malloc(sizeof(P)*m);
    for(i=0;i<m;i++)
    {
        scanf("%d %d",&t1,&t2);
        p[i].number=i;
        p[i].w=t1;
        p[i].f=t2;
    }
    qsort(p,m,sizeof(P),comp1);
    temp=0,now=0;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            now+=temp;
            temp++;
        }
        else{
            if(now==0)
                break;
            now--;
        }
    }
    if(i<m)
    {
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
        printf("-1\n");
        return 0;
    }
    t1=2;t2=2;j=1;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            p[i].left=1;
            p[i].right=++j;
        }
        else{
            if(++t2>j)
            {
                t1++;
                t2=t1+1;
            }
            p[i].left=t1;
            p[i].right=t2;
        }
    }
    qsort(p,m,sizeof(P),comp2);
    for(i=0;i<m;i++)
    {
        printf("%d %d\n",p[i].left,p[i].right);
    }
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100005

typedef struct POINT{
    int number;
    int w;
    int f;
    int left;
    int right;
}P;

int comp1(const void *a,const void *b)
{
    return (*(P*)a).w-(*(P*)b).w;
}

int comp2(const void *a,const void *b)
{
    return (*(P*)a).number-(*(P*)b).number;
}

int main()
{
    int n,m,i,j,t1,t2,temp,now;
    P* p;
    scanf("%d %d",&n,&m);
    p=(P*)malloc(sizeof(P)*m);
    for(i=0;i<m;i++)
    {
        scanf("%d %d",&t1,&t2);
        p[i].number=i;
        p[i].w=t1;
        p[i].f=t2;
    }
    qsort(p,m,sizeof(P),comp1);
    temp=0,now=0;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            now+=temp;
            temp++;
        }
        else if(now==0)
            break;
    }
    if(i<m)
    {
        printf("-1\n");
        return 0;
    }
    t1=2;t2=2;j=1;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            p[i].left=1;
            p[i].right=++j;
        }
        else{
            if(++t2>j)
            {
                t1++;
                t2=t1+1;
            }
            p[i].left=t1;
            p[i].right=t2;
        }
    }
    qsort(p,m,sizeof(P),comp2);
    for(i=0;i<m;i++)
    {
        printf("%d %d\n",p[i].left,p[i].right);
    }
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100005

typedef struct POINT{
    int number;
    int w;
    int f;
    int left;
    int right;
}P;

int comp1(const void *a,const void *b)
{
    int i;
    i=(*(P*)a).w-(*(P*)b).w;
    if(i==0)
        i=(*(P*)b).f-(*(P*)a).f;
    return i;
}

int comp2(const void *a,const void *b)
{
    return (*(P*)a).number-(*(P*)b).number;
}

int main()
{
    int n,m,i,j,t1,t2,temp,now;
    P* p;
    scanf("%d %d",&n,&m);
    p=(P*)malloc(sizeof(P)*m);
    for(i=0;i<m;i++)
    {
        scanf("%d %d",&t1,&t2);
        p[i].number=i;
        p[i].w=t1;
        p[i].f=t2;
    }
    qsort(p,m,sizeof(P),comp1);
    temp=0,now=0;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            now+=temp;
            temp++;
        }
        else{
            if(now==0)
                break;
            now--;
        }
    }
    if(i<m)
    {
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
        printf("-1\n");
        return 0;
    }
    t1=1;t2=3;j=1;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            p[i].left=1;
            p[i].right=++j;
        }
        else{
            t1++;
            if(t1>=t2)
            {
                t2++;
                t1=2;
            }
            p[i].left=t1;
            p[i].right=t2;
        }
    }
    qsort(p,m,sizeof(P),comp2);
    for(i=0;i<m;i++)
    {
        printf("%d %d\n",p[i].left,p[i].right);
    }
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100005

typedef struct POINT{
    int number;
    int w;
    int f;
    int left;
    int right;
}P;

int comp1(const void *a,const void *b)
{
    int i;
    i=(*(P*)a).w-(*(P*)b).w;
    if(i==0)
        i=(*(P*)b).f-(*(P*)a).f;
    return i;
}

int comp2(const void *a,const void *b)
{
    return (*(P*)a).number-(*(P*)b).number;
}

int main()
{
    int n,m,i,j,t1,t2,temp,now;
    P* p;
    scanf("%d %d",&n,&m);
    p=(P*)malloc(sizeof(P)*m);
    for(i=0;i<m;i++)
    {
        scanf("%d %d",&t1,&t2);
        p[i].number=i;
        p[i].w=t1;
        p[i].f=t2;
    }
    qsort(p,m,sizeof(P),comp1);
    temp=0,now=0;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            now+=temp;
            temp++;
        }
        else if(now==0)
            break;
    }
    if(i<m)
    {
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
        printf("-1\n");
        return 0;
    }
    t1=2;t2=2;j=1;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            p[i].left=1;
            p[i].right=++j;
        }
        else{
            if(++t2>j)
            {
                t1++;
                t2=t1+1;
            }
            p[i].left=t1;
            p[i].right=t2;
        }
    }
    qsort(p,m,sizeof(P),comp2);
    for(i=0;i<m;i++)
    {
        printf("%d %d\n",p[i].left,p[i].right);
    }
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100005

typedef struct POINT{
    int number;
    int w;
    int f;
    int left;
    int right;
}P;

int comp1(const void *a,const void *b)
{
    int i;
    i=(*(P*)a).w-(*(P*)b).w;
    if(i==0)
        i=(*(P*)b).f-(*(P*)a).f;
    return i;
}

int comp2(const void *a,const void *b)
{
    return (*(P*)a).number-(*(P*)b).number;
}

int main()
{
    int n,m,i,j,t1,t2,temp,now;
    P* p;
    scanf("%d %d",&n,&m);
    p=(P*)malloc(sizeof(P)*m);
    for(i=0;i<m;i++)
    {
        scanf("%d %d",&t1,&t2);
        p[i].number=i;
        p[i].w=t1;
        p[i].f=t2;
    }
    qsort(p,m,sizeof(P),comp1);
    temp=0,now=0;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            now+=temp;
            temp++;
        }
        else{
            if(now==0)
                break;
            now--;
        }
    }
    if(i<m)
    {
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
        printf("-1\n");
        return 0;
    }
    t1=1;t2=2;j=1;
    for(i=0;i<m;i++)
    {
        if(p[i].f)
        {
            p[i].left=1;
            p[i].right=++j;
        }
        else{
            if(t1>=t2)
            {
                t2++;
                t1=1;
            }
            p[i].left=t1;
            p[i].right=t2;
            t1++;
        }
    }
    qsort(p,m,sizeof(P),comp2);
    for(i=0;i<m;i++)
    {
        printf("%d %d\n",p[i].left,p[i].right);
    }
//    for(i=0;i<m;i++)
//        printf("%d: %d %d\n",p[i].number,p[i].w,p[i].f);
    return 0;
}


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

typedef struct __ITEM{
	int wt;
	int ind;
	int typ;
}ITEM;

int cmpfunc(const void *,const void *);

int main(){
	int n,m,ans[100005][2],i,j,x,y;
	ITEM ar[100005];
	scanf("%d %d",&n,&m);
	for(i=0;i<m;i++){
		scanf("%d %d",&x,&y);
		ar[i].wt=x;
		ar[i].typ=y;
		ar[i].ind=i;
	}
	qsort(ar,m,sizeof(ITEM),cmpfunc);
	x=0;y=2;
	for(i=0,j=0;i<m;i++){
		if(ar[i].typ){
			ans[ar[i].ind][0]=j;
			ans[ar[i].ind][1]=++j;
		}
		else{
			if(x==y-1||y>j){
				break;}
			ans[ar[i].ind][0]=x++;
			ans[ar[i].ind][1]=y;
			if(x==y-1)
				x=0;y++;
		}
	}
	if(i<m)printf("-1\n");
	else{
		for(i=0;i<m;i++)
			printf("%d %d\n",ans[i][0]+1,ans[i][1]+1);
	}
	return 0;
}

int cmpfunc (const void * a, const void * b)
{
	return ( ((ITEM *)a)->wt - ((ITEM *)b)->wt );
}


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

typedef struct __ITEM{
	int wt;
	int ind;
	int typ;
}ITEM;

int cmpfunc(const void *,const void *);

int main(){
	int n,m,ans[100005][2],i,j,x,y;
	ITEM ar[100005];
	scanf("%d %d",&n,&m);
	for(i=0;i<m;i++){
		scanf("%d %d",&x,&y);
		ar[i].wt=x;
		ar[i].typ=y;
		ar[i].ind=i;
	}
	qsort(ar,m,sizeof(ITEM),cmpfunc);
	x=0;y=2;
	for(i=0,j=0;i<m;i++){
		//	printf("%d %d\n",i,ar[i].ind);
		if(ar[i].typ){
			ans[ar[i].ind][0]=j;
			ans[ar[i].ind][1]=++j;
		}
		else{
			if(x==y-1||y>j){
				break;}
			ans[ar[i].ind][0]=x++;
			ans[ar[i].ind][1]=y;
			if(x==y-1)
				x=0;y++;
		}
	}
	if(i<m)printf("-1\n");
	else{
		for(i=0;i<m;i++)
			printf("%d %d\n",ans[i][0]+1,ans[i][1]+1);
	}
	return 0;
}

int cmpfunc (const void * a, const void * b)
{
	int wta,wtb;
	wta=((ITEM *)a)->wt;wtb=((ITEM *)b)->wt;
	if(wta!=wtb)return wta-wtb;
	else{
		return ((ITEM *)b)->typ-((ITEM *)a)->typ;
	}
}


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

typedef struct __ITEM{
	int wt;
	int ind;
	int typ;
}ITEM;

int cmpfunc(const void *,const void *);

int main(){
	int n,m,ans[100005][2],i,j,x,y;
	ITEM ar[100005];
	scanf("%d %d",&n,&m);
	for(i=0;i<m;i++){
		scanf("%d %d",&x,&y);
		ar[i].wt=x;
		ar[i].typ=y;
		ar[i].ind=i;
	}
	qsort(ar,m,sizeof(ITEM),cmpfunc);
	//	for(i=0;i<m;i++)printf("%d %d\n",ar[i].wt,ar[i].typ);
	x=0;y=2;
	for(i=0,j=0;i<m;i++){
		//		printf("%d %d %d %d\n",i,ar[i].ind,x,y);
		if(ar[i].typ){
			ans[ar[i].ind][0]=j;
			ans[ar[i].ind][1]=++j;
		}
		else{
			if(y>j)break;
			ans[ar[i].ind][0]=x++;
			ans[ar[i].ind][1]=y;
			if(y-x==1){
				x=0;y++;
			}
		}
	}
	if(i<m)printf("-1\n");
	else{
		for(i=0;i<m;i++)
			printf("%d %d\n",ans[i][0]+1,ans[i][1]+1);
	}
	return 0;
}

int cmpfunc (const void * a, const void * b)
{
	int wta,wtb;
	wta=((ITEM *)a)->wt;wtb=((ITEM *)b)->wt;
	if(wta!=wtb)return wta-wtb;
	else{
		return ((ITEM *)b)->typ-((ITEM *)a)->typ;
	}
}


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

typedef struct {
	int a;
	int b;
	int i;
} edge;

edge edges[100000] = {0};
int node1[100000] = {0};
int node2[100000] = {0};

int fcmp(const void *a, const void *b) {
	edge c = *(edge *)a;
	edge d = *(edge *)b;
	if(c.a == d.a && c.b >= d.b) return -1;
	if(c.a < d.a) return -1;
	return 1;
}

int main() {
	int n, m;
	int min;
	int from, to;
	scanf("%d%d", &n, &m);
	int i;

	for(i=0;i<m;i++) {
		scanf("%d%d", &(edges[i].a), &(edges[i].b));
		edges[i].i = i;
	}

	qsort(edges, m, sizeof(edge), fcmp);

	min = 1;
	from = 2;
	to = 3;

	for(i=0;i<m;i++) {
		int mst = edges[i].b;
		int index = edges[i].i;
		if(mst) {
			min++;
			node1[index] = 1;
			node2[index] = min;
		} else {
			if(to > min) {
				printf("-1\n");
				return 0;
			}
			node1[index] = from;
			node2[index] = to;
			from ++;
			if(from == to) {
				from = 2;
				to++;
			}
		}
	}

	for(i=0;i<m;i++) {
		printf("%d %d\n", node1[i], node2[i]);
	}

	return 0;
}


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

typedef struct {
	int a;
	int b;
	int i;
} edge;

edge edges[100000] = {0};
int node1[100000] = {0};
int node2[100000] = {0};

int fcmp(const void *a, const void *b) {
	edge c = *(edge *)a;
	edge d = *(edge *)b;
	if(c.a == d.a && c.b == d.b) return 0;
	if(c.a == d.a && c.b > d.b) return -1;
	if(c.a < d.a) return -1;
	return 1;
}

int main() {
	int n, m;
	int min;
	int from, to;
	scanf("%d%d", &n, &m);
	int i;

	for(i=0;i<m;i++) {
		scanf("%d%d", &(edges[i].a), &(edges[i].b));
		edges[i].i = i;
	}

	qsort(edges, m, sizeof(edge), fcmp);

	min = 1;
	from = 2;
	to = 3;

	for(i=0;i<m;i++) {
		int mst = edges[i].b;
		int index = edges[i].i;
		if(mst) {
			min++;
			node1[index] = 1;
			node2[index] = min;
		} else {
			if(to > min) {
				printf("-1\n");
				return 0;
			}
			node1[index] = from;
			node2[index] = to;
			from ++;
			if(from == to) {
				from = 2;
				to++;
			}
		}
	}

	for(i=0;i<m;i++) {
		printf("%d %d\n", node1[i], node2[i]);
	}

	return 0;
}


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

typedef struct {
	int a;
	int b;
	int i;
} edge;

edge edges[100000] = {0};
int node1[100000] = {0};
int node2[100000] = {0};

int fcmp(const void *a, const void *b) {
	edge c = *(edge *)a;
	edge d = *(edge *)b;
	if(c.a == d.a && c.b >= d.b) return -1;
	if(c.a < d.a) return -1;
	return 1;
}

int main() {
	int n, m;
	int min;
	int from, to;
	scanf("%d%d", &n, &m);
	int i;

	for(i=0;i<m;i++) {
		scanf("%d%d", &(edges[i].a), &(edges[i].b));
		edges[i].i = i;
	}

	qsort(edges, m, sizeof(edge), fcmp);

	min = 2;
	from = 2;
	to = 3;

	for(i=0;i<m;i++) {
		int mst = edges[i].b;
		int index = edges[i].i;
		if(mst) {
			node1[index] = 1;
			node2[index] = min;
			min++;
		} else {
			if(to > min) {
				printf("-1\n");
				return 0;
			}
			node1[index] = from;
			node2[index] = to;
			from ++;
			if(from == to) {
				from = 2;
				to++;
			}
		}
	}

	for(i=0;i<m;i++) {
		printf("%d %d\n", node1[i], node2[i]);
	}

	return 0;
}


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

typedef struct {
	int a;
	int b;
	int i;
} edge;

edge edges[100000] = {0};
int node1[100000] = {0};
int node2[100000] = {0};

int fcmp(const void *a, const void *b) {
	edge c = *(edge *)a;
	edge d = *(edge *)b;
	if(c.a == d.a && c.b >= d.b) return -1;
	if(c.a < d.a) return -1;
	return 1;
}

int main() {
	int n, m;
	int min;
	int from, to;
	scanf("%d%d", &n, &m);
	int i;

	for(i=0;i<m;i++) {
		scanf("%d%d", &(edges[i].a), &(edges[i].b));
		edges[i].i = i;
	}

	qsort(edges, m, sizeof(edge), fcmp);

	min = 1;
	from = 2;
	to = 3;

	for(i=0;i<m;i++) {
		int mst = edges[i].b;
		int index = edges[i].i;
		if(mst) {
			min++
			node1[index] = 1;
			node2[index] = min;
		} else {
			if(to > min) {
				printf("-1\n");
				return 0;
			}
			node1[index] = from;
			node2[index] = to;
			from ++;
			if(from == to) {
				from = 2;
				to++;
			}
		}
	}

	for(i=0;i<m;i++) {
		printf("%d %d\n", node1[i], node2[i]);
	}

	return 0;
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            Edge[] edges = new Edge[m];
            Answer[] ans = new Answer[m];
            for (int i = 0; i < m; ++i) {
                edges[i] = new Edge(in.nextInt(), in.nextInt(), i);
                ans[i] = new Answer(-1, -1);
            }
            Arrays.sort(edges);
            int availableEndPoint = 0;
            int[] degree = new int[n];
            int availableRepeatingVertex = 0;
            for (int i = 0; i < m; ++i) {
                if (edges[i].inTree) {
                    ++degree[availableEndPoint];
                    ans[edges[i].index].u = availableEndPoint++;
                    ++degree[availableEndPoint];
                    ans[edges[i].index].v = availableEndPoint;
                } else {
                    int cnt = 0;
                    while (cnt < availableEndPoint && degree[availableRepeatingVertex] == availableEndPoint) {
                        ++availableRepeatingVertex;
                        availableRepeatingVertex %= availableEndPoint;
                        ++cnt;
                    }
                    if (cnt == availableEndPoint) {
                        out.println("-1");
                        return;
                    }
                    ans[edges[i].index].u = availableRepeatingVertex;
                    ans[edges[i].index].v = degree[availableRepeatingVertex];
                    if (availableRepeatingVertex + 1 <= degree[availableRepeatingVertex]) {
                        ++ans[edges[i].index].v;
                    }
                    ++degree[availableRepeatingVertex];
                }
            }
            for (int i = 0; i < m; ++i) {
                out.println((ans[i].u + 1) + " " + (ans[i].v + 1));
            }
        }

        class Edge implements Comparable<Edge> {
            int w;
            boolean inTree;
            int index;

            public Edge(int w, int inside, int index) {
                this.w = w;
                this.inTree = inside == 1;
                this.index = index;
            }

            public int compareTo(Edge other) {
                if (w != other.w) return w - other.w;
                if (inTree) return -1;
                if (other.inTree) return 1;
                return index - other.index;
            }

        }

        class Answer {
            int u;
            int v;

            public Answer(int u, int v) {
                this.u = u;
                this.v = v;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 65536);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            Edge[] edges = new Edge[m];
            Answer[] ans = new Answer[m];
            for (int i = 0; i < m; ++i) {
                edges[i] = new Edge(in.nextInt(), in.nextInt(), i);
                ans[i] = new Answer(-1, -1);
            }
            Arrays.sort(edges);
            int availableEndPoint = 0;
            int[] degree = new int[n];
            int availableRepeatingVertex = 0;
            for (int i = 0; i < m; ++i) {
                if (edges[i].inTree) {
                    ++degree[availableEndPoint];
                    ans[edges[i].index].u = availableEndPoint++;
                    ++degree[availableEndPoint];
                    ans[edges[i].index].v = availableEndPoint;
                } else {
                    int cnt = 0;
                    while (cnt < availableEndPoint && degree[availableRepeatingVertex] == availableEndPoint) {
                        ++availableRepeatingVertex;
                        availableRepeatingVertex %= availableEndPoint;
                        ++cnt;
                    }
                    if (cnt == availableEndPoint) {
                        out.println("-1");
                        return;
                    }
                    ans[edges[i].index].u = availableRepeatingVertex;
                    ans[edges[i].index].v = degree[availableRepeatingVertex];
                    if (ans[edges[i].index].v >= ans[edges[i].index].u &&
                            ans[edges[i].index].v - ans[edges[i].index].u <= 1)
                        ++ans[edges[i].index].v;
                    ++degree[availableRepeatingVertex];
                }
            }
            for (int i = 0; i < m; ++i) {
                out.println((ans[i].u + 1) + " " + (ans[i].v + 1));
            }
        }

        class Edge implements Comparable<Edge> {
            int w;
            boolean inTree;
            int index;

            public Edge(int w, int inside, int index) {
                this.w = w;
                this.inTree = inside == 1;
                this.index = index;
            }

            public int compareTo(Edge other) {
                if (w != other.w) return w - other.w;
                if (inTree) return -1;
                if (other.inTree) return 1;
                return index - other.index;
            }

        }

        class Answer {
            int u;
            int v;

            public Answer(int u, int v) {
                this.u = u;
                this.v = v;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 65536);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            Edge[] edges = new Edge[m];
            Answer[] ans = new Answer[m];
            for (int i = 0; i < m; ++i) {
                edges[i] = new Edge(in.nextLong(), in.nextInt(), i);
                ans[i] = new Answer(-1, -1);
            }
            Arrays.sort(edges);
            int availableEndPoint = 0;
            int[] degree = new int[n];
            int availableRepeatingVertex = 0;
            long availableEdges = 0L;
            for (int i = 0; i < m; ++i) {
                if (edges[i].inTree) {
                    availableEdges += (long) (availableEndPoint);
                    ++degree[availableEndPoint];
                    ans[edges[i].index].u = availableEndPoint++;
                    ++degree[availableEndPoint];
                    ans[edges[i].index].v = availableEndPoint;
                } else {
                    if (availableEdges == 0L) {
                        out.println("-1");
                        return;
                    } else {
                        while (degree[availableRepeatingVertex] == availableEndPoint + 1) {
                            ++availableRepeatingVertex;
                            availableRepeatingVertex %= availableEndPoint;
                        }
                        ans[edges[i].index].u = availableRepeatingVertex;
                        ans[edges[i].index].v = degree[availableRepeatingVertex];
                        if (availableRepeatingVertex <= degree[availableRepeatingVertex]) {
                            ++ans[edges[i].index].v;
                        }
                        ++degree[availableRepeatingVertex];
                        --availableEdges;
                    }
                }
            }
            for (int i = 0; i < m; ++i) {
                out.println((ans[i].u + 1) + " " + (ans[i].v + 1));
            }
        }

        class Edge implements Comparable<Edge> {
            long w;
            boolean inTree;
            int index;

            public Edge(long w, int inside, int index) {
                this.w = w;
                this.inTree = inside == 1;
                this.index = index;
            }

            public int compareTo(Edge other) {
                if (w != other.w) return w - other.w < 0L ? -1 : 1;
                if (inTree) return -1;
                if (other.inTree) return 1;
                return index - other.index;
            }

        }

        class Answer {
            int u;
            int v;

            public Answer(int u, int v) {
                this.u = u;
                this.v = v;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 65536);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            Edge[] edges = new Edge[m];
            Answer[] ans = new Answer[m];
            for (int i = 0; i < m; ++i) {
                edges[i] = new Edge(in.nextInt(), in.nextInt(), i);
                ans[i] = new Answer(-1, -1);
            }
            Arrays.sort(edges);
            int availableEndPoint = 1;
            int[] degree = new int[n];
            int u = 1, v = 2;
            for (int i = 0; i < m; ++i) {
                if (edges[i].inTree) {
                    ans[edges[i].index].u = 0;
                    ans[edges[i].index].v = availableEndPoint++;
                } else {
                    if (u >= availableEndPoint || v >= availableEndPoint) {
                        out.println("-1");
                        return;
                    }
                    ans[edges[i].index].u = u;
                    ans[edges[i].index].v = v;
                    ++u;
                    if (u == v) {
                        u = 1;
                        ++v;
                    }
                }
            }
            for (int i = 0; i < m; ++i) {
                out.println((ans[i].u + 1) + " " + (ans[i].v + 1));
            }
        }

        class Edge implements Comparable<Edge> {
            int w;
            boolean inTree;
            int index;

            public Edge(int w, int inside, int index) {
                this.w = w;
                this.inTree = inside == 1;
                this.index = index;
            }

            public int compareTo(Edge other) {
                if (w != other.w) return w - other.w;
                if (inTree) return -1;
                if (other.inTree) return 1;
                return index - other.index;
            }

        }

        class Answer {
            int u;
            int v;

            public Answer(int u, int v) {
                this.u = u;
                this.v = v;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 65536);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            Edge[] edges = new Edge[m];
            Answer[] ans = new Answer[m];
            for (int i = 0; i < m; ++i) {
                edges[i] = new Edge(in.nextLong(), in.nextInt(), i);
                ans[i] = new Answer(-1, -1);
            }
            Arrays.sort(edges);
            int availableEndPoint = 0;
            int[] degree = new int[n];
            int availableRepeatingVertex = 0;
            for (int i = 0; i < m; ++i) {
                if (edges[i].inTree) {
                    ++degree[availableEndPoint];
                    ans[edges[i].index].u = availableEndPoint++;
                    ++degree[availableEndPoint];
                    ans[edges[i].index].v = availableEndPoint;
                } else {
                    int cnt = 0;
                    while (cnt < availableEndPoint && degree[availableRepeatingVertex] == availableEndPoint) {
                        ++availableRepeatingVertex;
                        availableRepeatingVertex %= availableEndPoint;
                        ++cnt;
                    }
                    if (cnt == availableEndPoint) {
                        out.println("-1");
                        return;
                    }
                    ans[edges[i].index].u = availableRepeatingVertex;
                    ans[edges[i].index].v = degree[availableRepeatingVertex];
                    if (availableRepeatingVertex <= degree[availableRepeatingVertex]) {
                        ++ans[edges[i].index].v;
                    }
                    ++degree[availableRepeatingVertex];
                }
            }
            for (int i = 0; i < m; ++i) {
                out.println((ans[i].u + 1) + " " + (ans[i].v + 1));
            }
        }

        class Edge implements Comparable<Edge> {
            long w;
            boolean inTree;
            int index;

            public Edge(long w, int inside, int index) {
                this.w = w;
                this.inTree = inside == 1;
                this.index = index;
            }

            public int compareTo(Edge other) {
                if (w != other.w) return w - other.w < 0L ? -1 : 1;
                if (inTree) return -1;
                if (other.inTree) return 1;
                return index - other.index;
            }

        }

        class Answer {
            int u;
            int v;

            public Answer(int u, int v) {
                this.u = u;
                this.v = v;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 65536);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            Edge[] edges = new Edge[m];
            Answer[] ans = new Answer[m];
            for (int i = 0; i < m; ++i) {
                edges[i] = new Edge(in.nextInt(), in.nextInt(), i);
                ans[i] = new Answer(-1, -1);
            }
            Arrays.sort(edges);
            int availableEndPoint = 0;
            int[] degree = new int[n];
            int availableRepeatingVertex = 0;
            for (int i = 0; i < m; ++i) {
                if (edges[i].inTree) {
                    ++degree[availableEndPoint];
                    ans[edges[i].index].u = availableEndPoint++;
                    ++degree[availableEndPoint];
                    ans[edges[i].index].v = availableEndPoint;
                } else {
                    int cnt = 0;
                    while (cnt < availableEndPoint && degree[availableRepeatingVertex] == availableEndPoint) {
                        ++availableRepeatingVertex;
                        availableRepeatingVertex %= availableEndPoint;
                        ++cnt;
                    }
                    if (cnt == availableEndPoint) {
                        out.println("-1");
                        return;
                    }
                    ans[edges[i].index].u = availableRepeatingVertex;
                    ans[edges[i].index].v = degree[availableRepeatingVertex];
                    if (availableRepeatingVertex <= degree[availableRepeatingVertex] ||
                            availableRepeatingVertex + 1 == degree[availableRepeatingVertex]) {
                        ++ans[edges[i].index].v;
                    }
                    ++degree[availableRepeatingVertex];
                }
            }
            for (int i = 0; i < m; ++i) {
                out.println((ans[i].u + 1) + " " + (ans[i].v + 1));
            }
        }

        class Edge implements Comparable<Edge> {
            int w;
            boolean inTree;
            int index;

            public Edge(int w, int inside, int index) {
                this.w = w;
                this.inTree = inside == 1;
                this.index = index;
            }

            public int compareTo(Edge other) {
                if (w != other.w) return w - other.w;
                if (inTree) return -1;
                if (other.inTree) return 1;
                return index - other.index;
            }

        }

        class Answer {
            int u;
            int v;

            public Answer(int u, int v) {
                this.u = u;
                this.v = v;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 65536);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            Edge[] edges = new Edge[m];
            Answer[] ans = new Answer[m];
            for (int i = 0; i < m; ++i) {
                edges[i] = new Edge(in.nextInt(), in.nextInt(), i);
                ans[i] = new Answer(-1, -1);
            }
            Arrays.sort(edges);
            int availableEndPoint = 0;
            int[] degree = new int[n];
            int availableRepeatingVertex = 0;
            for (int i = 0; i < m; ++i) {
                if (edges[i].inTree) {
                    ++degree[availableEndPoint];
                    ans[edges[i].index].u = availableEndPoint++;
                    ++degree[availableEndPoint];
                    ans[edges[i].index].v = availableEndPoint;
                } else {
                    int cnt = 0;
                    while (cnt < availableEndPoint && degree[availableRepeatingVertex] == availableEndPoint) {
                        ++availableRepeatingVertex;
                        availableRepeatingVertex %= availableEndPoint;
                        ++cnt;
                    }
                    if (cnt == availableEndPoint) {
                        out.println("-1");
                        return;
                    }
                    ans[edges[i].index].u = availableRepeatingVertex;
                    ans[edges[i].index].v = degree[availableRepeatingVertex];
                    if (availableRepeatingVertex <= degree[availableRepeatingVertex] ||
                            availableRepeatingVertex == degree[availableRepeatingVertex] + 1) {
                        ++ans[edges[i].index].v;
                    }
                    ++degree[availableRepeatingVertex];
                }
            }
            for (int i = 0; i < m; ++i) {
                out.println((ans[i].u + 1) + " " + (ans[i].v + 1));
            }
        }

        class Edge implements Comparable<Edge> {
            int w;
            boolean inTree;
            int index;

            public Edge(int w, int inside, int index) {
                this.w = w;
                this.inTree = inside == 1;
                this.index = index;
            }

            public int compareTo(Edge other) {
                if (w != other.w) return w - other.w;
                if (inTree) return -1;
                if (other.inTree) return 1;
                return index - other.index;
            }

        }

        class Answer {
            int u;
            int v;

            public Answer(int u, int v) {
                this.u = u;
                this.v = v;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 65536);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}