#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ld = long double;
using u32 = uint32_t;
using u64 = uint64_t;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
template <typename T>
istream &operator>>(istream &s, vector<T> &v) {
  for (auto &i : v) s >> i;
  return s;
}
template <typename A, typename B>
istream &operator>>(istream &s, pair<A, B> &p) {
  return s >> p.first >> p.second;
}
template <typename T>
T gcd(T a, T b) {
  while (b) {
    a %= b;
    swap(a, b);
  }
  return a;
}
template <typename T>
T binpow(T a, T b, T mod) {
  T res{1};
  while (1) {
    if (b & T(1)) res = (res * a) % mod;
    b >>= T(1);
    if (!b) break;
    a = (a * a) % mod;
  }
  return res;
}
struct cartesian {
  struct node {
    node() : value(-1), subsize(1), l(nullptr), r(nullptr) {}
    int value, subsize;
    node *l, *r;
  };
  using pnode = node *;
  static int getsize(const pnode v) { return v ? v->subsize : 0; }
  static void update(pnode v) {
    if (v) v->subsize = 1 + getsize(v->l) + getsize(v->r);
  }
  pair<pnode, pnode> split(pnode v, int key) {
    if (!v) return {nullptr, nullptr};
    int mykey = getsize(v->l);
    if (mykey >= key) {
      auto sub = split(v->l, key);
      v->l = sub.second;
      update(sub.first);
      update(v);
      return {sub.first, v};
    } else {
      auto sub = split(v->r, key - mykey - 1);
      v->r = sub.first;
      update(v);
      update(sub.second);
      return {v, sub.second};
    }
  }
  pair<pnode, pnode> cutfirst(pnode v) {
    if (!v) return {nullptr, nullptr};
    int mykey = getsize(v->l);
    if (mykey == 0) {
      pnode v2 = v->r;
      v->r = nullptr;
      update(v);
      return {v, v2};
    }
    auto sub = cutfirst(v->l);
    v->l = sub.second;
    update(sub.first);
    update(v);
    return {sub.first, v};
  }
  pnode merge(pnode v1, pnode v2) {
    if (!v1) return v2;
    if (!v2) return v1;
    pnode nroot;
    uint64_t buben = uint64_t(shara()) * uint64_t(getsize(v1) + getsize(v2));
    uint64_t score_l = uint64_t(getsize(v1)) * UINT32_MAX;
    if (buben < score_l) {
      nroot = v1;
      nroot->r = merge(nroot->r, v2);
    } else {
      nroot = v2;
      nroot->l = merge(v1, nroot->l);
    }
    update(nroot);
    return nroot;
  }
  pnode addlast(pnode v1, pnode v2) {
    if (!v1) return v2;
    if (!v2) return v1;
    v1->r = addlast(v1->r, v2);
    update(v1);
    return v1;
  }
  pnode build(int tl, int tr) {
    if (tl >= tr) return nullptr;
    int tm = (tl + tr) / 2;
    pnode v = &motor[tm];
    v->l = build(tl, tm);
    v->r = build(tm + 1, tr);
    update(v);
    return v;
  }
  void init(int tl, int tr) {
    motor.resize(tr - tl);
    root = build(tl, tr);
  }
  pnode root = nullptr;
  vector<node> motor;
  uint32_t shara_seed = 0xDEADBEEF;
  uint32_t shara() {
    shara_seed ^= shara_seed << uint32_t(13);
    shara_seed ^= shara_seed >> uint32_t(17);
    shara_seed ^= shara_seed << uint32_t(5);
    return shara_seed;
  }
};
int motor = 1;
vector<char> used;
void dfs(const cartesian::pnode v) {
  if (!v) return;
  dfs(v->l);
  if (v->value == -1) {
    while (used[motor]) motor++;
    used[motor] = 1;
    v->value = motor;
  }
  printf("%d ", v->value);
  dfs(v->r);
}
int main() {
  cin.sync_with_stdio(false);
  cout.sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  scanf("%d%d", &n, &m);
  used.resize(n + 1);
  vector<pair<int, int> > ops(m);
  for (auto &i1 : ops) scanf("%d%d", &i1.first, &i1.second);
  reverse(ops.begin(), ops.end());
  cartesian tree;
  tree.init(0, n);
  for (auto &i1 : ops) {
    int x = i1.first;
    int y = i1.second;
    auto cut = tree.cutfirst(tree.root);
    auto el = cut.first;
    tree.root = cut.second;
    if (el->value != -1 && el->value != x) {
      printf("-1\n");
      return 0;
    }
    if (el->value == -1 && used[x]) {
      printf("-1\n");
      return 0;
    }
    el->value = x;
    used[x] = 1;
    auto halves = tree.split(tree.root, y - 1);
    auto half1 = tree.merge(halves.first, el);
    tree.root = tree.merge(half1, halves.second);
  }
  dfs(tree.root);
  return 0;
}

