#![allow(unused_imports)]
#![allow(unused_macros)]
use itertools::Itertools;
use std::cmp::Reverse;
use std::cmp::{max, min};
use std::collections::*;
use std::fmt::Write as _Write;
use std::i64;
use std::io::{stdin, BufWriter, Read, Write};
use std::usize;

#[allow(unused_macros)]
macro_rules! parse {
    ($it: ident ) => {};
    ($it: ident, ) => {};
    ($it: ident, $var:ident : $t:tt $($r:tt)*) => {
        let $var = parse_val!($it, $t);
        parse!($it $($r)*);
    };
    ($it: ident, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = parse_val!($it, $t);
        parse!($it $($r)*);
    };
    ($it: ident, $var:ident $($r:tt)*) => {
        let $var = parse_val!($it, usize);
        parse!($it $($r)*);
    };
}

#[allow(unused_macros)]
macro_rules! parse_val {
    ($it: ident, [$t:tt; $len:expr]) => {
        (0..$len).map(|_| parse_val!($it, $t)).collect::<Vec<_>>();
    };
    ($it: ident, ($($t: tt),*)) => {
        ($(parse_val!($it, $t)),*)
    };
    ($it: ident, u1) => {
        $it.next().unwrap().parse::<usize>().unwrap() -1
    };
    ($it: ident, $t: ty) => {
        $it.next().unwrap().parse::<$t>().unwrap()
    };
}

fn solve(s: &str) {
    let stdout = std::io::stdout();
    let mut out = std::io::BufWriter::new(stdout.lock());
    let mut stdout = String::new();
    let mut it = s.split_whitespace();
    parse!(it, n: usize, xy: [(u1, u1); n]);
    let mut xy: Vec<(usize, usize)> = xy;
    let mut xi = vec![n; n];
    for (i, &(x, y)) in xy.iter().enumerate() {
        xi[i] = x;
    }
    xy.sort();
    let mut uf = UnionFind::new(n);
    let mut seen = BTreeSet::<(usize, usize)>::new();
    let mut ok = BinaryHeap::new();
    for &(x, y) in &xy {
        ok.clear();
        seen.insert((y, x));
        ok.push(Reverse((y, x)));
        for &p in seen.range(..(y, x)) {
            uf.union(x, p.1);
            ok.push(Reverse(p));
        }
        ok.pop();
        for x in ok.iter() {
            seen.remove(&x.0);
        }
    }
    let mut ps = HashMap::new();
    for x in 0..n {
        ps.entry(uf.root(x)).or_insert(vec![]).push(x);
    }
    let mut counts = vec![0; n];
    for x in 0..n {
        counts[x] = ps[&uf.root(x)].len();
    }
    for i in 0..n {
        stdout
            .write_fmt(format_args!("{}\n", counts[xi[i]]))
            .unwrap();
    }
    out.write_all(stdout.as_bytes()).unwrap();
}
pub struct UnionFind {
    pub parents: Vec<usize>,
}
impl UnionFind {
    pub fn new(n: usize) -> Self {
        let parents = (0..n).collect();
        UnionFind { parents }
    }
    pub fn root(&mut self, x: usize) -> usize {
        if self.parents[x] == x {
            return x;
        }
        let par = self.parents[x];
        self.parents[x] = self.root(par);
        self.parents[x]
    }
    pub fn union(&mut self, x: usize, y: usize) {
        let rx = self.root(x);
        let ry = self.root(y);
        if rx == ry {
            return;
        }
        self.parents[rx] = ry;
    }
    pub fn is_same(&mut self, x: usize, y: usize) -> bool {
        let rx = self.root(x);
        let ry = self.root(y);
        rx == ry
    }
}

fn main() {
    let mut s = String::new();
    stdin().read_to_string(&mut s).unwrap();
    solve(&s);
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_input() {
        let s = "
        ";
        solve(s);
    }
}
trait ChMinMax {
    fn chmin(&mut self, other: Self);
    fn chmax(&mut self, other: Self);
}
impl<T> ChMinMax for T
where
    T: PartialOrd,
{
    fn chmin(&mut self, other: Self) {
        if *self > other {
            *self = other
        }
    }
    fn chmax(&mut self, other: Self) {
        if *self < other {
            *self = other
        }
    }
}


Measured memory_bytes: 17016