#include <bits/stdc++.h>
using namespace std;

#define IOS                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define ll long long
#define pb push_back
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define S(x) (int)(x).size()
#define L(x) (int)(x).length()
#define ld long double
#define mem(x, y) memset(x, y, sizeof x)

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

const int mod = 1e9 + 7;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
pair<int, int> p[200009];
int cnt[200009];
int ind[200009];
int par[200009], sz[200009];
int fin(int v) {
  if (par[v] == -1)
    return par[v] = v;
  if (v == par[v])
    return v;
  return par[v] = fin(par[v]);
}
// union by size
void make_set(int v) {
  par[v] = -1;
  sz[v] = 1;
}

void uni(int a, int b) {
  a = fin(a);
  b = fin(b);
  if (a == b)
    return;
  if (sz[a] < sz[b])
    swap(a, b);
  par[b] = a;
  sz[a] += sz[b];
}

void solve() {
  int n;
  cin >> n;
  for (int i = 0; i < n; i++)
    cin >> p[i].fi >> p[i].se;
  iota(ind, ind + n, 0);
  sort(ind, ind + n, [](int A, int B) { return p[A] < p[B]; });
  for (int i = 0; i < n; i++)
    make_set(i);
  for (int i = 0; i < n; i++) {
    if (par[ind[i]] != -1)
      continue;
    par[ind[i]] = ind[i];
    for (int j = i + 1; j < n; j++)
      if (p[ind[j]].se > p[ind[i]].se)
        uni(ind[i], ind[j]);
  }
  for (int i = 0; i < n; i++)
    cout << sz[fin(i)] << '\\n';
}

int main() {
  IOS int t = 1;
  // cin>>t;
  while (t--) {
    solve();
  }
}

#include <bits/stdc++.h>
using namespace std;

#define IOS                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define ll long long
#define pb push_back
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define S(x) (int)(x).size()
#define L(x) (int)(x).length()
#define ld long double
#define mem(x, y) memset(x, y, sizeof x)

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

const int mod = 1e9 + 7;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;

int pos[200009];
int ind[200009], inv[200009], g[200009];
int ans[200009];
set<int> s;
int par[200009], sz[200009];
int fin(int v) {
  if (par[v] == -1)
    return par[v] = v;
  if (v == par[v])
    return v;
  return par[v] = fin(par[v]);
}

void uni(int a, int b) {
  a = fin(a);
  b = fin(b);
  if (a == b)
    return;
  if (sz[a] < sz[b])
    swap(a, b);
  par[b] = a;
  sz[a] += sz[b];
  g[a] = min(g[a], g[b]);
}
void solve() {
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    int a, b;
    cin >> a >> b;
    pos[a] = b;
    ind[a] = i;
    inv[b] = a;
    s.insert(b);
    par[i] = i;
    sz[i] = 1;
    g[i] = b;
  }
  set<int> small;
  for (int i = 1; i <= n; i++) {
    auto it = small.upper_bound(pos[i]);
    while (!small.empty() && it != small.begin()) {
      it--;
      assert(pos[i] > *it);
      uni(ind[i], ind[inv[*it]]);
      small.erase(it);
      it = small.upper_bound(pos[i]);
    }
    small.insert(g[fin(ind[i])]);
  }
  for (int i = 1; i <= n; i++)
    cout << sz[fin(i)] << '\\n';
}

int main() {
  IOS int t = 1;
  // cin>>t;
  while (t--) {
    solve();
  }
}


#if loc || local
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (ll i = 0; i < ll(n); ++i)
#define repr(i, n) for (ll i = ll(n); i-- > 0;)
using ll = int_fast64_t;
using pll = pair<ll, ll>;
constexpr ll INF = 1LL << 60;
constexpr ll MOD = 1e9 + 7;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
#if loc || local
template <class T> void dump(T &&t) { cerr << t << endl; }
template <class T, class... Ts> void dump(T &&h, Ts &&...t) {
  cerr << h << ", ";
  dump(forward<Ts>(t)...);
}
#else
void dump() {}
template <class T, class... Ts> void dump(T &&h, Ts &&...t) {}
#endif
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &elemnt : v)
    is >> elemnt;
  return is;
}
template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  for (auto const &vi : v)
    os << vi << " ";
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  os << p.first << "," << p.second;
  return os;
}
template <class T> vector<T> vec(size_t a) { return vector<T>(a); }
template <class T, class... Ts> auto vec(size_t a, Ts... ts) {
  return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...));
}
struct union_find {
  size_t n;
  std::vector<int> par;
  size_t group;
  union_find() {}
  union_find(size_t _n) : n(_n), group(_n) { par.resize(n, -1); }
  void reset(size_t _n) {
    n = _n;
    group = n;
    par.clear();
    par.resize(n, -1);
  }
  int root(int k) {
    if (par[k] < 0)
      return k;
    return par[k] = root(par[k]);
  }
  int size(int k) {
    k = root(k);
    return -par[k];
  }
  int operator[](int k) { return size(k); }
  bool unite(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b)
      return false;
    if (size(a) < size(b))
      std::swap(a, b);
    group--;
    par[a] += par[b];
    par[b] = a;
    return true;
  }
  bool operator()(int a, int b) { return unite(a, b); }
  bool same(int a, int b) { return root(a) == root(b); }
};
using T3 = tuple<ll, ll, ll>;
using T4 = tuple<ll, ll, ll, ll>;
signed main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  constexpr char newl = '\\n';

  int n;
  cin >> n;
  vector<T3> points(n);
  rep(i, n) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    points[i] = {x, y, i};
  }
  sort(begin(points), end(points));

  union_find uni(n);
  stack<pll> st;
  rep(i, n) {
    auto [xi, yi, ii] = points[i];
    stack<pll> nxt;
    ll merge_min = yi;
    while (!st.empty()) {
      auto [yj, j] = st.top();
      st.pop();
      if (yi > yj) {
        uni.unite(ii, j);
        chmin(merge_min, yj);
      } else {
        nxt.emplace(yj, j);
      }
    }
    nxt.emplace(merge_min, ii);
    st.swap(nxt);
  }
  rep(k, n) cout << uni[k] << newl;
}

#if loc || local
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (ll i = 0; i < ll(n); ++i)
#define repr(i, n) for (ll i = ll(n); i-- > 0;)
using ll = int_fast64_t;
using pll = pair<ll, ll>;
constexpr ll INF = 1LL << 60;
constexpr ll MOD = 1e9 + 7;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
#if loc || local
template <class T> void dump(T &&t) { cerr << t << endl; }
template <class T, class... Ts> void dump(T &&h, Ts &&...t) {
  cerr << h << ", ";
  dump(forward<Ts>(t)...);
}
#else
void dump() {}
template <class T, class... Ts> void dump(T &&h, Ts &&...t) {}
#endif
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &elemnt : v)
    is >> elemnt;
  return is;
}
template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  for (auto const &vi : v)
    os << vi << " ";
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  os << p.first << "," << p.second;
  return os;
}
template <class T> vector<T> vec(size_t a) { return vector<T>(a); }
template <class T, class... Ts> auto vec(size_t a, Ts... ts) {
  return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...));
}
struct union_find {
  size_t n;
  std::vector<int> par;
  size_t group;
  union_find() {}
  union_find(size_t _n) : n(_n), group(_n) { par.resize(n, -1); }
  void reset(size_t _n) {
    n = _n;
    group = n;
    par.clear();
    par.resize(n, -1);
  }
  int root(int k) {
    if (par[k] < 0)
      return k;
    return par[k] = root(par[k]);
  }
  int size(int k) {
    k = root(k);
    return -par[k];
  }
  int operator[](int k) { return size(k); }
  bool unite(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b)
      return false;
    if (size(a) < size(b))
      std::swap(a, b);
    group--;
    par[a] += par[b];
    par[b] = a;
    return true;
  }
  bool operator()(int a, int b) { return unite(a, b); }
  bool same(int a, int b) { return root(a) == root(b); }
};
using T3 = tuple<ll, ll, ll>;
using T4 = tuple<ll, ll, ll, ll>;
signed main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  constexpr char newl = '\\n';

  int n;
  cin >> n;
  vector<T3> points(n);
  rep(i, n) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    points[i] = {x, y, i};
  }
  sort(begin(points), end(points));

  union_find uni(n);
  set<pll> st;
  rep(i, n) {
    auto [xi, yi, ii] = points[i];
    ll merge_min = yi;
    for (auto itr = begin(st); itr != end(st);) {
      auto [yj, j] = *itr;
      if (yj > yi)
        break;
      uni.unite(ii, j);
      chmin(merge_min, yj);
      itr = st.erase(itr);
    }
    st.emplace(merge_min, ii);
  }
  rep(k, n) cout << uni[k] << newl;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\\n'
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define con continue
#define ub upper_bound
#define lb lower_bound
#define sum(a) (accumulate((a).begin(), (a).end(), 0ll))
#define mine(a) (*min_element((a).begin(), (a).end()))
#define maxe(a) (*max_element((a).begin(), (a).end()))
#define mini(a) (min_element((a).begin(), (a).end()) - (a).begin())
#define maxi(a) (max_element((a).begin(), (a).end()) - (a).begin())
#define lowb(a, x) (lower_bound((a).begin(), (a).end(), (x)) - (a).begin())
#define uppb(a, x) (upper_bound((a).begin(), (a).end(), (x)) - (a).begin())

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

