#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("avx,avx2,fma")

void trace(int x)                         { cerr << x; }
void trace(long x)                        { cerr << x; }
void trace(long long x)                   { cerr << x; }
void trace(unsigned x)                    { cerr << x; }
void trace(unsigned long x)               { cerr << x; }
void trace(unsigned long long x)          { cerr << x; }
void trace(float x)                       { cerr << x; }
void trace(double x)                      { cerr << x; }
void trace(long double x)                 { cerr << x; }
void trace(char x)                        { cerr << '\'' << x << '\''; }
void trace(const char *x)                 { cerr << '\"' << x << '\"'; }
void trace(const string &x)               { cerr << '\"' << x << '\"'; }
void trace(bool x)                        { cerr << (x ? "true" : "false"); }

template <typename A, typename B>                         void trace(const pair <A, B> &x)         { cerr << '{'; trace(x.first); cerr << ','; trace(x.second); cerr << '}'; }
template <typename A, typename B, typename C>             void trace(const tuple <A, B, C> &x)     { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << '}'; }
template <typename A, typename B, typename C, typename D> void trace(const tuple <A, B, C, D> &x)  { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << ','; trace(get <3> (x)); cerr << '}'; }
template <typename T>                                     void trace(const T &x)                   { int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), trace(i); cerr << "}"; }
template <size_t N>                                       void trace(bitset <N> v)                 { cerr << '{'; for (size_t i = 0; i < N; i++) cerr << static_cast <char> ('0' + v[i]); cerr << '}'; }
void _print()                                                                                { cerr << "]\n"; }
template <typename T, typename... V>                      void _print(T t, V... v)                 { trace(t); if (sizeof...(v)) cerr << ", "; _print(v...); }

#ifndef ONLINE_JUDGE
      #define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
      #define debug(x...)
#endif

template <typename T> using ordered_set                = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T1, typename T2> using ordered_map  = tree <T1, T2, less <T1>, rb_tree_tag, tree_order_statistics_node_update>;

template <class T> bool MIN(T &a, T b)                 { return a > b ? (a = b, true) : false; }
template <class T> bool MAX(T &a, T b)                 { return a < b ? (a = b, true) : false; }

template <class T> T binaryExpo(T a, T p)              { if (p == 0) { return 1LL; } if (p == 1) { return a; } if (p & 1) { return a * binaryExpo(a, p - 1); } T ret = binaryExpo(a, p / 2); return ret * ret; }
template <class T> T bigMod(T a, T p, T m)             { if (p == 0) { return 1LL % m; } if (p == 1) { return a % m; } if (p & 1) { return (a % m * bigMod(a, p - 1, m)) % m; } T ret = bigMod(a, p / 2, m) % m; return (ret * ret) % m; }
template <class T> T modInv(T a, T m)                  { return bigMod(a, m - 2, m); }

template <typename T> string num_str(T num)            { stringstream ss; ss << num; return ss.str(); }
long long str_num(string s)                            { long long num; istringstream iss(s); iss >> num; return num; }

inline long long ON(long long mask, int pos)           { return mask |= (1LL << pos); }
inline long long OFF(long long mask, int pos)          { return mask &= ~(1LL << pos); }
inline long long TOGGLE(long long mask, int pos)       { return mask ^= (1LL << pos); }
inline bool CHECK(long long mask, int pos)             { return (bool)(mask >> pos & 1LL); }

inline int ONE(long long mask)                         { return __builtin_popcountll(mask); }
inline int LZERO(long long mask)                       { return 31 - __builtin_clzll(mask); };
inline int TZERO(long long mask)                       { return __builtin_ctzll(mask); };

//int dr[] = {+1, -1, +0, +0};                         // 4 Direction - DOWN, UP, RIGHT, LEFT
//int dc[] = {+0, +0, +1, -1};
int dr[] = {+0, +0, +1, -1, +1, +1, -1, -1};       // 8 Direction - RIGHT, LEFT, DOWN, UP, RIGHT-DOWN, LEFT-DOWN, UP-RIGHT, UP-LEFT
int dc[] = {+1, -1, +0, +0, +1, -1, +1, -1};
//int dr[] = {-1, +1, -2, -2, -1, +1, +2, +2};       // knight Moves
//int dc[] = {-2, -2, -1, +1, +2, +2, +1, -1};

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define ll              long long int
#define ull             unsigned long long int
#define endl            '\n'
#define pii             pair <int, int>
#define pll             pair <ll, ll>
#define mk              make_pair
#define ff              first
#define ss              second
#define all(a)          (a).begin(), (a).end()
#define rall(a)         (a).rbegin(), (a).rend()
#define eb              emplace_back
#define pb              push_back
#define pf              push_front
#define allUpper(a)     transform(all(a), a.begin(), :: toupper)
#define allLower(a)     transform(all(a), a.begin(), :: tolower)
#define LINE            cerr << __LINE__ << " ";
#define memo(a, b)      memset(a, b, sizeof a)
#define ook             order_of_key
#define fbo             find_by_order

#define int             long long int

static const int maxn = 2e5 + 5;
static const int logn = 19;
static const long long MOD = 1e9 + 7;
static const long long INF = 1e18;

struct Edge {
      int u, v, w, t, id;
      Edge(int u = 0, int v = 0, int w = 0, int t = 0, int id = 0)
            : u(u), v(v), w(w), t(t), id(id) {}

      bool operator < (const Edge &other) const {
            if (w == other.w) {
                  return t > other.t;
            }
            return w < other.w;
      }
};

int par[maxn];

int find_rep(int r) {
      if (r == par[r]) {
            return r;
      }
      return par[r] = find_rep(par[r]);
}

void no() {
      cout << -1 << endl;
      exit(0);
}

signed main()
{
      ios_base::sync_with_stdio(false);
      cin.tie(nullptr);
      cout.precision(12);

      #ifndef ONLINE_JUDGE
          freopen("in.txt", "r", stdin);
      #endif // ONLINE_JUDGE

      int n, m;
      cin >> n >> m;
      deque <pii> alive;
      deque <pii> dead;
      for (int e = 1; e <= m; e++) {
            int w, t;
            cin >> w >> t;
            if (t == 1) {
                  alive.emplace_back(w, e);
            }
            else {
                  dead.emplace_back(w, e);
            }
      }
      sort(all(alive));
      sort(all(dead));
      vector <Edge> ans;
      for (int i = 0; i < alive.size(); i++) {
            int u = 1;
            int v = i + 2;
            int w = alive[i].first;
            int id = alive[i].second;
            ans.eb(u, v, w, 1, id);
      }
      int u = 2;
      while (u < n and dead.size()) {
            int v = u + 1;
            while (v <= n and dead.size()) {
                  int w = dead.front().first;
                  int id = dead.front().second; dead.pop_front();
                  ans.eb(u, v, w, 0, id);
                  v++;
            }
            u++;
      }
      if (dead.size()) {
            no();
      }
      iota(par, par + maxn, 0);
      sort(all(ans));
      for (Edge it : ans) {
            int u = it.u;
            int v = it.v;
            int w = it.w;
            int t = it.t;
            int id = it.id;
            int p = find_rep(u);
            int q = find_rep(v);
            debug(u, v, p, q, t, id);
            if (p == q) {
                  if (t == 1) {
                        no();
                  }
                  continue;
            }
            if (t == 0) {
                  no();
            }
            par[q] = p;
      }
      pii graph[n + 1];
      for (Edge it : ans) {
            graph[it.id] = {it.u, it.v};
      }
      for (int i = 1; i <= m; i++) {
            cout << graph[i].first << " " << graph[i].second << endl;
      }

      #ifndef ONLINE_JUDGE
            cerr << endl << "Time : " << 1.0 * clock() / CLOCKS_PER_SEC << " s." << endl;
      #endif // ONLINE_JUDGE

      return 0;
}


#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("avx,avx2,fma")

void trace(int x)                         { cerr << x; }
void trace(long x)                        { cerr << x; }
void trace(long long x)                   { cerr << x; }
void trace(unsigned x)                    { cerr << x; }
void trace(unsigned long x)               { cerr << x; }
void trace(unsigned long long x)          { cerr << x; }
void trace(float x)                       { cerr << x; }
void trace(double x)                      { cerr << x; }
void trace(long double x)                 { cerr << x; }
void trace(char x)                        { cerr << '\'' << x << '\''; }
void trace(const char *x)                 { cerr << '\"' << x << '\"'; }
void trace(const string &x)               { cerr << '\"' << x << '\"'; }
void trace(bool x)                        { cerr << (x ? "true" : "false"); }

template <typename A, typename B>                         void trace(const pair <A, B> &x)         { cerr << '{'; trace(x.first); cerr << ','; trace(x.second); cerr << '}'; }
template <typename A, typename B, typename C>             void trace(const tuple <A, B, C> &x)     { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << '}'; }
template <typename A, typename B, typename C, typename D> void trace(const tuple <A, B, C, D> &x)  { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << ','; trace(get <3> (x)); cerr << '}'; }
template <typename T>                                     void trace(const T &x)                   { int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), trace(i); cerr << "}"; }
template <size_t N>                                       void trace(bitset <N> v)                 { cerr << '{'; for (size_t i = 0; i < N; i++) cerr << static_cast <char> ('0' + v[i]); cerr << '}'; }
void _print()                                                                                { cerr << "]\n"; }
template <typename T, typename... V>                      void _print(T t, V... v)                 { trace(t); if (sizeof...(v)) cerr << ", "; _print(v...); }

#ifndef ONLINE_JUDGE
      #define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
      #define debug(x...)
#endif

template <typename T> using ordered_set                = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T1, typename T2> using ordered_map  = tree <T1, T2, less <T1>, rb_tree_tag, tree_order_statistics_node_update>;

template <class T> bool MIN(T &a, T b)                 { return a > b ? (a = b, true) : false; }
template <class T> bool MAX(T &a, T b)                 { return a < b ? (a = b, true) : false; }

template <class T> T binaryExpo(T a, T p)              { if (p == 0) { return 1LL; } if (p == 1) { return a; } if (p & 1) { return a * binaryExpo(a, p - 1); } T ret = binaryExpo(a, p / 2); return ret * ret; }
template <class T> T bigMod(T a, T p, T m)             { if (p == 0) { return 1LL % m; } if (p == 1) { return a % m; } if (p & 1) { return (a % m * bigMod(a, p - 1, m)) % m; } T ret = bigMod(a, p / 2, m) % m; return (ret * ret) % m; }
template <class T> T modInv(T a, T m)                  { return bigMod(a, m - 2, m); }

template <typename T> string num_str(T num)            { stringstream ss; ss << num; return ss.str(); }
long long str_num(string s)                            { long long num; istringstream iss(s); iss >> num; return num; }

