#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb(x) push_back(x)
#define mp(a, b) make_pair(a, b)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define lscan(x) scanf("%I64d", &x)
#define lprint(x) printf("%I64d", x)
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, n) for (ll i = n - 1; i >= 0; i--)
const int mod = 998244353;
ll gcd(ll a, ll b) {
  ll c = a % b;
  while (c != 0) {
    a = b;
    b = c;
    c = a % b;
  }
  return b;
}
long long extGCD(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  long long d = extGCD(b, a % b, y, x);
  y -= a / b * x;
  return d;
}

struct UnionFind {
  vector<ll> data;

  UnionFind(int sz) { data.assign(sz, -1); }

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

  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }

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

ll M = 1000000007;

vector<ll> fac(2000011);  // n!(mod M)
vector<ll> ifac(2000011); // k!^{M-2} (mod M)

ll mpow(ll x, ll n) {
  ll ans = 1;
  while (n != 0) {
    if (n & 1)
      ans = ans * x % M;
    x = x * x % M;
    n = n >> 1;
  }
  return ans;
}
ll mpow2(ll x, ll n, ll mod) {
  ll ans = 1;
  while (n != 0) {
    if (n & 1)
      ans = ans * x % mod;
    x = x * x % mod;
    n = n >> 1;
  }
  return ans;
}
void setcomb() {
  fac[0] = 1;
  ifac[0] = 1;
  for (ll i = 0; i < 2000010; i++) {
    fac[i + 1] = fac[i] * (i + 1) % M; // n!(mod M)
  }
  ifac[2000010] = mpow(fac[2000010], M - 2);
  for (ll i = 2000010; i > 0; i--) {
    ifac[i - 1] = ifac[i] * i % M;
  }
}
ll comb(ll a, ll b) {
  if (a == 0 && b == 0)
    return 1;
  if (a < b || a < 0)
    return 0;
  ll tmp = ifac[a - b] * ifac[b] % M;
  return tmp * fac[a] % M;
}
ll perm(ll a, ll b) {
  if (a == 0 && b == 0)
    return 1;
  if (a < b || a < 0)
    return 0;
  return fac[a] * ifac[a - b] % M;
}
long long modinv(long long a) {
  long long b = M, u = 1, v = 0;
  while (b) {
    long long t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= M;
  if (u < 0)
    u += M;
  return u;
}
ll modinv2(ll a, ll mod) {
  ll b = mod, u = 1, v = 0;
  while (b) {
    ll t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= mod;
  if (u < 0)
    u += mod;
  return u;
}

template <int mod> struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

  ModInt &operator+=(const ModInt &p) {
    if ((x += p.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &p) {
    if ((x += mod - p.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &p) {
    x = (int)(1LL * x * p.x % mod);
    return *this;
  }

  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }

  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }

  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }

  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

  bool operator==(const ModInt &p) const { return x == p.x; }

  bool operator!=(const ModInt &p) const { return x != p.x; }

  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }

  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while (n > 0) {
      if (n & 1)
        ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  friend ostream &operator<<(ostream &os, const ModInt &p) { return os << p.x; }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt<mod>(t);
    return (is);
  }

  static int get_mod() { return mod; }
};

using mint = ModInt<mod>;

vector<vector<mint>> mul(vector<vector<mint>> a, vector<vector<mint>> b) {
  int i, j, k;
  mint t;
  int n = a.size(), m = b[0].size(), l = a[0].size();
  vector<vector<mint>> c(n, vector<mint>(m));
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      t = 0;
      for (k = 0; k < l; k++)
        t += a[i][k] * b[k][j];
      c[i][j] = t;
    }
  }
  return c;
}

vector<vector<mint>> mat_pow(vector<vector<mint>> x, ll n) {
  ll k = x.size();
  vector<vector<mint>> ans(k, vector<mint>(k, 0));
  for (int i = 0; i < k; i++)
    ans[i][i] = 1;
  while (n != 0) {
    if (n & 1)
      ans = mul(ans, x);
    x = mul(x, x);
    n = n >> 1;
  }
  return ans;
}

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

template <unsigned mod> struct RollingHash {
  vector<unsigned> hashed, power;

  inline unsigned mul(unsigned a, unsigned b) const {
    unsigned long long x = (unsigned long long)a * b;
    unsigned xh = (unsigned)(x >> 32), xl = (unsigned)x, d, m;
    asm("divl %4; \\n\\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(mod));
    return m;
  }

  RollingHash(const string &s, unsigned base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  unsigned get(int l, int r) const {
    unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  int LCP(const RollingHash<mod> &b, int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = -1, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return (low);
  }
};

using RH = RollingHash<1000000007>;

template <typename T> struct edge {
  int src, to;
  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {
    to = x;
    return *this;
  }

  operator int() const { return to; }
};

template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedGraph = vector<Edges<T>>;
using UnWeightedGraph = vector<vector<int>>;
template <typename T> using Matrix = vector<vector<T>>;

template <typename G> struct DoublingLowestCommonAncestor {
  const int LOG;
  vector<int> dep;
  const G &g;
  vector<vector<int>> table;

  DoublingLowestCommonAncestor(const G &g)
      : g(g), dep(g.size()), LOG(32 - __builtin_clz(g.size())) {
    table.assign(LOG, vector<int>(g.size(), -1));
  }

  void dfs(int idx, int par, int d) {
    table[0][idx] = par;
    dep[idx] = d;
    for (auto &to : g[idx]) {
      if (to != par)
        dfs(to, idx, d + 1);
    }
  }

  void build() {
    dfs(0, -1, 0);
    for (int k = 0; k + 1 < LOG; k++) {
      for (int i = 0; i < table[k].size(); i++) {
        if (table[k][i] == -1)
          table[k + 1][i] = -1;
        else
          table[k + 1][i] = table[k][table[k][i]];
      }
    }
  }

  int query(int u, int v) {
    if (dep[u] > dep[v])
      swap(u, v);
    for (int i = LOG - 1; i >= 0; i--) {
      if (((dep[v] - dep[u]) >> i) & 1)
        v = table[i][v];
    }
    if (u == v)
      return u;
    for (int i = LOG - 1; i >= 0; i--) {
      if (table[i][u] != table[i][v]) {
        u = table[i][u];
        v = table[i][v];
      }
    }
    return table[0][u];
  }
};

template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

  int sz, height;
  vector<Monoid> data;
  vector<OperatorMonoid> lazy;
  const F f;
  const G g;
  const H h;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &M1,
                  const OperatorMonoid OM0)
      : f(f), g(g), h(h), M1(M1), OM0(OM0) {
    sz = 1;
    height = 0;
    while (sz < n)
      sz <<= 1, height++;
    data.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { data[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      data[k] = f(data[2 * k + 0], data[2 * k + 1]);
    }
  }

  inline void propagate(int k) {
    if (lazy[k] != OM0) {
      lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      data[k] = reflect(k);
      lazy[k] = OM0;
    }
  }

  inline Monoid reflect(int k) {
    return lazy[k] == OM0 ? data[k] : g(data[k], lazy[k]);
  }

  inline void recalc(int k) {
    while (k >>= 1)
      data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1));
  }

  inline void thrust(int k) {
    for (int i = height; i > 0; i--)
      propagate(k >> i);
  }

  void update(int a, int b, const OperatorMonoid &x) {
    thrust(a += sz);
    thrust(b += sz - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = h(lazy[l], x), ++l;
      if (r & 1)
        --r, lazy[r] = h(lazy[r], x);
    }
    recalc(a);
    recalc(b);
  }

  Monoid query(int a, int b) {
    thrust(a += sz);
    thrust(b += sz - 1);
    Monoid L = M1, R = M1;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        L = f(L, reflect(l++));
      if (r & 1)
        R = f(reflect(--r), R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) { return query(k, k + 1); }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      propagate(a);
      Monoid nxt =
          type ? f(reflect(2 * a + type), M) : f(M, reflect(2 * a + type));
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, reflect(1))))
        return find_subtree(1, check, L, false);
      return -1;
    }
    thrust(a + sz);
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, reflect(a));
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(reflect(1), R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    thrust(b + sz - 1);
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(reflect(--b), R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

int main() {
  ll n, y[222222], t[222222];
  cin >> n;
  UnionFind uf(n);
  rep(i, n) {
    ll x;
    cin >> x;
    x--;
    cin >> y[x];
    t[x] = i;
  }
  ll l = n, lt = n;
  stack<pair<ll, ll>> st;
  rep(i, n) {
    if (y[i] < l) {
      st.push(mp(l, lt));
      l = y[i];
      lt = t[i];
    } else {
      uf.unite(lt, t[i]);
      while (!st.empty()) {
        auto a = st.top();
        if (a.first < y[i]) {
          uf.unite(a.second, t[i]);
          st.pop();
        } else
          break;
      }
    }
  }
  rep(i, n) cout << uf.size(i) << endl;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb(x) push_back(x)
#define mp(a, b) make_pair(a, b)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define lscan(x) scanf("%I64d", &x)
#define lprint(x) printf("%I64d", x)
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, n) for (ll i = n - 1; i >= 0; i--)
const int mod = 998244353;
ll gcd(ll a, ll b) {
  ll c = a % b;
  while (c != 0) {
    a = b;
    b = c;
    c = a % b;
  }
  return b;
}
long long extGCD(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  long long d = extGCD(b, a % b, y, x);
  y -= a / b * x;
  return d;
}

struct UnionFind {
  vector<ll> data;

  UnionFind(int sz) { data.assign(sz, -1); }

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

  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }

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

ll M = 1000000007;

vector<ll> fac(2000011);  // n!(mod M)
vector<ll> ifac(2000011); // k!^{M-2} (mod M)

ll mpow(ll x, ll n) {
  ll ans = 1;
  while (n != 0) {
    if (n & 1)
      ans = ans * x % M;
    x = x * x % M;
    n = n >> 1;
  }
  return ans;
}
ll mpow2(ll x, ll n, ll mod) {
  ll ans = 1;
  while (n != 0) {
    if (n & 1)
      ans = ans * x % mod;
    x = x * x % mod;
    n = n >> 1;
  }
  return ans;
}
void setcomb() {
  fac[0] = 1;
  ifac[0] = 1;
  for (ll i = 0; i < 2000010; i++) {
    fac[i + 1] = fac[i] * (i + 1) % M; // n!(mod M)
  }
  ifac[2000010] = mpow(fac[2000010], M - 2);
  for (ll i = 2000010; i > 0; i--) {
    ifac[i - 1] = ifac[i] * i % M;
  }
}
ll comb(ll a, ll b) {
  if (a == 0 && b == 0)
    return 1;
  if (a < b || a < 0)
    return 0;
  ll tmp = ifac[a - b] * ifac[b] % M;
  return tmp * fac[a] % M;
}
ll perm(ll a, ll b) {
  if (a == 0 && b == 0)
    return 1;
  if (a < b || a < 0)
    return 0;
  return fac[a] * ifac[a - b] % M;
}
long long modinv(long long a) {
  long long b = M, u = 1, v = 0;
  while (b) {
    long long t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= M;
  if (u < 0)
    u += M;
  return u;
}
ll modinv2(ll a, ll mod) {
  ll b = mod, u = 1, v = 0;
  while (b) {
    ll t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= mod;
  if (u < 0)
    u += mod;
  return u;
}

template <int mod> struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

  ModInt &operator+=(const ModInt &p) {
    if ((x += p.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &p) {
    if ((x += mod - p.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &p) {
    x = (int)(1LL * x * p.x % mod);
    return *this;
  }

  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }

  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }

  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }

  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

  bool operator==(const ModInt &p) const { return x == p.x; }

  bool operator!=(const ModInt &p) const { return x != p.x; }

  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }

  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while (n > 0) {
      if (n & 1)
        ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  friend ostream &operator<<(ostream &os, const ModInt &p) { return os << p.x; }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt<mod>(t);
    return (is);
  }

  static int get_mod() { return mod; }
};

using mint = ModInt<mod>;

vector<vector<mint>> mul(vector<vector<mint>> a, vector<vector<mint>> b) {
  int i, j, k;
  mint t;
  int n = a.size(), m = b[0].size(), l = a[0].size();
  vector<vector<mint>> c(n, vector<mint>(m));
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      t = 0;
      for (k = 0; k < l; k++)
        t += a[i][k] * b[k][j];
      c[i][j] = t;
    }
  }
  return c;
}

vector<vector<mint>> mat_pow(vector<vector<mint>> x, ll n) {
  ll k = x.size();
  vector<vector<mint>> ans(k, vector<mint>(k, 0));
  for (int i = 0; i < k; i++)
    ans[i][i] = 1;
  while (n != 0) {
    if (n & 1)
      ans = mul(ans, x);
    x = mul(x, x);
    n = n >> 1;
  }
  return ans;
}

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

template <unsigned mod> struct RollingHash {
  vector<unsigned> hashed, power;

  inline unsigned mul(unsigned a, unsigned b) const {
    unsigned long long x = (unsigned long long)a * b;
    unsigned xh = (unsigned)(x >> 32), xl = (unsigned)x, d, m;
    asm("divl %4; \\n\\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(mod));
    return m;
  }

  RollingHash(const string &s, unsigned base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  unsigned get(int l, int r) const {
    unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  int LCP(const RollingHash<mod> &b, int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = -1, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return (low);
  }
};

using RH = RollingHash<1000000007>;

template <typename T> struct edge {
  int src, to;
  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {
    to = x;
    return *this;
  }

  operator int() const { return to; }
};

template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedGraph = vector<Edges<T>>;
using UnWeightedGraph = vector<vector<int>>;
template <typename T> using Matrix = vector<vector<T>>;

template <typename G> struct DoublingLowestCommonAncestor {
  const int LOG;
  vector<int> dep;
  const G &g;
  vector<vector<int>> table;

  DoublingLowestCommonAncestor(const G &g)
      : g(g), dep(g.size()), LOG(32 - __builtin_clz(g.size())) {
    table.assign(LOG, vector<int>(g.size(), -1));
  }

  void dfs(int idx, int par, int d) {
    table[0][idx] = par;
    dep[idx] = d;
    for (auto &to : g[idx]) {
      if (to != par)
        dfs(to, idx, d + 1);
    }
  }

  void build() {
    dfs(0, -1, 0);
    for (int k = 0; k + 1 < LOG; k++) {
      for (int i = 0; i < table[k].size(); i++) {
        if (table[k][i] == -1)
          table[k + 1][i] = -1;
        else
          table[k + 1][i] = table[k][table[k][i]];
      }
    }
  }

  int query(int u, int v) {
    if (dep[u] > dep[v])
      swap(u, v);
    for (int i = LOG - 1; i >= 0; i--) {
      if (((dep[v] - dep[u]) >> i) & 1)
        v = table[i][v];
    }
    if (u == v)
      return u;
    for (int i = LOG - 1; i >= 0; i--) {
      if (table[i][u] != table[i][v]) {
        u = table[i][u];
        v = table[i][v];
      }
    }
    return table[0][u];
  }
};

template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

  int sz, height;
  vector<Monoid> data;
  vector<OperatorMonoid> lazy;
  const F f;
  const G g;
  const H h;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &M1,
                  const OperatorMonoid OM0)
      : f(f), g(g), h(h), M1(M1), OM0(OM0) {
    sz = 1;
    height = 0;
    while (sz < n)
      sz <<= 1, height++;
    data.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { data[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      data[k] = f(data[2 * k + 0], data[2 * k + 1]);
    }
  }

  inline void propagate(int k) {
    if (lazy[k] != OM0) {
      lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      data[k] = reflect(k);
      lazy[k] = OM0;
    }
  }

  inline Monoid reflect(int k) {
    return lazy[k] == OM0 ? data[k] : g(data[k], lazy[k]);
  }

  inline void recalc(int k) {
    while (k >>= 1)
      data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1));
  }

  inline void thrust(int k) {
    for (int i = height; i > 0; i--)
      propagate(k >> i);
  }

  void update(int a, int b, const OperatorMonoid &x) {
    thrust(a += sz);
    thrust(b += sz - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = h(lazy[l], x), ++l;
      if (r & 1)
        --r, lazy[r] = h(lazy[r], x);
    }
    recalc(a);
    recalc(b);
  }

  Monoid query(int a, int b) {
    thrust(a += sz);
    thrust(b += sz - 1);
    Monoid L = M1, R = M1;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        L = f(L, reflect(l++));
      if (r & 1)
        R = f(reflect(--r), R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) { return query(k, k + 1); }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      propagate(a);
      Monoid nxt =
          type ? f(reflect(2 * a + type), M) : f(M, reflect(2 * a + type));
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, reflect(1))))
        return find_subtree(1, check, L, false);
      return -1;
    }
    thrust(a + sz);
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, reflect(a));
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(reflect(1), R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    thrust(b + sz - 1);
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(reflect(--b), R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

int main() {
  ll n, y[222222], t[222222];
  cin >> n;
  UnionFind uf(n);
  rep(i, n) {
    ll x;
    cin >> x;
    x--;
    cin >> y[x];
    y[x]--;
    t[x] = i;
  }
  ll l = n, lt = n;
  stack<pair<ll, ll>> st;
  rep(i, n) {
    if (y[i] < l) {
      st.push(mp(l, lt));
      l = y[i];
      lt = t[i];
    } else {
      uf.unite(lt, t[i]);
      while (1) {
        auto a = st.top();
        if (a.first < y[i]) {
          uf.unite(a.second, t[i]);
          st.pop();
        } else
          break;
      }
    }
  }
  rep(i, n) cout << uf.size(i) << endl;
}


#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, ll>;

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)]; }
};

