#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
#define rep(i,n) for(int i=0; i<n; i++)
#define REP(i,m,n) for(ll i=(ll)(m);i<(ll)(n);i++)
#define fi first
#define se second
long long mo = 1000000007;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> Pii;
typedef pair<ll,ll> Pll;
typedef pair<ll,Pll> PlP;
template<class T, class S> void cmin(T &a, const S &b) { if (a > b)a = b; }
template<class T, class S> void cmax(T &a, const S &b) { if (a < b)a = b; }
template<class A>void PR(A a,ll n){rep(i,n){if(i)cout<<' ';cout<<a[i];}cout << "\n";}
ld PI=3.14159265358979323846;
using namespace atcoder;

struct UnionFind {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
    vector<int> size;
    UnionFind(int N): par(N),size(N) {

         //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++){
            par[i] = i;
            size[i] = -1;
        }
            
    }
    int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }

    void unite(int x, int y) { // xとyの木を併合
        int rx = root(x); //xの根をrx
        int ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
        size[ry] += size[rx];
    }

    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }
    int getsize(int x){
        return -size[root(x)];
    }
    int getNunion(){//これちょっと遅い sameと組み合わせて順次数えていけば早くなりそう。
        map<int,int> m;
        rep(i,par.size()){
            m[this->root(i)]++;
        }
        return int(m.size());
    }
};

int main(){
    ll N;
    cin >> N;
    vector<ll> x(N), y(N);
    vector<Pll> ys(N+2), yt(N+2), xs(N+2), xt(N+2);
    //vector<vector<ll>> S(N+2, vector<ll>(N+2));
    //vector<Pll> pp(N), qq(N);
    vector<Pll> fx(N+2), fy(N+2);
    rep(i,N){
        cin >> x[i] >> y[i];
        fx[x[i]] = {y[i], i};
        fy[y[i]] = {x[i], i};
    }
    fx[0] = {1e18,-1};
    fy[0] = {1e18,-1};
    fx[N+1] = {-1,-1};
    fy[N+1] = {-1,-1};
    ys[N] = fx[N];
    ys[N+1] = {-1, -1};
    yt[0] = {1e18, -1};
    for(ll i = N-1;i>0;i--){
        ys[i] = max(fx[i], ys[i+1]);
    }
    yt[1] = fx[1];
    for(ll i = 2; i<=N;i++){
        yt[i] = min(fx[i], yt[i-1]);
    }

    xs[N] = fy[N];
    xs[N+1] = {-1, -1};
    xt[0] = {1e18, -1};
    for(ll i = N-1;i>0;i--){
        xs[i] = max(fy[i], xs[i+1]);
    }
    xt[1] = fy[1];
    for(ll i = 2; i<=N;i++){
        xt[i] = min(fy[i], xt[i-1]);
    }



    UnionFind tr(N);
    rep(i,N){
        //ll xx = x[i]-1;
        //ll yy = y[i]-1;
        //cout << "y[i]:" << y[i] << endl;
        //cout << "fx[x[i]-1]:" << fx[x[i]-1].fi << endl;
        //cout << "x[i]-1:" << x[i]-1 << endl;
        if(y[i] > yt[x[i]-1].fi){
            //cout << "a"<<endl;
            tr.unite(i, yt[x[i]-1].se);
        }
        
        if(y[i] < ys[x[i]+1].fi){
            //cout << "b" << x[i]+1 << " " << fx[x[i]+1].fi <<endl;
            tr.unite(i, ys[x[i]+1].se);
        }
        if(x[i] > xt[y[i]-1].fi){
            //cout << "c" << y[i]-1 << " " << fx[y[i]-1].fi <<endl;
            tr.unite(i, xt[y[i]-1].se);
        }
        if(x[i] < xs[y[i]+1].fi){
            //cout << "d" << y[i]+1 << " " << fx[y[i]+1].fi <<endl;
            tr.unite(i, xs[y[i]+1].se);
        }
        /*
        rep(j,N){
            cout << i << " " << tr.getsize(j) << endl;
        }*/
    }
    rep(i,N){
        cout << tr.getsize(i) << endl;
    }
    /*
    sort(pp.begin(), pp.end());
    sort(qq.begin(), qq.end());
    UnionFind tr(N);
    ll id = pp[0].se;
    rep(i,N){
        if(x[id] < x[i] && y[id] < y[i]){
            tr.unite(id, i);
        }
    }
    id = qq[0].se;
    rep(i,N){
        if(x[id] < x[i] && y[id] < y[i]){
            tr.unite(id, i);
        }
    }
    sort(pp.rbegin(), pp.rend());
    sort(qq.rbegin(), qq.rend());
    id = pp[0].se;
    rep(i,N){
        if(x[i] < x[id] && y[i] < y[id]){
            tr.unite(id, i);
        }
    }
    id = qq[0].se;
    rep(i,N){
        if(x[i] < x[id] && y[i] < y[id]){
            tr.unite(id, i);
        }
    }
    rep(i,N){
        cout << tr.getsize(i) << endl;
    }
    /*rep(i,N){
        rep(j,N){
            if(x[j] < x[i] && y[j] < y[i] || x[i] < )
        }
    }
    /*
    rep(i,N+2){
        rep(j,N+1){
            S[i][j+1] += S[i][j];
        }
    }
    rep(i,N+2){
        rep(j,N+1){
            S[j+1][i] += S[j][i];
        }
    }
    rep(i,N){
        ll tm = S[y[i]-1][x[i]-1];
        ll tM = S[N+1][N+1] - S[N+1][x[i]] - S[y[i]][N+1] + S[y[i]][x[i]];
        cout << tm + tM + 1<< endl;
    }*/

}

Measured memory_bytes: 26800