#include<iostream>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;
const int N = 2.5e5 + 10;
const int INF = 0x7fffffff;
struct Range {
int l, r, w, id;
inline bool operator<(const Range &b) const {
if(r != b.r) return r < b.r;
if(l != b.l) return l > b.l;
return id < b.id;
}
inline bool operator>(const Range &b) const {
return b < *this;
}
inline bool operator==(const Range &b) const {
return id == b.id;
}
} a[N];
int n;
int swp[N];
int num[2 * N], nn;
void lisanhua() {
for(int i = 1; i <= n; i++) num[++nn] = a[i].l, num[++nn] = a[i].r;
sort(num + 1, num + 1 + nn);
nn = unique(num + 1, num + 1 + nn) - (num + 1);
for(int i = 1; i <= n; i++) {
a[i].l = lower_bound(num + 1, num + 1 + nn, a[i].l) - num;
a[i].r = lower_bound(num + 1, num + 1 + nn, a[i].r) - num;
}
}
namespace SegT1 {
struct Node {
int mnl, mxl, mn, mnp, tag;
} tr[8 * N];
inline int lc(int x) { return x << 1; }
inline int rc(int x) { return x << 1 | 1; }
inline void push_up(int p) {
int l = lc(p), r = rc(p);
tr[p].mnl = min(tr[l].mnl, tr[r].mnl);
tr[p].mxl = max(tr[l].mxl, tr[r].mxl);
if(tr[l].mn < tr[r].mn || tr[l].mn == tr[r].mn && tr[l].mnp < tr[r].mnp) {
tr[p].mn = tr[l].mn, tr[p].mnp = tr[l].mnp;
} else tr[p].mn = tr[r].mn, tr[p].mnp = tr[r].mnp;
}
inline void spread(int p, int tg) { tr[p].mn += tg, tr[p].tag += tg; }
inline void push_down(int p) {
if(tr[p].tag) spread(lc(p), tr[p].tag), spread(rc(p), tr[p].tag), tr[p].tag = 0;
}
void build() {
for(int i = 0; i <= 4 * nn; i++) tr[i].mn = tr[i].mnl = INF;
}
void insert(int p, int l, int r, Range &v) {
if(l == r) {
tr[p].mn = v.w; tr[p].mnl = tr[p].mxl = v.l; tr[p].mnp = v.id;
return;
}
int mid = (l + r) >> 1; push_down(p);
if(v.r <= mid) insert(lc(p), l, mid, v);
else insert(rc(p), mid + 1, r, v);
push_up(p);
}
void erase(int p, int l, int r, int q) {
if(l == r) {
tr[p].mn = tr[p].mnl = INF; tr[p].mnp = tr[p].mxl = 0;
return;
}
int mid = (l + r) >> 1; push_down(p);
if(q <= mid) erase(lc(p), l, mid, q);
else erase(rc(p), mid + 1, r, q);
push_up(p);
}
void add(int p, int l, int r, int q) {
if(tr[p].mnl > q) return;
if(tr[p].mxl <= q && q < l) return spread(p, -(num[q + 1] - num[q]));
int mid = (l + r) >> 1; push_down(p);
if(mid > q) add(lc(p), l, mid, q);
add(rc(p), mid + 1, r, q);
push_up(p);
}
}
namespace SegT2 {
priority_queue<Range, vector<Range>, greater<Range>> q1[2 * N], q2[2 * N];
int mx[8 * N];
inline int lc(int x) { return x << 1; }
inline int rc(int x) { return x << 1 | 1; }
inline void push_up(int p) { mx[p] = max(mx[lc(p)], mx[rc(p)]); }
void build() {
for(int i = 0; i <= 4 * nn; i++) mx[i] = -1;
for(int i = 1; i <= nn; i++) q1[i].push({-1, INF, 0, 0});
}
void insert(int p, int l, int r, Range &v) {
if(l == r) {
q1[l].push(v);
mx[p] = q1[l].top().l;
return;
}
int mid = (l + r) >> 1;
if(v.r <= mid) insert(lc(p), l, mid, v);
else insert(rc(p), mid + 1, r, v);
push_up(p);
}
void erase(int p, int l, int r, Range &v) {
if(l == r) {
q2[l].push(v);
while(!q2[l].empty() && q1[l].top() == q2[l].top()) q1[l].pop(), q2[l].pop();
mx[p] = q1[l].top().l;
return;
}
int mid = (l + r) >> 1;
if(v.r <= mid) erase(lc(p), l, mid, v);
else erase(rc(p), mid + 1, r, v);
push_up(p);
}
int query(int p, int l, int r, int ql, int qr, int lim) {
if(r < ql || l > qr) return -1;
if(mx[p] < lim) return -1;
if(l == r) return q1[l].top().id;
int mid = (l + r) >> 1;
int res = query(lc(p), l, mid, ql, qr, lim);
if(~res) return res;
return query(rc(p), mid + 1, r, ql, qr, lim);
}
}
namespace BIT {
int sum[2 * N];
inline void add(int p, int v) {
for(int i = p + 2; i <= nn + 5; i += i & -i) sum[i] += v;
}
inline int query(int l, int r) {
int res = 0;
for(int i = l + 1; i; i -= i & -i) res -= sum[i];
for(int i = r + 2; i; i -= i & -i) res += sum[i];
return res;
}
}
int fa[2 * N];
int find(int x) { if(fa[x] == x) return x; return fa[x] = find(fa[x]); }
void fill(int l, int r) {
for(int i = find(l); i <= r; i = find(i)) {
SegT1::add(1, 1, nn, i);
BIT::add(i, -(num[i + 1] - num[i]));
fa[i] = find(i + 1);
}
}
set<Range> valid;
int main() {
freopen("ds.in", "r", stdin);
freopen("ds.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i].l >> a[i].r, a[i].id = i;
lisanhua();
sort(a + 1, a + 1 + n);
for(int i = 1; i <= n; i++) swp[a[i].id] = i;
for(int i = 1; i <= nn; i++) fa[i] = i;
for(int i = 1; i <= nn - 1; i++) BIT::add(i, num[i + 1] - num[i]);
SegT1::build();
SegT2::build();
for(int i = 1, mn = -1; i <= n; i++) {
a[i].w = num[a[i].r] - num[a[i].l];
if(a[i].l > mn) SegT1::insert(1, 1, nn, a[i]), valid.insert(a[i]), mn = a[i].l;
else SegT2::insert(1, 1, nn, a[i]);
}
for(int cnt = 1; cnt <= n; cnt++) {
int cur = swp[SegT1::tr[1].mnp];
cout << a[cur].id << ' ';
SegT1::erase(1, 1, nn, a[cur].r);
valid.erase(a[cur]);
fill(a[cur].l, a[cur].r - 1);
auto it = valid.lower_bound(a[cur]);
int preR, nxtR, preL;
if(it != valid.end()) nxtR = it->r - 1;
else nxtR = nn;
if(it != valid.begin()) preR = (--it)->r + 1, preL = it->l + 1;
else preR = 1, preL = 0;
int tmp = SegT2::query(1, 1, nn, preR, nxtR, preL);
while(~tmp) {
tmp = swp[tmp];
SegT2::erase(1, 1, nn, a[tmp]);
a[tmp].w = BIT::query(a[tmp].l, a[tmp].r - 1);
SegT1::insert(1, 1, nn, a[tmp]); valid.insert(a[tmp]);
tmp = SegT2::query(1, 1, nn, a[tmp].r + 1, nxtR, a[tmp].l + 1);
}
}
cout << endl;
return 0;
}