int main() {
  ll N;
  cin >> N;
  vector<P> xy(N);
  vector<ll> original(N), xPlaceAtY(N);
  set<ll> yset;
  rep(i, N) {
    cin >> xy[i].first >> xy[i].second;
    --xy[i].first;
    --xy[i].second;
    yset.insert(xy[i].second);
    xPlaceAtY[xy[i].second] = xy[i].first;
    original[i] = xy[i].first;
  }

  sort(xy.begin(), xy.end());
  UnionFind uf = UnionFind(N);
  rep(i, N) {
    for (auto itr = yset.upper_bound(xy[i].second); itr != yset.end(); ++itr) {
      uf.unite(i, xPlaceAtY[*itr]);
    }
    yset.erase(xy[i].second);
  }

  rep(i, N) { cout << uf.size(original[i]) << "\\n"; }

  return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, ll>;

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)]; }
};

int main() {
  ll N;
  cin >> N;
  vector<P> xy(N);
  vector<ll> original(N), xPlaceAtY(N);
  set<ll> yset;
  rep(i, N) {
    cin >> xy[i].first >> xy[i].second;
    --xy[i].first;
    --xy[i].second;
    yset.insert(xy[i].second);
    xPlaceAtY[xy[i].second] = xy[i].first;
    original[i] = xy[i].first;
  }

  sort(xy.begin(), xy.end());
  UnionFind uf = UnionFind(N);
  rep(i, N) {
    yset.erase(xy[i].second);
    if (uf.size(i) > 1) {
      continue;
    }
    // cerr << "i=" << i << "xy[i].first=" << xy[i].first << "xy[i].second=" <<
    // xy[i].second << endl;
    for (auto itr = yset.upper_bound(xy[i].second); itr != yset.end(); ++itr) {
      uf.unite(i, xPlaceAtY[*itr]);
    }
  }

  rep(i, N) { cout << uf.size(original[i]) << "\\n"; }

  return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ff first
#define ss second
#define pb push_back
using namespace std;

const int N = 2e5 + 5;

int n, x, y;
vector<pair<int, int>> P;
int A[N], tree[N], X[N], Y[N];
int sz[N], par[N];

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

void union_set(int x, int y) {
  if (sz[x] < sz[y]) {
    swap(x, y);
  }
  sz[x] += sz[y];
  par[y] = x;
}

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

  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> x >> y;
    P.pb({x, i});
    X[i] = x;
    Y[i] = y;
    A[y] = i;
    par[i] = i;
    sz[i] = 1;
  }

  sort(P.begin(), P.end());
  vector<int> v;
  for (int i = 0; i < n; i++) {
    int ind = P[i].ss;
    int y = Y[ind];
    if (v.size() == 0) {
      v.pb(y);
    } else if (v.back() >= y) {
      v.pb(y);
    } else {
      int x = v.back();
      while (v.back() < y) {
        int a = find_set(A[y]);
        int b = find_set(A[v.back()]);
        if (a != b)
          union_set(a, b);
        v.pop_back();
      }
      v.pb(x);
    }
  }

  for (int i = 1; i <= n; i++) {
    cout << sz[find_set(i)] << " ";
  }
}

#include <bits/stdc++.h>
#define ll long long
#define ff first
#define ss second
#define pb push_back
using namespace std;

const int N = 2e5 + 5;

int n, x, y;
vector<pair<int, int>> P;
int A[N], tree[N], X[N], Y[N];
int sz[N], par[N];

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

void union_set(int x, int y) {
  if (sz[x] < sz[y]) {
    swap(x, y);
  }
  sz[x] += sz[y];
  par[y] = x;
}

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

  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> x >> y;
    P.pb({x, i});
    X[i] = x;
    Y[i] = y;
    A[y] = i;
    par[i] = i;
    sz[i] = 1;
  }

  sort(P.begin(), P.end());
  vector<int> v;
  for (int i = 0; i < n; i++) {
    int ind = P[i].ss;
    int y = Y[ind];
    if (v.size() == 0) {
      v.pb(y);
    } else {
      int x = v.back();
      while (v.size() && v.back() < y) {
        int a = find_set(A[y]);
        int b = find_set(A[v.back()]);
        if (a != b)
          union_set(a, b);
        v.pop_back();
      }
      x = min(x, y);
      v.pb(x);
    }
  }

  for (int i = 1; i <= n; i++) {
    cout << sz[find_set(i)] << " ";
  }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#include <cassert>

