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: Accepted)

fn main() {
    let stdin = std::io::stdin();
    let mut rd = ProconReader::new(stdin.lock());

    let n: usize = rd.get();
    let mut xyi: Vec<(usize, usize, usize)> = (0..n)
        .map(|i| {
            let x: usize = rd.get();
            let y: usize = rd.get();
            (x, y, i)
        })
        .collect();
    xyi.sort();
    let lb = xyi[0];
    let mut lb = (lb.1, lb.2);
    let mut uf = UnionFind::new(n);
    for &(_, y, i) in &xyi[1..] {
        let (yy, j) = lb;
        if yy < y {
            uf.unite(i, j);
        }
        if y < yy {
            lb = (y, i);
        }
    }
    let rt = xyi[n - 1];
    let mut rt = (rt.1, rt.2);
    for &(_, y, i) in xyi[0..(n - 1)].iter().rev() {
        let (yy, j) = rt;
        if y < yy {
            uf.unite(i, j);
        }
        if yy < y {
            rt = (y, i);
        }
    }
    xyi.sort_by(|(px, py, i), (qx, qy, j)| (py, px, i).cmp(&(qy, qx, j)));
    lb = (xyi[0].0, xyi[0].2);
    for &(x, _, i) in &xyi[1..] {
        let (xx, j) = lb;
        if xx < x {
            uf.unite(i, j);
        }
        if x < xx {
            lb = (x, i);
        }
    }
    rt = (xyi[n - 1].0, xyi[n - 1].2);
    for &(x, _, i) in xyi[0..(n - 1)].iter().rev() {
        let (xx, j) = rt;
        if x < xx {
            uf.unite(i, j);
        }
        if xx < x {
            rt = (x, i);
        }
    }
    println!(
        "{}",
        (0..n)
            .map(|i| uf.get_size(i).to_string())
            .collect::<Vec<_>>()
            .join("\n")
    );
}

pub struct UnionFind {
    par: Vec<usize>,
    size: Vec<usize>,
}

impl UnionFind {
    pub fn new(n: usize) -> UnionFind {
        UnionFind {
            par: (0..n).map(|i| i).collect::<Vec<_>>(),
            size: vec![1; n],
        }
    }
    pub fn find(&mut self, i: usize) -> usize {
        if self.par[i] == i {
            self.par[i]
        } else {
            self.par[i] = self.find(self.par[i]);
            self.par[i]
        }
    }
    pub fn unite(&mut self, i: usize, j: usize) {
        let i = self.find(i);
        let j = self.find(j);
        if i == j {
            return;
        }
        let (i, j) = if self.size[i] >= self.size[j] {
            (i, j)
        } else {
            (j, i)
        };
        self.par[j] = i;
        self.size[i] += self.size[j];
    }
    pub fn get_size(&mut self, i: usize) -> usize {
        let p = self.find(i);
        self.size[p]
    }
    pub fn same(&mut self, i: usize, j: usize) -> bool {
        self.find(i) == self.find(j)
    }
}

pub struct ProconReader<R: std::io::Read> {
    reader: R,
}

impl<R: std::io::Read> ProconReader<R> {
    pub fn new(reader: R) -> Self {
        Self { reader }
    }
    pub fn get<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .reader
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&byte| byte == b' ' || byte == b'\n' || byte == b'\r')
            .take_while(|&byte| byte != b' ' && byte != b'\n' && byte != b'\r')
            .collect::<Vec<_>>();
        std::str::from_utf8(&buf)
            .unwrap()
            .parse()
            .ok()
            .expect("Parse Error.")
    }
}