inline long long ON(long long mask, int pos)           { return mask |= (1LL << pos); }
inline long long OFF(long long mask, int pos)          { return mask &= ~(1LL << pos); }
inline long long TOGGLE(long long mask, int pos)       { return mask ^= (1LL << pos); }
inline bool CHECK(long long mask, int pos)             { return (bool)(mask >> pos & 1LL); }

inline int ONE(long long mask)                         { return __builtin_popcountll(mask); }
inline int LZERO(long long mask)                       { return 31 - __builtin_clzll(mask); };
inline int TZERO(long long mask)                       { return __builtin_ctzll(mask); };

//int dr[] = {+1, -1, +0, +0};                         // 4 Direction - DOWN, UP, RIGHT, LEFT
//int dc[] = {+0, +0, +1, -1};
int dr[] = {+0, +0, +1, -1, +1, +1, -1, -1};       // 8 Direction - RIGHT, LEFT, DOWN, UP, RIGHT-DOWN, LEFT-DOWN, UP-RIGHT, UP-LEFT
int dc[] = {+1, -1, +0, +0, +1, -1, +1, -1};
//int dr[] = {-1, +1, -2, -2, -1, +1, +2, +2};       // knight Moves
//int dc[] = {-2, -2, -1, +1, +2, +2, +1, -1};

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define ll              long long int
#define ull             unsigned long long int
#define endl            '\n'
#define pii             pair <int, int>
#define pll             pair <ll, ll>
#define mk              make_pair
#define ff              first
#define ss              second
#define all(a)          (a).begin(), (a).end()
#define rall(a)         (a).rbegin(), (a).rend()
#define eb              emplace_back
#define pb              push_back
#define pf              push_front
#define allUpper(a)     transform(all(a), a.begin(), :: toupper)
#define allLower(a)     transform(all(a), a.begin(), :: tolower)
#define LINE            cerr << __LINE__ << " ";
#define memo(a, b)      memset(a, b, sizeof a)
#define ook             order_of_key
#define fbo             find_by_order

#define int             long long int

static const int maxn = 2e5 + 5;
static const int logn = 19;
static const long long MOD = 1e9 + 7;
static const long long INF = 1e18;

struct Edge {
      int u, v, w, t, id;
      Edge(int u = 0, int v = 0, int w = 0, int t = 0, int id = 0)
            : u(u), v(v), w(w), t(t), id(id) {}

      bool operator < (const Edge &other) const {
            if (w == other.w) {
                  return t > other.t;
            }
            return w < other.w;
      }
};

int par[maxn];

int find_rep(int r) {
      if (r == par[r]) {
            return r;
      }
      return par[r] = find_rep(par[r]);
}

void no() {
      cout << -1 << endl;
      exit(0);
}

signed main()
{
      ios_base::sync_with_stdio(false);
      cin.tie(nullptr);
      cout.precision(12);

      #ifndef ONLINE_JUDGE
          freopen("in.txt", "r", stdin);
      #endif // ONLINE_JUDGE

      int n, m;
      cin >> n >> m;
      deque <pii> alive;
      deque <pii> dead;
      for (int e = 1; e <= m; e++) {
            int w, t;
            cin >> w >> t;
            if (t == 1) {
                  alive.emplace_back(w, e);
            }
            else {
                  dead.emplace_back(w, e);
            }
      }
      sort(all(alive));
      sort(all(dead));
      vector <Edge> ans;
      vector <int> asign(n + 1);
      for (int i = 0; i < alive.size(); i++) {
            int u = i + 1;
            int v = u + 1;
            int w = alive[i].first;
            int id = alive[i].second;
            ans.eb(u, v, w, 1, id);
            debug(u, v, w);
            asign[v] = w;
      }
      int last = 1;
      multiset <pii> ms;
      for (auto it : dead) {
            ms.insert(it);
      }
      while (last < n and ms.size()) {
            int u = last;
            int v = u + 2;
            while (v <= n and ms.size()) {
                  int myw = asign[v];
                  auto lb = ms.lower_bound(mk(myw, -1));
                  if (lb == ms.end()) {
                        break;
                  }
                  int w = (*lb).ff;
                  int id = (*lb).ss;
                  ans.eb(u, v, w, 0, id);
                  ms.erase(lb);
                  v++;
            }
            last++;
      }
      if (ms.size()) {
            no();
      }
//      for (Edge it : ans) {
//            cerr << it.u << " " << it.v << " " << it.w << " " << it.t << " " << it.id << endl;
//      }
      iota(par, par + maxn, 0);
      sort(all(ans));
      for (Edge it : ans) {
            int u = it.u;
            int v = it.v;
            int w = it.w;
            int t = it.t;
            int id = it.id;
            int p = find_rep(u);
            int q = find_rep(v);
            debug(u, v, p, q, t, id);
            if (p == q) {
                  if (t == 1) {
                        no();
                  }
                  continue;
            }
            if (t == 0) {
                  no();
            }
            par[q] = p;
      }
      pii graph[m + 1];
      for (Edge it : ans) {
            graph[it.id] = {it.u, it.v};
      }
      for (int i = 1; i <= m; i++) {
            cout << graph[i].first << " " << graph[i].second << endl;
      }

      #ifndef ONLINE_JUDGE
            cerr << endl << "Time : " << 1.0 * clock() / CLOCKS_PER_SEC << " s." << endl;
      #endif // ONLINE_JUDGE

      return 0;
}


#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("avx,avx2,fma")

void trace(int x)                         { cerr << x; }
void trace(long x)                        { cerr << x; }
void trace(long long x)                   { cerr << x; }
void trace(unsigned x)                    { cerr << x; }
void trace(unsigned long x)               { cerr << x; }
void trace(unsigned long long x)          { cerr << x; }
void trace(float x)                       { cerr << x; }
void trace(double x)                      { cerr << x; }
void trace(long double x)                 { cerr << x; }
void trace(char x)                        { cerr << '\'' << x << '\''; }
void trace(const char *x)                 { cerr << '\"' << x << '\"'; }
void trace(const string &x)               { cerr << '\"' << x << '\"'; }
void trace(bool x)                        { cerr << (x ? "true" : "false"); }

template <typename A, typename B>                         void trace(const pair <A, B> &x)         { cerr << '{'; trace(x.first); cerr << ','; trace(x.second); cerr << '}'; }
template <typename A, typename B, typename C>             void trace(const tuple <A, B, C> &x)     { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << '}'; }
template <typename A, typename B, typename C, typename D> void trace(const tuple <A, B, C, D> &x)  { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << ','; trace(get <3> (x)); cerr << '}'; }
template <typename T>                                     void trace(const T &x)                   { int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), trace(i); cerr << "}"; }
template <size_t N>                                       void trace(bitset <N> v)                 { cerr << '{'; for (size_t i = 0; i < N; i++) cerr << static_cast <char> ('0' + v[i]); cerr << '}'; }
void _print()                                                                                { cerr << "]\n"; }
template <typename T, typename... V>                      void _print(T t, V... v)                 { trace(t); if (sizeof...(v)) cerr << ", "; _print(v...); }

#ifndef ONLINE_JUDGE
      #define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
      #define debug(x...)
#endif

template <typename T> using ordered_set                = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T1, typename T2> using ordered_map  = tree <T1, T2, less <T1>, rb_tree_tag, tree_order_statistics_node_update>;

template <class T> bool MIN(T &a, T b)                 { return a > b ? (a = b, true) : false; }
template <class T> bool MAX(T &a, T b)                 { return a < b ? (a = b, true) : false; }

template <class T> T binaryExpo(T a, T p)              { if (p == 0) { return 1LL; } if (p == 1) { return a; } if (p & 1) { return a * binaryExpo(a, p - 1); } T ret = binaryExpo(a, p / 2); return ret * ret; }
template <class T> T bigMod(T a, T p, T m)             { if (p == 0) { return 1LL % m; } if (p == 1) { return a % m; } if (p & 1) { return (a % m * bigMod(a, p - 1, m)) % m; } T ret = bigMod(a, p / 2, m) % m; return (ret * ret) % m; }
template <class T> T modInv(T a, T m)                  { return bigMod(a, m - 2, m); }

template <typename T> string num_str(T num)            { stringstream ss; ss << num; return ss.str(); }
long long str_num(string s)                            { long long num; istringstream iss(s); iss >> num; return num; }

inline long long ON(long long mask, int pos)           { return mask |= (1LL << pos); }
inline long long OFF(long long mask, int pos)          { return mask &= ~(1LL << pos); }
inline long long TOGGLE(long long mask, int pos)       { return mask ^= (1LL << pos); }
inline bool CHECK(long long mask, int pos)             { return (bool)(mask >> pos & 1LL); }

inline int ONE(long long mask)                         { return __builtin_popcountll(mask); }
inline int LZERO(long long mask)                       { return 31 - __builtin_clzll(mask); };
inline int TZERO(long long mask)                       { return __builtin_ctzll(mask); };

//int dr[] = {+1, -1, +0, +0};                         // 4 Direction - DOWN, UP, RIGHT, LEFT
//int dc[] = {+0, +0, +1, -1};
int dr[] = {+0, +0, +1, -1, +1, +1, -1, -1};       // 8 Direction - RIGHT, LEFT, DOWN, UP, RIGHT-DOWN, LEFT-DOWN, UP-RIGHT, UP-LEFT
int dc[] = {+1, -1, +0, +0, +1, -1, +1, -1};
//int dr[] = {-1, +1, -2, -2, -1, +1, +2, +2};       // knight Moves
//int dc[] = {-2, -2, -1, +1, +2, +2, +1, -1};

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define ll              long long int
#define ull             unsigned long long int
#define endl            '\n'
#define pii             pair <int, int>
#define pll             pair <ll, ll>
#define mk              make_pair
#define ff              first
#define ss              second
#define all(a)          (a).begin(), (a).end()
#define rall(a)         (a).rbegin(), (a).rend()
#define eb              emplace_back
#define pb              push_back
#define pf              push_front
#define allUpper(a)     transform(all(a), a.begin(), :: toupper)
#define allLower(a)     transform(all(a), a.begin(), :: tolower)
#define LINE            cerr << __LINE__ << " ";
#define memo(a, b)      memset(a, b, sizeof a)
#define ook             order_of_key
#define fbo             find_by_order

#define int             long long int

static const int maxn = 2e5 + 5;
static const int logn = 19;
static const long long MOD = 1e9 + 7;
static const long long INF = 1e18;

void no() {
      cout << -1 << endl;
      exit(0);
}

