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)

// template {{{
#![allow(clippy::many_single_char_names)]

#[allow(dead_code)]
mod ngtio {
    use ::std::collections::VecDeque;

    pub struct Buffer {
        buf: VecDeque<String>,
    }

    impl Buffer {
        pub fn new() -> Self {
            Self {
                buf: VecDeque::new(),
            }
        }

        fn load(&mut self) {
            while self.buf.is_empty() {
                let mut s = String::new();
                let length = ::std::io::stdin().read_line(&mut s).unwrap();
                if length == 0 {
                    break;
                }
                self.buf.extend(s.split_whitespace().map(|s| s.to_owned()));
            }
        }

        pub fn string(&mut self) -> String {
            self.load();
            self.buf
                .pop_front()
                .unwrap_or_else(|| panic!("入力が終了したのですが。"))
        }

        pub fn string_char_vec(&mut self) -> Vec<char> {
            let s = self.string();
            s.chars().collect::<Vec<_>>()
        }

        pub fn string_char_vec_trusted_len(&mut self, len: usize) -> Vec<char> {
            let s = self.string();
            let s = s.chars().collect::<Vec<_>>();
            assert_eq!(s.len(), len, "あら、思ったのと長さ違いますね……");
            s
        }

        pub fn char(&mut self) -> char {
            let string = self.string();
            let mut chars = string.chars();
            let res = chars.next().unwrap();
            assert!(
                chars.next().is_none(),
                "char で受け取りたいのも山々なのですが、さては 2 文字以上ありますね？"
            );
            res
        }

        pub fn read<T: ::std::str::FromStr>(&mut self) -> T
        where
            <T as ::std::str::FromStr>::Err: ::std::fmt::Debug,
        {
            self.string()
                .parse::<T>()
                .expect("Failed to parse the input.")
        }

        pub fn read_vec<T: ::std::str::FromStr>(&mut self, len: usize) -> Vec<T>
        where
            <T as ::std::str::FromStr>::Err: ::std::fmt::Debug,
        {
            (0..len).map(|_| self.read::<T>()).collect()
        }
    }

    macro_rules! define_primitive_reader {
        ($($ty:tt,)*) => {
            impl Buffer {
                $(
#[inline]
                    pub fn $ty(&mut self) -> $ty {
                        self.read::<$ty>()
                    }
                )*
            }
        }
    }

    define_primitive_reader! {
        u8, u16, u32, u64, usize,
        i8, i16, i32, i64, isize,
    }

    impl Default for Buffer {
        fn default() -> Self {
            Self::new()
        }
    }
}

#[allow(unused_imports)]
use std::{collections, iter, mem, ops};
// }}}
// segtree2 {{{
#[allow(dead_code)]
mod segtree2 {
    use crate::type_traits::*;
    use std::{iter, ops};

    #[derive(Debug, Clone, PartialEq)]
    pub struct Segtree<T> {
        len: usize,
        table: Vec<T>,
    }

    impl<T: Assoc> Segtree<T> {
        pub fn from_slice(src: &[T]) -> Self {
            if src.is_empty() {
                Self {
                    len: 0,
                    table: Vec::new(),
                }
            } else {
                let mut me = Self {
                    len: src.len(),
                    table: src.iter().chain(src).cloned().collect::<Vec<_>>(),
                };
                for i in (0..src.len()).rev() {
                    me.update(i);
                }
                me
            }
        }

        pub fn set(&mut self, i: usize, x: T) {
            assert!(i < self.len);
            self.modify(i, |y| y.clone_from(&x));
        }

        pub fn get(&mut self, i: usize) -> &T {
            assert!(i < self.len);
            &self.table[self.len + i]
        }

        pub fn modify(&mut self, mut i: usize, f: impl Fn(&mut T)) {
            assert!(i < self.len);
            i += self.len;
            f(&mut self.table[i]);
            for i in iter::successors(Some(i / 2), |&x| if x == 0 { None } else { Some(x / 2) }) {
                self.update(i);
            }
        }

        pub fn fold(&self, range: impl ops::RangeBounds<usize>) -> Option<T> {
            let (mut start, mut end) = open(self.len, range);
            assert!(start <= end, "変な区間を渡すのをやめませんか？");
            assert!(end <= self.len, "範囲外は禁止です！");
            start += self.len;
            end += self.len;

            if start == end {
                None
            } else if start + 1 == end {
                Some(self.table[start].clone())
            } else {
                let mut left = self.table[start].clone();
                start += 1;
                end -= 1;
                let mut right = self.table[end].clone();
                while start != end {
                    if start % 2 == 1 {
                        left.op_from_right(&self.table[start]);
                        start += 1;
                    }
                    if end % 2 == 1 {
                        end -= 1;
                        right.op_from_left(&self.table[end]);
                    }
                    start /= 2;
                    end /= 2;
                }
                Some(T::op(left, right))
            }
        }