const int dx8[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dy8[] = {0, -1, 0, 1, 1, -1, 1, -1};

vector<ll> arr, rank1;
unordered_map<ll, ll> m;

ll p(ll x) {

  if (x == arr[x])
    return x;
  return arr[x] = p(arr[x]);
}
ll join(ll x, ll y) {

  x = p(x), y = p(y);
  if (rank1[x] < rank1[y])
    arr[x] = y;
  else if (rank1[x] > rank1[y])
    arr[y] = x;
  else {
    rank1[y]++;
    arr[x] = y;
  }
}

void solve() {
  ll n;
  cin >> n;
  vector<pair<ll, pair<ll, ll>>> ans;

  arr.clear();
  rank1.clear();
  for (ll i = 0; i < n; i++) {
    rank1.pb(0);
    arr.pb(i);
  }

  for (ll i = 0; i < n; i++) {
    ll x, y;
    cin >> x >> y;
    ans.pb({x * -1, {i, y}});
  }
  sort(ans.begin(), ans.end());
  stack<ll> s;
  for (ll i = n - 1; i >= 0; i--) {
    while (!s.empty() && ans[i].ss.ss > ans[s.top()].ss.ss) {
      join(ans[i].ss.ff, ans[s.top()].ss.ff);
      s.pop();
    }
    s.push(i);
  }
  m.clear();
  for (ll i = 0; i < arr.size(); i++) {

    m[p(i)]++;
  }
  for (ll i = 0; i < n; i++) {
    cout << m[p(i)] << endl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  solve();
}

#include <bits/stdc++.h>
using namespace std;
#define ll int
#define endl '\\n'
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define con continue
#define ub upper_bound
#define lb lower_bound
#define sum(a) (accumulate((a).begin(), (a).end(), 0ll))
#define mine(a) (*min_element((a).begin(), (a).end()))
#define maxe(a) (*max_element((a).begin(), (a).end()))
#define mini(a) (min_element((a).begin(), (a).end()) - (a).begin())
#define maxi(a) (max_element((a).begin(), (a).end()) - (a).begin())
#define lowb(a, x) (lower_bound((a).begin(), (a).end(), (x)) - (a).begin())
#define uppb(a, x) (upper_bound((a).begin(), (a).end(), (x)) - (a).begin())

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

const int dx8[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dy8[] = {0, -1, 0, 1, 1, -1, 1, -1};

vector<ll> arr, rank1;
unordered_map<ll, ll> m;

ll p(ll x) {

  if (x == arr[x])
    return x;
  return arr[x] = p(arr[x]);
}
void join(ll x, ll y) {

  x = p(x), y = p(y);
  if (rank1[x] < rank1[y])
    arr[x] = y;
  else if (rank1[x] > rank1[y])
    arr[y] = x;
  else {
    rank1[y]++;
    arr[x] = y;
  }
}

void solve() {
  ll n;
  cin >> n;
  vector<pair<ll, pair<ll, ll>>> ans, ans2;

  arr.clear();
  rank1.clear();
  for (ll i = 0; i < n; i++) {
    rank1.pb(0);
    arr.pb(i);
  }

  for (ll i = 0; i < n; i++) {
    ll x, y;
    cin >> x >> y;
    ans.pb({x * -1, {i, y}});
    ans2.pb({y * -1, {i, x}});
  }
  sort(ans.begin(), ans.end());
  stack<ll> s;
  for (ll i = n - 1; i >= 0; i--) {
    while (!s.empty() && ans[i].ss.ss > ans[s.top()].ss.ss) {
      join(ans[i].ss.ff, ans[s.top()].ss.ff);
      s.pop();
    }
    s.push(i);
  }

  sort(ans2.begin(), ans2.end());
  stack<ll> s2;
  for (ll i = n - 1; i >= 0; i--) {
    while (!s2.empty() && ans2[i].ss.ss > ans2[s2.top()].ss.ss) {
      join(ans2[i].ss.ff, ans2[s2.top()].ss.ff);
      s2.pop();
    }
    s2.push(i);
  }
  stack<ll> s3;
  for (ll i = 0; i < n; i++) {
    while (!s3.empty() && ans[i].ss.ss < ans[s3.top()].ss.ss) {
      join(ans[i].ss.ff, ans[s3.top()].ss.ff);
      s3.pop();
    }
    s3.push(i);
  }

  stack<ll> s4;
  for (ll i = 0; i < n; i++) {
    while (!s4.empty() && ans2[i].ss.ss < ans2[s4.top()].ss.ss) {
      join(ans2[i].ss.ff, ans2[s4.top()].ss.ff);
      s4.pop();
    }
    s4.push(i);
  }

  m.clear();
  for (ll i = 0; i < n; i++) {

    m[p(i)]++;
  }
  for (ll i = 0; i < n; i++) {
    cout << m[p(i)] << endl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  solve();
}


#include <bits/stdc++.h>

using namespace std;

void __print(int x) { cout << x; }
void __print(long x) { cout << x; }
void __print(long long x) { cout << x; }
void __print(unsigned x) { cout << x; }
void __print(unsigned long x) { cout << x; }
void __print(unsigned long long x) { cout << x; }
void __print(float x) { cout << x; }
void __print(double x) { cout << x; }
void __print(long double x) { cout << x; }
void __print(char x) { cout << '\\'' << x << '\\''; }
void __print(const char *x) { cout << '\\"' << x << '\\"'; }
void __print(const string &x) { cout << '\\"' << x << '\\"'; }
void __print(bool x) { cout << (x ? "true" : "false"); }
template <typename T, typename V> void __print(const pair<T, V> &x) {
  cout << '{';
  __print(x.first);
  cout << ',';
  __print(x.second);
  cout << '}';
}
template <typename T> void __print(const T &x) {
  int f = 0;
  cout << '{';
  for (auto &i : x)
    cout << (f++ ? "," : ""), __print(i);
  cout << "}";
}
void _print() { cout << "]\\n"; }
template <typename T, typename... V> void _print(T t, V... v) {
  __print(t);
  if (sizeof...(v))
    cout << ", ";
  _print(v...);
}
#ifndef ONLINE_JUDGE
#define debug(x...)                                                            \\
  cout << "[" << #x << "] = [";                                                \\
  _print(x)
#else
#define debug(x...)
#endif
#define ll long long
#define all(x) (x).begin(), (x).end()
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int d4i[4] = {-1, 0, 1, 0}, d4j[4] = {0, 1, 0, -1};
const int d8i[8] = {-1, -1, 0, 1, 1, 1, 0, -1},
          d8j[8] = {0, 1, 1, 1, 0, -1, -1, -1};

const int NMAX = 200'000 + 4;
int n, ind[NMAX], y[NMAX];

class UnionFind {
private:
  vector<int> p, rank, setSize;
  int numSets;

public:
  UnionFind(int N) {
    setSize.assign(N, 1);
    numSets = N;
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++)
      p[i] = i;
  }

  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }

  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }

  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      numSets--;
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        setSize[x] += setSize[y];
      } else {
        p[x] = y;
        setSize[y] += setSize[x];
        if (rank[x] == rank[y])
          rank[y]++;
      }
    }
  }
  int numDisjointSets() { return numSets; }
  int sizeOfSet(int i) { return setSize[findSet(i)]; }
};

