Problem:
Score : 300 points

Problem Statement

There are N cities on a 2D plane. The coordinate of the i-th city is (x_i, y_i). Here (x_1, x_2, \dots, x_N) and (y_1, y_2, \dots, y_N) are both permuations of (1, 2, \dots, N).

For each k = 1,2,\dots,N, find the answer to the following question:

Rng is in City k.
Rng can perform the following move arbitrarily many times:

move to another city that has a smaller x-coordinate and a smaller y-coordinate, or a larger x-coordinate and a larger y-coordinate, than the city he is currently in.

How many cities (including City k) are reachable from City k?

Constraints

1 \leq N \leq 200,000

(x_1, x_2, \dots, x_N) is a permutation of (1, 2, \dots, N).

(y_1, y_2, \dots, y_N) is a permutation of (1, 2, \dots, N).

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_N y_N

Output

Print N lines. In i-th line print the answer to the question when k = i.

Sample Input 1

4
1 4
2 3
3 1
4 2

Sample Output 1

1
1
2
2

Rng can reach City 4 from City 3, or conversely City 3 from City 4.

Sample Input 2

7
6 4
4 3
3 5
7 1
2 7
5 2
1 6

Sample Output 2

3
3
1
1
2
3
2

Solution in Rust (1.42.0) (judge verdict: Time Limit Exceeded)

use proconio::input;
use std::cmp::Ordering;
use std::io::{stdout, BufWriter, Write};

enum ParRank {
    Parent(usize),
    Rank(usize),
}

struct UnionFind {
    v: Vec<ParRank>,
}

impl UnionFind {
    fn new(n: usize) -> UnionFind {
        let mut v = Vec::new();
        for _ in 0..n {
            v.push(ParRank::Rank(1));
        }
        UnionFind { v }
    }

    fn root(&self, i: usize) -> usize {
        match self.v[i] {
            ParRank::Rank(_) => i,
            ParRank::Parent(j) => {
                let r = self.root(j);
                // self.v[i] = ParRank::Parent(r);
                r
            }
        }
    }

    fn size(&self, i: usize) -> usize {
        if let ParRank::Rank(r) = self.v[self.root(i)] {
            r
        } else {
            panic!("UnionFind: root is not root");
        }
    }

    fn unite(&mut self, i1: usize, i2: usize) -> bool {
        let r1 = self.root(i1);
        let r2 = self.root(i2);
        if r1 == r2 {
            return false;
        }
        let rank1 = if let ParRank::Rank(r) = self.v[r1] { r } else {
            panic!("UnionFind: root is not root");
        };
        let rank2 = if let ParRank::Rank(r) = self.v[r2] { r } else {
            panic!("UnionFind: root is not root");
        };
        match self.size(r1).cmp(&self.size(r2)) {
            Ordering::Less => {
                self.v[r1] = ParRank::Parent(r2);
                self.v[r2] = ParRank::Rank(rank1 + rank2);
            },
            Ordering::Equal => {
                self.v[r1] = ParRank::Parent(r2);
                self.v[r2] = ParRank::Rank(rank1 + rank2);
            },
            Ordering::Greater => {
                self.v[r2] = ParRank::Parent(r1);
                self.v[r1] = ParRank::Rank(rank1 + rank2);
            },
        }
        return true;
    }
}

fn same(xy0: (usize, usize), xy1: (usize, usize)) -> bool {
    if xy0.0 < xy1.0 && xy0.1 < xy1.1 {
        return true;
    }
    if xy0.0 > xy1.0 && xy0.1 > xy1.1 {
        return true;
    }
    return false;
}

fn main() {
    input! {
        n: usize,
        xy: [(usize, usize);n],
    };
    let mut uf = UnionFind::new(n);
    for i in 0..n {
        for j in 0..i {
            if same(xy[i], xy[j]) {
                uf.unite(i, j);
            }
        }
    }
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    for i in 0..n {
        writeln!(out, "{}", uf.size(i)).unwrap();
    }
}