namespace atcoder {

// Implement (union by size) + (path compression)
// Reference:
// Zvi Galil and Giuseppe F. Italiano,
// Data structures and algorithms for disjoint set union problems
struct dsu {
public:
  dsu() : _n(0) {}
  dsu(int n) : _n(n), parent_or_size(n, -1) {}

  int merge(int a, int b) {
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    int x = leader(a), y = leader(b);
    if (x == y)
      return x;
    if (-parent_or_size[x] < -parent_or_size[y])
      std::swap(x, y);
    parent_or_size[x] += parent_or_size[y];
    parent_or_size[y] = x;
    return x;
  }

  bool same(int a, int b) {
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    return leader(a) == leader(b);
  }

  int leader(int a) {
    assert(0 <= a && a < _n);
    if (parent_or_size[a] < 0)
      return a;
    return parent_or_size[a] = leader(parent_or_size[a]);
  }

  int size(int a) {
    assert(0 <= a && a < _n);
    return -parent_or_size[leader(a)];
  }

  std::vector<std::vector<int>> groups() {
    std::vector<int> leader_buf(_n), group_size(_n);
    for (int i = 0; i < _n; i++) {
      leader_buf[i] = leader(i);
      group_size[leader_buf[i]]++;
    }
    std::vector<std::vector<int>> result(_n);
    for (int i = 0; i < _n; i++) {
      result[i].reserve(group_size[i]);
    }
    for (int i = 0; i < _n; i++) {
      result[leader_buf[i]].push_back(i);
    }
    result.erase(
        std::remove_if(result.begin(), result.end(),
                       [&](const std::vector<int> &v) { return v.empty(); }),
        result.end());
    return result;
  }

private:
  int _n;
  // root node: -1 * component size
  // otherwise: parent
  std::vector<int> parent_or_size;
};

} // namespace atcoder

using namespace atcoder;
vector<pair<ll, ll>> vp;

bool jud(pair<ll, ll> a, pair<ll, ll> b) {
  bool flag = false;
  if (a.first < b.first && a.second < b.second) {
    flag = true;
  }
  if (a.first > b.first && a.second > b.second) {
    flag = true;
  }
  return flag;
}

int main() {
  ll N;
  cin >> N;
  vp.resize(N);

  for (ll i = 0; i < N; i++) {
    cin >> vp[i].first >> vp[i].second;
  }

  dsu d(N);

  for (ll i = 0; i < N - 1; i++) {
    for (ll j = i + 1; j < N; j++) {
      if (jud(vp[i], vp[j])) {

        d.merge(i, j);
      }
    }
  }

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

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#include <cassert>

namespace atcoder {

// Implement (union by size) + (path compression)
// Reference:
// Zvi Galil and Giuseppe F. Italiano,
// Data structures and algorithms for disjoint set union problems
struct dsu {
public:
  dsu() : _n(0) {}
  dsu(int n) : _n(n), parent_or_size(n, -1) {}

  int merge(int a, int b) {
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    int x = leader(a), y = leader(b);
    if (x == y)
      return x;
    if (-parent_or_size[x] < -parent_or_size[y])
      std::swap(x, y);
    parent_or_size[x] += parent_or_size[y];
    parent_or_size[y] = x;
    return x;
  }

  bool same(int a, int b) {
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    return leader(a) == leader(b);
  }

  int leader(int a) {
    assert(0 <= a && a < _n);
    if (parent_or_size[a] < 0)
      return a;
    return parent_or_size[a] = leader(parent_or_size[a]);
  }

  int size(int a) {
    assert(0 <= a && a < _n);
    return -parent_or_size[leader(a)];
  }

  std::vector<std::vector<int>> groups() {
    std::vector<int> leader_buf(_n), group_size(_n);
    for (int i = 0; i < _n; i++) {
      leader_buf[i] = leader(i);
      group_size[leader_buf[i]]++;
    }
    std::vector<std::vector<int>> result(_n);
    for (int i = 0; i < _n; i++) {
      result[i].reserve(group_size[i]);
    }
    for (int i = 0; i < _n; i++) {
      result[leader_buf[i]].push_back(i);
    }
    result.erase(
        std::remove_if(result.begin(), result.end(),
                       [&](const std::vector<int> &v) { return v.empty(); }),
        result.end());
    return result;
  }

private:
  int _n;
  // root node: -1 * component size
  // otherwise: parent
  std::vector<int> parent_or_size;
};

} // namespace atcoder

using namespace atcoder;

bool jud(pair<ll, ll> a, pair<ll, ll> b) {
  bool flag = false;
  if (a.first < b.first && a.second < b.second) {
    flag = true;
  }
  if (a.first > b.first && a.second > b.second) {
    flag = true;
  }
  return flag;
}

int main() {

  int N;

  cin >> N;

  vector<pair<pair<int, int>, int>> vp;

  int x, y;

  for (int i = 0; i < N; i++) {
    cin >> x >> y;
    vp.emplace_back(make_pair(x, y), i);
  }

  sort(vp.begin(), vp.end(),
       [](pair<pair<int, int>, int> a, pair<pair<int, int>, int> b) {
         return a.first.first < b.first.first;
       });
  /*
      for(int i=0;i<N;i++){
          cout<<vp[i].first.first<<":"<<vp[i].first.second<<":"<<vp[i].second<<endl;
      }
  */
  set<pair<int, int>> st; //(y,id)  yが最小かつ

  dsu d(N);
  for (int i = 0; i < N; i++) {

    int org = vp[i].first.second;
    int id = vp[i].second;
    int l = org;

    // cout<<"org:"<<org<<" id:"<<id<<" l:"<<l<<endl;

    set<pair<int, int>>::iterator itr = st.begin();

    while (!st.empty()) {
      // cout<<"judge: y:"<<itr->first<<" id:"<<itr->second<<endl;

      if (itr->first < org) {
        l = min(l, itr->first);
        d.merge(itr->second, id);
        // cout<<"erase:y:"<<itr->first<<":id"<<itr->second<<endl;
        itr = st.erase(itr);
        // cout<<"l:"<<l<<endl;
      } else {
        break;
      }
    }
    // cout<<"add:y:"<<l<<" :id "<<id<<endl;
    st.emplace(l, id);
  }

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


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
using namespace std;
const int N = 200010;
int n;
int tr[N];
int res[N];
struct node {
  int x;
  int y;
  int id;
  bool operator<(const node &W) const {
    if (x != W.x)
      return x < W.x;
    return y < W.y;
  }
} q[N];
int p[N];
int sz[N];
int find(int x) {
  if (p[x] != x)
    p[x] = find(p[x]);
  return p[x];
}
set<pair<int, int>> s;
set<pair<int, int>> S;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d%d", &q[i].x, &q[i].y), q[i].id = i, p[i] = i, sz[i] = 1;
  sort(q + 1, q + n + 1);
  for (int i = 1; i <= n; i++) {
    s.insert({q[i].y, q[i].id});
    auto it = s.lower_bound({q[i].y, 0});
    int b = q[i].id;
    b = find(b);
    for (set<pair<int, int>>::iterator x = s.begin(); x != it; x++) {
      int a = x->second;
      a = find(a);
      if (a != b) {
        p[a] = b;
        sz[b] += sz[a];
        //  break;
      }
    }
  }
  for (int i = 1; i <= n; i++)
    printf("%d\\n", sz[find(i)]);
  return 0;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
using namespace std;
const int N = 200010;
int n;
int tr[N];
int res[N];
struct node {
  int x;
  int y;
  int id;
  bool operator<(const node &W) const {
    if (x != W.x)
      return x < W.x;
    return y < W.y;
  }
} q[N];
int p[N];
int sz[N];
int find(int x) {
  if (p[x] != x)
    p[x] = find(p[x]);
  return p[x];
}
set<pair<int, int>> s;
set<pair<int, int>> S;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d%d", &q[i].x, &q[i].y), q[i].id = i, p[i] = i, sz[i] = 1;
  sort(q + 1, q + n + 1);
  for (int i = 1; i <= n; i++) {
    if (s.empty())
      s.insert({q[i].y, q[i].id});
    auto it = s.lower_bound({q[i].y, 0});
    int b = q[i].id;
    b = find(b);
    bool flag = false;
    for (set<pair<int, int>>::iterator x = s.begin(); x != it; x++) {
      flag = true;
      int a = x->second;
      a = find(a);
      if (a != b) {
        p[a] = b;
        sz[b] += sz[a];
        //  break;
      }
    }
    if (!flag)
      s.insert({q[i].y, q[i].id});
  }
  for (int i = 1; i <= n; i++)
    printf("%d\\n", sz[find(i)]);
  return 0;
}


#include <bits/stdc++.h>
#define maxn 200005
#define pii pair<int, int>
#define mk make_pair
using namespace std;

int n;

struct node {
  int x, y, id;
} poi[maxn];

bool cmp1(node i, node j) { return i.x < j.x; }

int ans[maxn], siz[maxn];

set<pii> sets;
set<pii>::iterator it;

int fa[maxn];

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

signed main() {
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> poi[i].x >> poi[i].y, poi[i].id = fa[i] = i, siz[i] = 1;
  sort(poi + 1, poi + n + 1, cmp1);
  sets.insert(mk(9999999, 9999999));
  for (int i = 1; i <= n; i++) {
    it = sets.begin();
    while ((*it).first < poi[i].y) {

      int fx = find(poi[i].id), fy = find((*it).second);
      if (fx != fy) {
        fa[fx] = fy;
        siz[fy] += siz[fx];
      }
      it++;
    }
    sets.insert(mk(poi[i].y, poi[i].id));
  }
  for (int i = 1; i <= n; i++)
    cout << siz[find(i)] << endl;
}

#include <bits/stdc++.h>
#define maxn 200005
#define pii pair<int, int>
#define mk make_pair
using namespace std;

int n;

struct node {
  int x, y, id;
} poi[maxn];

bool cmp1(node i, node j) { return i.x < j.x; }

int ans[maxn], siz[maxn];

set<pii> sets;
set<pii>::iterator it;

int fa[maxn];

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

signed main() {
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> poi[i].x >> poi[i].y, poi[i].id = fa[i] = i, siz[i] = 1;
  sort(poi + 1, poi + n + 1, cmp1);
  sets.insert(mk(9999999, 9999999));
  for (int i = 1; i <= n; i++) {
    it = sets.begin();
    if ((*it).first < poi[i].y) {
      while ((*it).first < poi[i].y) {
        int fx = find(poi[i].id), fy = find((*it).second);
        if (fx != fy) {
          fa[fx] = fy;
          siz[fy] += siz[fx];
        }
        it++;
      }
    } else
      sets.insert(mk(poi[i].y, poi[i].id));
  }
  for (int i = 1; i <= n; i++)
    cout << siz[find(i)] << endl;
}


#include <algorithm>
#include <iostream>

using namespace std;

#define PII pair<int, int>
#define x first
#define y second

const int N = 200010;

PII a[N];
int cnt[N], p[N];
int n;

int find(int x) {
  if (x != p[x])
    x = find(p[x]);
  return p[x];
}

int main() {
  cin >> n;

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

  for (int i = 0; i < n; i++)
    cnt[i] = 1, p[i] = i;

  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      if (a[i].x < a[j].x && a[i].y < a[j].y ||
          a[i].x > a[j].x && a[i].y > a[j].y) {
        int x = find(i), y = find(j);
        if (a[x] != a[y]) {
          p[y] = x;
          cnt[x] += cnt[y];
        }
      }
    }
  }

  for (int i = 0; i < n; i++)
    cout << cnt[find(i)] << endl;

  return 0;
}

