#include <bits/stdc++.h>
using namespace std;
const int dr[] = {0, -1, 0, 1, -1, 1, 1, -1};
const int dc[] = {1, 0, -1, 0, 1, 1, -1, -1};
const double eps = 1e-9;
template <class T>
void print(const vector<T> &v) {
  ostringstream os;
  for (int i = 0; i < v.size(); ++i) {
    if (i) os << ' ';
    os << v[i];
  }
  cout << os.str() << endl;
}
template <class T>
int sz(const T &c) {
  return (int)c.size();
}
template <class T>
void srt(T &c) {
  sort(c.begin(), c.end());
}
template <class T>
void checkmin(T &a, T b) {
  if (b < a) a = b;
}
template <class T>
void checkmax(T &a, T b) {
  if (b > a) a = b;
}
template <class T>
T sqr(T x) {
  return x * x;
}
template <class T, class U>
T cast(U x) {
  ostringstream os;
  os << x;
  T res;
  istringstream is(os.str());
  is >> res;
  return res;
}
template <class T>
vector<T> split(string s, string x = " ") {
  vector<T> res;
  for (int i = 0; i < s.size(); i++) {
    string a;
    while (i < (int)s.size() && x.find(s[i]) == string::npos) a += s[i++];
    if (!a.empty()) res.push_back(cast<T>(a));
  }
  return res;
}
template <class T>
bool inside(T r, T c, T R, T C) {
  return r >= 0 && r < R && c >= 0 && c < C;
}
struct node {
  int cnt;
  int prio;
  int value;
  int pos;
  int maxv;
  node *l;
  node *r;
};
const int MAXN = 200000;
node treap[MAXN];
int t_cnt;
node *root;
vector<int> rnd;
int cnt(node *p) { return p ? p->cnt : 0; }
int maxv(node *p) { return p ? p->maxv : INT_MIN; }
void update(node *p) {
  p->cnt = 1 + cnt(p->l) + cnt(p->r);
  p->maxv = max(p->value, max(maxv(p->l), maxv(p->r)));
}
void merge(node *&t, node *l, node *r) {
  if (!l)
    t = r;
  else if (!r)
    t = l;
  else if (l->prio < r->prio)
    merge(l->r, l->r, r), t = l;
  else
    merge(r->l, l, r->l), t = r;
  update(t);
}
void split(node *t, node *&l, node *&r, int key) {
  if (!t) {
    l = r = NULL;
    return;
  } else if (key <= cnt(t->l))
    split(t->l, l, t->l, key), r = t;
  else
    split(t->r, t->r, r, key - cnt(t->l) - 1), l = t;
  update(t);
}
int get(node *&t, int index) {
  if (index < cnt(t->l))
    return get(t->l, index);
  else if (index > cnt(t->l))
    return get(t->r, index - cnt(t->l) - 1);
  return t->value;
}
int get(int index) { return get(root, index); }
void add(node *&t, node *it, int index) {
  if (!t)
    t = it;
  else if (it->prio < t->prio)
    split(t, it->l, it->r, index), t = it;
  else if (index <= cnt(t->l))
    add(t->l, it, index);
  else
    add(t->r, it, index - cnt(t->l) - 1);
  update(t);
}
void add(int index, int value, int pos) {
  node *it = &treap[t_cnt];
  it->value = value;
  it->pos = pos;
  it->prio = rnd[t_cnt];
  ++t_cnt;
  add(root, it, index);
}
void remove(node *&t, int index) {
  if (index == cnt(t->l))
    merge(t, t->l, t->r);
  else {
    if (index < cnt(t->l))
      remove(t->l, index);
    else
      remove(t->r, index - cnt(t->l) - 1);
  }
  update(t);
}
void remove(int index) { remove(root, index); }
int maxv(int a, int b) {
  node *l1, *r1;
  split(root, l1, r1, b + 1);
  node *l2, *r2;
  split(l1, l2, r2, a);
  int res = maxv(r2);
  node *t;
  merge(t, l2, r2);
  merge(root, t, r1);
  return res;
}
void print(node *t, vector<int> &res) {
  if (t) {
    print(t->l, res);
    res.push_back(t->pos);
    print(t->r, res);
  }
}
void print1(vector<int> &res) { print(root, res); }
int main(int argc, char *argv[]) {
  for (int i = 0; i < MAXN; i++) rnd.push_back(i);
  random_shuffle(rnd.begin(), rnd.end());
  int n;
  cin >> n;
  vector<int> a(n), c(n);
  for (int i(0), _n(n); i < _n; ++i) {
    scanf("%d%d", &a[i], &c[i]);
  }
  for (int i(0), _n(n); i < _n; ++i) {
    int lo = -1;
    int hi = min(c[i], cnt(root));
    while (hi - lo > 1) {
      int mid = (lo + hi) / 2;
      int mx = maxv(0, mid);
      if (mx < a[i])
        lo = mid;
      else
        hi = mid;
    }
    add(hi, a[i], i + 1);
  }
  vector<int> res;
  print1(res);
  reverse(res.begin(), res.end());
  print(res);
  return 0;
}