        pub fn forward_partition_point(
            &self,
            start: usize,
            mut f: impl FnMut(&T) -> bool,
        ) -> usize {
            assert!(start <= self.len, "範囲外は禁止です！");
            let mut i = self.len + start;
            if self.fold(start..).map(|x| f(&x)).unwrap_or(true) {
                self.len
            } else if !f(&self.table[i]) {
                start
            } else {
                let mut current = self.table[i].clone();
                i += 1;
                let mut next = current.clone().op(self.table[i].clone());

                while f(&next) {
                    if i % 2 == 0 {
                        i /= 2;
                    } else {
                        current = next.clone();
                        i += 1;
                    }
                    next = current.clone().op(self.table[i].clone());
                }
                loop {
                    if f(&next) {
                        current = next.clone();
                        i += 1;
                    } else {
                        if self.len < i {
                            return i - self.len;
                        }
                        i *= 2;
                    }
                    next = current.clone().op(self.table[i].clone());
                }
            }
        }

        pub fn backward_partition_point(&self, end: usize, mut f: impl FnMut(&T) -> bool) -> usize {
            assert!(end <= self.len, "範囲外は禁止です！");
            let mut i = self.len + end;
            if self.fold(..end).map(|x| f(&x)).unwrap_or(true) {
                0
            } else if !f(&self.table[i - 1]) {
                end
            } else {
                i -= 1;
                let mut current = self.table[i].clone();
                let mut next = current.clone().op(self.table[i - 1].clone());

                while f(&next) {
                    if i % 2 == 0 {
                        i /= 2;
                    } else {
                        i -= 1;
                        current = next.clone();
                    }
                    next = self.table[i - 1].clone().op(current.clone());
                }
                loop {
                    if f(&next) {
                        i -= 1;
                        current = next.clone();
                    } else {
                        if self.len < i {
                            return i - self.len;
                        }
                        i *= 2;
                    }
                    next = self.table[i - 1].clone().op(current.clone());
                }
            }
        }

        fn update(&mut self, i: usize) {
            let x = T::op(self.table[2 * i].clone(), self.table[2 * i + 1].clone());
            self.table[i] = x;
        }
    }

    impl<T: Assoc + Ord> Segtree<T> {
        pub fn forward_lower_bound(&self, start: usize, value: &T) -> usize {
            self.forward_partition_point(start, |x| x < value)
        }
        pub fn forward_upper_bound(&self, start: usize, value: &T) -> usize {
            self.forward_partition_point(start, |x| x <= value)
        }
        pub fn backward_lower_bound(&self, end: usize, value: &T) -> usize {
            self.backward_partition_point(end, |x| x < value)
        }
        pub fn backward_upper_bound(&self, end: usize, value: &T) -> usize {
            self.backward_partition_point(end, |x| x <= value)
        }
    }

    fn open(len: usize, range: impl ops::RangeBounds<usize>) -> (usize, usize) {
        use ops::Bound::*;
        (
            match range.start_bound() {
                Unbounded => 0,
                Included(&x) => x,
                Excluded(&x) => x + 1,
            },
            match range.end_bound() {
                Excluded(&x) => x,
                Included(&x) => x + 1,
                Unbounded => len,
            },
        )
    }
}
// }}}
// type_traits {{{
#[allow(dead_code)]
mod type_traits {
    #![warn(missing_docs)]

    use std::{cmp, fmt, ops};

    mod primitive {
        use super::{One, Zero};

        macro_rules! int {
            ($($T:ty,)*) => {
                $(
                    impl Zero for $T {
                        fn zero() -> $T {
                            0
                        }
                        fn times(self, n: u64) -> $T {
                            self * n as $T
                        }
                        fn times_assign(&mut self, n: u64) {
                            *self *= n as $T
                        }
                        fn from_u64(n: u64) -> $T {
                            n as $T
                        }
                    }
                    impl One for $T {
                        fn one() -> $T {
                            1
                        }
                    }
                )*
            }
        }

        int! {
            u8, u16, u32, u64, u128, usize,
            i8, i16, i32, i64, i128, isize,
        }
    }

    pub mod wrappers {
        use super::{Assoc, Element, Identity, One, Zero};
        use std::ops;

        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Add<T>(pub T);
        impl<T> Assoc for Add<T>
        where
            T: ops::Add<Output = T> + Element,
        {
            fn op(self, rhs: Self) -> Self {
                Add(self.0 + rhs.0)
            }
        }
        impl<T> Identity for Add<T>
        where
            T: Zero,
        {
            fn identity() -> Self {
                Add(T::zero())
            }
        }

        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Mul<T>(pub T);

        impl<T> Assoc for Mul<T>
        where
            T: ops::Mul<Output = T> + Element,
        {
            fn op(self, rhs: Self) -> Self {
                Mul(self.0 * rhs.0)
            }
        }
        impl<T> Identity for Mul<T>
        where
            T: One,
        {
            fn identity() -> Self {
                Mul(T::one())
            }
        }

        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Affine<T> {
            pub a: T,
            pub b: T,
        }

