Problem: Information technologies are developing and are increasingly penetrating into all spheres of human activity. Incredible as it is, the most modern technology are used in farming!

A large farm has a meadow with grazing sheep. Overall there are n sheep and each of them contains a unique number from 1 to n — because the sheep need to be distinguished and you need to remember information about each one, and they are so much alike! The meadow consists of infinite number of regions numbered from 1 to infinity. It's known that sheep i likes regions from li to ri.

There are two shepherds taking care of the sheep: First and Second. First wakes up early in the morning and leads the sheep graze on the lawn. Second comes in the evening and collects all the sheep.

One morning, First woke up a little later than usual, and had no time to lead the sheep graze on the lawn. So he tied together every two sheep if there is a region they both like. First thought that it would be better — Second would have less work in the evening, because sheep won't scatter too much, being tied to each other!

In the evening Second came on the lawn, gathered the sheep and tried to line them up in a row. But try as he might, the sheep wouldn't line up as Second want! Second had neither the strength nor the ability to untie the sheep so he left them as they are, but with one condition: he wanted to line up the sheep so that the maximum distance between two tied sheep was as small as possible. The distance between the sheep is the number of sheep in the ranks that are between these two.

Help Second find the right arrangement.

Input

The first input line contains one integer n (1 ≤ n ≤ 2000). Each of the following n lines contains two integers li and ri (1 ≤ li, ri ≤ 109; li ≤ ri).

Output

In the single output line print n space-separated numbers — the sought arrangement of the sheep. The i-th value in the line must represent the number of the sheep that took the i-th place from left in the optimal arrangement line. 

If there are multiple optimal arrangements, print any of them.

Examples

Input

3
1 3
5 7
2 4


Output

1 3 2

Input

5
1 5
2 4
3 6
1 7
2 6


Output

2 1 3 5 4

Input

4
1 3
4 6
5 7
2 3


Output

1 4 2 3

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
using pi = pair<int, int>;
const int MAXN = 50005;
const int MAXT = 132000;
pi merge(pi a, pi b) {
  if (a < b) swap(a, b);
  if (a.first == b.first) a.second = min(a.second, b.second);
  return a;
}
int n;
struct seg {
  pi tree[MAXT];
  int lazy[MAXT];
  void lazydown(int p) {
    for (int i = 2 * p; i < 2 * p + 2; i++) {
      tree[i].first += lazy[p];
      lazy[i] += lazy[p];
    }
    lazy[p] = 0;
  }
  void init(int s = 0, int e = n, int p = 1) {
    lazy[p] = 0;
    if (s == e) {
      tree[p] = pi(0, s);
      return;
    }
    int m = (s + e) / 2;
    init(s, m, 2 * p);
    init(m + 1, e, 2 * p + 1);
    tree[p] = merge(tree[2 * p], tree[2 * p + 1]);
  }
  pi query(int s, int e, int ps = 0, int pe = n, int p = 1) {
    if (e < ps || pe < s) return pi(-1e9, 0);
    if (s <= ps && pe <= e) return tree[p];
    lazydown(p);
    int pm = (ps + pe) / 2;
    return merge(query(s, e, ps, pm, 2 * p),
                 query(s, e, pm + 1, pe, 2 * p + 1));
  }
  void add(int s, int e, int x, int ps = 0, int pe = n, int p = 1) {
    if (e < ps || pe < s) return;
    if (s <= ps && pe <= e) {
      tree[p].first += x;
      lazy[p] += x;
      return;
    }
    lazydown(p);
    int pm = (ps + pe) / 2;
    add(s, e, x, ps, pm, 2 * p);
    add(s, e, x, pm + 1, pe, 2 * p + 1);
    tree[p] = merge(tree[2 * p], tree[2 * p + 1]);
  }
} seg;
pi a[MAXN];
auto cmp = [](int x, int y) {
  return pi(a[x].second, a[x].first) > pi(a[y].second, a[y].first);
};
auto cmp2 = [](int x, int y) { return a[x].first > a[y].first; };
struct seg2 {
  struct node {
    int idx, frm;
    node operator+(const node &n) const {
      if (cmp(idx, n.idx)) return n;
      return *this;
    }
  } tree[MAXT];
  int lim;
  void init(int n) {
    for (lim = 1; lim <= n; lim <<= 1)
      ;
    for (int i = 0; i < lim; i++) {
      tree[i + lim] = {n, i};
    }
    for (int i = lim - 1; i; i--) {
      tree[i] = tree[2 * i] + tree[2 * i + 1];
    }
  }
  void update(int x, int v) {
    x += lim;
    tree[x].idx = v;
    while (x > 1) {
      x >>= 1;
      tree[x] = tree[2 * x] + tree[2 * x + 1];
    }
  }
  pi query(int s, int e) {
    node ret = (node){n, -1};
    s += lim;
    e += lim;
    while (s < e) {
      if (s % 2 == 1) ret = ret + tree[s++];
      if (e % 2 == 0) ret = ret + tree[e--];
      s >>= 1;
      e >>= 1;
    }
    if (s == e) ret = ret + tree[s];
    return pi(ret.idx, ret.frm);
  }
} seg2;
int ans[MAXN];
bool trial(int k) {
  vector<priority_queue<int, vector<int>, decltype(cmp)>> lvl(
      n, priority_queue<int, vector<int>, decltype(cmp)>(cmp));
  priority_queue<int, vector<int>, decltype(cmp2)> pqForLast(cmp2);
  vector<int> f(n);
  for (int i = 0; i < n; i++) {
    f[i] = n - 1;
    lvl[n - 1].push(i);
    pqForLast.push(i);
  }
  seg.init();
  for (int i = 0; i < n; i++) {
    seg.add(i + 1, n, ((int)(lvl[i]).size()) - 1);
  }
  seg2.init(n);
  auto update_node = [&](int x) {
    seg2.update(x, ((int)(lvl[x]).size()) ? lvl[x].top() : n);
  };
  update_node(n - 1);
  for (int i = 0; i < n; i++) {
    auto val = seg.query(i + 1, n);
    if (val.first > -i) return 0;
    int lastpos = val.second;
    int idx = -1;
    while (true) {
      auto qq = seg2.query(i, lastpos - 1);
      if (f[qq.first] != qq.second) {
        lvl[qq.second].pop();
        update_node(qq.second);
        continue;
      }
      idx = qq.first;
      break;
    }
    ans[i] = idx;
    lvl[f[idx]].pop();
    update_node(f[idx]);
    seg.add(f[idx] + 1, n, -1);
    f[idx] = -1;
    if (k + i < n - 1) {
      while (((int)(pqForLast).size()) &&
             a[pqForLast.top()].first <= a[idx].second) {
        int x = pqForLast.top();
        pqForLast.pop();
        if (f[x] == -1) continue;
        f[x] = k + i;
        lvl[k + i].push(x);
        seg.add(k + i + 1, n - 1, 1);
        update_node(k + i);
      }
    }
  }
  return 1;
}
void solve() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d %d", &a[i].first, &a[i].second);
  a[n] = pi(2e9, 2e9);
  int s = 1, e = n - 1;
  while (s != e) {
    int m = (s + e) / 2;
    if (trial(m))
      e = m;
    else
      s = m + 1;
  }
  trial(s);
  for (int i = 0; i < n; i++) printf("%d ", 1 + ans[i]);
}
int main() {
  int tc = 1;
  while (tc--) {
    solve();
  }
}