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;
const int maxn = 20005;
int test, n;
pair<pair<int, int>, int> a[maxn];
int lim[maxn], ans[maxn];
namespace Segtree {
int t[maxn * 4], tag[maxn * 4];
pair<int, int> mn[maxn * 4];
void pushdown(int cur) {
  if (tag[cur]) {
    t[cur << 1] += tag[cur];
    tag[cur << 1] += tag[cur];
    t[cur << 1 | 1] += tag[cur];
    tag[cur << 1 | 1] += tag[cur];
    tag[cur] = 0;
  }
}
void pushup(int cur) {
  t[cur] = min(t[cur << 1], t[cur << 1 | 1]);
  mn[cur] = min(mn[cur << 1], mn[cur << 1 | 1]);
}
void build(int cur, int l, int r) {
  tag[cur] = 0;
  if (l == r) {
    t[cur] = n - l;
    mn[cur] = make_pair(a[l].first.second, l);
    return;
  }
  int mid = l + r >> 1;
  build(cur << 1, l, mid);
  build(cur << 1 | 1, mid + 1, r);
  pushup(cur);
}
void update(int cur, int l, int r, int vl, int vr, int val) {
  if (l >= vl && r <= vr) {
    t[cur] += val;
    tag[cur] += val;
    return;
  }
  pushdown(cur);
  int mid = l + r >> 1;
  if (mid >= vl) update(cur << 1, l, mid, vl, vr, val);
  if (mid < vr) update(cur << 1 | 1, mid + 1, r, vl, vr, val);
  pushup(cur);
}
void erase(int cur, int l, int r, int k) {
  if (l == r) {
    mn[cur] = make_pair(int(1e9), int(1e9));
    return;
  }
  pushdown(cur);
  int mid = l + r >> 1;
  if (k <= mid)
    erase(cur << 1, l, mid, k);
  else
    erase(cur << 1 | 1, mid + 1, r, k);
  pushup(cur);
}
int getpos(int cur, int l, int r, int val) {
  if (l == r) {
    if (t[cur] > val) return l + 1;
    return l;
  }
  pushdown(cur);
  int mid = l + r >> 1;
  if (t[cur << 1] > val)
    return getpos(cur << 1 | 1, mid + 1, r, val);
  else
    return getpos(cur << 1, l, mid, val);
}
pair<int, int> query(int cur, int l, int r, int vl, int vr) {
  if (l >= vl && r <= vr) return mn[cur];
  pushdown(cur);
  int mid = l + r >> 1;
  pair<int, int> sl = mid >= vl ? query(cur << 1, l, mid, vl, vr)
                                : make_pair(int(1e9), int(1e9));
  pair<int, int> sr = mid < vr ? query(cur << 1 | 1, mid + 1, r, vl, vr)
                               : make_pair(int(1e9), int(1e9));
  return min(sl, sr);
}
}  // namespace Segtree
bool check(int x) {
  Segtree::build(1, 1, n);
  for (int i = 1; i <= (n); i++) lim[i] = n;
  int pt = 1;
  for (int i = 1; i <= (n); i++) {
    int p = min(Segtree::getpos(1, 1, n, i - 1), n);
    if (!p) return false;
    int id = Segtree::query(1, 1, n, 1, p).second;
    ans[i] = id;
    if (id == int(1e9) || lim[id] < i) return false;
    Segtree::erase(1, 1, n, id);
    if (id < n) Segtree::update(1, 1, n, id + 1, n, 1);
    Segtree::update(1, 1, n, id, id, int(1e9) - lim[id]);
    lim[id] = int(1e9);
    if (i + x < n) {
      while (pt <= n && a[pt].first.first <= a[id].first.second) {
        if (lim[pt] != int(1e9)) {
          Segtree::update(1, 1, n, pt, pt, i + x - lim[pt]);
          lim[pt] = i + x;
        }
        pt++;
      }
    }
  }
  return true;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= (n); i++)
    scanf("%d%d", &a[i].first.first, &a[i].first.second), a[i].second = i;
  sort(a + 1, a + 1 + n);
  int l = -1, r = n - 1;
  while (r - l > 1) {
    int mid = l + r >> 1;
    if (check(mid))
      r = mid;
    else
      l = mid;
  }
  check(r);
  for (int i = 1; i <= (n); i++)
    printf("%d%c", a[ans[i]].second, i == n ? '\n' : ' ');
  return 0;
}