        impl<T> Assoc for Affine<T>
        where
            T: ops::Add<Output = T> + Element,
            T: ops::Mul<Output = T> + Element,
        {
            fn op(self, rhs: Self) -> Self {
                Self {
                    a: self.a.clone() * rhs.a,
                    b: self.b + self.a * rhs.b,
                }
            }
        }
        impl<T> Identity for Affine<T>
        where
            T: Zero + One,
        {
            fn identity() -> Self {
                Self {
                    a: T::one(),
                    b: T::zero(),
                }
            }
        }

        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Cat(pub String);

        impl Assoc for Cat {
            fn op(self, rhs: Self) -> Self {
                Cat(self.0.chars().chain(rhs.0.chars()).collect())
            }
        }
        impl Identity for Cat {
            fn identity() -> Self {
                Cat(String::new())
            }
        }
    }

    pub trait Element: Sized + Clone + PartialEq + fmt::Debug {}
    impl<T: Sized + Clone + PartialEq + fmt::Debug> Element for T {}

    pub trait Assoc: Element {
        fn op(self, rhs: Self) -> Self;

        fn op_from_left(&mut self, left: &Self) {
            *self = Self::op(left.clone(), self.clone());
        }

        fn op_from_right(&mut self, right: &Self) {
            *self = Self::op(self.clone(), right.clone());
        }
    }

    pub trait Identity: Assoc {
        fn identity() -> Self;
    }

    pub trait Zero: ops::Add<Output = Self> + ops::AddAssign + Element {
        fn zero() -> Self;

        fn is_zero(&self) -> bool
        where
            Self: cmp::PartialEq,
        {
            self == &Self::zero()
        }

        fn times(self, n: u64) -> Self;

        fn times_assign(&mut self, n: u64);

        fn from_u64(x: u64) -> Self;
    }

    pub trait One: ops::Mul<Output = Self> + ops::MulAssign + Element {
        fn one() -> Self;

        fn is_one(&self) -> bool
        where
            Self: cmp::PartialEq,
        {
            self == &Self::one()
        }
    }

    pub trait Ring: Zero + One + ops::Neg + ops::Sub<Output = Self> + ops::SubAssign {}
    impl<T: Zero + One + ops::Neg + ops::Sub<Output = Self> + ops::SubAssign> Ring for T {}

    #[macro_export]
    macro_rules! define_constant {
        ($(#[$attr:meta])? $vis:vis type $wrapper_type:ident: $value_type:ty = $value:expr;) => {
            $(#[$attr])?
            #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
            $vis struct $wrapper_type {}

            impl Constant for $wrapper_type {
                type Output = $value_type;
                const VALUE: Self::Output = $value;
            }
        };
    }

    pub trait Constant: Copy {
        type Output: Copy;

        const VALUE: Self::Output;
    }
}
// }}}
// ordtools {{{
#[allow(dead_code)]
mod ordtools {
    #![warn(missing_docs)]
    #![warn(missing_doc_code_examples)]

    pub trait Ordtools: PartialOrd + Sized {
        fn change_min(&mut self, mut rhs: Self) {
            if self > &mut rhs {
                *self = rhs;
            }
        }

        fn change_max(&mut self, mut rhs: Self) {
            if self < &mut rhs {
                *self = rhs;
            }
        }
    }

    impl<T: PartialOrd + Sized> Ordtools for T {}
}
// }}}

use ordtools::Ordtools;

use type_traits::{Assoc, Element};

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Max<T>(pub T);
impl<T> Assoc for Max<T>
where
    T: Ord + Element,
{
    fn op(self, rhs: Self) -> Self {
        Max(self.0.max(rhs.0))
    }
}

fn main() {
    let mut buf = ngtio::Buffer::new();
    let n = buf.usize();
    let (a, b): (Vec<_>, Vec<_>) = iter::repeat_with(|| (buf.usize() - 1, buf.usize() - 1))
        .take(n)
        .unzip();

    let mut c = vec![Max(0); n];
    for (&x, &y) in a.iter().zip(&b) {
        c[x] = Max(y);
    }
    let seg = segtree2::Segtree::from_slice(&c);
    let right = (0..n)
        .map(|i| seg.backward_partition_point(n, |&x| x < c[i]))
        .collect::<Vec<_>>();

    let mut size = vec![0; n];
    let mut start = 0;
    let mut end = 0usize;
    for i in 0..n {
        end.change_max(right[i]);
        if i + 1 == end {
            (start..end).for_each(|j| size[j] = end - start);
            start = end;
        }
    }

    let mut ans = vec![0; n];
    for (i, &x) in a.iter().enumerate() {
        ans[i] = size[x];
    }
    for &x in &ans {
        println!("{}", x);
    }
}