### Prompt

Construct a cpp code solution to the problem outlined:

The employees of the F company have lots of ways to entertain themselves. Today they invited a famous magician who shows a trick with plastic cups and a marble.

The point is to trick the spectator's attention. Initially, the spectator stands in front of a line of n plastic cups. Then the magician places a small marble under one cup and shuffles the cups. Then the spectator should guess which cup hides the marble.

But the head coder of the F company isn't easy to trick. When he saw the performance, he noticed several important facts:

  * each cup contains a mark — a number from 1 to n; all marks on the cups are distinct; 
  * the magician shuffles the cups in m operations, each operation looks like that: take a cup marked xi, sitting at position yi in the row of cups (the positions are numbered from left to right, starting from 1) and shift it to the very beginning of the cup row (on the first position). 



When the head coder came home after work he wanted to re-do the trick. Unfortunately, he didn't remember the starting or the final position of the cups. He only remembered which operations the magician performed. Help the coder: given the operations in the order they were made find at least one initial permutation of the cups that can go through the described operations in the given order. Otherwise, state that such permutation doesn't exist.

Input

The first line contains integers n and m (1 ≤ n, m ≤ 106). Each of the next m lines contains a couple of integers. The i-th line contains integers xi, yi (1 ≤ xi, yi ≤ n) — the description of the i-th operation of the magician. Note that the operations are given in the order in which the magician made them and the coder wants to make them in the same order.

Output

If the described permutation doesn't exist (the programmer remembered wrong operations), print -1. Otherwise, print n distinct integers, each from 1 to n: the i-th number should represent the mark on the cup that initially is in the row in position i.

If there are multiple correct answers, you should print the lexicographically minimum one.

Examples

Input

2 1
2 1


Output

2 1 


Input

3 2
1 2
1 1


Output

2 1 3 


Input

3 3
1 3
2 3
1 3


Output