#include <algorithm>
#include <iostream>

using namespace std;

#define PII pair<int, int>

const int N = 200010, INF = 0x3f3f3f3f;

typedef struct {
  int x, y, pos;
} state;

state a[N];
int cnt[N], p[N];
int n;
PII stk[N];
int tt = -1;

int cmp(const state &a, const state &b) { return a.x < b.x; }

int find(int x) {
  if (x != p[x])
    p[x] = find(p[x]);
  return p[x];
}

int main() {
  cin >> n;

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

    a[i] = {x, y, i};
  }

  for (int i = 0; i < n; i++)
    p[i] = i, cnt[i] = 1;

  sort(a, a + n, cmp);

  for (int i = 0; i < n; i++) {
    if (tt == -1)
      stk[++tt] = {a[i].pos, a[i].y};
    else {
      int minv = a[i].y;
      while (~tt && a[i].y > stk[tt].second) {
        minv = min(minv, stk[tt].second);
        int x = find(a[i].pos), y = find(stk[tt].first);
        if (x != y) {
          p[x] = y;
          cnt[y] += cnt[x];
        }
        tt--;
      }
      stk[++tt] = {a[i].pos, minv};
    }
  }

  for (int i = 0; i < n; i++)
    cout << cnt[find(i)] << endl;

  return 0;
}


/*
 * Package: StandardCodeLibrary.Core
 * */
// 引进常用的头文件并使用std名字空间;
#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

// 用于减少代码量的宏;
#define lp for (;;)
#define repf(i, a, b) for (int i = (a); i < (b); ++i)
#define ft(i, a, b) for (int i = (a); i <= (b); ++i)
#define fdt(i, a, b) for (int i = (a); i >= (b); --i)
#define rrepf(i, a, b) fdt(i, (a)-1, b)
#define rep(i, n) repf(i, 0, n)
#define rrep(i, n) rrepf(i, n, 0)
#define for_each(e, s)                                                         \\
  for (__typeof__((s).begin()) e = (s).begin(); e != (s).end(); ++e)
#define for_nonempty_subsets(subset, set)                                      \\
  for (int subset = set; subset; subset = (subset - 1) & (set))
#define for_in_charset(i, charset) for (cstr i = (charset); *i; i++)
#define whl(x) while (x)
#define rtn return
#define fl(x, y) memset((x), char(y), sizeof(x))
#define clr(x) fl(x, char(0))
#define cpy(x, y) memcpy(x, y, sizeof(x))
#define sf scanf
#define pf printf
#define vec vector
#define pr pair
#define que queue
#define prq priority_queue
#define itr iterator
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ins insert
#define ers erase
#define lb lower_bound
#define ub upper_bound
#define rnk order_of_key
#define sel find_by_order
#define ctz __builtin_ctz
#define clz __builtin_clz
#define bc __builtin_popcount
#define sz(x) (int((x).size()))
#define all(x) (x).begin(), (x).end()
#define srt(x) sort(all(x))
#define uniq(x) srt(x), (x).erase(unique(all(x)), (x).end())
#define rev(x) reverse(all(x))
#define shf(x) random_shuffle(all(x))
#define nxtp(x) next_permutation(all(x))

// 调试相关的宏;
#ifndef DEBUG
#define prt(x) (cerr)
#define asrtWA(s)                                                              \\
  do                                                                           \\
    if (!(s))                                                                  \\
      exit(0);                                                                 \\
  whl(0)
#define asrtTLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      whl(1);                                                                  \\
  whl(0)
#define asrtMLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      whl(new int);                                                            \\
  whl(0)
#define asrtOLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      whl(1) puts("OLE");                                                      \\
  whl(0)
#define asrtRE(s)                                                              \\
  do                                                                           \\
    if (!(s))                                                                  \\
      *(int *)0 = 0;                                                           \\
  whl(0)
#define runtime() (cerr)
#define input(in) freopen(in, "r", stdin)
#define output(out) freopen(out, "w", stdout)
#else
#define prt(x) cerr << "第" << __LINE__ << "行\\t: " << #x "\\t=" << (x) << endl
#define asrtWA(s)                                                              \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define asrtTLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define asrtMLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define asrtOLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define asrtRE(s)                                                              \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define runtime()                                                              \\
  cerr << "Used: " << db(clock()) / CLOCKS_PER_SEC << "s" << endl
#define input(in)
#define output(out)
#endif

// 常用数据类型;
typedef long long int lli;
typedef double db;
typedef const char *cstr;
typedef string str;
typedef vec<int> vi;
typedef vec<vi> vvi;
typedef vec<lli> vl;
typedef vec<vl> vvl;
typedef vec<bool> vb;
typedef vec<vb> vvb;
typedef vec<char> vc;
typedef vec<vc> vvc;
typedef vec<str> vs;
typedef pr<int, int> pii;
typedef pr<lli, lli> pll;
typedef pr<db, db> pdd;
typedef vec<pii> vpii;
typedef vec<pll> vpll;
typedef vec<pdd> vpdd;
typedef map<int, int> mii;
typedef map<str, int> msi;
typedef map<char, int> mci;
typedef set<int> si;
typedef set<str> ss;
typedef que<int> qi;

// 常用常量:int的最大值;lli的最大值;db的误差相关常数;欧拉常数;圆周率;移动向量;取模使用的除数;
int oo = (~0u) >> 1;
lli ooll = (~0ull) >> 1;
db inf = 1e+10;
db eps = 1e-10;
db gam = 0.5772156649015328606;
db pi = acos(-1.0);
int dx[] = {1, 0, -1, 0, 1, -1, -1, 1, 0};
int dy[] = {0, 1, 0, -1, 1, 1, -1, -1, 0};
int MOD = 1000000007;

// 常用函数:最大最小值更新;数学相关函数;输入和输出;树状数组;并查集;可合并堆;
template <typename type> inline bool cmax(type &a, const type &b) {
  rtn a < b ? a = b, true : false;
}
template <typename type> inline bool cmin(type &a, const type &b) {
  rtn b < a ? a = b, true : false;
}
template <typename type> inline type sqr(const type &x) { rtn x *x; }
template <typename type> inline type mod(const type &x) { rtn x % MOD; }
inline int sgn(const db &x) { rtn(x > +eps) - (x < -eps); }
inline int dbcmp(const db &a, const db &b) { rtn sgn(a - b); }
template <typename type>
inline pr<type, type> operator-(const pr<type, type> &x) {
  rtn mp(-x.x, -x.y);
}
template <typename type>
inline pr<type, type> operator+(const pr<type, type> &a,
                                const pr<type, type> &b) {
  rtn mp(a.x + b.x, a.y + b.y);
}
template <typename type>
inline pr<type, type> operator-(const pr<type, type> &a,
                                const pr<type, type> &b) {
  rtn mp(a.x - b.x, a.y - b.y);
}
template <typename type>
inline pr<type, type> operator*(const pr<type, type> &a, const type &b) {
  rtn mp(a.x * b, a.y * b);
}
template <typename type>
inline pr<type, type> operator/(const pr<type, type> &a, const type &b) {
  rtn mp(a.x / b, a.y / b);
}
template <typename type>
inline pr<type, type> &operator-=(pr<type, type> &a, const pr<type, type> &b) {
  rtn a = a - b;
}
template <typename type>
inline pr<type, type> &operator+=(pr<type, type> &a, const pr<type, type> &b) {
  rtn a = a + b;
}
template <typename type>
inline pr<type, type> &operator*=(pr<type, type> &a, const type &b) {
  rtn a = a * b;
}
template <typename type>
inline pr<type, type> &operator/=(pr<type, type> &a, const type &b) {
  rtn a = a / b;
}
template <typename type>
inline type cross(const pr<type, type> &a, const pr<type, type> &b) {
  rtn a.x *b.y - a.y *b.x;
}
template <typename type>
inline type dot(const pr<type, type> &a, const pr<type, type> &b) {
  rtn a.x *b.x + a.y *b.y;
}
template <typename type> inline type gcd(type a, type b) {
  if (b)
    whl((a %= b) && (b %= a));
  rtn a + b;
}
template <typename type> inline type lcm(type a, type b) {
  rtn a *b / gcd(a, b);
}
inline lli bin_pow(lli x, lli y) {
  lli z = 1;
  whl(y) {
    if (y & 1)
      z = mod(z * x);
    x = mod(sqr(x)), y >>= 1;
  }
  rtn z;
}
template <typename istream, typename first_type, typename second_type>
inline istream &operator>>(istream &cin, pr<first_type, second_type> &x) {
  rtn cin >> x.x >> x.y;
}
template <typename ostream, typename first_type, typename second_type>
inline ostream &operator<<(ostream &cout,
                           const pr<first_type, second_type> &x) {
  rtn cout << x.x << " " << x.y;
}
template <typename istream, typename type>
inline istream &operator>>(istream &cin, vec<type> &x) {
  rep(i, sz(x)) cin >> x[i];
  rtn cin;
}
template <typename ostream, typename type>
inline ostream &operator<<(ostream &cout, const vec<type> &x) {
  rep(i, sz(x)) cout << x[i] << (i + 1 == sz(x) ? "" : " ");
  rtn cout;
}
inline ostream &pdb(int prcs, db x) {
  rtn cout << setprecision(prcs) << fixed << (sgn(x) ? (x) : 0);
}
template <typename type> inline void bit_inc(vec<type> &st, int x, type inc) {
  whl(x < sz(st)) st[x] += inc, x |= x + 1;
}
template <typename type> inline type bit_sum(const vec<type> &st, int x) {
  type s = 0;
  whl(x >= 0) s += st[x], x = (x & (x + 1)) - 1;
  rtn s;
}
template <typename type> inline type bit_kth(const vec<type> &st, int k) {
  int x = 0, y = 0, z = 0;
  whl((1 << (++y)) <= sz(st));
  rrep(i, y) {
    if ((x += 1 << i) > sz(st) || z + st[x - 1] > k)
      x -= 1 << i;
    else
      z += st[x - 1];
  }
  rtn x;
}
inline void make_set(vi &st) { rep(i, sz(st)) st[i] = i; }
inline int find_set(vi &st, int x) {
  int y = x, z;
  whl(y != st[y]) y = st[y];
  whl(x != st[x]) z = st[x], st[x] = y, x = z;
  rtn y;
}
inline bool union_set(vi &st, int a, int b) {
  a = find_set(st, a), b = find_set(st, b);
  rtn a != b ? st[a] = b, true : false;
}
inline void make_set(vpii &st) { rep(i, sz(st)) st[i] = mp(i, 1); }
inline int find_set(vpii &st, int x) {
  int y = x, z;
  whl(y != st[y].x) y = st[y].x;
  whl(x != st[x].x) z = st[x].x, st[x].x = y, x = z;
  rtn y;
}
inline bool union_set(vpii &st, int a, int b) {
  a = find_set(st, a), b = find_set(st, b);
  rtn a != b ? (st[a].y > st[b].y  ? st[a].x = b,
                st[a].y += st[b].y : st[b].x = a, st[b].y += st[a].y),
      true   : false;
}
template <typename type> inline void merge(type &a, type &b) {
  if (sz(a) < sz(b))
    swap(a, b);
  whl(sz(b)) a.ins(*b.begin()), b.ers(b.begin());
}