signed main()
{
      ios_base::sync_with_stdio(false);
      cin.tie(nullptr);
      cout.precision(12);

      #ifndef ONLINE_JUDGE
          freopen("in.txt", "r", stdin);
      #endif // ONLINE_JUDGE

      int n, m;
      cin >> n >> m;
      deque <pii> alive;
      deque <pii> dead;
      for (int e = 1; e <= m; e++) {
            int w, t;
            cin >> w >> t;
            if (t == 1) {
                  alive.emplace_back(w, e);
            }
            else {
                  dead.emplace_back(w, e);
            }
      }
      sort(all(alive));
      sort(all(dead));
      vector <pii> graph(m + 1);
      vector <int> asign(n + 1);
      for (int i = 0; i < alive.size(); i++) {
            int u = 1;
            int v = i + 2;
            int w = alive[i].first;
            int id = alive[i].second;
            graph[id] = mk(u, v);
            debug(u, v, w);
            asign[v] = w;
      }
      int last = 2;
      multiset <pii> ms;
      for (auto it : dead) {
            ms.insert(it);
      }
      while (last < n and ms.size()) {
            int u = last;
            int v = u + 1;
            while (v <= n and ms.size()) {
                  int myw = asign[v];
                  auto lb = ms.lower_bound(mk(myw, -1));
                  if (lb == ms.end()) {
                        break;
                  }
                  int w = (*lb).ff;
                  int id = (*lb).ss;
                  graph[id] = mk(u, v);
                  ms.erase(lb);
                  u++;
                  v++;
            }
            last++;
      }
      if (ms.size()) {
            no();
      }
      for (int i = 1; i <= m; i++) {
            cout << graph[i].first << " " << graph[i].second << endl;
      }

      #ifndef ONLINE_JUDGE
            cerr << endl << "Time : " << 1.0 * clock() / CLOCKS_PER_SEC << " s." << endl;
      #endif // ONLINE_JUDGE

      return 0;
}


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

struct st {
	int len, type, num;
};

int n, m;
vector<st> arr;
vector<pair<int, int> > ans;

bool cmp(const st &a, const st &b) {
	return (a.len != b.len) ? a.len < b.len : a.type > b.type;
}

void solve() {
	int y = 2,
		from = 2,
		to = 3;
	for(int i = 0; i < m; ++i) {
		if(arr[i].type == 1) {
			ans[arr[i].num].first = 1;
			ans[arr[i].num].second = y++;
		} else if((y > 3) && (to < y)) {
			ans[arr[i].num].first = from;
			ans[arr[i].num].second = to;
			++from;
			if(from == to) {
				++to;
			}
		} else {
			printf("-1");
			exit(0);
		}
	}
}

int main (int argc, char *argv[])
{
	scanf("%d%d", &n, &m);
	arr.resize(m);
	for(int i = 0; i < m; ++i) {
		scanf("%d%d", &arr[i].len, &arr[i].type);
		arr[i].num = i;
	}
	ans.resize(m);
	sort(arr.begin(), arr.end(), cmp);
	solve();
	for(int i = 0; i < m; ++i) {
		printf("%d %d\n", ans[i].first, ans[i].second);
	}

	return 0;
}


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

struct st {
	int len, type, num;
};

int n, m;
vector<st> arr;
vector<pair<int, int> > ans;

bool cmp(const st &a, const st &b) {
	return (a.len != b.len) ? a.len < b.len : a.type > b.type;
}

void solve() {
	int y = 2,
		from = 2,
		to = 3;
	for(int i = 0; i < m; ++i) {
		if(arr[i].type == 1) {
			ans[arr[i].num].first = 1;
			ans[arr[i].num].second = y++;
		} else if((y > 3) && (to < y)) {
			ans[arr[i].num].first = from;
			ans[arr[i].num].second = to;
			++from;
			if(from == to) {
				++to;
				from = 2;
			}
		} else {
			printf("-1");
			exit(0);
		}
	}
}

