// ---------- begin SegmentTree Point update Range query ----------
mod segment_tree {
    pub struct PURQ<T, F> {
        n: usize,
        a: Vec<T>,
        id: T,
        op: F,
    }
    #[allow(dead_code)]
    impl<T: Clone, F: Fn(&T, &T) -> T> PURQ<T, F> {
        pub fn new(n: usize, id: T, op: F) -> PURQ<T, F> {
            let mut k = 1;
            while k < n {
                k *= 2;
            }
            PURQ {
                n: k,
                a: vec![id.clone(); 2 * k],
                id: id,
                op: op,
            }
        }
        pub fn update(&mut self, x: usize, v: T) {
            let mut k = self.n + x;
            let a = &mut self.a;
            a[k] = v;
            k >>= 1;
            while k > 0 {
                a[k] = (self.op)(&a[2 * k], &a[2 * k + 1]);
                k >>= 1;
            }
        }
        pub fn update_tmp(&mut self, x: usize, v: T) {
            self.a[x + self.n] = v;
        }
        pub fn update_all(&mut self) {
            let a = &mut self.a;
            for k in (1..(self.n)).rev() {
                a[k] = (self.op)(&a[2 * k], &a[2 * k + 1]);
            }
        }
        pub fn find(&self, mut l: usize, mut r: usize) -> T {
            let mut p = self.id.clone();
            let mut q = self.id.clone();
            l += self.n;
            r += self.n;
            let a = &self.a;
            while l < r {
                if (l & 1) == 1 {
                    p = (self.op)(&p, &a[l]);
                    l += 1;
                }
                if (r & 1) == 1 {
                    r -= 1;
                    q = (self.op)(&a[r], &q);
                }
                l >>= 1;
                r >>= 1;
            }
            (self.op)(&p, &q)
        }
    }
}
// ---------- end SegmentTree Point update Range query ----------
//---------- begin union_find ----------
pub struct DSU {
    p: Vec<i32>,
}
impl DSU {
    pub fn new(n: usize) -> DSU {
        DSU { p: vec![-1; n] }
    }
    pub fn init(&mut self) {
        for p in self.p.iter_mut() {
            *p = -1;
        }
    }
    pub fn root(&self, mut x: usize) -> usize {
        assert!(x < self.p.len());
        while self.p[x] >= 0 {
            x = self.p[x] as usize;
        }
        x
    }
    pub fn same(&self, x: usize, y: usize) -> bool {
        assert!(x < self.p.len());
        assert!(y < self.p.len());
        self.root(x) == self.root(y)
    }
    pub fn unite(&mut self, x: usize, y: usize) -> Option<(usize, usize)> {
        assert!(x < self.p.len());
        assert!(y < self.p.len());
        let mut x = self.root(x);
        let mut y = self.root(y);
        if x == y {
            return None;
        }
        if self.p[x] > self.p[y] {
            std::mem::swap(&mut x, &mut y);
        }
        self.p[x] += self.p[y];
        self.p[y] = x as i32;
        Some((x, y))
    }
    pub fn parent(&self, x: usize) -> Option<usize> {
        assert!(x < self.p.len());
        let p = self.p[x];
        if p >= 0 {
            Some(p as usize)
        } else {
            None
        }
    }
    pub fn size(&self, x: usize) -> usize {
        assert!(x < self.p.len());
        let r = self.root(x);
        (-self.p[r]) as usize
    }
}
//---------- end union_find ----------

use proconio::*;
use proconio::marker::*;
use std::collections::*;
use std::cmp::*;
use std::ops::Bound::*;

#[fastout]
fn run() {
    input! {
        n: usize,
        p: [(usize, usize); n],
    }
    let mut u = DSU::new(n);
    let mut seg0 = segment_tree::PURQ::new(n + 1, (n + 1, n), |a, b| std::cmp::min(*a, *b));
    let mut seg1 = segment_tree::PURQ::new(n + 1, (0, n), |a, b| std::cmp::max(*a, *b));
    for (i, &(x, y)) in p.iter().enumerate() {
        seg0.update(x, (y, i));
        seg1.update(x, (y, i));
    }
    let mut used = vec![false; n];
    for v in 0..n {
        if used[v] {
            continue;
        }
        used[v] = true;
        seg0.update(p[v].0, (n + 1, n));
        seg1.update(p[v].0, (0, n));
        let mut q = std::collections::VecDeque::new();
        q.push_back(v);
        while let Some(v) = q.pop_front() {
            let (x, y) = p[v];
            loop {
                let (a, b) = seg0.find(0, x);
                if b < n && a < y {
                    seg0.update(p[b].0, (n + 1, n));
                    seg1.update(p[b].0, (0, n));
                    q.push_back(b);
                    used[b] = true;
                    u.unite(v, b);
                } else {
                    break;
                }
            }
            loop {
                let (a, b) = seg1.find(x, n + 1);
                if b < n && a > y {
                    seg0.update(p[b].0, (n + 1, n));
                    seg1.update(p[b].0, (0, n));
                    q.push_back(b);
                    used[b] = true;
                    u.unite(v, b);
                } else {
                    break;
                }
            }
        }
    }
    for k in 0..n {
        println!("{}", u.size(k));
    }
}

fn main() {
    run();
}


Measured memory_bytes: 26704