void solve() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    int a, b;
    cin >> a >> b;
    y[a] = b;
    ind[a] = i;
  }

  set<pii> s;
  UnionFind uf(n + 1);
  for (int i = 1; i <= n; ++i) {
    auto it = s.insert({y[i], ind[i]}).first;
    while (it != s.begin()) {
      it = prev(it);
      uf.unionSet(ind[i], it->second);
    }
  }

  for (int i = 1; i <= n; ++i)
    cout << uf.sizeOfSet(i) << endl;
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  // int t;
  // cin >> t;
  // while (t--)
  solve();

  return 0;
}

#include <bits/stdc++.h>

using namespace std;

void __print(int x) { cout << x; }
void __print(long x) { cout << x; }
void __print(long long x) { cout << x; }
void __print(unsigned x) { cout << x; }
void __print(unsigned long x) { cout << x; }
void __print(unsigned long long x) { cout << x; }
void __print(float x) { cout << x; }
void __print(double x) { cout << x; }
void __print(long double x) { cout << x; }
void __print(char x) { cout << '\\'' << x << '\\''; }
void __print(const char *x) { cout << '\\"' << x << '\\"'; }
void __print(const string &x) { cout << '\\"' << x << '\\"'; }
void __print(bool x) { cout << (x ? "true" : "false"); }
template <typename T, typename V> void __print(const pair<T, V> &x) {
  cout << '{';
  __print(x.first);
  cout << ',';
  __print(x.second);
  cout << '}';
}
template <typename T> void __print(const T &x) {
  int f = 0;
  cout << '{';
  for (auto &i : x)
    cout << (f++ ? "," : ""), __print(i);
  cout << "}";
}
void _print() { cout << "]\\n"; }
template <typename T, typename... V> void _print(T t, V... v) {
  __print(t);
  if (sizeof...(v))
    cout << ", ";
  _print(v...);
}
#ifndef ONLINE_JUDGE
#define debug(x...)                                                            \\
  cout << "[" << #x << "] = [";                                                \\
  _print(x)
#else
#define debug(x...)
#endif
#define ll long long
#define all(x) (x).begin(), (x).end()
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int d4i[4] = {-1, 0, 1, 0}, d4j[4] = {0, 1, 0, -1};
const int d8i[8] = {-1, -1, 0, 1, 1, 1, 0, -1},
          d8j[8] = {0, 1, 1, 1, 0, -1, -1, -1};

const int NMAX = 200'000 + 4;
int n, ind[NMAX], y[NMAX];

class UnionFind {
private:
  vector<int> p, rank, setSize;
  int numSets;

public:
  UnionFind(int N) {
    setSize.assign(N, 1);
    numSets = N;
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++)
      p[i] = i;
  }

  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }

  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }

  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      numSets--;
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        setSize[x] += setSize[y];
      } else {
        p[x] = y;
        setSize[y] += setSize[x];
        if (rank[x] == rank[y])
          rank[y]++;
      }
    }
  }
  int numDisjointSets() { return numSets; }
  int sizeOfSet(int i) { return setSize[findSet(i)]; }
};

void solve() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    int a, b;
    cin >> a >> b;
    y[a] = b;
    ind[a] = i;
  }

  set<pii> s;
  UnionFind uf(n + 1);
  for (int i = 1; i <= n; ++i) {
    auto it = s.insert({y[i], ind[i]}).first;
    vector<pii> tmp;
    while (it != s.begin()) {
      tmp.push_back(*it);
      it = prev(it);
      uf.unionSet(ind[i], it->second);
    }
    for (auto x : tmp)
      s.erase(x);
  }

  for (int i = 1; i <= n; ++i)
    cout << uf.sizeOfSet(i) << endl;
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  // int t;
  // cin >> t;
  // while (t--)
  solve();

  return 0;
}


#include "bits/stdc++.h"

#include <algorithm>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
  int x = 0;
  while ((1U << x) < (unsigned int)(n))
    x++;
  return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
  unsigned long index;
  _BitScanForward(&index, n);
  return index;
#else
  return __builtin_ctz(n);