int main (int argc, char *argv[])
{
	scanf("%d%d", &n, &m);
	arr.resize(m);
	for(int i = 0; i < m; ++i) {
		scanf("%d%d", &arr[i].len, &arr[i].type);
		arr[i].num = i;
	}
	ans.resize(m);
	sort(arr.begin(), arr.end(), cmp);
	solve();
	for(int i = 0; i < m; ++i) {
		printf("%d %d\n", ans[i].first, ans[i].second);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
#define mem(a, b) memset(a, b, sizeof(a))
#define INF 0X3f3f3f3f
const ll MAXN = 100000 + 7;
const ll MOD = 1e9 + 7;
//-------------------------------------------//
struct pop
{
    int v,p,i;
}pos[MAXN];
bool cmp1(pop x,pop y)
{
    if(x.v==y.v)
    return x.p>y.p;
    return x.v<y.v;
}
queue<pop>s;
map<int,pop>mp;
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    int cnt=0;
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&pos[i].v,&pos[i].p);
        pos[i].i=i;
        if(pos[i].p==0)
        cnt++;
    }
    sort(pos+1,pos+1+m,cmp1);
    int now=1,flag=0;
    for(int i=1;i<=m;i++)
    {
        if(pos[i].p==0)
        {
            if(s.empty())
            {
                flag=1;
                break;
            }
            else
            {
                pop x=s.front();
                mp[pos[i].i].p=x.p;
                mp[pos[i].i].v=x.v;
                s.pop();
                cnt--;
            }
        }
        else
        {
            now++;
            if(now>n)
            {
                flag=1;
                break;
            }
            mp[pos[i].i].p=1;
            mp[pos[i].i].v=now;
            for(int j=2;j<now;j++)
            {
                pop x;
                x.p=j;
                x.v=now;
                s.push(x);
            }
            if(s.size()>cnt)
            {
                flag=1;
                break;
            }
        }
    }
    if(flag==1)
    printf("-1\n");
    else
    {
        for(int i=1;i<=m;i++)
        {
            printf("%d %d\n",mp[i].p,mp[i].v);
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
#define mem(a, b) memset(a, b, sizeof(a))
#define INF 0X3f3f3f3f
const ll MAXN = 100000 + 7;
const ll MOD = 1e9 + 7;
//-------------------------------------------//
struct pop
{
    int v, p, i;
} pos[MAXN];
bool cmp1(pop x, pop y)
{
    if (x.v == y.v)
        return x.p > y.p;
    return x.v < y.v;
}
queue<pop> s;
map<int, pop> mp;
int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    int cnt = 0;
    for (int i = 1; i <= m; i++)
    {
        scanf("%d %d", &pos[i].v, &pos[i].p);
        pos[i].i = i;
        if (pos[i].p == 0)
            cnt++;
    }
    sort(pos + 1, pos + 1 + m, cmp1);
    int now = 1, flag = 0;
    for (int i = 1; i <= m; i++)
    {
        if (pos[i].p == 0)
        {
            if (s.empty())
            {
                flag = 1;
                break;
            }
            else
            {
                pop x = s.front();
                mp[pos[i].i].p = x.p;
                mp[pos[i].i].v = x.v;
                s.pop();
                cnt--;
            }
        }
        else
        {
            now++;
            if (now > n)
            {
                flag = 1;
                break;
            }
            mp[pos[i].i].p = 1;
            mp[pos[i].i].v = now;
            for (int j = 2; j < now; j++)
            {
                if (s.size() > cnt)
                {
                    break;
                }
                pop x;
                x.p = j;
                x.v = now;
                s.push(x);
            }
        }
    }
    if (flag == 1)
        printf("-1\n");
    else
    {
        for (int i = 1; i <= m; i++)
        {
            printf("%d %d\n", mp[i].p, mp[i].v);
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
#define mem(a, b) memset(a, b, sizeof(a))
#define INF 0X3f3f3f3f
const ll MAXN = 100000 + 7;
const ll MOD = 1e9 + 7;
//-------------------------------------------//
struct pop
{
    int v,p,i;
}pos[MAXN],l[MAXN];
bool cmp1(pop x,pop y)
{
    if(x.v==y.v)
    return x.p>y.p;
    return x.v<y.v;
}
queue<pop>s;
map<int,pop>mp;
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    int cnt=0;
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&pos[i].v,&pos[i].p);
        pos[i].i=i;
        if(pos[i].p==0)
        cnt++;
    }
    sort(pos+1,pos+1+m,cmp1);
    int now=1,flag=0;
    for(int i=1;i<=m;i++)
    {
        if(pos[i].p==0)
        {
            if(s.empty())
            {
                flag=1;
                break;
            }
            else
            {
                pop x=s.front();
                mp[pos[i].i].p=x.p;
                mp[pos[i].i].v=x.v;
                s.pop();
                cnt--;
            }
        }
        else
        {
            now++;
            if(now>n)
            {
                flag=1;
                break;
            }
            mp[pos[i].i].p=1;
            mp[pos[i].i].v=now;
            for(int j=2;j<now;j++)
            {
                pop x;
                x.p=j;
                x.v=now;
                s.push(x);
            }
        }
    }
    if(flag==1)
    printf("-1\n");
    else
    {
        for(int i=1;i<=m;i++)
        {
            printf("%d %d\n",mp[i].p,mp[i].v);
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
#define mem(a, b) memset(a, b, sizeof(a))
#define INF 0X3f3f3f3f
const ll MAXN = 100000 + 7;
const ll MOD = 1e9 + 7;
//-------------------------------------------//
struct pop
{
    int v,p,i;
}pos[MAXN],l[MAXN];
bool cmp1(pop x,pop y)
{
    if(x.v==y.v)
    return x.p>y.p;
    return x.v<y.v;
}
queue<pop>s;
map<int,pop>mp;
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    int cnt=0;
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&pos[i].v,&pos[i].p);
        pos[i].i=i;
        if(pos[i].p==0)
        cnt++;
    }
    sort(pos+1,pos+1+m,cmp1);
    int now=1,flag=0;
    for(int i=1;i<=m;i++)
    {
        if(pos[i].p==0)
        {
            if(s.empty())
            {
                flag=1;
                break;
            }
            else
            {
                pop x=s.front();
                mp[pos[i].i].p=x.p;
                mp[pos[i].i].v=x.v;
                s.pop();
                cnt--;
            }
        }
        else
        {
            now++;
            if(now>n)
            {
                flag=1;
                break;
            }
            mp[pos[i].i].p=1;
            mp[pos[i].i].v=now;
            for(int j=1;j<now;j++)
            {
                pop x;
                x.p=j;
                x.v=now;
                s.push(x);
            }
        }
    }
    if(flag==1)
    printf("-1\n");
    else
    {
        for(int i=1;i<=m;i++)
        {
            printf("%d %d\n",mp[i].p,mp[i].v);
        }
    }
}


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

const int N = 700;
int taken[N][N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

bool operator< (const edge &a, const edge &b) {
    if (a.w == b.w) return a.inc > b.inc;
    return a.w < b.w;
}

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            taken[cstep][cstep + 1] = 1;
            cstep++;
        }
        else {
            int f = -1, t = -1;
            for (int x = 1; x <= cstep; x++) {
                for (int y = 1; y < x - 1; y++) {
                    if (!taken[x][y]) f = x, t = y;
                }
            }
            if (f != -1) taken[f][t] = 1, V[i.i] = {f, t};
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


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

const int N = 700;
int taken[N][N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

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

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            taken[cstep][cstep + 1] = 1;
            cstep++;
        }
        else {
            int f = -1, t = -1;
            for (int x = 1; x <= cstep; x++) {
                for (int y = 1; y < x - 1; y++) {
                    if (!taken[x][y]) f = x, t = y;
                }
            }
            if (f != -1) taken[f][t] = 1, V[i.i] = {f, t};
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


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

const int N = 700;
int taken[N][N], d[N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

bool operator< (const edge &a, const edge &b) {
    if (a.w == b.w) return a.inc > b.inc;
    return a.w < b.w;
}

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    for (int i = 0; i < 700; i++) d[i] = i - 1;
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            taken[cstep][cstep + 1] = 1;
            cstep++;
        }
        else {
            int f = -1, t = -1;
            for (int x = 1; x <= min(699ll, cstep); x++) {
                if (!d[x]) continue;
                for (int y = 1; y < x - 1; y++) {
                    if (!taken[x][y]) {
                        f = x, t = y;
                        break;
                    }
                }
            }
            if (f != -1) taken[f][t] = 1, d[f]--, V[i.i] = {f, t};
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


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

const int N = 700;
int taken[N][N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

bool operator< (const edge &a, const edge &b) {
    if (a.w == b.w) return a.inc > b.inc;
    return a.w < b.w;
}

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            cstep++;
        }
        else {
            int f = -1, t = -1;
            for (int x = 1; x <= min(699ll, cstep); x++) {
                for (int y = 1; y < x - 1; y++) {
                    if (!taken[x][y]) {
                        f = x, t = y;
                        break;
                    }
                }
            }
            if (f != -1) taken[f][t] = 1, V[i.i] = {f, t};
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


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

const int N = 700;
int taken[N][N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

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

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            taken[cstep][cstep + 1] = 1;
            cstep++;
        }
        else {
            int f = -1, t = -1;
            for (int x = 1; x <= cstep; x++) {
                for (int y = 1; y < x; y++) {
                    if (!taken[x][y]) f = x, t = y;
                }
            }
            if (f != -1) taken[f][t] = 1, V[i.i] = {f, t};
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


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

const int N = 700;
int taken[N][N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

bool operator< (const edge &a, const edge &b) {
    if (a.w == b.w) return a.inc > b.inc;
    return a.w < b.w;
}

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            taken[cstep][cstep + 1] = 1;
            cstep++;
        }
        else {
            int f = -1, t = -1;
            for (int x = 1; x <= min(699ll, cstep); x++) {
                for (int y = 1; y < x - 1; y++) {
                    if (!taken[x][y]) f = x, t = y;
                }
            }
            if (f != -1) taken[f][t] = 1, V[i.i] = {f, t};
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


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

const int N = 700;
int taken[N][N], d[N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

bool operator< (const edge &a, const edge &b) {
    if (a.w == b.w) return a.inc > b.inc;
    return a.w < b.w;
}

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    for (int i = 0; i < 700; i++) d[i] = i - 1;
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            cstep++;
        }
        else {
            int f = -1, t = -1;
            for (int x = 1; x <= min(699ll, cstep); x++) {
                if (!d[x]) continue;
                for (int y = 1; y < x - 1; y++) {
                    if (!taken[x][y]) {
                        f = x, t = y;
                        break;
                    }
                }
            }
            if (f != -1) taken[f][t] = 1, d[f]--, V[i.i] = {f, t};
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


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

const int N = 700;
int taken[N][N], d[N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

bool operator< (const edge &a, const edge &b) {
    if (a.w == b.w) return a.inc > b.inc;
    return a.w < b.w;
}

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    set<pair<int, int>> S;
    for (int i = 1; i < 700; i++) {
        for (int j = 1; j < i - 1; j++) S.insert({i, j});
    };
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            cstep++;
        }
        else {
            pair<int,int> cur = *S.begin();
            if (cur.first <= cstep) V[i.i] = cur, S.erase(cur);
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


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

const int N = 700;
int taken[N][N], d[N];

struct edge {
    int w = 0, inc = 0, i = 0;
};

bool operator< (const edge &a, const edge &b) {
    if (a.w == b.w) return a.inc > b.inc;
    return a.w < b.w;
}

pair<int, int> V[400000];

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<edge> v;
    set<pair<int, int>> S;
    for (int i = 1; i < 700; i++) {
        for (int j = 1; j < i - 1; j++) S.insert({i, j});
    };
    for (int i = 0; i < m; i++) {
        int w, inc;
        cin >> w >> inc;
        v.push_back({w, inc, i});
    }
    sort(v.begin(), v.end());
    int cstep = 1;
    for (auto i : v) {
        if (i.inc) {
            V[i.i] = {cstep, cstep + 1};
            taken[cstep][cstep + 1] = 1;
            cstep++;
        }
        else {
            pair<int,int> cur = *S.begin();
            if (cur.first <= cstep) V[i.i] = cur, S.erase(cur);
            else {
                cout << -1;
                return 0;
            }
        }
    }
    for (int i = 0; i < m; i++) cout << V[i].first << " " << V[i].second << "\n";
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define foreach(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define in(A, B, C) assert( B <= A && A <= C)
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}
vpr yes,no;
vector<vpr> g(ee5);
int n;
int ok[ee5];

pr ans[ee5];

void go()
{
	int index=0;
	queue<pr>q;
	q.push(mp(0,n-1));
	while(!q.empty())
	{
		pr x=q.front();
		q.pop();
		int mid=(x.ff+x.ss)/2;
		g[mid].pb(mp(mid+1,yes[index].ff));
		ans[yes[index].ss]=mp(mid,mid+1);
		ok[mid]=yes[index].ff;
		g[mid+1].pb(mp(mid,yes[index].ff));
		index++;
		if(x.ff<mid)
		q.push(mp(x.ff,mid));
		if(x.ss>mid+1)
		q.push(mp(mid+1,x.ss));
	}
}

bool solve()
{
	if(no.size()==0)return 1;
	int index=0;
	queue<pr>q;
	q.push(mp(0,n-1));
	while(!q.empty())
	{
		int low=q.front().ff;
		int high=q.front().ss;
		q.pop();
		int mid=(low+high)/2;

		if(ok[mid]>no[index].ff)return 0;

		for(int st=low;st<=mid;st++)
		{
			for(int en=mid+1;en<=high;en++)
			{
				if(st==mid and en==mid+1)continue;
				if(index==no.size())return 1;
				g[st].pb(mp(en,no[index].ff));
				g[en].pb(mp(st,no[index].ff));
				ans[no[index].ss]=mp(st,en);
				index++;

			}
		}
		if(mid>low)
		q.push(mp(low,mid));
		if(high>mid+1)
		q.push(mp(mid+1,high));
	}

}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;cin>>n>>m;
	rep(i,m)
	{int aj,bj;cin>>aj>>bj;if(bj==1)yes.pb(mp(aj,i));else no.pb(mp(aj,i));}

	sort(all(no));sort(all(yes));
	go();

/*
	rep(i,n){
	cout<<i<<" ";
	rep(j,g[i].size())
		cout<<g[i][j].ff<<":"<<g[i][j].ss<<" ";cout<<"\n";}
*/
	if(!solve())
		{cout<<"-1";return 0;}

	rep(i,m)
	{
		cout<<ans[i].ff+1<<" "<<ans[i].ss+1<<"\n";
	}

}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define foreach(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define in(A, B, C) assert( B <= A && A <= C)
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}
vpr yes,no;
vector<vpr> g(ee5);
int n;
int ok[ee5];

pr ans[ee5];

void go()
{
	int index=0;
	queue<pr>q;
	q.push(mp(0,n-1));
	while(!q.empty())
	{
		pr x=q.front();
		q.pop();
		int mid=(x.ff+x.ss)/2;
		g[mid].pb(mp(mid+1,yes[index].ff));
		ans[yes[index].ss]=mp(mid,mid+1);
		ok[mid]=yes[index].ff;
		g[mid+1].pb(mp(mid,yes[index].ff));
		index++;
		if(x.ff<mid)
		q.push(mp(x.ff,mid));
		if(x.ss>mid+1)
		q.push(mp(mid+1,x.ss));
	}
}

bool solve()
{
	int index=0;
	queue<pr>q;
	q.push(mp(0,n-1));
	while(!q.empty())
	{
		int low=q.front().ff;
		int high=q.front().ss;
		q.pop();
		int mid=(low+high)/2;

		if(ok[mid]>no[index].ff)return 0;

		for(int st=low;st<=mid;st++)
		{
			for(int en=mid+1;en<=high;en++)
			{
				if(st==mid and en==mid+1)continue;
				if(index==no.size())return 1;
				g[st].pb(mp(en,no[index].ff));
				g[en].pb(mp(st,no[index].ff));
				ans[no[index].ss]=mp(st,en);
				index++;

			}
		}
		if(mid>low)
		q.push(mp(low,mid));
		if(high>mid+1)
		q.push(mp(mid+1,high));
	}

}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;cin>>n>>m;
	rep(i,m)
	{int aj,bj;cin>>aj>>bj;if(bj==1)yes.pb(mp(aj,i));else no.pb(mp(aj,i));}

	sort(all(no));sort(all(yes));
	go();

/*
	rep(i,n){
	cout<<i<<" ";
	rep(j,g[i].size())
		cout<<g[i][j].ff<<":"<<g[i][j].ss<<" ";cout<<"\n";}
*/
	if(!solve())
		{cout<<"-1";return 0;}

	rep(i,m)
	{
		cout<<ans[i].ff+1<<" "<<ans[i].ss+1<<"\n";
	}

}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define foreach(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define in(A, B, C) assert( B <= A && A <= C)
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}
vpr yes,no;

ll n;
pr ans[ee5];
ll go[ee5];

bool solve()
{
	ll index=0;
	for(ll st=0;st<n-2;st++)
	{
		ll maxi=max(go[st],go[st+1]);
		for(ll en=st+2;en<n;en++)
		{
			if(index==no.size())return 1;
			if(maxi<=no[index].ff)
				{ans[no[index].ss]=mp(st,en);
				index++;}
			else break;
			maxi=max(maxi,go[en]);

		}
	}
	if(no.size()==0 or index==no.size())return 1;
	return 0;

}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	ll m;cin>>n>>m;
	rep(i,m)
	{ll aj,bj;cin>>aj>>bj;if(bj==1)yes.pb(mp(aj,i));else no.pb(mp(aj,i));}

	sort(all(no));sort(all(yes));

	for(ll i=0;i<n-1;i++){

		go[i]=yes[i].ff;
		ans[yes[i].ss]=mp(i,i+1);
	}

	if(solve()==0)cout<<"-1";
	else{
		rep(i,m)cout<<ans[i].ff+1<<" "<<ans[i].ss+1<<"\n";
	}

}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define foreach(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define in(A, B, C) assert( B <= A && A <= C)
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}
vpr yes,no;

ll n;
pr ans[ee5];
ll go[ee5];

bool solve()
{
	ll index=0;
	for(ll st=0;st<n-2;st++)
	{
		ll maxi=max(go[st],go[st+1]);
		for(ll en=st+2;en<n;en++)
		{
			if(index==no.size())return 1;
			if(maxi<=no[index].ff)
				{ans[no[index].ss]=mp(st,en);
				index++;}
			else break;
			maxi=max(maxi,go[en]);

		}
	}
	return 0;

}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	ll m;cin>>n>>m;
	rep(i,m)
	{ll aj,bj;cin>>aj>>bj;if(bj==1)yes.pb(mp(aj,i));else no.pb(mp(aj,i));}

	sort(all(no));sort(all(yes));

	for(ll i=0;i<n-1;i++){

		go[i]=yes[i].ff;
		ans[yes[i].ss]=mp(i,i+1);
	}

	if(solve()==0)cout<<"-1";
	else{
		rep(i,m)cout<<ans[i].ff+1<<" "<<ans[i].ss+1<<"\n";
	}

}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define foreach(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define in(A, B, C) assert( B <= A && A <= C)
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}
vpr yes,no;

int n;
pr ans[ee5];
int go[ee5];

bool solve()
{
	ll index=0;
	for(ll st=0;st<n-2;st++)
	{
		ll maxi=max(go[st],go[st+1]);
		for(ll en=st+2;en<n;en++)
		{
			if(index==no.size())return 1;
			if(maxi<=no[index].ff)
				{ans[no[index].ss]=mp(st,en);
				index++;}
			else break;
			maxi=max(maxi,no[en].ff);

		}
	}
	return 0;

}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	ll m;cin>>n>>m;
	rep(i,m)
	{ll aj,bj;cin>>aj>>bj;if(bj==1)yes.pb(mp(aj,i));else no.pb(mp(aj,i));}

	sort(all(no));sort(all(yes));

	for(ll i=0;i<n-1;i++){

		go[i]=yes[i].ff;
		ans[yes[i].ss]=mp(i,i+1);
	}

	if(solve()==0)cout<<"-1";
	else{
		rep(i,m)cout<<ans[i].ff+1<<" "<<ans[i].ss+1<<"\n";
	}

}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define foreach(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define in(A, B, C) assert( B <= A && A <= C)
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}
vpr yes,no;
vector<vpr> g(ee5);
int n;
pr ans[ee5];
int go[ee5];

bool solve()
{

	ll index=0;
	for(ll st=0;st<n-2;st++)
	{
		ll maxi=max(go[st],go[st+1]);
		for(ll en=st+2;en<n;en++)
		{
			if(index==no.size())return 1;
			if(maxi<=no[index].ff)
				{ans[no[index].ss]=mp(st,en);
				index++;}
			else break;
			maxi=max(maxi,no[en].ff);

		}
	}
	return 0;

}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	ll m;cin>>n>>m;
	rep(i,m)
	{ll aj,bj;cin>>aj>>bj;if(bj==1)yes.pb(mp(aj,i));else no.pb(mp(aj,i));}

	sort(all(no));sort(all(yes));

	for(ll i=0;i<n-1;i++){

		go[i]=yes[i].ff;
		ans[yes[i].ss]=mp(i,i+1);
	}

	if(!solve())cout<<"-1";
	else{
		rep(i,m)cout<<ans[i].ff+1<<" "<<ans[i].ss+1<<"\n";
	}

}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define foreach(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define in(A, B, C) assert( B <= A && A <= C)
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}
vpr yes,no;

ll n;
pr ans[ee5];
ll go[ee5];

bool solve()
{
	ll index=0;
	for(ll st=0;st<n-2;st++)
	{
		ll maxi=max(go[st],go[st+1]);
		for(ll en=st+2;en<n;en++)
		{
			if(index==no.size())return 1;
			if(maxi<=no[index].ff)
				{ans[no[index].ss]=mp(st,en);
				index++;}
			else break;
			maxi=max(maxi,go[en]);

		}
	}
	if(no.size()==0)return 1;
	return 0;

}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	ll m;cin>>n>>m;
	rep(i,m)
	{ll aj,bj;cin>>aj>>bj;if(bj==1)yes.pb(mp(aj,i));else no.pb(mp(aj,i));}

	sort(all(no));sort(all(yes));

	for(ll i=0;i<n-1;i++){

		go[i]=yes[i].ff;
		ans[yes[i].ss]=mp(i,i+1);
	}

	if(solve()==0)cout<<"-1";
	else{
		rep(i,m)cout<<ans[i].ff+1<<" "<<ans[i].ss+1<<"\n";
	}

}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define foreach(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define in(A, B, C) assert( B <= A && A <= C)
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}
vpr yes,no;

ll n;
pr ans[ee5];
ll go[ee5];

bool solve()
{
	ll index=0;

	for(int en=2;en<n;en++)
	{
		ll maxi=go[en-1];
		for(int st=en-2;st>=0;st--)
		{
			maxi=max(maxi,go[st]);
			if(index==no.size())return 1;
			if(maxi<=no[index].ff)
				{ans[no[index].ss]=mp(st,en);
				index++;}
			else break;

		}
	}
/*

	//not the correct way to check possibilities
	for(ll st=0;st<n-2;st++)
	{
		ll maxi=max(go[st],go[st+1]);
		for(ll en=st+2;en<n;en++)
		{
			cout<<no[index].ff<<" ";
			if(index==no.size())return 1;
			if(maxi<=no[index].ff)
				{ans[no[index].ss]=mp(st,en);
				index++;}
			else break;
			maxi=max(maxi,go[en]);

		}
	}
	*/
	if(no.size()==0 or index==no.size())return 1;
	return 0;

}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	ll m;cin>>n>>m;
	rep(i,m)
	{ll aj,bj;cin>>aj>>bj;if(bj==1)yes.pb(mp(aj,i));else no.pb(mp(aj,i));}

	sort(all(no));sort(all(yes));

	for(ll i=0;i<n-1;i++){

		go[i]=yes[i].ff;
		ans[yes[i].ss]=mp(i,i+1);
	}/*
	rep(i,n-1)
	cout<<i<<" "<<go[i]<<"\n";*/

	if(solve()==0)cout<<"-1";
	else{
		rep(i,m)cout<<ans[i].ff+1<<" "<<ans[i].ss+1<<"\n";
	}

}


#include <bits/stdc++.h>
#define N 100050
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;

int n, m, q, k, v[N], grau[N], MST[N], imp;

int L[N], R[N];

vector<pair<pii, int> > A, en;

int pai[N], peso[N];

set<pii> ss;

int x = 2, y = 2, z = 2;

int find(int x)
{
	if(x == pai[x]) return x;

	return pai[x] = find(pai[x]);
}

bool join(int a, int b)
{
	a = find(a);

	b = find(b);

	if(a == b) return false;

	if(peso[a] > peso[b]) swap(a,b);

	pai[a] = b;

	if(peso[a] == peso[b]) peso[b] ++;

	return true;
}

int32_t main()
{
	ios::sync_with_stdio(false); cin.tie(0);

	cin>>n>>m;

	for(int i = 1; i <= n; i++) pai[i] = i;

	for(int i = 1, a, b; i <= m; i++)
	{
		cin>>a>>b;

		A.push_back({{a, -b}, i});

		if(b) MST[i] = 1;
	}

	sort(A.begin(), A.end());

	for(int i = 0; i < (int)A.size(); i++)
	{
		//cout<<i<<" "<<imp<<"\n";

		A[i].f.s *= -1;

		if(A[i].f.s)
		{
			L[A[i].s] = 1;

			R[A[i].s] = x;

			bool T = join(1, x);

			if(T and !MST[A[i].s]) imp = 1;

			if(!T and MST[A[i].s]) imp = 1;

		//	cout<<"edge "<<x<<" "<<x + 1<<"\n";

			x ++;
		}

		else
		{
			if(z == y) z = 2, y ++;

			L[A[i].s] = z;

			R[A[i].s] = y;

			bool T = join(z, y);

			if(T and !MST[A[i].s]) imp = 1;

			if(!T and MST[A[i].s]) imp = 1;

			z ++;
		}

	//	cout<<"end = "<<imp<<"\n";
	}

	if(imp) cout<<"-1\n";

	else
		for(int i = 1; i <= m; i++) cout<<L[i]<<" "<<R[i]<<"\n";
}


#include <map>
#include <unordered_map>
#include <set>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <bitset>
#define PI acos(-1.0)
#define INF 1e6
#define llINF 923372036854775807
#define EPS 1e-9
#define sz(v)        static_cast<int>((v).size())
#define pb(...)      push_back(__VA_ARGS__)
#define mp(x, y)     make_pair((x), (y))
#define clr(x) memset(x, 0, sizeof(x))
#define clr1(x) memset(x, INF, sizeof(x))
#define dREP(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define DFS_WHITE -1
#define DFS_BLACK 1
#define DFS_GRAY 2
#define NOT(x)  (1^(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef vector<vi> Graph;
typedef map<int, int>::iterator it_type;
typedef vector<int> row;
typedef vector<row> matrix;
int MOD  = 1000000007;
inline int toInt(string s){int v; istringstream sin(s);sin>>v;return v;}
inline ll toll(string s){ll v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) { ostringstream sout; sout << x; return sout.str();}
#define rep(i, v) for(int i=0;i<sz(v);++i)
#define MAX 100002
#define LSOne(S) (S & (-S))

struct edge{
    int cost,in,i,u,v;
};

bool cmp(edge f,edge s){
    return f.cost < s.cost;
}
bool cmp2(edge f,edge s){
    return f.i < s.i;
}
bool done[MAX];
int main() {
    ios_base::sync_with_stdio(0);cin.tie(0);
    //freopen("grant.in" , "r", stdin);
    //freopen("grant.out" , "w", stdout);
    int n,m;
    cin>>n>>m;
    vector<edge> v(m);
    for(int i = 0 ; i < m ; i++){
        cin>>v[i].cost>>v[i].in;
        v[i].i = i;
    }
    sort(v.begin(), v.end(), cmp);
    int available = 0;
    int lastConnected = 1;
    int needTo = 2;
    for(int i = 0 ; i < m ; i++){
        if (!v[i].in) {
            if (available > 0) {
                available --;
            }else{
                cout<<-1<<endl;
                return 0;
            }
        }else{
            v[i].u = lastConnected;
            v[i].v = needTo;
            available += (needTo - 2);
            lastConnected = needTo;
            needTo ++;
            done[i] = 1;
        }
    }
    int u = 1;
    int vv = u + 2;
    for(int i = 0 ; i < m ; i++){
        if (!done[i]) {
            v[i].u = u;
            v[i].v = vv;
            vv++;
            if (vv == n+1) {
                u ++;
                vv = u+2;
            }
        }
    }
    sort(v.begin(), v.end(), cmp2);
    for(int i = 0 ; i < m ; i++){
        cout<<v[i].u<<" "<<v[i].v<<"\n";
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n;
pair<int,int>a[200200];

bool cmp(pair<int,int>x,pair<int,int>y){
  return x.second-x.first<y.second-y.first;
}

int main() {
  #ifdef LOCAL
  freopen("in", "r", stdin);
  #endif

  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>a[i].second>>a[i].first;
  }
  sort(a+1,a+n+1);
  int ans=1;
  for(int l=1;l<=n/3;l++){
    long long sum=0;
    int mx=l,mn=l;
    int c=0;
    for(int r=l;r<=n;r++){
      if(a[r].second>a[mx].second)mx=r;
      if(a[r].second<a[mn].second)mn=r;
      sum+=a[r].first*2;
      if(a[mx].second-a[mn].second>=sum-a[mx].first-a[mn].first)
        ++c;
      else break;
    }
    ans=max(ans,c);
  }
  cout<<ans;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n;
pair<int,int>a[200200];

int main() {
  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>a[i].second>>a[i].first;
  }
  sort(a+1,a+n+1);
  int ans=0;
  for(int i=1;i<=n;i++) {
    bool ok=1;
    for(int j=1;j<i;j++){
      ok&=(abs(a[i].second-a[j].second)>=a[i].first+a[j].first);
    }
    if (ok) ++ans;
  }
  cout<<ans;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n;
pair<int,int>a[200200];

int main() {
  #ifdef LOCAL
  freopen("in", "r", stdin);
  #endif

  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>a[i].second>>a[i].first;
  }
  sort(a+1,a+n+1);
  int ans=1,cur=1;
  long long sum=a[1].first*2;
  int minid=1,maxid=1;
  for(int i=2;i<=n;i++) {
    sum+=a[i].first*2;
    int oldmi=minid,oldmx=maxid;
    if(a[i].second<a[minid].second)minid=i;
    if(a[i].second>a[maxid].second)maxid=i;
    bool ok=(a[maxid].second-a[minid].second>=sum-a[maxid].first-a[minid].first);
    if (ok) ++cur;
    else {
      sum-=a[i].first*2;
      minid=oldmi;
      maxid=oldmx;
    }
    ans=max(ans,cur);
  }
  ans=max(ans,cur);
  cout<<ans;
  return 0;
}


#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std ;

typedef long long LL ;

#define rep( i , a , b ) for ( int i = ( a ) ; i <  ( b ) ; ++ i )
#define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define clr( a , x ) memset ( a , x , sizeof a )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
#define root 1 , 1 , n
#define mid ( ( l + r ) >> 1 )

const int MAXN = 200005 ;

struct Node {
	int x , y ;
	Node () {}
	Node ( int x , int y ) : x ( x ) , y ( y ) {}
	bool operator < ( const Node& a ) const {
		return y < a.y ;
	}
} ;

Node a[MAXN] ;
int dp[MAXN] , pre[MAXN] ;
int maxv[MAXN << 2] ;
int n ;

int search ( int x , int l = 1 , int r = n ) {
	while ( l < r ) {
		int m = ( l + r + 1 ) >> 1 ;
		if ( a[m].x <= x ) l = m ;
		else r = m - 1 ;
	}
	return l ;
}

void update ( int x , int v , int o , int l , int r ) {
	if ( l == r ) {
		maxv[o] = v ;
		return ;
	}
	int m = mid ;
	if ( x <= m ) update ( x , v , lson ) ;
	else update ( x , v , rson ) ;
	maxv[o] = max ( maxv[ls] , maxv[rs] ) ;
}

int query ( int L , int R , int o , int l , int r ) {
	if ( L <= l && r <= R ) return maxv[o] ;
	int m = mid ;
	if ( R <= m ) return query ( L , R , lson ) ;
	if ( m <  L ) return query ( L , R , rson ) ;
	return max ( query ( L , R , lson ) , query ( L , R , rson ) ) ;
}

void solve () {
	int x , w ;
	int ans = 1 ;
	clr ( pre , 0 ) ;
	clr ( maxv , 0 ) ;
	For ( i , 1 , n ) {
		scanf ( "%d%d" , &x , &w ) ;
		a[i] = Node ( x + w , x - w ) ;
	}
	sort ( a + 1 , a + n + 1 ) ;
	For ( i , 1 , n ) {
		int j = search ( a[i].y ) ;
		if ( a[j].x <= a[i].y ) {
			dp[i] = query ( 1 , j , root ) + 1 ;
			ans = max ( ans , dp[i] ) ;
			update ( i , dp[i] , root ) ;
		} else update ( i , 1 , root ) ;
	}
	printf ( "%d\n" , ans ) ;
}

int main () {
	while ( ~scanf ( "%d" , &n ) ) solve () ;
	return 0 ;
}


#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std ;

typedef long long LL ;

#define rep( i , a , b ) for ( int i = ( a ) ; i <  ( b ) ; ++ i )
#define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 200005 ;

struct Node {
	int x , y ;
	Node () {}
	Node ( int x , int y ) : x ( x ) , y ( y ) {}
	bool operator < ( const Node& a ) const {
		return y < a.y ;
	}
} ;

Node a[MAXN] , b[MAXN] ;
int dp[MAXN] , pre[MAXN] ;
int n ;

int search ( int x , int l = 1 , int r = n ) {
	while ( l < r ) {
		int m = ( l + r ) >> 1 ;
		if ( a[m].y >= x ) r = m ;
		else l = m + 1 ;
	}
	return l ;
}

void solve () {
	int x , w ;
	clr ( dp , 0 ) ;
	clr ( pre , 0 ) ;
	For ( i , 1 , n ) {
		scanf ( "%d%d" , &x , &w ) ;
		a[i] = Node ( x + w , x - w ) ;
	}
	sort ( a + 1 , a + n + 1 ) ;
	For ( i , 1 , n ) {
		int j = search ( a[i].x ) ;
		if ( a[j].y >= a[i].x ) {
			pre[j] = i ;
		}
	}
	For ( i , 1 , n ) {
		dp[i] = dp[i - 1] ;
		if ( pre[pre[i]] ) dp[i] = max ( dp[i] , dp[pre[i]] + 1 ) ;
		if ( pre[i] ) dp[i] = max ( dp[i] , dp[pre[i] - 1] + 2 ) ;
	}
	printf ( "%d\n" , dp[n] ) ;
}

int main () {
	while ( ~scanf ( "%d" , &n ) ) solve () ;
	return 0 ;
}


#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std ;

typedef long long LL ;

#define rep( i , a , b ) for ( int i = ( a ) ; i <  ( b ) ; ++ i )
#define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define clr( a , x ) memset ( a , x , sizeof a )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
#define root 1 , 1 , n
#define mid ( ( l + r ) >> 1 )

const int MAXN = 200005 ;

struct Node {
	int x , y ;
	Node () {}
	Node ( int x , int y ) : x ( x ) , y ( y ) {}
	bool operator < ( const Node& a ) const {
		return x < a.x ;
	}
} ;

Node a[MAXN] ;
int dp[MAXN] , pre[MAXN] ;
int maxv[MAXN << 2] ;
int n ;

int search ( int x , int l = 1 , int r = n ) {
	while ( l < r ) {
		int m = ( l + r + 1 ) >> 1 ;
		if ( a[m].x <= x ) l = m ;
		else r = m - 1 ;
	}
	return l ;
}

void update ( int x , int v , int o , int l , int r ) {
	if ( l == r ) {
		maxv[o] = v ;
		return ;
	}
	int m = mid ;
	if ( x <= m ) update ( x , v , lson ) ;
	else update ( x , v , rson ) ;
	maxv[o] = max ( maxv[ls] , maxv[rs] ) ;
}

int query ( int L , int R , int o , int l , int r ) {
	if ( L <= l && r <= R ) return maxv[o] ;
	int m = mid ;
	if ( R <= m ) return query ( L , R , lson ) ;
	if ( m <  L ) return query ( L , R , rson ) ;
	return max ( query ( L , R , lson ) , query ( L , R , rson ) ) ;
}

void solve () {
	int x , w ;
	int ans = 1 ;
	clr ( pre , 0 ) ;
	clr ( maxv , 0 ) ;
	For ( i , 1 , n ) {
		scanf ( "%d%d" , &x , &w ) ;
		a[i] = Node ( x + w , x - w ) ;
	}
	sort ( a + 1 , a + n + 1 ) ;
	For ( i , 1 , n ) {
		int j = search ( a[i].y ) ;
		if ( a[j].x <= a[i].y ) {
			dp[i] = query ( 1 , j , root ) + 1 ;
			ans = max ( ans , dp[i] ) ;
			update ( i , dp[i] , root ) ;
		} else update ( i , 1 , root ) ;
	}
	printf ( "%d\n" , ans ) ;
}

int main () {
	while ( ~scanf ( "%d" , &n ) ) solve () ;
	return 0 ;
}


#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std ;

typedef long long LL ;

#define rep( i , a , b ) for ( int i = ( a ) ; i <  ( b ) ; ++ i )
#define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 200005 ;

struct Node {
	int x , y ;
	Node () {}
	Node ( int x , int y ) : x ( x ) , y ( y ) {}
	bool operator < ( const Node& a ) const {
		return y < a.y ;
	}
} ;

Node a[MAXN] , b[MAXN] ;
int dp[MAXN] , pre[MAXN] ;
int n ;

int search ( int x , int l = 1 , int r = n ) {
	while ( l < r ) {
		int m = ( l + r ) >> 1 ;
		if ( a[m].y >= x ) r = m ;
		else l = m + 1 ;
	}
	return l ;
}

void solve () {
	int x , w ;
	clr ( dp , 0 ) ;
	clr ( pre , 0 ) ;
	For ( i , 1 , n ) {
		scanf ( "%d%d" , &x , &w ) ;
		a[i] = Node ( x + w , x - w ) ;
	}
	sort ( a + 1 , a + n + 1 ) ;
	For ( i , 1 , n ) {
		int j = search ( a[i].x ) ;
		if ( a[j].y >= a[i].x ) {
			pre[j] = i ;
		}
	}
	For ( i , 1 , n ) {
		dp[i] = max ( dp[i - 1] , 1 ) ;
		if ( pre[pre[i]] ) dp[i] = max ( dp[i] , dp[pre[i]] + 1 ) ;
		if ( pre[i] ) dp[i] = max ( dp[i] , dp[pre[i] - 1] + 2 ) ;
	}
	printf ( "%d\n" , dp[n] ) ;
}

int main () {
	while ( ~scanf ( "%d" , &n ) ) solve () ;
	return 0 ;
}


#include <bits/stdc++.h>
using namespace std;
int a[200002];
pair<int, int> b[200002];
int main() {
  int n, k, max = 0;
  for (int i=0; i<200001; i++) {
    a[i] = 2147483647;
  }
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d %d", &b[i].first, &b[i].second);
  }
  sort(b, b + n);
  for (int i = 0; i < n; i++) {
    int d = b[i].first - b[i].second;
    int* c = upper_bound(a, a+max, d);
    int index = c-a;
    //printf("d = %d, index %d\n", d, index);
    if (index + 1 > max) {
      max = index + 1;
    }
    a[index] = min(a[index], b[i].first + b[i].second);
    /*k = b[i].first + b[i].second;
    //printf("pushing %d\n", k);
    c = upper_bound(a, a+max, k);
    index = c-a;
    a[index] = k;*/
  }
  printf("%d\n", max);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
int a[200002];
pair<int, int> b[200002];
int main() {
  int n, k, max = 0;
  for (int i=0; i<200001; i++) {
    a[i] = 2147483647;
  }
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d %d", &b[i].first, &b[i].second);
  }
  sort(b, b + n);
  for (int i = 0; i < n; i++) {
    int d = b[i].first - b[i].second;
    int* c = upper_bound(a, a+max, d);
    int index = c-a;
    //printf("d = %d, index %d\n", d, index);
    if (index + 1 > max) {
      max = index + 1;
    }
    k = b[i].first + b[i].second;
    //printf("pushing %d\n", k);
    c = lower_bound(a, a+max, k);
    index = c-a;
    a[index] = k;
  }
  printf("%d\n", max);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
int a[200002];
pair<int, int> b[200002];
int main() {
  int n, k, max = 0;
  for (int i=0; i<200001; i++) {
    a[i] = 2147483647;
  }
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d %d", &b[i].first, &b[i].second);
  }
  sort(b, b + n);
  for (int i = 0; i < n; i++) {
    int d = b[i].first - b[i].second;
    int* c = upper_bound(a, a+max, d);
    int index = c-a;
    //printf("d = %d, index %d\n", d, index);
    if (index + 1 > max) {
      max = index + 1;
    }
    k = b[i].first + b[i].second;
    //printf("pushing %d\n", k);
    c = upper_bound(a, a+max, k);
    index = c-a;
    a[index] = k;
  }
  printf("%d\n", max);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
int a[200002];
pair<int, int> b[200002];
int main() {
  int n, k, max = 0;
  for (int i=0; i<200001; i++) {
    a[i] = 2147483647;
  }
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d %d", &b[i].first, &b[i].second);
  }
  sort(b, b + n);
  for (int i = 0; i < n; i++) {
    k = b[i].first + b[i].second;
    int* c = lower_bound(a, a+max, k);
    int index = c-a;
    a[index] = k;
    if (index + 1 > max) {
      max = index + 1;
    }
  }
  printf("%d\n", max);
  return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct Point
{
    int l,r;
    bool operator < (struct Point t) const
    {
        return r > t.r;
    }
}p[200009];

int main()
{
    int n,x,y;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&x,&y);
            p[i].l = x - y;
            p[i].r = x + y;
        }
        sort(p,p+n);
        int mn = -99999999,ans = 0;
        for(int i=0; i<n; i++)
        {
            if(p[i].l>=mn)
            {
                mn=p[i].r;
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


/* DHUOJ solution #362345 @ 2018-08-13 21:11:45.737 */

#include <iostream>
#include <stdio.h>
#include <cstring>
#include<algorithm>
using namespace std;
const int NUM=2e5+10;
struct node
{
    int index,q;
    bool operator <(const node &a)const
    {
        return index+q<a.index+a.q;
    }
}no[NUM];
int main()
{
    int n;
    scanf("%d",&n);
    for (int i=0;i<n;i++)
        scanf("%d%d",&no[i].index,&no[i].q);
    sort(no,no+n);
    int ans=1,last=0;
    for (int i=1;i<n;i++)
    {
        if (no[i].index-no[i].q>=no[last].index+no[last].q)
        {
            last=i;
            ans++;
        }
    }
    printf("%d\n",ans);
    return 0;
}


/* DHUOJ solution #362345 @ 2018-08-13 20:19:48.048 */

#include <iostream>
#include <stdio.h>
#include <cstring>
#include<algorithm>
using namespace std;
const int NUM=2e5+10;
struct node
{
    int index,q;
    bool operator <(const node &a)const
    {
        return index+q<a.index+a.q;
    }
}no[NUM];
int main()
{
    int n;
    scanf("%d",&n);
    for (int i=0;i<n;i++)
        scanf("%d%d",&no[i].index,&no[i].q);
    sort(no,no+n);
    int ans=1,last=0;
    for (int i=1;i<n;i++)
    {
        if (no[i].index-no[i].q>=no[last].index+no[last].q)
        {
            last=i;
            ans++;
        }
    }
    printf("%d\n",ans);
    return 0;
}


/* DHUOJ solution #362345 @ 2018-08-13 20:56:12.919 */

#include <iostream>
#include <stdio.h>
#include <cstring>
#include<algorithm>
using namespace std;
const int NUM=2e5+10;
struct node
{
    int index,q;
    bool operator <(const node &a)const
    {
        return index+q<a.index+a.q;
    }
}no[NUM];
int main()
{
    int n;
    scanf("%d",&n);
    for (int i=0;i<n;i++)
        scanf("%d%d",&no[i].index,&no[i].q);
    sort(no,no+n);
    int ans=1,last=0;
    for (int i=1;i<n;i++)
    {
        if (no[i].index-no[i].q>=no[last].index+no[last].q)
        {
            last=i;
            ans++;
        }
    }
    printf("%d\n",ans);
    return 0;
}


/* DHUOJ solution #362405 @ 2018-08-14 00:17:33.766 */

#include <bits/stdc++.h>
#define ll int
using namespace std;
pair<ll,ll>p[200005];
int main()
{
	ll n,i,w,x,s=0,l=-(1<<31);
	cin>>n;
	for(i=0;i<n;i++)
		cin>>x>>w,p[i]=make_pair(x+w,x-w);
	sort(p,p+n);
	for(i=0;i<n;i++)
		if(p[i].second>=l)
			l=p[i].first,s++;
	cout<<s;
}


/* DHUOJ solution #362540 @ 2018-08-14 10:33:58.234 */

#include<bits/stdc++.h>
using namespace std;
const int Max=200010;
int n;
int ans,last;
struct node
{
    int pos;
    int w;
};
node p[Max],check[Max];
bool cmp(node a,node b)
{
    if(a.w==b.w)
    {
        return a.pos<b.pos;
    }
    return a.w<b.w;
}
int main()
{
    while(scanf("%d",&n)!=-1)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].pos,&p[i].w);
            check[i].pos=p[i].pos-p[i].w;
            check[i].w=p[i].pos+p[i].w;
        }
        sort(check+1,check+1+n,cmp);
        ans=0;
        last=-1e9;
        for(int i=1;i<=n;i++)
        {
            if(check[i].pos>=last)
            {
                last=check[i].w;
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


/* DHUOJ solution #362394 @ 2018-08-13 22:19:35.213 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll cg=1e9;
const int maxn=2e5+100;
struct Node
{
    int x,f;
    int op;
};
vector<Node> nodes;
map<ll,int> dp;
bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int main()
{
    int n,x,w,pre=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&w);
        Node temp1,temp2;
        temp1.x=x-w,temp1.f=-1;
        temp2.x=x+w,temp2.f=1,temp2.op=temp1.x;
        nodes.push_back(temp1),nodes.push_back(temp2);
    }
    sort(nodes.begin(),nodes.end(),cmp);
    dp[nodes[0].x+cg]=0;
    for(int i=1;i<nodes.size();i++)
    {
            dp[nodes[i].x+cg]=pre;
            if(nodes[i].f==1)
            dp[nodes[i].x+cg]=max(dp[nodes[i].x+cg],dp[nodes[i].op+cg]+1);
        pre=dp[nodes[i].x+cg];
    }
    printf("%d\n",dp[nodes[nodes.size()-1].x+cg]);
    return 0;
}


/* DHUOJ solution #362409 @ 2018-08-14 00:07:11.526 */

#include <bits/stdc++.h>
using namespace std;
pair<int,int> a[200005];
int main()
{
    int n,x,y;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x>>y;
        a[i].first=x+y;
        a[i].second=x-y;
    }
    sort(a,a+n);
    int l=1<<31;
    int ans=0;
    for(int i=0;i<n;i++)
        if(a[i].second>=l)
            l=a[i].first,ans++;
        cout<<ans<<endl;
}
/*
4 3 4
H 2
V 2
V 3
V 1
*/


/* DHUOJ solution #362409 @ 2018-08-14 00:57:18.657 */

#include <bits/stdc++.h>
using namespace std;
pair<int,int> a[200005];
int main()
{
    int n,x,y;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x>>y;
        a[i].first=x+y;
        a[i].second=x-y;
    }
    sort(a,a+n);
    int l=1<<31;
    int ans=0;
    for(int i=0;i<n;i++)
        if(a[i].second>=l)
            l=a[i].first,ans++;
        cout<<ans<<endl;
}
/*
4 3 4
H 2
V 2
V 3
V 1
*/


/* DHUOJ solution #362409 @ 2018-08-14 02:27:28.672 */

#include <bits/stdc++.h>
using namespace std;
pair<int,int> a[200005];
int main()
{
    int n,x,y;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x>>y;
        a[i].first=x+y;
        a[i].second=x-y;
    }
    sort(a,a+n);
    int l=1<<31;
    int ans=0;
    for(int i=0;i<n;i++)
        if(a[i].second>=l)
            l=a[i].first,ans++;
        cout<<ans<<endl;
}
/*
4 3 4
H 2
V 2
V 3
V 1
*/