// 初始化;
struct Initializer {
#ifndef DEBUG
  Initializer() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
  }
#else
  ~Initializer() { runtime(); }
#endif
} initializer;

// 非标准;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
typedef __gnu_cxx ::rope<char> rope;
template <typename key, typename value>
class ext_map
    : public __gnu_pbds::tree<key, value, less<key>, __gnu_pbds ::rb_tree_tag,
                              __gnu_pbds ::tree_order_statistics_node_update> {
};
template <typename key>
class ext_set
    : public __gnu_pbds::tree<key, __gnu_pbds ::null_type, less<key>,
                              __gnu_pbds ::rb_tree_tag,
                              __gnu_pbds ::tree_order_statistics_node_update> {
};

inline pii find_set(map<pii, pii> &st, pii x) {
  if (!st.count(x)) {
    rtn st[x] = x;
  } else if (st[x] == x) {
    rtn x;
  } else {
    rtn st[x] = find_set(st, st[x]);
  }
}
inline bool union_set(map<pii, pii> &st, pii a, pii b) {
  a = find_set(st, a), b = find_set(st, b);
  rtn a != b ? st[a] = b, true : false;
}

int main() {
  int n;
  cin >> n;
  vpii p(n);
  cin >> p;

  vpii lst = p;
  srt(lst);
  vpii q;
  map<pii, pii> st;
  prt(lst);
  for (auto p : lst) {
    if ((!sz(q)) || q.back().y > p.y) {
      q.pb(p);
    } else {
      int i = lb(all(q), p, [](auto x, auto y) { rtn x.y > y.y; }) - q.begin();
      while (i < sz(q)) {
        prt(i);
        i = lb(all(q), find_set(st, q[i]),
               [](auto x, auto y) { rtn x.y > y.y; }) -
            q.begin();
        prt((i));
        prt(sz(q) - 1);
        union_set(st, q[i], q.back());
        i++;
      }
      union_set(st, q.back(), p);
    }
  }
  map<pii, int> cnt;
  for (auto x : p) {
    prt(mp(x, find_set(st, x)));
    cnt[find_set(st, x)]++;
  }
  rep(i, n) { cout << cnt[find_set(st, p[i])] << endl; }
}

/*
 * Package: StandardCodeLibrary.Core
 * */
// 引进常用的头文件并使用std名字空间;
#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

// 用于减少代码量的宏;
#define lp for (;;)
#define repf(i, a, b) for (int i = (a); i < (b); ++i)
#define ft(i, a, b) for (int i = (a); i <= (b); ++i)
#define fdt(i, a, b) for (int i = (a); i >= (b); --i)
#define rrepf(i, a, b) fdt(i, (a)-1, b)
#define rep(i, n) repf(i, 0, n)
#define rrep(i, n) rrepf(i, n, 0)
#define for_each(e, s)                                                         \\
  for (__typeof__((s).begin()) e = (s).begin(); e != (s).end(); ++e)
#define for_nonempty_subsets(subset, set)                                      \\
  for (int subset = set; subset; subset = (subset - 1) & (set))
#define for_in_charset(i, charset) for (cstr i = (charset); *i; i++)
#define whl(x) while (x)
#define rtn return
#define fl(x, y) memset((x), char(y), sizeof(x))
#define clr(x) fl(x, char(0))
#define cpy(x, y) memcpy(x, y, sizeof(x))
#define sf scanf
#define pf printf
#define vec vector
#define pr pair
#define que queue
#define prq priority_queue
#define itr iterator
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ins insert
#define ers erase
#define lb lower_bound
#define ub upper_bound
#define rnk order_of_key
#define sel find_by_order
#define ctz __builtin_ctz
#define clz __builtin_clz
#define bc __builtin_popcount
#define sz(x) (int((x).size()))
#define all(x) (x).begin(), (x).end()
#define srt(x) sort(all(x))
#define uniq(x) srt(x), (x).erase(unique(all(x)), (x).end())
#define rev(x) reverse(all(x))
#define shf(x) random_shuffle(all(x))
#define nxtp(x) next_permutation(all(x))

// 调试相关的宏;
#ifndef DEBUG
#define prt(x) (cerr)
#define asrtWA(s)                                                              \\
  do                                                                           \\
    if (!(s))                                                                  \\
      exit(0);                                                                 \\
  whl(0)
#define asrtTLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      whl(1);                                                                  \\
  whl(0)
#define asrtMLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      whl(new int);                                                            \\
  whl(0)
#define asrtOLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      whl(1) puts("OLE");                                                      \\
  whl(0)
#define asrtRE(s)                                                              \\
  do                                                                           \\
    if (!(s))                                                                  \\
      *(int *)0 = 0;                                                           \\
  whl(0)
#define runtime() (cerr)
#define input(in) freopen(in, "r", stdin)
#define output(out) freopen(out, "w", stdout)
#else
#define prt(x) cerr << "第" << __LINE__ << "行\\t: " << #x "\\t=" << (x) << endl
#define asrtWA(s)                                                              \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define asrtTLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define asrtMLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define asrtOLE(s)                                                             \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define asrtRE(s)                                                              \\
  do                                                                           \\
    if (!(s))                                                                  \\
      cerr << "assert(" #s ")" << endl;                                        \\
  whl(0)
#define runtime()                                                              \\
  cerr << "Used: " << db(clock()) / CLOCKS_PER_SEC << "s" << endl
#define input(in)
#define output(out)
#endif

// 常用数据类型;
typedef long long int lli;
typedef double db;
typedef const char *cstr;
typedef string str;
typedef vec<int> vi;
typedef vec<vi> vvi;
typedef vec<lli> vl;
typedef vec<vl> vvl;
typedef vec<bool> vb;
typedef vec<vb> vvb;
typedef vec<char> vc;
typedef vec<vc> vvc;
typedef vec<str> vs;
typedef pr<int, int> pii;
typedef pr<lli, lli> pll;
typedef pr<db, db> pdd;
typedef vec<pii> vpii;
typedef vec<pll> vpll;
typedef vec<pdd> vpdd;
typedef map<int, int> mii;
typedef map<str, int> msi;
typedef map<char, int> mci;
typedef set<int> si;
typedef set<str> ss;
typedef que<int> qi;

// 常用常量:int的最大值;lli的最大值;db的误差相关常数;欧拉常数;圆周率;移动向量;取模使用的除数;
int oo = (~0u) >> 1;
lli ooll = (~0ull) >> 1;
db inf = 1e+10;
db eps = 1e-10;
db gam = 0.5772156649015328606;
db pi = acos(-1.0);
int dx[] = {1, 0, -1, 0, 1, -1, -1, 1, 0};
int dy[] = {0, 1, 0, -1, 1, 1, -1, -1, 0};
int MOD = 1000000007;

// 常用函数:最大最小值更新;数学相关函数;输入和输出;树状数组;并查集;可合并堆;
template <typename type> inline bool cmax(type &a, const type &b) {
  rtn a < b ? a = b, true : false;
}
template <typename type> inline bool cmin(type &a, const type &b) {
  rtn b < a ? a = b, true : false;
}
template <typename type> inline type sqr(const type &x) { rtn x *x; }
template <typename type> inline type mod(const type &x) { rtn x % MOD; }
inline int sgn(const db &x) { rtn(x > +eps) - (x < -eps); }
inline int dbcmp(const db &a, const db &b) { rtn sgn(a - b); }
template <typename type>
inline pr<type, type> operator-(const pr<type, type> &x) {
  rtn mp(-x.x, -x.y);
}
template <typename type>
inline pr<type, type> operator+(const pr<type, type> &a,
                                const pr<type, type> &b) {
  rtn mp(a.x + b.x, a.y + b.y);
}
template <typename type>
inline pr<type, type> operator-(const pr<type, type> &a,
                                const pr<type, type> &b) {
  rtn mp(a.x - b.x, a.y - b.y);
}
template <typename type>
inline pr<type, type> operator*(const pr<type, type> &a, const type &b) {
  rtn mp(a.x * b, a.y * b);
}
template <typename type>
inline pr<type, type> operator/(const pr<type, type> &a, const type &b) {
  rtn mp(a.x / b, a.y / b);
}
template <typename type>
inline pr<type, type> &operator-=(pr<type, type> &a, const pr<type, type> &b) {
  rtn a = a - b;
}
template <typename type>
inline pr<type, type> &operator+=(pr<type, type> &a, const pr<type, type> &b) {
  rtn a = a + b;
}
template <typename type>
inline pr<type, type> &operator*=(pr<type, type> &a, const type &b) {
  rtn a = a * b;
}
template <typename type>
inline pr<type, type> &operator/=(pr<type, type> &a, const type &b) {
  rtn a = a / b;
}
template <typename type>
inline type cross(const pr<type, type> &a, const pr<type, type> &b) {
  rtn a.x *b.y - a.y *b.x;
}
template <typename type>
inline type dot(const pr<type, type> &a, const pr<type, type> &b) {
  rtn a.x *b.x + a.y *b.y;
}
template <typename type> inline type gcd(type a, type b) {
  if (b)
    whl((a %= b) && (b %= a));
  rtn a + b;
}
template <typename type> inline type lcm(type a, type b) {
  rtn a *b / gcd(a, b);
}
inline lli bin_pow(lli x, lli y) {
  lli z = 1;
  whl(y) {
    if (y & 1)
      z = mod(z * x);
    x = mod(sqr(x)), y >>= 1;
  }
  rtn z;
}
template <typename istream, typename first_type, typename second_type>
inline istream &operator>>(istream &cin, pr<first_type, second_type> &x) {
  rtn cin >> x.x >> x.y;
}
template <typename ostream, typename first_type, typename second_type>
inline ostream &operator<<(ostream &cout,
                           const pr<first_type, second_type> &x) {
  rtn cout << x.x << " " << x.y;
}
template <typename istream, typename type>
inline istream &operator>>(istream &cin, vec<type> &x) {
  rep(i, sz(x)) cin >> x[i];
  rtn cin;
}
template <typename ostream, typename type>
inline ostream &operator<<(ostream &cout, const vec<type> &x) {
  rep(i, sz(x)) cout << x[i] << (i + 1 == sz(x) ? "" : " ");
  rtn cout;
}
inline ostream &pdb(int prcs, db x) {
  rtn cout << setprecision(prcs) << fixed << (sgn(x) ? (x) : 0);
}
template <typename type> inline void bit_inc(vec<type> &st, int x, type inc) {
  whl(x < sz(st)) st[x] += inc, x |= x + 1;
}
template <typename type> inline type bit_sum(const vec<type> &st, int x) {
  type s = 0;
  whl(x >= 0) s += st[x], x = (x & (x + 1)) - 1;
  rtn s;
}
template <typename type> inline type bit_kth(const vec<type> &st, int k) {
  int x = 0, y = 0, z = 0;
  whl((1 << (++y)) <= sz(st));
  rrep(i, y) {
    if ((x += 1 << i) > sz(st) || z + st[x - 1] > k)
      x -= 1 << i;
    else
      z += st[x - 1];
  }
  rtn x;
}
inline void make_set(vi &st) { rep(i, sz(st)) st[i] = i; }
inline int find_set(vi &st, int x) {
  int y = x, z;
  whl(y != st[y]) y = st[y];
  whl(x != st[x]) z = st[x], st[x] = y, x = z;
  rtn y;
}
inline bool union_set(vi &st, int a, int b) {
  a = find_set(st, a), b = find_set(st, b);
  rtn a != b ? st[a] = b, true : false;
}
inline void make_set(vpii &st) { rep(i, sz(st)) st[i] = mp(i, 1); }
inline int find_set(vpii &st, int x) {
  int y = x, z;
  whl(y != st[y].x) y = st[y].x;
  whl(x != st[x].x) z = st[x].x, st[x].x = y, x = z;
  rtn y;
}
inline bool union_set(vpii &st, int a, int b) {
  a = find_set(st, a), b = find_set(st, b);
  rtn a != b ? (st[a].y > st[b].y  ? st[a].x = b,
                st[a].y += st[b].y : st[b].x = a, st[b].y += st[a].y),
      true   : false;
}
template <typename type> inline void merge(type &a, type &b) {
  if (sz(a) < sz(b))
    swap(a, b);
  whl(sz(b)) a.ins(*b.begin()), b.ers(b.begin());
}