#endif
}

} // namespace internal

} // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
public:
  segtree() : segtree(0) {}
  segtree(int n) : segtree(std::vector<S>(n, e())) {}
  segtree(const std::vector<S> &v) : _n(int(v.size())) {
    log = internal::ceil_pow2(_n);
    size = 1 << log;
    d = std::vector<S>(2 * size, e());
    for (int i = 0; i < _n; i++)
      d[size + i] = v[i];
    for (int i = size - 1; i >= 1; i--) {
      update(i);
    }
  }

  void set(int p, S x) {
    assert(0 <= p && p < _n);
    p += size;
    d[p] = x;
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  S get(int p) {
    assert(0 <= p && p < _n);
    return d[p + size];
  }

  S prod(int l, int r) {
    assert(0 <= l && l <= r && r <= _n);
    S sml = e(), smr = e();
    l += size;
    r += size;

    while (l < r) {
      if (l & 1)
        sml = op(sml, d[l++]);
      if (r & 1)
        smr = op(d[--r], smr);
      l >>= 1;
      r >>= 1;
    }
    return op(sml, smr);
  }

  S all_prod() { return d[1]; }

  template <bool (*f)(S)> int max_right(int l) {
    return max_right(l, [](S x) { return f(x); });
  }
  template <class F> int max_right(int l, F f) {
    assert(0 <= l && l <= _n);
    assert(f(e()));
    if (l == _n)
      return _n;
    l += size;
    S sm = e();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!f(op(sm, d[l]))) {
        while (l < size) {
          l = (2 * l);
          if (f(op(sm, d[l]))) {
            sm = op(sm, d[l]);
            l++;
          }
        }
        return l - size;
      }
      sm = op(sm, d[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }

  template <bool (*f)(S)> int min_left(int r) {
    return min_left(r, [](S x) { return f(x); });
  }
  template <class F> int min_left(int r, F f) {
    assert(0 <= r && r <= _n);
    assert(f(e()));
    if (r == 0)
      return 0;
    r += size;
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!f(op(d[r], sm))) {
        while (r < size) {
          r = (2 * r + 1);
          if (f(op(d[r], sm))) {
            sm = op(d[r], sm);
            r--;
          }
        }
        return r + 1 - size;
      }
      sm = op(d[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

private:
  int _n, size, log;
  std::vector<S> d;

  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

} // namespace atcoder

using namespace std;
typedef long long li;

li li_min(li x, li y) { return min(x, y); }

li li_min_e() { return 1LL << 60; }

li li_max(li x, li y) { return max(x, y); }

li li_max_e() { return -li_min_e(); }

using min_segtree = atcoder::segtree<li, li_min, li_min_e>;
using max_segtree = atcoder::segtree<li, li_max, li_max_e>;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  li n;
  cin >> n;
  min_segtree ys(n);
  max_segtree xs(n);
  set<pair<li, li>> xis;
  set<pair<li, li>> yis;
  vector<li> ans(n), ixs, iys;

  for (int i = 0; i < n; ++i) {
    li x, y;
    cin >> x >> y;
    x--;
    y--;
    xis.emplace(x, i);
    yis.emplace(y, i);
    xs.set(y, x);
    ys.set(x, y);
    ixs.push_back(x);
    iys.push_back(y);
  }

  while (not xis.empty()) {
    const li leftmost_x = xis.begin()->first;
    li cur_y = ys.get(leftmost_x);
    li cur_x = leftmost_x;
    while (true) {
      li next_x = xs.prod(cur_y + 1, n);
      if (next_x <= cur_x) {
        break;
      }
      cur_x = next_x;

      li next_y = ys.prod(0, cur_x);
      if (next_y >= cur_y) {
        break;
      }
      cur_y = next_y;
    }

    set<li> uni;
    for (auto p : xis) {
      const li x = p.first;
      if (x <= cur_x) {
        uni.emplace(p.second);
      } else {
        break;
      }
    }
    for (auto p : yis) {
      const li y = p.first;
      if (y >= cur_y) {
        uni.emplace(p.second);
      }
    }
    for (auto i : uni) {
      const li x = ixs[i];
      const li y = iys[i];
      ans[i] = uni.size();
      xis.erase(make_pair(x, i));
      yis.erase(make_pair(y, i));
    }
  }
  for (int i = 0; i < n; ++i) {
    cout << ans[i] << endl;
  }

  return 0;
}

#include "bits/stdc++.h"

#include <algorithm>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
  int x = 0;
  while ((1U << x) < (unsigned int)(n))
    x++;
  return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
  unsigned long index;
  _BitScanForward(&index, n);
  return index;
#else
  return __builtin_ctz(n);
#endif
}

} // namespace internal

} // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
public:
  segtree() : segtree(0) {}
  segtree(int n) : segtree(std::vector<S>(n, e())) {}
  segtree(const std::vector<S> &v) : _n(int(v.size())) {
    log = internal::ceil_pow2(_n);
    size = 1 << log;
    d = std::vector<S>(2 * size, e());
    for (int i = 0; i < _n; i++)
      d[size + i] = v[i];
    for (int i = size - 1; i >= 1; i--) {
      update(i);
    }
  }

  void set(int p, S x) {
    assert(0 <= p && p < _n);
    p += size;
    d[p] = x;
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  S get(int p) {
    assert(0 <= p && p < _n);
    return d[p + size];
  }

  S prod(int l, int r) {
    assert(0 <= l && l <= r && r <= _n);
    S sml = e(), smr = e();
    l += size;
    r += size;

    while (l < r) {
      if (l & 1)
        sml = op(sml, d[l++]);
      if (r & 1)
        smr = op(d[--r], smr);
      l >>= 1;
      r >>= 1;
    }
    return op(sml, smr);
  }

  S all_prod() { return d[1]; }

  template <bool (*f)(S)> int max_right(int l) {
    return max_right(l, [](S x) { return f(x); });
  }
  template <class F> int max_right(int l, F f) {
    assert(0 <= l && l <= _n);
    assert(f(e()));
    if (l == _n)
      return _n;
    l += size;
    S sm = e();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!f(op(sm, d[l]))) {
        while (l < size) {
          l = (2 * l);
          if (f(op(sm, d[l]))) {
            sm = op(sm, d[l]);
            l++;
          }
        }
        return l - size;
      }
      sm = op(sm, d[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }

  template <bool (*f)(S)> int min_left(int r) {
    return min_left(r, [](S x) { return f(x); });
  }
  template <class F> int min_left(int r, F f) {
    assert(0 <= r && r <= _n);
    assert(f(e()));
    if (r == 0)
      return 0;
    r += size;
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!f(op(d[r], sm))) {
        while (r < size) {
          r = (2 * r + 1);
          if (f(op(d[r], sm))) {
            sm = op(d[r], sm);
            r--;
          }
        }
        return r + 1 - size;
      }
      sm = op(d[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

private:
  int _n, size, log;
  std::vector<S> d;

  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

} // namespace atcoder

using namespace std;
typedef long long li;

li li_min(li x, li y) { return min(x, y); }

li li_min_e() { return 1LL << 60; }

li li_max(li x, li y) { return max(x, y); }

li li_max_e() { return -li_min_e(); }

using min_segtree = atcoder::segtree<li, li_min, li_min_e>;
using max_segtree = atcoder::segtree<li, li_max, li_max_e>;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  li n;
  cin >> n;
  min_segtree ys(n);
  max_segtree xs(n);
  set<pair<li, li>> xis;
  set<pair<li, li>> yis;
  vector<li> ans(n), ixs, iys;

  for (int i = 0; i < n; ++i) {
    li x, y;
    cin >> x >> y;
    x--;
    y--;
    xis.emplace(x, i);
    yis.emplace(y, i);
    xs.set(y, x);
    ys.set(x, y);
    ixs.push_back(x);
    iys.push_back(y);
  }

  while (not xis.empty()) {
    const li leftmost_x = xis.begin()->first;
    li cur_y = ys.get(leftmost_x);
    li cur_x = leftmost_x;
    while (true) {
      li next_x = xs.prod(cur_y + 1, n);
      if (next_x <= cur_x) {
        break;
      }
      cur_x = next_x;

      li next_y = ys.prod(0, cur_x);
      if (next_y >= cur_y) {
        break;
      }
      cur_y = next_y;
    }

    set<li> uni;
    for (auto p : xis) {
      const li x = p.first;
      if (x <= cur_x) {
        uni.emplace(p.second);
      } else {
        break;
      }
    }
    for (auto p : yis) {
      const li y = p.first;
      if (y >= cur_y) {
        uni.emplace(p.second);
      } else {
        break;
      }
    }
    for (auto i : uni) {
      const li x = ixs[i];
      const li y = iys[i];
      ans[i] = uni.size();
      xis.erase(make_pair(x, i));
      yis.erase(make_pair(y, i));
    }
  }
  for (int i = 0; i < n; ++i) {
    cout << ans[i] << endl;
  }

  return 0;
}


#include <algorithm>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
#define MOD 1000000007
using namespace std;
typedef long long ll;
#include <cstring>
int n, m;

struct unionfind {
  int parent;
  int node;
  int edge;
};
unionfind g[100001];

void init() {
  for (int i = 0; i <= n; i++) {
    g[i].parent = i;
    g[i].node = 1;
    g[i].edge = 0;
  }
}

int ufind(int x) {
  if (x == g[x].parent) {
    return x;
  }
  int res = ufind(g[x].parent);
  g[x].node = g[res].node;
  g[x].edge = g[res].edge;
  g[x].parent = res;
  return res;
}

void umerge(int x, int y) {
  g[x].node += g[y].node;
  g[x].edge += g[y].edge + 1;
  g[y].parent = x;
}

int main() {
  int x, y, flag;
  cin >> n;
  vector<int> ans(n + 1), dp(n + 5);
  set<pair<int, int>> s;
  vector<pair<pair<int, int>, int>> v;
  for (int i = 0; i < n; i++) {
    cin >> x >> y;
    v.push_back({{x, y}, i});
  }
  sort(v.begin(), v.end());
  init();
  s.insert({v[0].first.second, v[0].second});
  for (int i = 1; i < n; i++) {
    y = min(v[i].first.second, s.begin()->first);
    while (!s.empty() && s.begin()->first < v[i].first.second) {
      umerge(v[i].second, s.begin()->second);
      s.erase(s.begin());
    }
    s.insert({y, v[i].second});
  }
  for (int i = 0; i < n; i++) {
    x = ufind(i);
    cout << g[x].node << endl;
  }
}

#include <algorithm>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
#define MOD 1000000007
using namespace std;
typedef long long ll;
#include <cstring>
int n, m;

struct unionfind {
  int parent;
  int node;
  int edge;
};
unionfind g[200001];

void init() {
  for (int i = 0; i <= n; i++) {
    g[i].parent = i;
    g[i].node = 1;
    g[i].edge = 0;
  }
}

int ufind(int x) {
  if (x == g[x].parent) {
    return x;
  }
  int res = ufind(g[x].parent);
  g[x].node = g[res].node;
  g[x].edge = g[res].edge;
  g[x].parent = res;
  return res;
}

void umerge(int x, int y) {
  g[x].node += g[y].node;
  g[x].edge += g[y].edge + 1;
  g[y].parent = x;
}

int main() {
  int x, y, flag;
  cin >> n;
  vector<int> ans(n + 1), dp(n + 5);
  set<pair<int, int>> s;
  vector<pair<pair<int, int>, int>> v;
  for (int i = 0; i < n; i++) {
    cin >> x >> y;
    v.push_back({{x, y}, i});
  }
  sort(v.begin(), v.end());
  init();
  s.insert({v[0].first.second, v[0].second});
  for (int i = 1; i < n; i++) {
    y = min(v[i].first.second, s.begin()->first);
    while (!s.empty() && s.begin()->first < v[i].first.second) {
      umerge(v[i].second, s.begin()->second);
      s.erase(s.begin());
    }
    s.insert({y, v[i].second});
  }
  for (int i = 0; i < n; i++) {
    x = ufind(i);
    cout << g[x].node << endl;
  }
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define sz(v) (int)((v).size())
#define fs first
#define sd second

typedef long long ll;

typedef pair<int, int> pi;
typedef pair<pi, int> ppi;

typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<pi> vpi;
typedef vector<vpi> vvpi;
typedef vector<ppi> vppi;

void fast() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
}

vector<string> vec_splitter(string s) {
  s += ',';
  vector<string> res;
  while (!s.empty()) {
    res.push_back(s.substr(0, s.find(',')));
    s = s.substr(s.find(',') + 1);
  }
  return res;
}

void debug_out(vector<string> __attribute__((unused)) args,
               __attribute__((unused)) int idx,
               __attribute__((unused)) int LINE_NUM) {
  cerr << endl;
}
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
  if (idx > 0)
    cerr << ", ";
  else
    cerr << "Line(" << LINE_NUM << ") ";
  stringstream ss;
  ss << H;
  cerr << args[idx] << " = " << ss.str();
  debug_out(args, idx + 1, LINE_NUM, T...);
}

#ifdef LOCAL
#define debug(...)                                                             \\
  debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif

double get_time() { return 1.0 * clock() / CLOCKS_PER_SEC; }

const int MAX = 2E5 + 100;

int upd(vector<int> &f, int pos, int del) {
  int siz = f.size();
  for (; pos < siz; pos |= pos + 1)
    f[pos] += del;
}

int get(const vector<int> &f, int pos) {
  int ret = 0;
  for (; pos >= 0; pos = (pos & (pos + 1)) - 1)
    ret += f[pos];

  return ret;
}

int main() {
  int n;
  cin >> n;
  vector<int> x(n), y(n), res(n);
  vector<pair<int, int>> points;
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
    points.push_back({x[i], y[i]});
  }

  sort(points.begin(), points.end());
  // cout << '\\n';
  // for(auto pp : points) {
  // 	cout << pp.first << ' ' << pp.second << '\\n';
  // }

  vector<int> f1(n + 1), f2(n + 1);
  for (int i = 1; i <= n; i++) {
    upd(f2, i, 1);
  }

  for (int i = 0; i < n; i++) {
    int a = points[i].first, b = points[i].second;
    res[i] = get(f1, b) + (get(f2, n) - get(f2, b - 1));
    upd(f1, b, 1);
    upd(f2, b, -1);
  }

  for (int i = 0; i < n; i++) {
    cout << res[x[i] - 1] << '\\n';
  }
}