/* DHUOJ solution #362409 @ 2018-08-13 22:04:01.858 */

#include <bits/stdc++.h>
using namespace std;
pair<int,int> a[200005];
int main()
{
    int n,x,y;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x>>y;
        a[i].first=x+y;
        a[i].second=x-y;
    }
    sort(a,a+n);
    int l=1<<31;
    int ans=0;
    for(int i=0;i<n;i++)
        if(a[i].second>=l)
            l=a[i].first,ans++;
        cout<<ans<<endl;
}
/*
4 3 4
H 2
V 2
V 3
V 1
*/


/* DHUOJ solution #362394 @ 2018-08-13 23:12:46.971 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll cg=1e9;
const int maxn=2e5+100;
struct Node
{
    int x,f;
    int op;
};
vector<Node> nodes;
map<ll,int> dp;
bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int main()
{
    int n,x,w,pre=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&w);
        Node temp1,temp2;
        temp1.x=x-w,temp1.f=-1;
        temp2.x=x+w,temp2.f=1,temp2.op=temp1.x;
        nodes.push_back(temp1),nodes.push_back(temp2);
    }
    sort(nodes.begin(),nodes.end(),cmp);
    dp[nodes[0].x+cg]=0;
    for(int i=1;i<nodes.size();i++)
    {
            dp[nodes[i].x+cg]=pre;
            if(nodes[i].f==1)
            dp[nodes[i].x+cg]=max(dp[nodes[i].x+cg],dp[nodes[i].op+cg]+1);
        pre=dp[nodes[i].x+cg];
    }
    printf("%d\n",dp[nodes[nodes.size()-1].x+cg]);
    return 0;
}


/* DHUOJ solution #362394 @ 2018-08-14 00:12:23.574 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll cg=1e9;
const int maxn=2e5+100;
struct Node
{
    int x,f;
    int op;
};
vector<Node> nodes;
map<ll,int> dp;
bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int main()
{
    int n,x,w,pre=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&w);
        Node temp1,temp2;
        temp1.x=x-w,temp1.f=-1;
        temp2.x=x+w,temp2.f=1,temp2.op=temp1.x;
        nodes.push_back(temp1),nodes.push_back(temp2);
    }
    sort(nodes.begin(),nodes.end(),cmp);
    dp[nodes[0].x+cg]=0;
    for(int i=1;i<nodes.size();i++)
    {
            dp[nodes[i].x+cg]=pre;
            if(nodes[i].f==1)
            dp[nodes[i].x+cg]=max(dp[nodes[i].x+cg],dp[nodes[i].op+cg]+1);
        pre=dp[nodes[i].x+cg];
    }
    printf("%d\n",dp[nodes[nodes.size()-1].x+cg]);
    return 0;
}


/* DHUOJ solution #362405 @ 2018-08-13 21:48:16.586 */

