#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <bitset>     //UWAGA - w czasie kompilacji musi byc znany rozmiar wektora - nie mozna go zmienic
#include <cassert>
#include <iomanip>        //do setprecision
#include <ctime>
#include <complex>
using namespace std;

#define FOR(i,b,e) for(int i=(b);i<(e);++i)
#define FORQ(i,b,e) for(int i=(b);i<=(e);++i)
#define FORD(i,b,e) for(int i=(b)-1;i>=(e);--i)
#define REP(x, n) for(int x = 0; x < (n); ++x)

#define ST first
#define ND second
#define PB push_back
#define PF push_front
#define MP make_pair
#define LL long long
#define ULL unsigned LL
#define LD long double
#define pii pair<int,int>
#define pll pair<LL,LL>
#define vi vector<int>
#define vl vector<LL>
#define vii vector<vi>
#define vll vector<vl>

const double pi = 3.14159265358979323846264;
const int mod=1000000007;

vector<int> i2g;          // i2g[i] := アイテム i の所属するグループの番号(find)
vector<vector<int>> g2i;  // g2i[g] := グループ g に所属するアイテムたち

void union_init(int n) {
  i2g.resize(n);
  g2i.resize(n);
  for (int i = 0; i < n; ++i) {
    // 最初はアイテム i はグループ i に所属
    i2g[i] = i;
    g2i[i].assign(1, i);
  }
}

int find(int i){
  return i2g[i];
}

// アイテム ia の所属するグループとアイテム ib の所属するグループを 1 つにする
void merge(int ia, int ib) {
  if(i2g[ia]==i2g[ib])return;
  // ia の所属するグループが ib の所属するグループより小さくならないようにする
  if (g2i[i2g[ia]].size() < g2i[i2g[ib]].size()) {
    swap(ia, ib);
  }
  int ga = i2g[ia], gb = i2g[ib];
  // グループ gb に所属する全てのアイテムをグループ ga に移す
  for (int j : g2i[gb]) i2g[j] = ga;
  g2i[ga].insert(g2i[ga].end(), g2i[gb].begin(), g2i[gb].end());
  g2i[gb].clear();
}

// アイテム ia とアイテム ib は同じグループに所属しているか？
bool is_same_group(int ia, int ib) {
  return i2g[ia] == i2g[ib];
}

class BIT//1-index
{
public:
    vector<int> bit;
    int M;

    BIT(int M):
        bit(vector<int>(M+1, 0)), M(M) {}

    int sum(int i) {//1~iまでの和
        if (!i) return 0;
        return bit[i] + sum(i-(i&-i));
    }

    void add(int i, int x) {//bit[i]にxを足す更新
        if (i > M) return;
        bit[i] += x;
        add(i+(i&-i), x);
    }
};


int main(){
	int n;
    cin>>n;
    vi x(n),y(n);
    vector<array<int,3>> v(n);
    BIT bt(n+1);
    FOR(i,0,n){
        cin>>x[i]>>y[i];
        x[i]--;y[i]--;
        v[i]={x[i],y[i],i};
    }
    sort(v.begin(),v.end());
    FOR(i,0,n){
        //cerr<<v[i][0]<<" "<<v[i][1]<<" "<<v[i][2]<<endl;
    }
    union_init(n);
    map<int,int> mp;
    map<int,int> mp2;
    mp[n]=n;
    FOR(i,0,n){
        int yy=v[i][1];
        mp[-yy]=i;
        auto itr=mp.lower_bound(-yy);
        itr++;
        while(itr->second!=n){
            auto idx=itr->second;
            if(!is_same_group(i,idx)){
                merge(i,idx);
            }
            auto itr2=++itr;
            itr--;
            if(itr2->second==n){
                break;
            }else{
                mp.erase(itr);
                itr=itr2;
            }
        }
    }
    FORD(i,n,0){
        int yy=v[i][1];
        auto itr=mp2.lower_bound(yy);
        while(itr!=mp2.end()){
            auto idx=itr->second;
            if(!is_same_group(i,idx)){
                merge(i,idx);
            }
            if(itr==(mp2.end()--)){
                break;
            }else{
                itr=mp2.erase(itr);
            }
        }
        mp2[yy]=i;
    }
    vi ans(n,0);
    FOR(i,0,n){
        ans[v[i][2]]=g2i[i2g[i]].size();
    }
    FOR(i,0,n){
        cout<<ans[i]<<endl;
    }


}


Measured memory_bytes: 23328