#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define sz(v) (int)((v).size())
#define fs first
#define sd second

typedef long long ll;

typedef pair<int, int> pi;
typedef pair<pi, int> ppi;

typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<pi> vpi;
typedef vector<vpi> vvpi;
typedef vector<ppi> vppi;

void fast() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
}

vector<string> vec_splitter(string s) {
  s += ',';
  vector<string> res;
  while (!s.empty()) {
    res.push_back(s.substr(0, s.find(',')));
    s = s.substr(s.find(',') + 1);
  }
  return res;
}

void debug_out(vector<string> __attribute__((unused)) args,
               __attribute__((unused)) int idx,
               __attribute__((unused)) int LINE_NUM) {
  cerr << endl;
}
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
  if (idx > 0)
    cerr << ", ";
  else
    cerr << "Line(" << LINE_NUM << ") ";
  stringstream ss;
  ss << H;
  cerr << args[idx] << " = " << ss.str();
  debug_out(args, idx + 1, LINE_NUM, T...);
}

#ifdef LOCAL
#define debug(...)                                                             \\
  debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif

double get_time() { return 1.0 * clock() / CLOCKS_PER_SEC; }

const int MAX = 2E5 + 100;

void upd(vector<int> &f, int pos, int del) {
  int siz = f.size();
  for (; pos < siz; pos |= pos + 1)
    f[pos] += del;
}

int get(vector<int> &f, int pos) {
  int ret = 0;
  for (; pos >= 0; pos = (pos & (pos + 1)) - 1)
    ret += f[pos];

  return ret;
}

int main() {
  int n;
  cin >> n;
  vector<int> x(n), y(n), res(n);
  vector<pair<int, int>> points;
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
    points.push_back({x[i], y[i]});
  }

  sort(points.begin(), points.end());
  // cout << '\\n';
  // for(auto pp : points) {
  // 	cout << pp.first << ' ' << pp.second << '\\n';
  // }

  // vector<int> f1(n + 1), f2(n + 1);
  // for(int i = 1; i <= n; i++) {
  // 	upd(f2, i, 1);
  // }

  // for(int i = 0; i < n; i++) {
  // 	int a = points[i].first, b = points[i].second;
  // 	res[i] = get(f1, b) + (get(f2, n) - get(f2, b - 1));
  // 	upd(f1, b, 1);
  // 	upd(f2, b, -1);
  // }

  // for(int i = 0; i < n; i++) {
  // 	cout << res[x[i] - 1] << '\\n';
  // }

  set<int> s;
  for (int i = 1; i <= n; i++)
    s.insert(i);

  for (int i = 0; i < n; i++) {
    int j = i;
    int mn = points[i].second;
    s.erase(points[i].second);

    while (j + 1 < n && *s.rbegin() > mn) {
      j++;
      mn = min(mn, points[j].second);
      s.erase(points[j].second);
    }

    for (int k = i; k <= j; k++)
      res[points[k].first - 1] = j - i + 1;

    i = j;
  }

  for (int i = 0; i < n; i++)
    cout << res[x[i] - 1] << '\\n';
}


#include <bits/stdc++.h>

using namespace std;

using ll = long long;

constexpr char newl = '\\n';

struct UnionFind {
  // 各要素が属する集合の代表(根)を管理する
  // もし、要素xが根であればdata[x]は負の値を取り、-data[x]はxが属する集合の大きさに等しい
  vector<int> data;

  UnionFind(int sz) : data(sz, -1) {}

  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    bool is_union = (x != y);
    if (is_union) {
      if (data[x] > data[y])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return is_union;
  }

  int find(int x) {
    if (data[x] < 0) { // 要素xが根である
      return x;
    } else {
      data[x] = find(
          data[x]); // data[x]がxの属する集合の根でない場合、根になるよう更新される
      return data[x];
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }

  int size(int x) { return -data[find(x)]; }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  int n;
  cin >> n;

  vector<int> x(n), y(n);
  vector<int> xtoi(n);
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
    --x[i];
    --y[i];
    xtoi[x[i]] = i;
  }

  map<int, int> memo;
  UnionFind uf(n);
  for (int xx = n - 1; xx >= 0; --xx) {
    int i = xtoi[xx];
    for (auto it = memo.lower_bound(y[i]); it != memo.end(); ++it) {
      uf.unite(i, it->second);
    }
    memo[y[i]] = i;
  }

  for (int i = 0; i < n; i++) {
    cout << uf.size(i) << newl;
  }

  return 0;
}

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

constexpr char newl = '\\n';

struct UnionFind {
  // 各要素が属する集合の代表(根)を管理する
  // もし、要素xが根であればdata[x]は負の値を取り、-data[x]はxが属する集合の大きさに等しい
  vector<int> data;

  UnionFind(int sz) : data(sz, -1) {}

  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    bool is_union = (x != y);
    if (is_union) {
      if (data[x] > data[y])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return is_union;
  }

  int find(int x) {
    if (data[x] < 0) { // 要素xが根である
      return x;
    } else {
      data[x] = find(
          data[x]); // data[x]がxの属する集合の根でない場合、根になるよう更新される
      return data[x];
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }

  int size(int x) { return -data[find(x)]; }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  int n;
  cin >> n;

  vector<int> x(n), y(n);
  vector<int> xtoi(n);
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
    --x[i];
    --y[i];
    xtoi[x[i]] = i;
  }

  map<int, int> memo;
  UnionFind uf(n);
  for (int xx = n - 1; xx >= 0; --xx) {
    int i = xtoi[xx];
    int lasti = i;
    for (auto it = memo.lower_bound(y[i]); it != memo.end();) {
      uf.unite(i, it->second);
      lasti = it->second;
      it = memo.erase(it);
    }
    memo[y[lasti]] = lasti;
  }

  for (int i = 0; i < n; i++) {
    cout << uf.size(i) << newl;
  }

  return 0;
}


#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), id(N);
  vector<Pll> p(N);
  rep(i, N) {
    cin >> x[i] >> y[i];
    p[i] = {x[i], y[i]};
    id[i] = x[i] - 1;
  }
  sort(p.begin(), p.end());
  UnionFind tr(N);
  set<Pll> my;
  rep(i, N) {
    // ll xx = p[i].fi;
    ll yy = p[i].se;
    bool flag = 0;
    for (auto &pp : my) {
      if (pp.fi < yy) {
        tr.unite(i, pp.se);
        flag = 1;
      } else {
        break;
      }
    }
    if (!flag) {
      my.insert({yy, i});
    } else {
      Pll tmp = *my.begin();
      auto itr = lower_bound(my.begin(), my.end(), Pll(yy, -1));
      my.erase(my.begin(), itr);
      my.insert(tmp);
    }
  }
  rep(i, N) { cout << tr.getsize(id[i]) << endl; }
}

