#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cstdlib>
#include<queue>
#include<set>
#include<cstdio>

using namespace std;

#define ll long long
#define rep(i, n) for(int i = 0; i < n; i++)
#define P pair<int, int>

typedef vector<int> vec;
typedef vector<vec> mat;

const ll mod = 1000000007;


int const MAX_N = 200010;
int par[MAX_N]; // 親
int depth[MAX_N]; // 木の深さ
int num[MAX_N];




// n要素で初期化
void init(int n){
    for(int i = 0; i < n; i++){
        par[i] = i;
        depth[i] = 0;
        num[i] = 1;
    }
}

// 木の根を求める
int find(int x){
    if (par[x] == x) {
        return x;
    }else{
        return par[x] = find(par[x]);
    }
}

int count(int x){
    return num[find(x)];
}

// xとyの属する集合を合併
void unite(int x, int y){
    x = find(x);
    y = find(y);
    if (x == y) return;

    if (depth[x] < depth[y]) {
        par[x] = y;
        num[y] += num[x];
    }else{
        par[y] = x;
        num[x] += num[y];
        if (depth[x] == depth[y]) depth[x]++;
    }
}

// xとyが同じ集合に属するか否か
bool same(int x, int y){
    return find(x) == find(y);
}


int main(){
    int n;
    cin >> n;
    set<P> sx1, sx2;
    set<P> sy1, sy2;
    P dec[n];
    rep(i, n) {
        int x, y;
        cin >> x >> y;
        dec[i].first = x;
        dec[i].second = y;
        sx1.insert(P(x,i));
        sy1.insert(P(y,i));
        sx2.insert(P(x,i));
        sy2.insert(P(y,i));
    }
    init(n);
    // rep(i, n){
    //     cout << x[i].first.first << " " << x[i].first.second << endl;
    // }
    while(sx1.size() > 0){
        // for (auto it = sx1.begin(); it != sx1.end(); it++){
        //     cout << (*it).first << ":" << (*it).second << " ";
        // }cout << endl;
        // for (auto it = sy1.begin(); it != sy1.end(); it++){
        //     cout << (*it).first << ":" << (*it).second << " ";
        // }cout << endl;
        P x = *sx1.begin();
        int idx = x.second;
        int y = dec[idx].second;
        sx1.erase(sx1.begin());
        auto itr = sy1.end();
        itr--;
        while((*itr).second != idx){
            // cout << (*itr).first << endl;
            unite((*itr).second, idx);
            sy1.erase(itr);
            int idx_ = (*itr).second;
            sx1.erase(P(dec[idx_].first,idx_));
            // cout << idx_ << endl;
            itr = sy1.end();
            itr--;
        }
        sy1.erase(P(y,idx));

        // cout << i << endl;
    }
    while(sy2.size() > 0){
        P y = *(--sy2.end());
        int idx = y.second;
        int x = dec[idx].first;
        sy2.erase(--sy2.end());
        auto itr = sx2.begin();
        while((*itr).second != idx){
            // cout << (*itr).first << endl;
            unite((*itr).second, idx);
            sx2.erase(itr);
            sy2.erase(P(dec[(*itr).second].second,(*itr).second));
            itr = sx2.begin();
        }
        sx2.erase(P(x,idx));
        // cout << idx << endl;
        // for (auto it = sx2.begin(); it != sx2.end(); it++){
        //     cout << (*it).first << ":" << (*it).second << " ";
        // }cout << endl;
        // for (auto it = sy2.begin(); it != sy2.end(); it++){
        //     cout << (*it).first << ":" << (*it).second << " ";
        // }cout << endl;
        // rep(i, n){
        //     cout << count(i) << endl;
        // }
    }
    // rep(i, n){
    //     cout << num[i] << endl;
    // }
    rep(i, n){
        cout << count(i) << endl;
    }
}

Measured memory_bytes: 45000