-1

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ld = long double;
using u32 = uint32_t;
using u64 = uint64_t;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
template <typename T>
istream &operator>>(istream &s, vector<T> &v) {
  for (auto &i : v) s >> i;
  return s;
}
template <typename A, typename B>
istream &operator>>(istream &s, pair<A, B> &p) {
  return s >> p.first >> p.second;
}
template <typename T>
T gcd(T a, T b) {
  while (b) {
    a %= b;
    swap(a, b);
  }
  return a;
}
template <typename T>
T binpow(T a, T b, T mod) {
  T res{1};
  while (1) {
    if (b & T(1)) res = (res * a) % mod;
    b >>= T(1);
    if (!b) break;
    a = (a * a) % mod;
  }
  return res;
}
struct cartesian {
  struct node {
    node() : value(-1), subsize(1), l(nullptr), r(nullptr) {}
    int value, subsize;
    node *l, *r;
  };
  using pnode = node *;
  static int getsize(const pnode v) { return v ? v->subsize : 0; }
  static void update(pnode v) {
    if (v) v->subsize = 1 + getsize(v->l) + getsize(v->r);
  }
  pair<pnode, pnode> split(pnode v, int key) {
    if (!v) return {nullptr, nullptr};
    int mykey = getsize(v->l);
    if (mykey >= key) {
      auto sub = split(v->l, key);
      v->l = sub.second;
      update(sub.first);
      update(v);
      return {sub.first, v};
    } else {
      auto sub = split(v->r, key - mykey - 1);
      v->r = sub.first;
      update(v);
      update(sub.second);
      return {v, sub.second};
    }
  }
  pair<pnode, pnode> cutfirst(pnode v) {
    if (!v) return {nullptr, nullptr};
    int mykey = getsize(v->l);
    if (mykey == 0) {
      pnode v2 = v->r;
      v->r = nullptr;
      update(v);
      return {v, v2};
    }
    auto sub = cutfirst(v->l);
    v->l = sub.second;
    update(sub.first);
    update(v);
    return {sub.first, v};
  }
  pnode merge(pnode v1, pnode v2) {
    if (!v1) return v2;
    if (!v2) return v1;
    pnode nroot;
    uint64_t buben = uint64_t(shara()) * uint64_t(getsize(v1) + getsize(v2));
    uint64_t score_l = uint64_t(getsize(v1)) * UINT32_MAX;
    if (buben < score_l) {
      nroot = v1;
      nroot->r = merge(nroot->r, v2);
    } else {
      nroot = v2;
      nroot->l = merge(v1, nroot->l);
    }
    update(nroot);
    return nroot;
  }
  pnode addlast(pnode v1, pnode v2) {
    if (!v1) return v2;
    if (!v2) return v1;
    v1->r = addlast(v1->r, v2);
    update(v1);
    return v1;
  }
  pnode build(int tl, int tr) {
    if (tl >= tr) return nullptr;
    int tm = (tl + tr) / 2;
    pnode v = &motor[tm];
    v->l = build(tl, tm);
    v->r = build(tm + 1, tr);
    update(v);
    return v;
  }
  void init(int tl, int tr) {
    motor.resize(tr - tl);
    root = build(tl, tr);
  }
  pnode root = nullptr;
  vector<node> motor;
  uint32_t shara_seed = 0xDEADBEEF;
  uint32_t shara() {
    shara_seed ^= shara_seed << uint32_t(13);
    shara_seed ^= shara_seed >> uint32_t(17);
    shara_seed ^= shara_seed << uint32_t(5);
    return shara_seed;
  }
};
int motor = 1;
vector<char> used;
void dfs(const cartesian::pnode v) {
  if (!v) return;
  dfs(v->l);
  if (v->value == -1) {
    while (used[motor]) motor++;
    used[motor] = 1;
    v->value = motor;
  }
  printf("%d ", v->value);
  dfs(v->r);
}
int main() {
  cin.sync_with_stdio(false);
  cout.sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  scanf("%d%d", &n, &m);
  used.resize(n + 1);
  vector<pair<int, int> > ops(m);
  for (auto &i1 : ops) scanf("%d%d", &i1.first, &i1.second);
  reverse(ops.begin(), ops.end());
  cartesian tree;
  tree.init(0, n);
  for (auto &i1 : ops) {
    int x = i1.first;
    int y = i1.second;
    auto cut = tree.cutfirst(tree.root);
    auto el = cut.first;
    tree.root = cut.second;
    if (el->value != -1 && el->value != x) {
      printf("-1\n");
      return 0;
    }
    if (el->value == -1 && used[x]) {
      printf("-1\n");
      return 0;
    }
    el->value = x;
    used[x] = 1;
    auto halves = tree.split(tree.root, y - 1);
    auto half1 = tree.merge(halves.first, el);
    tree.root = tree.merge(half1, halves.second);
  }
  dfs(tree.root);
  return 0;
}

```