#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), id(N);
  vector<Pll> p(N);
  rep(i, N) {
    cin >> x[i] >> y[i];
    p[i] = {x[i], y[i]};
    id[i] = x[i] - 1;
  }
  sort(p.begin(), p.end());
  UnionFind tr(N);
  set<Pll> my;
  /*Pll my = p[0];
  rep(i,N){
      ll yy = p[i].se;
      if(my.fi < yy){
          tr.unite(my.se,i);
      }
      cmin(my,Pll(yy,i));
  }*/
  rep(i, N) {
    // ll xx = p[i].fi;
    ll yy = p[i].se;
    bool flag = 0;
    // Pll abc = *my.begin();
    for (auto &pp : my) {
      if (pp.fi < yy) {
        tr.unite(i, pp.se);
        // my.erase(pp);
        flag = 1;
        // break;
      } else {
        break;
      }
    }
    // my.insert(abc);
    if (!flag) {
      my.insert({yy, i});
    } else {
      Pll tmp = *my.begin();
      for (auto &e : my) {
        if (e.fi < yy) {
          my.erase(e);
        } else {
          break;
        }
      }
      // auto itr = lower_bound(my.begin(),my.end(),Pll(yy,-1));
      // my.erase(my.begin(), itr);
      my.insert(tmp);
    }
  }
  rep(i, N) { cout << tr.getsize(id[i]) << endl; }
}


#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
using ll = long long;
const int INF = (1 << 30) - 1;
const long long LINF = (1LL << 62) - 1;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

class UnionFind {
  vector<int> par, sz;

public:
  UnionFind(int n) : par(n), sz(n, 1) {
    for (int i = 0; i < n; i++)
      par[i] = i;
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int size(int x) { return sz[root(x)]; }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (sz[x] >= sz[y]) {
      sz[x] += sz[y];
      par[y] = x;
    } else {
      sz[y] += sz[x];
      par[x] = y;
    }
    return true;
  }
};

using P = pair<int, int>;

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<P> a(n);
  rep(i, n) {
    int x, y;
    cin >> x >> y;
    --x, --y;
    a[x].first = i;
    a[x].second = y;
  }
  UnionFind uf(n);
  set<int> st;
  st.insert(a[0].second);
  for (int i = 1; i < n; i++) {
    for (auto e : st) {
      if (e < a[i].second)
        uf.unite(e, a[i].second);
      else {
        st.insert(a[i].second);
        break;
      }
    }
  }
  sort(a.begin(), a.end());
  rep(i, n) cout << uf.size(a[i].second) << endl;
  return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
using ll = long long;
const int INF = (1 << 30) - 1;
const long long LINF = (1LL << 62) - 1;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

class UnionFind {
  vector<int> par, sz;

public:
  UnionFind(int n) : par(n), sz(n, 1) {
    for (int i = 0; i < n; i++)
      par[i] = i;
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int size(int x) { return sz[root(x)]; }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (sz[x] >= sz[y]) {
      sz[x] += sz[y];
      par[y] = x;
    } else {
      sz[y] += sz[x];
      par[x] = y;
    }
    return true;
  }
};

using P = pair<int, int>;

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> a(n);
  map<int, int> mp;
  rep(i, n) {
    int x, y;
    cin >> x >> y;
    --x, --y;
    a[x] = y;
    mp[a[x]] = i;
  }
  UnionFind uf(n);
  set<int> st;
  st.insert(a[0]);
  for (int i = 1; i < n; i++) {
    priority_queue<int> que;
    que.push(a[i]);
    st.insert(a[i]);
    for (auto e : st) {
      if (e >= a[i])
        break;
      uf.unite(e, a[i]);
      que.push(e);
    }
    while (que.size() > 1) {
      int num = que.top();
      que.pop();
      st.erase(num);
    }
  }
  vector<int> res(n);
  rep(i, n) res[mp[a[i]]] = uf.size(a[i]);
  rep(i, n) cout << res[i] << '\\n';
  return 0;
}


#include <bits/stdc++.h>
#define int long long
#define ld long double
#define pb push_back
#define ff first
#define ss second
#define PI acos(-1)
#define bp __builtin_popcountll
#define all(x) x.begin(), x.end()
#define sp fixed << setprecision
#define pii pair<long long, long long>
#define FAST                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
using namespace std;

int MOD = (1e9) + 7;
const int N = 200005;

int root[N], siz[N];

int get_root(int c) {
  if (root[c] == c)
    return c;
  return root[c] = get_root(root[c]);
}
void _union(int a, int b) {
  a = get_root(a);
  b = get_root(b);
  if (a <= b)
    root[b] = a, siz[a] += siz[b];
  else
    root[a] = b, siz[b] += siz[a];
}
int init(int n) {
  for (int i = 1; i <= n; i++)
    root[i] = i, siz[i] = 1;
}

signed main() {
  FAST int tc = 1;
  // cin>>tc;
  for (int ti = 1; ti <= tc; ti++) {
    int n;
    cin >> n;
    init(n);
    vector<pair<pii, int>> a(n);
    for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      a[i] = {{x, y}, i};
    }
    sort(all(a));
    // for(int i=0;i<n;i++)cout<<a[i].ff.ff<<" "<<a[i].ff.ss<<endl;
    set<int> s;
    for (int i = 0; i < n; i++) {
      // for(int x:s)cout<<x<<" - ";cout<<endl;
      int now = a[i].ff.ss;
      if (!s.size()) {
        s.insert(now);
        continue;
      }
      auto it = s.begin();
      if (*it > now) {
        s.insert(now);
        continue;
      }
      int r = get_root(*it);
      set<int> v;
      it++;
      while (it != s.end()) {
        if (*it > now)
          break;
        _union(r, *it);
        v.insert(*it);
        it++;
      }
      for (int u : v)
        s.erase(u);
      _union(now, r);
    }
    int ans[n];
    for (int i = 0; i < n; i++) {
      int now = get_root(a[i].ff.ss);
      ans[a[i].ss] = siz[now];
    }
    for (int i = 0; i < n; i++)
      cout << ans[i] << endl;
  }
  return 0;
}

#include <bits/stdc++.h>
#define int long long
#define ld long double
#define pb push_back
#define ff first
#define ss second
#define PI acos(-1)
#define bp __builtin_popcountll
#define all(x) x.begin(), x.end()
#define sp fixed << setprecision
#define pii pair<long long, long long>
#define FAST                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
using namespace std;

int MOD = (1e9) + 7;
const int N = 200005;

int root[N], siz[N];

int get_root(int c) {
  if (root[c] == c)
    return c;
  return root[c] = get_root(root[c]);
}
void _union(int a, int b) {
  a = get_root(a);
  b = get_root(b);
  if (a <= b)
    root[b] = a, siz[a] += siz[b];
  else
    root[a] = b, siz[b] += siz[a];
}
void init(int n) {
  for (int i = 1; i <= n; i++)
    root[i] = i, siz[i] = 1;
}

signed main() {
  FAST int tc = 1;
  // cin>>tc;
  for (int ti = 1; ti <= tc; ti++) {
    int n;
    cin >> n;
    init(n);
    vector<pair<pii, int>> a(n);
    for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      a[i] = {{x, y}, i};
    }
    sort(all(a));
    set<int> s;
    for (int i = 0; i < n; i++) {
      // for(int x:s)cout<<x<<" - ";cout<<endl;
      int now = a[i].ff.ss;
      if (!s.size()) {
        s.insert(now);
        continue;
      }
      auto it = s.begin();
      if (*it > now) {
        s.insert(now);
        continue;
      }
      int r = *it;
      vector<int> v;
      it++;
      while (it != s.end()) {
        if (*it > now)
          break;
        _union(r, *it);
        v.pb(*it);
        it++;
      }
      for (auto u : v)
        s.erase(u);
      _union(now, r);
    }
    int ans[n];
    for (int i = 0; i < n; i++) {
      int now = get_root(a[i].ff.ss);
      ans[a[i].ss] = siz[now];
    }
    for (int i = 0; i < n; i++)
      cout << ans[i] << endl;
  }
  return 0;
}


#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
#define int long long

struct UnionFind {
  vector<int> par;
  vector<int> siz;