#include <bits/stdc++.h>
#define ll int
using namespace std;
pair<ll,ll>p[200005];
int main()
{
	ll n,i,w,x,s=0,l=-(1<<31);
	cin>>n;
	for(i=0;i<n;i++)
		cin>>x>>w,p[i]=make_pair(x+w,x-w);
	sort(p,p+n);
	for(i=0;i<n;i++)
		if(p[i].second>=l)
			l=p[i].first,s++;
	cout<<s;
}


/* DHUOJ solution #362394 @ 2018-08-13 22:09:12.603 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll cg=1e9;
const int maxn=2e5+100;
struct Node
{
    int x,f;
    int op;
};
vector<Node> nodes;
map<ll,int> dp;
bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int main()
{
    int n,x,w,pre=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&w);
        Node temp1,temp2;
        temp1.x=x-w,temp1.f=-1;
        temp2.x=x+w,temp2.f=1,temp2.op=temp1.x;
        nodes.push_back(temp1),nodes.push_back(temp2);
    }
    sort(nodes.begin(),nodes.end(),cmp);
    dp[nodes[0].x+cg]=0;
    for(int i=1;i<nodes.size();i++)
    {
            dp[nodes[i].x+cg]=pre;
            if(nodes[i].f==1)
            dp[nodes[i].x+cg]=max(dp[nodes[i].x+cg],dp[nodes[i].op+cg]+1);
        pre=dp[nodes[i].x+cg];
    }
    printf("%d\n",dp[nodes[nodes.size()-1].x+cg]);
    return 0;
}


/* DHUOJ solution #362394 @ 2018-08-14 01:22:22.441 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll cg=1e9;
const int maxn=2e5+100;
struct Node
{
    int x,f;
    int op;
};
vector<Node> nodes;
map<ll,int> dp;
bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int main()
{
    int n,x,w,pre=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&w);
        Node temp1,temp2;
        temp1.x=x-w,temp1.f=-1;
        temp2.x=x+w,temp2.f=1,temp2.op=temp1.x;
        nodes.push_back(temp1),nodes.push_back(temp2);
    }
    sort(nodes.begin(),nodes.end(),cmp);
    dp[nodes[0].x+cg]=0;
    for(int i=1;i<nodes.size();i++)
    {
            dp[nodes[i].x+cg]=pre;
            if(nodes[i].f==1)
            dp[nodes[i].x+cg]=max(dp[nodes[i].x+cg],dp[nodes[i].op+cg]+1);
        pre=dp[nodes[i].x+cg];
    }
    printf("%d\n",dp[nodes[nodes.size()-1].x+cg]);
    return 0;
}


/* DHUOJ solution #362394 @ 2018-08-13 22:51:41.103 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll cg=1e9;
const int maxn=2e5+100;
struct Node
{
    int x,f;
    int op;
};
vector<Node> nodes;
map<ll,int> dp;
bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int main()
{
    int n,x,w,pre=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&w);
        Node temp1,temp2;
        temp1.x=x-w,temp1.f=-1;
        temp2.x=x+w,temp2.f=1,temp2.op=temp1.x;
        nodes.push_back(temp1),nodes.push_back(temp2);
    }
    sort(nodes.begin(),nodes.end(),cmp);
    dp[nodes[0].x+cg]=0;
    for(int i=1;i<nodes.size();i++)
    {
            dp[nodes[i].x+cg]=pre;
            if(nodes[i].f==1)
            dp[nodes[i].x+cg]=max(dp[nodes[i].x+cg],dp[nodes[i].op+cg]+1);
        pre=dp[nodes[i].x+cg];
    }
    printf("%d\n",dp[nodes[nodes.size()-1].x+cg]);
    return 0;
}


/* DHUOJ solution #362394 @ 2018-08-13 22:29:57.836 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll cg=1e9;
const int maxn=2e5+100;
struct Node
{
    int x,f;
    int op;
};
vector<Node> nodes;
map<ll,int> dp;
bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int main()
{
    int n,x,w,pre=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&w);
        Node temp1,temp2;
        temp1.x=x-w,temp1.f=-1;
        temp2.x=x+w,temp2.f=1,temp2.op=temp1.x;
        nodes.push_back(temp1),nodes.push_back(temp2);
    }
    sort(nodes.begin(),nodes.end(),cmp);
    dp[nodes[0].x+cg]=0;
    for(int i=1;i<nodes.size();i++)
    {
            dp[nodes[i].x+cg]=pre;
            if(nodes[i].f==1)
            dp[nodes[i].x+cg]=max(dp[nodes[i].x+cg],dp[nodes[i].op+cg]+1);
        pre=dp[nodes[i].x+cg];
    }
    printf("%d\n",dp[nodes[nodes.size()-1].x+cg]);
    return 0;
}


#include <bits/stdc++.h>

#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define Rep(i, n) for (int i = 1; i <= (n); ++i)
#define clr(x, a) memset(x, (a), sizeof x)
using namespace std;
typedef long long ll;
int const N = 202020;
struct Node {
	int x, w;
	friend bool operator<(Node a, Node b) {
		return a.x < b.x;
	}
} p[N];
int xpos[N*3];
map<int, int> mp;
int tree[N*12];
void upd(int l, int r, int a, int c, int p) {
	if (l == r) {
		tree[p] = c;
		return;
	}
	int mid = (l + r) >> 1, lp = p << 1, rp = p << 1 | 1;
	if (a <= mid) upd(l, mid, a, c, lp);
	else upd(mid + 1, r, a, c, rp);
	tree[p] = max(tree[lp], tree[rp]);
}
int qry(int l, int r, int a, int b, int p) {
	if (l == a && r == b) return tree[p];
	int mid = (l + r) >> 1, lp = p << 1, rp = p << 1 | 1;
	if (b <= mid) return qry(l, mid, a, b, lp);
	else if (a > mid) return qry(mid + 1, r, a, b, rp);
	else return max(qry(l, mid, a, mid, lp), qry(mid + 1, r, mid + 1, b, rp));
}

int main() {
	int n; scanf("%d", &n);
	int m = 0;
	rep(i, n) {
		scanf("%d%d", &p[i].x, &p[i].w);
		xpos[m++] = p[i].x;
		xpos[m++] = p[i].x - p[i].w;
		xpos[m++] = p[i].x + p[i].w;
	}
	sort(p, p + n);
	sort(xpos, xpos + m);
	int idx = 0;
	rep(i, m) {
		if (mp.find(xpos[i]) == mp.end()) {
			mp[xpos[i]] = ++idx;
		}
	}
	int ans = 0;
	rep(i, n) {
		int lid = mp[p[i].x - p[i].w];
		int rid = mp[p[i].x + p[i].w];
		int mx = qry(1, idx, 1, lid, 1);
		int t = mx + 1;
		ans = max(ans, t);
		upd(1, idx, rid, t, 1);
	}
	printf("%d\n", ans);
	return 0;
}


#include <bits/stdc++.h>

#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define Rep(i, n) for (int i = 1; i <= (n); ++i)
#define clr(x, a) memset(x, (a), sizeof x)
using namespace std;
typedef long long ll;
int const N = 202020;
struct Node {
	int x, w;
	friend bool operator<(Node a, Node b) {
		return a.x < b.x;
	}
} p[N];
int xpos[N*3];
map<int, int> mp;
int tree[N*4];
void upd(int l, int r, int a, int c, int p) {
	if (l == r) {
		tree[p] = c;
		return;
	}
	int mid = (l + r) >> 1, lp = p << 1, rp = p << 1 | 1;
	if (mid <= a) upd(l, mid, a, c, lp);
	else upd(mid + 1, r, a, c, rp);
	tree[p] = max(tree[lp], tree[rp]);
}
int qry(int l, int r, int a, int b, int p) {
	if (l == a && r == b) return tree[p];
	int mid = (l + r) >> 1, lp = p << 1, rp = p << 1 | 1;
	if (b <= mid) return qry(l, mid, a, b, lp);
	else if (a > mid) return qry(mid + 1, r, a, b, rp);
	else return max(qry(l, mid, a, mid, lp), qry(mid + 1, r, mid + 1, b, rp));
}

int main() {
	int n; scanf("%d", &n);
	int m = 0;
	rep(i, n) {
		scanf("%d%d", &p[i].x, &p[i].w);
		xpos[m++] = p[i].x;
		xpos[m++] = p[i].x - p[i].w;
		xpos[m++] = p[i].x + p[i].w;
	}
	sort(p, p + n);
	sort(xpos, xpos + m);
	int idx = 0;
	rep(i, m) {
		if (mp.find(xpos[i]) == mp.end()) {
			mp[xpos[i]] = ++idx;
		}
	}
	int ans = 0;
	rep(i, n) {
		int lid = mp[p[i].x - p[i].w];
		int rid = mp[p[i].x + p[i].w];
		int mx = qry(1, idx, 1, lid, 1);
		int t = mx + 1;
		ans = max(ans, t);
		upd(1, idx, rid, t, 1);
	}
	printf("%d\n", ans);
	return 0;
}