#include <bits/stdc++.h>
template <class T, class Compare>
struct SegmentTree {
  const long long n;
  const Compare CMP;
  const T LEAST_EXTREME;
  T *delta, *min;
  SegmentTree(const long long& _n, const T& le)
      : n(_n), CMP(), LEAST_EXTREME(le) {
    delta = new T[4 * n + 1]();
    min = new T[4 * n + 1]();
  }
  ~SegmentTree(void) {
    delete[] delta;
    delete[] min;
  }
  void prop(const long long& idx) {
    if (delta[idx] == T()) return;
    set(2 * idx + 1, delta[idx]);
    set(2 * idx + 2, delta[idx]);
    delta[idx] = T();
  }
  void set(const long long& idx, const T& value) {
    delta[idx] = min[idx] = value;
  }
  void update(const long long& left, const long long& right, const T& val) {
    update(0, 0, n - 1, left, right, val);
  }
  void update(const long long& i, const long long& lr, const long long& rr,
              const long long& left, const long long& right, const T& val) {
    if (lr == left && rr == right) {
      set(i, val);
    } else {
      prop(i);
      const long long mid = (lr + rr) / 2;
      if (left <= mid)
        update(2 * i + 1, lr, mid, left, std::min(mid, right), val);
      if (mid < right)
        update(2 * i + 2, mid + 1, rr, std::max(mid + 1, left), right, val);
      min[i] = std::min(min[2 * i + 1], min[2 * i + 2], CMP);
    }
  }
  T query(const long long& left, const long long& right) {
    return query(0, 0, n - 1, left, right);
  }
  T query(const long long& i, const long long& lr, const long long& rr,
          const long long& left, const long long& right) {
    if (lr == left && rr == right) return min[i];
    prop(i);
    const long long mid = (lr + rr) / 2;
    T ret = LEAST_EXTREME;
    if (left <= mid) {
      T tmp = query(2 * i + 1, lr, mid, left, std::min(mid, right));
      ret = std::min(ret, tmp, CMP);
    }
    if (mid < right) {
      T tmp = query(2 * i + 2, mid + 1, rr, std::max(mid + 1, left), right);
      ret = std::min(ret, tmp, CMP);
    }
    return ret;
  }
  long long find(const long long& left, const long long& right, const T& val) {
    return find(0, 0, n - 1, left, right, val);
  }
  long long find(const long long& i, const long long& lr, const long long& rr,
                 const long long& left, const long long& right, const T& val) {
    if (lr == rr) return lr;
    const long long mid = (lr + rr) / 2;
    if (left <= mid &&
        query(2 * i + 1, lr, mid, left, std::min(mid, right)) == val) {
      return find(2 * i + 1, lr, mid, left, std::min(mid, right), val);
    }
    if (mid < right &&
        query(2 * i + 2, mid + 1, rr, std::max(mid + 1, left), right) == val) {
      return find(2 * i + 2, mid + 1, rr, std::max(mid + 1, left), right, val);
    }
    return -1;
  }
};
const static long long INF = 0x3f3f3f3f3f3f3f3f;
static inline void setio(void);
long long ord[100001];
std::pair<long long, long long> edges[100001];
std::vector<std::pair<long long, long long>> gr[100001];
char in[100001];
int main(void) {
  setio();
  memset(in, 0, sizeof(in));
  long long n, m;
  std::cin >> n >> m;
  SegmentTree<long long, std::less<long long>> fnct(n, INF);
  for (long long i = 0; i < m; ++i) {
    std::cin >> edges[i].first >> edges[i].second;
    ord[i] = i;
  }
  for (long long i = 0; i < n; ++i) fnct.update(i, i, i + 1);
  std::sort(ord, ord + m, [&](const long long& a, const long long& b) {
    return edges[a].first < edges[b].first ||
           (edges[a].first == edges[b].first &&
            edges[a].second > edges[b].second);
  });
  long long curr_n = 2;
  if (!edges[ord[0]].second) {
    std::cout << "-1\n";
    return 0;
  }
  edges[ord[0]] = {0, 1};
  fnct.update(0, 0, 2);
  for (long long i = 1; i < m; ++i) {
    const long long idx = ord[i];
    if (edges[idx].second) {
      if (curr_n >= n) {
        std::cout << "-1\n";
        return 0;
      }
      fnct.update(curr_n - 1, curr_n - 1, curr_n + 1);
      edges[idx] = std::pair<long long, long long>{curr_n - 1, curr_n++};
    } else {
      const long long min = fnct.query(0, curr_n - 1);
      if (min >= curr_n) {
        std::cout << "-1\n";
        return 0;
      }
      long long found = fnct.find(0, curr_n - 1, min);
      edges[idx] = std::pair<long long, long long>{found, min};
      fnct.update(found, found, min + 1);
    }
  }
  for (long long i = 0; i < m; ++i)
    std::cout << edges[i].first + 1 << " " << edges[i].second + 1 << "\n";
  std::cerr << static_cast<double>(clock()) / CLOCKS_PER_SEC << "\n";
  return 0;
}
static inline void setio(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.precision(10);
  std::cout << std::fixed;
}