// 初始化;
struct Initializer {
#ifndef DEBUG
  Initializer() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
  }
#else
  ~Initializer() { runtime(); }
#endif
} initializer;

// 非标准;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
typedef __gnu_cxx ::rope<char> rope;
template <typename key, typename value>
class ext_map
    : public __gnu_pbds::tree<key, value, less<key>, __gnu_pbds ::rb_tree_tag,
                              __gnu_pbds ::tree_order_statistics_node_update> {
};
template <typename key>
class ext_set
    : public __gnu_pbds::tree<key, __gnu_pbds ::null_type, less<key>,
                              __gnu_pbds ::rb_tree_tag,
                              __gnu_pbds ::tree_order_statistics_node_update> {
};

inline pii find_set(map<pii, pii> &st, pii x) {
  if (!st.count(x)) {
    rtn st[x] = x;
  } else if (st[x] == x) {
    rtn x;
  } else {
    rtn st[x] = find_set(st, st[x]);
  }
}
inline bool union_set(map<pii, pii> &st, pii a, pii b) {
  a = find_set(st, a), b = find_set(st, b);
  rtn a != b ? st[a] = b, true : false;
}

int main() {
  int n;
  cin >> n;
  vpii p(n);
  cin >> p;

  vpii lst = p;
  srt(lst);
  vpii q;
  map<pii, pii> st;
  //	prt(lst);
  for (auto p : lst) {
    if ((!sz(q)) || q.back().y > p.y) {
      q.pb(p);
    } else {
      union_set(st, p, q.back());
      int i = lb(all(q), p, [](auto x, auto y) { rtn x.y > y.y; }) - q.begin();
      while (i < sz(q)) {
        //				prt(i);
        i = lb(all(q), find_set(st, q[i]),
               [](auto x, auto y) { rtn x.y > y.y; }) -
            q.begin();
        //				prt((i));
        //				prt(sz(q)-1);
        union_set(st, q[i], q.back());
        i++;
      }
    }
  }
  map<pii, int> cnt;
  for (auto x : p) {
    //		prt(mp(x,find_set(st,x)));
    cnt[find_set(st, x)]++;
  }
  rep(i, n) { cout << cnt[find_set(st, p[i])] << endl; }
}


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

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef vector<ll> vi;
typedef vector<pll> vpll;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
#define endl '\\n'
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define F first
#define S second
#define rs(v, n) v.resize(n)
#define hell 1000000007
// #define hell        998244353
#define peak 9e18
#define pii acos(-1)
#define clr(a, x) memset(a, x, sizeof(a))
auto clk = clock();
mt19937_64
    rang(chrono::high_resolution_clock::now().time_since_epoch().count());

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

namespace Ops {
template <class y, class z> z expo(ll b, y e, z m) {
  ll a = 1;
  b %= m;
  while (e != 0) {
    if ((e & 1) == 1) {
      a = a * b;
      a = a % m;
    }
    b = b * b;
    b %= m;
    e >>= 1;
  }
  return a % m;
}
template <class y, class z> z power(ll b, y e) {
  ll a = 1;
  while (e != 0) {
    if ((e & 1) == 1) {
      a = a * b;
    }
    b = b * b;
    e >>= 1;
  }
  return a;
}
template <class x, class z> z inv(x b, z m) { return expo(b, m - 2, m); }
template <class x, class y> x invGeneral(x a, y b) {
  if (a == 0)
    return b == 1 ? 0 : -1;
  x m = invGeneral(b % a, a);
  return m == -1 ? -1 : ((1 - (ll)b * m) / a + b) % b;
}
template <class x, class y> x min(x a, y b) {
  x c;
  if (a <= b)
    c = a;
  else
    c = b;
  return c;
}
template <class x, class y> x max(x a, y b) {
  x c;
  if (a >= b)
    c = a;
  else
    c = b;
  return c;
}
} // namespace Ops
using namespace Ops;

namespace InOp {
template <class x> istream &operator>>(istream &in, vector<x> &v) {
  for (auto &i : v)
    in >> i;
  return in;
}
template <class x, class y> ostream &operator<<(ostream &out, pair<x, y> &p) {
  out << "(" << p.F << "," << p.S << ")";
  return out;
}
template <class x> ostream &operator<<(ostream &out, vector<x> &v) {
  out << "Size : " << v.size() << endl;
  for (auto i : v)
    out << i << " ";
  out << endl;
  return out;
}
} // namespace InOp
using namespace InOp;

namespace Debug {
#define LOCAL
#ifdef LOCAL
#define deb(...) printall(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void printall(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void printall(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  printall(comma + 1, args...);
}
#else
#define deb(...) void(0)
#endif
} // namespace Debug
using namespace Debug;

namespace Bits {
template <class x> constexpr int onbits(x a) { return __builtin_popcount(a); }
constexpr int bits(long long x) {
  return 64 - __builtin_clzll(x);
} // take care of 0
constexpr int bits(int x) { return 32 - __builtin_clz(x); } // take care of 0
constexpr int traz(int a) { return __builtin_ctz(a); }
constexpr int traz(long long a) { return __builtin_ctzll(a); }
} // namespace Bits
using namespace Bits;

namespace YesNo {
// #define CAPITAL
void yes() {
#ifdef CAPITAL
  cout << "YES"
       << "\\n";
#else
  cout << "Yes"
       << "\\n";
#endif
}
void no() {
#ifdef CAPITAL
  cout << "NO"
       << "\\n";
#else
  cout << "No"
       << "\\n";
#endif
}
} // namespace YesNo
using namespace YesNo;

void maester();
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  srand(chrono::high_resolution_clock::now().time_since_epoch().count());
  cout << fixed << setprecision(6);
  ll test = 1;
  // cin>>test;
  while (test--) {
    maester();
  }
#ifndef ONLINE_JUDGE
  cout << endl
       << endl
       << endl
       << endl
       << "Time elapsed: " << (double)(clock() - clk) / CLOCKS_PER_SEC << endl;
#endif
  return 0;
}
#define N 25
vi pa(N), sz(N);
ll findpa(ll x) {
  ll y = pa[x];
  if (y == x)
    return y;
  pa[x] = findpa(y);
  return pa[x];
}
void connect(ll x, ll y) {
  // deb(x,y);
  ll px = findpa(x);
  ll py = findpa(y);
  if (px < py)
    swap(px, py);
  pa[px] = py;
  sz[py] += sz[px];
}
void maester() {
  ll i, j, k, l, r, m, n, x, y;
  cin >> n;
  for (i = 0; i <= n; i++)
    pa[i] = i, sz[i] = 1;
  vector<pair<ll, pair<ll, ll>>> v;
  for (i = 0; i < n; i++) {
    cin >> x >> y;
    v.pb({x, {y, i}});
  }
  sort(all(v));
  // deb(v);
  vi vv(n);
  for (i = 0; i < n; i++)
    vv[i] = v[i].S.F;
  set<ll> s;
  for (i = 0; i < n; i++) {
    vi vp;
    for (auto j : s) {
      if (j > vv[i])
        break;
      vp.pb(j);
      connect(j, vv[i]);
    }
    for (auto j : vp)
      s.erase(j);
    x = findpa(vv[i]);
    s.insert(x);
  }
  // deb(sz,pa);
  vi ans(n);
  for (i = 0; i < n; i++) {
    ans[v[i].S.S] = sz[findpa(v[i].S.F)];
  }
  for (i = 0; i < n; i++)
    cout << ans[i] << endl;
}

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

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef vector<ll> vi;
typedef vector<pll> vpll;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
#define endl '\\n'
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define F first
#define S second
#define rs(v, n) v.resize(n)
#define hell 1000000007
// #define hell        998244353
#define peak 9e18
#define pii acos(-1)
#define clr(a, x) memset(a, x, sizeof(a))
auto clk = clock();
mt19937_64
    rang(chrono::high_resolution_clock::now().time_since_epoch().count());

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

namespace Ops {
template <class y, class z> z expo(ll b, y e, z m) {
  ll a = 1;
  b %= m;
  while (e != 0) {
    if ((e & 1) == 1) {
      a = a * b;
      a = a % m;
    }
    b = b * b;
    b %= m;
    e >>= 1;
  }
  return a % m;
}
template <class y, class z> z power(ll b, y e) {
  ll a = 1;
  while (e != 0) {
    if ((e & 1) == 1) {
      a = a * b;
    }
    b = b * b;
    e >>= 1;
  }
  return a;
}
template <class x, class z> z inv(x b, z m) { return expo(b, m - 2, m); }
template <class x, class y> x invGeneral(x a, y b) {
  if (a == 0)
    return b == 1 ? 0 : -1;
  x m = invGeneral(b % a, a);
  return m == -1 ? -1 : ((1 - (ll)b * m) / a + b) % b;
}
template <class x, class y> x min(x a, y b) {
  x c;
  if (a <= b)
    c = a;
  else
    c = b;
  return c;
}
template <class x, class y> x max(x a, y b) {
  x c;
  if (a >= b)
    c = a;
  else
    c = b;
  return c;
}
} // namespace Ops
using namespace Ops;