  UnionFind(int n) : par(n), siz(n) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
      siz[i] = 1;
    }
  }

  int root(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = root(par[x]);
  }

  int size(int x) { return siz[root(x)]; }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx != ry) {
      par[ry] = rx;
      siz[rx] += siz[ry];
    }
  }

  bool same(int x, int y) { return root(x) == root(y); }
};

signed main() {
  // cout << fixed << setprecision(10) << flush;

  int n;
  cin >> n;

  vector<int> x(n), y(n);
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }

  vector<int> inv_x(n + 1), inv_y(n + 1);
  for (int i = 0; i < n; i++) {
    inv_x[x[i]] = i;
    inv_y[y[i]] = i;
  }

  sort(x.begin(), x.end());

  UnionFind uf(n);
  set<pair<int, int>> st;
  for (int i = 0; i < x.size(); i++) {
    auto itr_lim = st.lower_bound(make_pair(y[inv_x[x[i]]], inv_x[x[i]]));
    for (auto itr = st.begin(); itr != itr_lim; itr++) {
      uf.unite(inv_x[x[i]], itr->second);
    }
    auto itr_lim2 = itr_lim;
    if (itr_lim->first != st.begin()->first) {
      itr_lim--;
      int y_prev = y[inv_x[x[i]]];
      bool flag = true;
      while (flag) {
        if (itr_lim->first + 1 == y_prev) {
          auto itr_del = itr_lim;
          y_prev--;
          // cout << itr_lim->first << endl;
          // cout << st.begin()->first << endl;
          if (itr_lim->first == st.begin()->first)
            flag = false;
          else
            itr_lim--;
          st.erase(itr_del);
        } else
          break;
      }
    }

    if (itr_lim2 != st.end()) {
      int y_prev = y[inv_x[x[i]]];
      bool flag = true;
      itr_lim2++;
      while (itr_lim2 != st.end()) {
        if (itr_lim2->first == y_prev + 1) {
          auto itr_del = itr_lim2;
          y_prev++;
          itr_lim++;
          st.erase(itr_del);
        } else
          break;
      }
    }

    st.insert(make_pair(y[inv_x[x[i]]], inv_x[x[i]]));
  }

  for (int i = 0; i < n; i++) {
    cout << uf.size(i) << endl;
  }

  return 0;
}

#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
#define int long long

struct UnionFind {
  vector<int> par;
  vector<int> siz;

  UnionFind(int n) : par(n), siz(n) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
      siz[i] = 1;
    }
  }

  int root(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = root(par[x]);
  }

  int size(int x) { return siz[root(x)]; }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx != ry) {
      par[ry] = rx;
      siz[rx] += siz[ry];
    }
  }

  bool same(int x, int y) { return root(x) == root(y); }
};

signed main() {
  // cout << fixed << setprecision(10) << flush;

  int n;
  cin >> n;

  vector<int> x(n), y(n);
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }

  vector<int> inv_x(n + 1), inv_y(n + 1);
  for (int i = 0; i < n; i++) {
    inv_x[x[i]] = i;
    inv_y[y[i]] = i;
  }

  sort(x.begin(), x.end());

  UnionFind uf(n);
  set<pair<int, int>> st;
  for (int i = 0; i < x.size(); i++) {
    auto itr_lim = st.lower_bound(make_pair(y[inv_x[x[i]]], inv_x[x[i]]));
    bool f = true;
    for (auto itr = st.begin(); itr != itr_lim; itr++) {
      uf.unite(inv_x[x[i]], itr->second);
      f = false;
    }

    if (f)
      st.insert(make_pair(y[inv_x[x[i]]], inv_x[x[i]]));
  }

  for (int i = 0; i < n; i++) {
    cout << uf.size(i) << endl;
  }

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