namespace InOp {
template <class x> istream &operator>>(istream &in, vector<x> &v) {
  for (auto &i : v)
    in >> i;
  return in;
}
template <class x, class y> ostream &operator<<(ostream &out, pair<x, y> &p) {
  out << "(" << p.F << "," << p.S << ")";
  return out;
}
template <class x> ostream &operator<<(ostream &out, vector<x> &v) {
  out << "Size : " << v.size() << endl;
  for (auto i : v)
    out << i << " ";
  out << endl;
  return out;
}
} // namespace InOp
using namespace InOp;

namespace Debug {
#define LOCAL
#ifdef LOCAL
#define deb(...) printall(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void printall(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void printall(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  printall(comma + 1, args...);
}
#else
#define deb(...) void(0)
#endif
} // namespace Debug
using namespace Debug;

namespace Bits {
template <class x> constexpr int onbits(x a) { return __builtin_popcount(a); }
constexpr int bits(long long x) {
  return 64 - __builtin_clzll(x);
} // take care of 0
constexpr int bits(int x) { return 32 - __builtin_clz(x); } // take care of 0
constexpr int traz(int a) { return __builtin_ctz(a); }
constexpr int traz(long long a) { return __builtin_ctzll(a); }
} // namespace Bits
using namespace Bits;

namespace YesNo {
// #define CAPITAL
void yes() {
#ifdef CAPITAL
  cout << "YES"
       << "\\n";
#else
  cout << "Yes"
       << "\\n";
#endif
}
void no() {
#ifdef CAPITAL
  cout << "NO"
       << "\\n";
#else
  cout << "No"
       << "\\n";
#endif
}
} // namespace YesNo
using namespace YesNo;

void maester();
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  srand(chrono::high_resolution_clock::now().time_since_epoch().count());
  cout << fixed << setprecision(6);
  ll test = 1;
  // cin>>test;
  while (test--) {
    maester();
  }
#ifndef ONLINE_JUDGE
  cout << endl
       << endl
       << endl
       << endl
       << "Time elapsed: " << (double)(clock() - clk) / CLOCKS_PER_SEC << endl;
#endif
  return 0;
}
#define N 200005
vi pa(N), sz(N);
ll findpa(ll x) {
  ll y = pa[x];
  if (y == x)
    return y;
  pa[x] = findpa(y);
  return pa[x];
}
void connect(ll x, ll y) {
  // deb(x,y);
  ll px = findpa(x);
  ll py = findpa(y);
  if (px < py)
    swap(px, py);
  pa[px] = py;
  sz[py] += sz[px];
}
void maester() {
  ll i, j, k, l, r, m, n, x, y;
  cin >> n;
  for (i = 0; i <= n; i++)
    pa[i] = i, sz[i] = 1;
  vector<pair<ll, pair<ll, ll>>> v;
  for (i = 0; i < n; i++) {
    cin >> x >> y;
    v.pb({x, {y, i}});
  }
  sort(all(v));
  // deb(v);
  vi vv(n);
  for (i = 0; i < n; i++)
    vv[i] = v[i].S.F;
  set<ll> s;
  for (i = 0; i < n; i++) {
    vi vp;
    for (auto j : s) {
      if (j > vv[i])
        break;
      vp.pb(j);
      connect(j, vv[i]);
    }
    for (auto j : vp)
      s.erase(j);
    x = findpa(vv[i]);
    s.insert(x);
  }
  // deb(sz,pa);
  vi ans(n);
  for (i = 0; i < n; i++) {
    ans[v[i].S.S] = sz[findpa(v[i].S.F)];
  }
  for (i = 0; i < n; i++)
    cout << ans[i] << endl;
}


#include "algorithm"
#include "bitset"
#include "cassert"
#include "climits"
#include "cmath"
#include "cstdio"
#include "ctime"
#include "functional"
#include "iomanip"
#include "iostream"
#include "list"
#include "map"
#include "numeric"
#include "queue"
#include "random"
#include "set"
#include "stack"
#include "string"
#include "unordered_map"
#include "unordered_set"

using namespace std;

constexpr long long int MOD = 1000000007;
// constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
// constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

// int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

struct Node {
  int x, y, index;
  bool operator<(const Node &n) const {
    return make_pair(x, y) < make_pair(n.x, n.y);
  }
};

class Add_Segment_Tree {
  vector<long long int> v;
  long long int ret;
  int num;
  long long int Update(int place) {
    if (place >= v.size() / 2) {
      return v[place];
    }
    v[place] = Update(place * 2) + Update(place * 2 + 1);
    return v[place];
  }

public:
  Add_Segment_Tree(int n) {
    n++;
    num = 1;
    while (num < n * 2)
      num *= 2;
    v.resize(num, 0);
  }
  void Add(int place, long long int num, bool update) {
    place += v.size() / 2;
    v[place] += num;
    if (!update)
      return;
    place /= 2;
    while (place) {
      v[place] = v[place * 2] + v[place * 2 + 1];
      place /= 2;
    }
  }
  void TopDown() { Update(1); }
  long long int Sum(int a, int b) {
    ret = 0;
    b++;
    for (a += num / 2, b += num / 2; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        ret += v[a++];
      if (b & 1)
        ret += v[--b];
    }
    return ret;
  }
};

class UnionFind {
  vector<int> parent;
  vector<int> rank;

public:
  UnionFind(int num) {
    num++;
    parent.resize(num);
    rank.resize(num);
    for (int i = 0; i < num; i++) {
      parent[i] = i;
      rank[i] = 0;
    }
  }
  int Find(int node) {
    if (parent[node] == node)
      return node;
    else
      return parent[node] = Find(parent[node]);
  }
  void Unite(int u, int v) {
    u = Find(u);
    v = Find(v);
    if (u == v)
      return;
    if (rank[u] < rank[v])
      parent[u] = v;
    else {
      parent[v] = u;
      if (rank[u] == rank[v])
        rank[u]++;
    }
  }
  bool Check_Same(int u, int v) { return Find(u) == Find(v); }
};

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

  cin >> N;
  vector<Node> v(N);
  for (int i = 0; i < N; i++) {
    cin >> v[i].x >> v[i].y;
    v[i].index = i;
  }
  sort(v.begin(), v.end());
  vector<int> ans(N);
  UnionFind uf(N);
  {
    map<int, int> mp;
    for (auto i : v) {
      if (prev(mp.lower_bound(i.y)) != mp.end())
        uf.Unite(i.index, prev(mp.lower_bound(i.y))->second);
      mp[i.y] = i.index;
    }
  }
  {
    map<int, int> mp;
    reverse(v.begin(), v.end());
    for (auto i : v) {
      if (mp.lower_bound(i.y) != mp.end())
        uf.Unite(i.index, mp.lower_bound(i.y)->second);
      mp[i.y] = i.index;
    }
  }
  for (int i = 0; i < N; i++) {
    ans[uf.Find(i)]++;
  }
  for (int i = 0; i < N; i++) {
    cout << ans[uf.Find(i)] << endl;
  }
}

#include "algorithm"
#include "bitset"
#include "cassert"
#include "climits"
#include "cmath"
#include "cstdio"
#include "ctime"
#include "functional"
#include "iomanip"
#include "iostream"
#include "list"
#include "map"
#include "numeric"
#include "queue"
#include "random"
#include "set"
#include "stack"
#include "string"
#include "unordered_map"
#include "unordered_set"

using namespace std;

constexpr long long int MOD = 1000000007;
// constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
// constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

// int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

struct Node {
  int x, y, index;
  bool operator<(const Node &n) const {
    return make_pair(x, y) < make_pair(n.x, n.y);
  }
};

class Segment_Tree {
  vector<long long int> v;
  int num;
  long long int ret;
  bool is_min;
  long long int Update(int place) {
    if (place >= v.size() / 2) {
      return v[place];
    }
    if (is_min) {
      v[place] = min(Update(place * 2), Update(place * 2 + 1));
      return v[place];
    }
    v[place] = max(Update(place * 2), Update(place * 2 + 1));
    return v[place];
  }

public:
  Segment_Tree(int n, bool min) {
    n++;
    num = 1;
    while (num < n * 2) {
      num *= 2;
    }
    is_min = min;
    if (min) {
      v.resize(num, MOD * MOD);
    } else
      v.resize(num, -MOD * MOD);
  }
  void Insert(int place, long long int num, bool update) {
    place += v.size() / 2;
    v[place] = num;
    if (!update)
      return;
    place /= 2;
    while (place) {
      if (is_min)
        v[place] = min(v[place * 2], v[place * 2 + 1]);
      else
        v[place] = max(v[place * 2], v[place * 2 + 1]);
      place /= 2;
    }
  }
  void TopDown() { Update(1); }
  long long int RMQ(int a, int b) {
    if (is_min)
      ret = INT_MAX;
    else
      ret = INT_MIN;
    if (is_min) {
      b++;
      for (a += num / 2, b += num / 2; a < b; a >>= 1, b >>= 1) {
        if (a & 1)
          ret = min(ret, v[a++]);
        if (b & 1)
          ret = min(ret, v[--b]);
      }
    } else {
      b++;
      for (a += num / 2, b += num / 2; a < b; a >>= 1, b >>= 1) {
        if (a & 1)
          ret = max(ret, v[a++]);
        if (b & 1)
          ret = max(ret, v[--b]);
      }
    }
    return ret;
  }
};

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

  cin >> N;
  vector<Node> v(N);
  vector<int> y_to_x(N);
  vector<int> x(N);
  for (int i = 0; i < N; i++) {
    cin >> v[i].x >> v[i].y;
    v[i].x--, v[i].y--;
    v[i].index = i;
    x[i] = y_to_x[v[i].y] = v[i].x;
  }
  sort(v.begin(), v.end());
  vector<int> ans(N);
  Segment_Tree msg(N, true);
  Segment_Tree Msg(N, false);
  for (int i = 0; i < N; i++) {
    msg.Insert(i, v[i].y, false);
    Msg.Insert(i, v[i].y, false);
  }
  msg.TopDown();
  Msg.TopDown();
  for (auto i : v) {
    if (ans[i.index])
      continue;
    int cnt = 1;
    queue<int> Q;
    vector<int> box;
    Q.push(i.x);
    box.push_back(i.index);
    msg.Insert(i.x, MOD, true);
    Msg.Insert(i.x, -MOD, true);
    while (!Q.empty()) {
      int cx = Q.front();
      int cy = v[cx].y;
      Q.pop();
      while (Msg.RMQ(cx + 1, N - 1) > cy) {
        cnt++;
        auto xp = y_to_x[Msg.RMQ(cx + 1, N - 1)];
        Q.push(xp);
        box.push_back(v[xp].index);
        Msg.Insert(xp, -MOD, true);
        msg.Insert(xp, MOD, true);
      }
      while (msg.RMQ(0, cx - 1) < cy) {
        cnt++;
        auto xp = y_to_x[msg.RMQ(0, cx - 1)];
        Q.push(xp);
        box.push_back(v[xp].index);
        msg.Insert(xp, MOD, true);
        Msg.Insert(xp, -MOD, true);
      }
    }
    for (auto j : box) {
      ans[j] = cnt;
    }
  }
  for (auto i : ans)
    cout << i << endl;
}