class UnionFindTree {
private:
  vector<int> parent;
  vector<int> count;

public:
  UnionFindTree(int n) : parent(n), count(n, 1) {
    // 最初は全てを根として初期化
    for (int i = 0; i < n; i++)
      parent[i] = i;
  }
  int get_root(const int x) {
    // データxが属する木の根を取得する
    if (parent[x] == x)
      return x;
    // 取得したものは直接木の根をつなぐ(経路圧縮)
    return parent[x] = get_root(parent[x]);
  }
  void unite(const int x, const int y) {
    // xとyの木を併合する
    int rx = get_root(x);
    int ry = get_root(y);
    // 元から同じ木に属している場合は何もしない
    if (rx == ry)
      return;
    // xの属する木をyの属する木につける
    parent[rx] = ry;
    count[ry] += count[rx];
    count[rx] = 0;
  }
  bool is_same_root(const int x, const int y) {
    return get_root(x) == get_root(y);
  }
  int get_size(const int x) { return count[get_root(x)]; }
  void print() {
    for (auto elm : parent)
      cout << elm << " ";
    cout << endl;
    for (auto elm : count)
      cout << elm << " ";
    cout << endl;
  }
};
int main() {
  int n;
  cin >> n;
  vector<pair<int, int>> p(n), x(n), y(n);
  UnionFindTree tree(n);
  for (auto i = 0; i < n; i++) {
    cin >> p[i].first >> p[i].second;
    x[i] = {p[i].first, i}, y[i] = {p[i].second, i};
  }
  sort(x.begin(), x.end());
  sort(y.begin(), y.end());
  for (auto i = 0; i < n; i++) {
    auto itr =
        lower_bound(y.begin(), y.end(), make_pair(p[x[i].second].second, 0));
    for (auto j = itr; j != y.end(); j++) {
      if (x[i].first < p[j->second].first)
        tree.unite(x[i].second, j->second);
    }
  }
  for (auto i = 0; i < n; i++)
    cout << tree.get_size(i) << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;

class UnionFindTree {
private:
  vector<int> parent;
  vector<int> count;

public:
  UnionFindTree(int n) : parent(n), count(n, 1) {
    for (int i = 0; i < n; i++)
      parent[i] = i;
  }
  int get_root(const int x) {
    if (parent[x] == x)
      return x;
    return parent[x] = get_root(parent[x]);
  }
  void unite(const int x, const int y) {
    int rx = get_root(x), ry = get_root(y);
    if (rx == ry)
      return;
    parent[rx] = ry;
    count[ry] += count[rx];
    count[rx] = 0;
  }
  bool is_same_root(const int x, const int y) {
    return get_root(x) == get_root(y);
  }
  int get_size(const int x) { return count[get_root(x)]; }
  void print() {
    for (auto elm : parent)
      cout << elm << " ";
    cout << endl;
    for (auto elm : count)
      cout << elm << " ";
    cout << endl;
  }
};
int main() {
  int n;
  cin >> n;
  vector<pair<int, int>> p(n), x(n);
  set<pair<int, int>> y;
  UnionFindTree tree(n);
  for (auto i = 0; i < n; i++) {
    cin >> p[i].first >> p[i].second;
    x[i] = {p[i].first, i};
  }
  sort(x.begin(), x.end());
  for (auto i = 0; i < n; i++) {
    auto tmp = y.lower_bound({p[x[i].second].second, 0});
    for (auto itr = y.begin(); itr != tmp;) {
      tree.unite(x[i].second, itr->second);
      if (itr == y.begin())
        ++itr;
      else
        itr = y.erase(itr);
    }
    if (tmp == y.begin())
      y.insert({p[x[i].second].second, x[i].second});
  }
  for (auto i = 0; i < n; i++)
    cout << tree.get_size(i) << endl;
  return 0;
}


#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, x, n) for (int i = x; i < (n); i++)
#define ALL(c) (c).begin(), (c).end()
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
const long long INF = 1LL << 60; // 仮想的な無限大の値;
using ll = long long;
using P = pair<int, int>;
#define vi vector<int>
#define vll vector<ll>
#define vs vector<string>
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
struct UnionFind {
  vector<int> d;
  UnionFind(int n = 0) : d(n, -1) {}
  int find(int x) {
    if (d[x] < 0)
      return x;
    return d[x] = find(d[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (d[x] > d[y])
      swap(x, y);
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -d[find(x)]; }
};
struct DATA {
  int a, b, c;
  DATA(int a, int b, int c) : a(a), b(b), c(c){};
  bool operator<(const DATA &rhs) const {
    if (a < rhs.a) {
      return true;
    } else if (a == rhs.a) {
      if (b < rhs.b) {
        return true;
      } else if (b == rhs.b) {
        return c < rhs.c;
      }
    }
    return false;
  }
};
int main() {
  int N;
  cin >> N;
  vector<DATA> A;
  rep(i, N) {
    int x, y;
    cin >> x >> y;
    A.emplace_back(x, y, i);
  }
  sort(ALL(A));

  UnionFind UF(N);
  rep(j, N) rep(i, j) {
    int x = A[i].a;
    int y = A[i].b;
    int index = A[i].c;
    // rep2(j, i+1, N){// min(N,i+N-y)){
    if (y < A[j].b)
      UF.unite(index, A[j].c);
    // }
  }
  rep(i, N) { cout << UF.size(i) << endl; }

  return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, x, n) for (int i = x; i < (n); i++)
#define ALL(c) (c).begin(), (c).end()
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
const long long INF = 1LL << 60; // 仮想的な無限大の値;
using ll = long long;
using P = pair<int, int>;
#define vi vector<int>
#define vll vector<ll>
#define vs vector<string>
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
struct UnionFind {
  vector<int> d;
  UnionFind(int n = 0) : d(n, -1) {}
  int find(int x) {
    if (d[x] < 0)
      return x;
    return d[x] = find(d[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (d[x] > d[y])
      swap(x, y);
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -d[find(x)]; }
};
struct DATA {
  int a, b, c;
  DATA(int a, int b, int c) : a(a), b(b), c(c){};
  bool operator<(const DATA &rhs) const {
    if (a < rhs.a) {
      return true;
    } else if (a == rhs.a) {
      if (b < rhs.b) {
        return true;
      } else if (b == rhs.b) {
        return c < rhs.c;
      }
    }
    return false;
  }
};
int main() {
  int N;
  cin >> N;
  vector<DATA> A;
  rep(i, N) {
    int x, y;
    cin >> x >> y;
    A.emplace_back(x, y, i);
  }
  sort(ALL(A));
  set<P> s;
  // rep2(i, 1, N) s.insert(P(A[i].b, A[i].c));

  UnionFind UF(N);
  rep(i, N) {
    int x = A[i].a;
    int y = A[i].b;
    int idx = A[i].c;
    while (!s.empty() && A[i].b >= s.begin()->first) {
      UF.unite(s.begin()->second, idx);
      chmin(y, s.begin()->first);
      s.erase(s.begin());
    }
    s.insert(P(y, idx));
  }
  // rep(j, N)rep(i, j){
  //     int x = A[i].a;
  //     int y = A[i].b;
  //     int index = A[i].c;
  //     if(y < A[j].b) UF.unite(index, A[j].c);

  // }
  rep(i, N) { cout << UF.size(i) << endl; }

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vector<T>>;

#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define repe(i, l, r) for (ll i = (l); i < (r); i++)
#define reper(i, l, r) for (ll i = (r)-1; i >= (l); i--)
#define repa(i, n) for (auto &i : n)

template <class T> inline bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
struct init {
  init() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
  }
} init_;

#ifdef DEBUG
template <class T, class N> void verr(const T &a, const N &n) {
  rep(i, n) cerr << a[i] << " ";
  cerr << "\\n" << flush;
}
ll dbgt = 1;
void err() { cerr << "passed " << dbgt++ << "\\n" << flush; }
template <class H, class... T> void err(H &&h, T &&...t) {
  cerr << h << (sizeof...(t) ? " " : "\\n") << flush;
  if (sizeof...(t) > 0)
    err(forward<T>(t)...);
}
#endif

const ll INF = 4e18;
const ld EPS = 1e-11;
const ld PI = acos(-1.0L);
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
//--------------------------------------------------------------------------------//
struct UnionFind {
private:
  vector<int> par;
  vector<int> count;
  vector<int> rank;

public:
  UnionFind(int N) {
    count.assign(N, 1);
    rank.assign(N, 0);
    par.assign(N, 0);
    rep(i, N) par[i] = i;
  }

  int root(int x) {
    if (par[x] == x)
      return x;
    else {
      par[x] = root(par[x]);
      return par[x];
    }
  }

  void unite(int x, int y) {
    x = root(x), y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      swap(x, y);
    else if (rank[x] == rank[y])
      rank[y]++;
    par[y] = x;
    count[x] += count[y];
    return;
  }

  int size(int x) { return count[root(x)]; }

  bool issame(int x, int y) { return root(x) == root(y); }
};
using UF = struct UnionFind;

struct p {
  ll x, y, id;
  p(ll x = 0, ll y = 0, ll id = 0) : x(x), y(y), id(id) {}
};

int main() {
  ll N;
  cin >> N;
  vc<p> P(N);
  rep(i, N) cin >> P[i].x >> P[i].y, P[i].x--, P[i].y--, P[i].id = i;

  sort(all(P), [](p a, p b) { return a.x < b.x; });

  UF uf(N);
  auto comp = [](p a, p b) { return a.y < b.y; };
  set<p, decltype(comp)> st{comp};

  st.emplace(P[0]);

  repe(i, 1, N) {
    auto [x, y, id] = P[i];
    bool merged = false;

    for (auto it = st.begin(); it != st.lower_bound(P[i]);) {
      auto [tx, ty, tid] = *it;
      bool erased = false;
      uf.unite(id, tid);
      if (merged)
        st.erase(it), erased = true;
      merged = true;
      if (!erased)
        it++;
    }
    if (!merged)
      st.emplace(P[i]);
    // for (auto [tx, ty, tid] : st) err(i, tx, ty, tid);
  }

  rep(i, N) cout << uf.size(i) << '\\n';
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vector<T>>;

#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define repe(i, l, r) for (ll i = (l); i < (r); i++)
#define reper(i, l, r) for (ll i = (r)-1; i >= (l); i--)
#define repa(i, n) for (auto &i : n)

template <class T> inline bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
struct init {
  init() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
  }
} init_;

#ifdef DEBUG
template <class T, class N> void verr(const T &a, const N &n) {
  rep(i, n) cerr << a[i] << " ";
  cerr << "\\n" << flush;
}
ll dbgt = 1;
void err() { cerr << "passed " << dbgt++ << "\\n" << flush; }
template <class H, class... T> void err(H &&h, T &&...t) {
  cerr << h << (sizeof...(t) ? " " : "\\n") << flush;
  if (sizeof...(t) > 0)
    err(forward<T>(t)...);
}
#endif

const ll INF = 4e18;
const ld EPS = 1e-11;
const ld PI = acos(-1.0L);
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
//--------------------------------------------------------------------------------//
struct UnionFind {
private:
  vector<int> par;
  vector<int> count;
  vector<int> rank;

public:
  UnionFind(int N) {
    count.assign(N, 1);
    rank.assign(N, 0);
    par.assign(N, 0);
    rep(i, N) par[i] = i;
  }

  int root(int x) {
    if (par[x] == x)
      return x;
    else {
      par[x] = root(par[x]);
      return par[x];
    }
  }

  void unite(int x, int y) {
    x = root(x), y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      swap(x, y);
    else if (rank[x] == rank[y])
      rank[y]++;
    par[y] = x;
    count[x] += count[y];
    return;
  }

  int size(int x) { return count[root(x)]; }

  bool issame(int x, int y) { return root(x) == root(y); }
};
using UF = struct UnionFind;

struct p {
  ll x, y, id;
  p(ll x = 0, ll y = 0, ll id = 0) : x(x), y(y), id(id) {}
};

int main() {
  ll N;
  cin >> N;
  vc<p> P(N);
  rep(i, N) cin >> P[i].x >> P[i].y, P[i].x--, P[i].y--, P[i].id = i;

  sort(all(P), [](p a, p b) { return a.x < b.x; });

  UF uf(N);
  auto comp = [](p a, p b) { return a.y < b.y; };
  set<p, decltype(comp)> st{comp};

  st.emplace(P[0]);

  repe(i, 1, N) {
    auto [x, y, id] = P[i];
    bool merged = false;

    for (auto it = st.begin(); it != st.lower_bound(P[i]);) {
      auto [tx, ty, tid] = *it;
      bool erased = false;
      uf.unite(id, tid);
      if (merged)
        it = st.erase(it), erased = true;
      else
        it++;
      merged = true;
    }
    if (!merged)
      st.emplace(P[i]);
    // for (auto [tx, ty, tid] : st) err(i, tx, ty, tid);
  }

  rep(i, N) cout << uf.size(i) << '\\n';
}