/*
このコード、と～おれ!
Be accepted!
∧＿∧
（｡･ω･｡)つ━☆・*。
⊂　　 ノ 　　　・゜+.
　しーＪ　　　°。+ *´¨)
 　　　　　　　　　.· ´¸.·*´¨) ¸.·*¨)
                  　　　　　　　　　　(¸.·´ (¸.·'* ☆
*/

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

////多倍長整数, cpp_intで宣言
// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;
//
#pragma GCC target("avx2")
#pragma GCC optimization("Ofast")
#pragma GCC optimization("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define repeat(i, n, m) for (int i = n; i < (m); ++i)
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define printynl(a) printf(a ? "yes\\n" : "no\\n")
#define printyn(a) printf(a ? "Yes\\n" : "No\\n")
#define printYN(a) printf(a ? "YES\\n" : "NO\\n")
#define printim(a) printf(a ? "possible\\n" : "imposible\\n")
#define printdb(a) printf("%.50lf\\n", a)    // 少数出力
#define printLdb(a) printf("%.50Lf\\n", a)   // 少数出力
#define printdbd(a) printf("%.16lf\\n", a)   // 少数出力(桁少なめ)
#define prints(s) printf("%s\\n", s.c_str()) // string出力
#define all(x) (x).begin(), (x).end()
#define deg_to_rad(deg) (((deg) / 360.0L) * 2.0L * PI)
#define rad_to_deg(rad) (((rad) / 2.0L / PI) * 360.0L)
#define Please return
#define AC 0
#define manhattan_dist(a, b, c, d)                                             \\
  (abs(a - c) + abs(b - d)) /*(a, b) から (c, d) のマンハッタン距離 */
#define inf numeric_limits<double>::infinity();
#define linf numeric_limits<long double>::infinity()

using ll = long long;
using ull = unsigned long long;

constexpr int INF = 1073741823;
constexpr int MINF = -1073741823;
constexpr ll LINF = ll(4661686018427387903);
constexpr ll MOD = 1e9 + 7;
constexpr ll mod = 998244353;
constexpr long double eps = 1e-6;
const long double PI = acosl(-1.0L);

using namespace std;

void scans(string &str) {
  char c;
  str = "";
  scanf("%c", &c);
  if (c == '\\n')
    scanf("%c", &c);
  while (c != '\\n' && c != -1 && c != ' ') {
    str += c;
    scanf("%c", &c);
  }
}

void scanc(char &str) {
  char c;
  scanf("%c", &c);
  if (c == -1)
    return;
  while (c == '\\n') {
    scanf("%c", &c);
  }
  str = c;
}

double acot(double x) { return PI / 2 - atan(x); }

ll LSB(ll n) { return (n & (-n)); }

template <typename T> inline T chmin(T &a, const T &b) {
  if (a > b)
    a = b;
  return a;
}

template <typename T> inline T chmax(T &a, const T &b) {
  if (a < b)
    a = b;
  return a;
}

////atcoder library
// #include <atcoder/all>
// using namespace atcoder;

/*-----------------------------------------ここからコード-----------------------------------------*/

/*
 * @title unionfind
 * @docs kyopro/docs/unionfind.md
 */

// 0-indexed
struct unionfind {
  vector<int> par, siz;

  unionfind(int n) : par(n), siz(n) {
    for (int i = 0; i < n; ++i) {
      // 全部根で初期化
      par[i] = i;
      // サイズは1
      siz[i] = 1;
    }
  }

  void init(int n) {
    par.resize(n);
    siz.resize(n);
    for (int i = 0; i < n; ++i) {
      // 全部根で初期化
      par[i] = i;
      // サイズは1
      siz[i] = 1;
    }
  }

  // 根を返す
  int find(int a) { return par[a] == a ? a : par[a] = find(par[a]); }

  // くっつける。元から同じだったらfalseを返す
  bool unite(int a, int b) {
    int x = find(a), y = find(b);
    if (x == y)
      return false;
    else if (siz[x] < siz[y]) {
      par[x] = y;
      siz[y] += siz[x];
    } else if (siz[x] > siz[y]) {
      par[y] = x;
      siz[x] += siz[y];
    } else {
      par[x] = y;
      siz[y] += siz[x];
    }
    return true;
  }

  // 同じ集合か判定する
  bool same(int a, int b) { return find(a) == find(b); }

  // サイズを返す
  int size(int a) { return siz[find(a)]; }

  // 同じ集合に属す葉を纏めて返す
  vector<int> leaf(int a) {
    vector<int> x;
    int n = par.size();
    for (int i = 0; i < n; ++i)
      if (same(a, i))
        x.push_back(i);
    return x;
  }
};

int main() {

  int n;
  scanf("%d", &n);
  int cnt = 0, flag = 0;
  queue<tuple<int, int, int>> que;
  vector<bool> check(n);
  unionfind uni(n);
  vector<tuple<int, int, int>> xy(n);
  for (auto &[a, b, qu] : xy) {
    scanf("%d%d", &a, &b);
    --a, --b;
    qu = cnt++;
  }
  rep(i, n) {
    if (check[get<2>(xy[i])])
      continue;
    check[get<2>(xy[i])] = true;
    ++flag;
    que.push(xy[i]);
    while (not que.empty()) {
      auto [x, y, q] = que.front();
      que.pop();
      rep(j, n) {
        if (check[j])
          continue;
        else if ((x > get<0>(xy[j]) and y > get<1>(xy[j])) or
                 (x < get<0>(xy[j]) and y < get<1>(xy[j]))) {
          check[get<2>(xy[j])] = true;
          que.push(xy[j]);
          uni.unite(i, j);
          ++flag;
        }
      }
    }
    if (flag == n)
      break;
  }
  rep(i, n) printf("%d\\n", uni.size(i));

  Please AC;
}

/*
このコード、と～おれ!
Be accepted!
∧＿∧
（｡･ω･｡)つ━☆・*。
⊂　　 ノ 　　　・゜+.
　しーＪ　　　°。+ *´¨)
 　　　　　　　　　.· ´¸.·*´¨) ¸.·*¨)
                  　　　　　　　　　　(¸.·´ (¸.·'* ☆
*/

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

////多倍長整数, cpp_intで宣言
// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;
//
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("Ofast")
// #pragma GCC optimization ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define repeat(i, n, m) for (int i = n; i < (m); ++i)
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define printynl(a) printf(a ? "yes\\n" : "no\\n")
#define printyn(a) printf(a ? "Yes\\n" : "No\\n")
#define printYN(a) printf(a ? "YES\\n" : "NO\\n")
#define printim(a) printf(a ? "possible\\n" : "imposible\\n")
#define printdb(a) printf("%.50lf\\n", a)    // 少数出力
#define printLdb(a) printf("%.50Lf\\n", a)   // 少数出力
#define printdbd(a) printf("%.16lf\\n", a)   // 少数出力(桁少なめ)
#define prints(s) printf("%s\\n", s.c_str()) // string出力
#define all(x) (x).begin(), (x).end()
#define deg_to_rad(deg) (((deg) / 360.0L) * 2.0L * PI)
#define rad_to_deg(rad) (((rad) / 2.0L / PI) * 360.0L)
#define Please return
#define AC 0
#define manhattan_dist(a, b, c, d)                                             \\
  (abs(a - c) + abs(b - d)) /*(a, b) から (c, d) のマンハッタン距離 */
#define inf numeric_limits<double>::infinity();
#define linf numeric_limits<long double>::infinity()

using ll = long long;
using ull = unsigned long long;

constexpr int INF = 1073741823;
constexpr int MINF = -1073741823;
constexpr ll LINF = ll(4661686018427387903);
constexpr ll MOD = 1e9 + 7;
constexpr ll mod = 998244353;
constexpr long double eps = 1e-6;
const long double PI = acosl(-1.0L);

using namespace std;

void scans(string &str) {
  char c;
  str = "";
  scanf("%c", &c);
  if (c == '\\n')
    scanf("%c", &c);
  while (c != '\\n' && c != -1 && c != ' ') {
    str += c;
    scanf("%c", &c);
  }
}

void scanc(char &str) {
  char c;
  scanf("%c", &c);
  if (c == -1)
    return;
  while (c == '\\n') {
    scanf("%c", &c);
  }
  str = c;
}

double acot(double x) { return PI / 2 - atan(x); }

ll LSB(ll n) { return (n & (-n)); }

template <typename T> inline T chmin(T &a, const T &b) {
  if (a > b)
    a = b;
  return a;
}

template <typename T> inline T chmax(T &a, const T &b) {
  if (a < b)
    a = b;
  return a;
}

////atcoder library
// #include <atcoder/all>
// using namespace atcoder;

/*-----------------------------------------ここからコード-----------------------------------------*/

/*
 * @title unionfind
 * @docs kyopro/docs/unionfind.md
 */

// 0-indexed
struct unionfind {
  vector<int> par, siz;

  unionfind(int n) : par(n), siz(n) {
    for (int i = 0; i < n; ++i) {
      // 全部根で初期化
      par[i] = i;
      // サイズは1
      siz[i] = 1;
    }
  }

  void init(int n) {
    par.resize(n);
    siz.resize(n);
    for (int i = 0; i < n; ++i) {
      // 全部根で初期化
      par[i] = i;
      // サイズは1
      siz[i] = 1;
    }
  }

  // 根を返す
  int find(int a) { return par[a] == a ? a : par[a] = find(par[a]); }

  // くっつける。元から同じだったらfalseを返す
  bool unite(int a, int b) {
    int x = find(a), y = find(b);
    if (x == y)
      return false;
    else if (siz[x] < siz[y]) {
      par[x] = y;
      siz[y] += siz[x];
    } else if (siz[x] > siz[y]) {
      par[y] = x;
      siz[x] += siz[y];
    } else {
      par[x] = y;
      siz[y] += siz[x];
    }
    return true;
  }

  // 同じ集合か判定する
  bool same(int a, int b) { return find(a) == find(b); }

  // サイズを返す
  int size(int a) { return siz[find(a)]; }

  // 同じ集合に属す葉を纏めて返す
  vector<int> leaf(int a) {
    vector<int> x;
    int n = par.size();
    for (int i = 0; i < n; ++i)
      if (same(a, i))
        x.push_back(i);
    return x;
  }
};

int main() {

  int n;
  scanf("%d", &n);
  int cnt = 0;
  unionfind uni(n);
  set<pair<int, int>> st;
  vector<tuple<int, int, int>> xy(n);
  for (auto &[a, b, qu] : xy) {
    scanf("%d%d", &a, &b);
    --a, --b;
    qu = cnt++;
  }
  sort(all(xy));
  rep(i, n) {
    int nm = get<1>(xy[i]);
    for (auto ite = st.begin();
         ite != st.end() and ite->first < get<1>(xy[i]);) {
      uni.unite(ite->second, get<2>(xy[i]));
      chmin(nm, ite->first);
      ite = st.erase(ite);
    }
    st.insert({nm, get<2>(xy[i])});
  }
  rep(i, n) printf("%d\\n", uni.size(i));

  Please AC;
}