Problem:
Score : 600 points

Problem Statement

There is a grid of squares with H+1 horizontal rows and W vertical columns.

You will start at one of the squares in the top row and repeat moving one square right or down. However, for each integer i from 1 through H, you cannot move down from the A_i-th, (A_i + 1)-th, \ldots, B_i-th squares from the left in the i-th row from the top.

For each integer k from 1 through H, find the minimum number of moves needed to reach one of the squares in the (k+1)-th row from the top. (The starting square can be chosen individually for each case.) If, starting from any square in the top row, none of the squares in the (k+1)-th row can be reached, print -1 instead.

Constraints

1 \leq H,W \leq 2\times 10^5

1 \leq A_i \leq B_i \leq W

Input

Input is given from Standard Input in the following format:

H W
A_1 B_1
A_2 B_2
:
A_H B_H

Output

Print H lines. The i-th line should contain the answer for the case k=i.

Sample Input 1

4 4
2 4
1 1
2 3
2 4

Sample Output 1

1
3
6
-1

Let (i,j) denote the square at the i-th row from the top and j-th column from the left.

For k=1, we need one move such as (1,1) → (2,1).

For k=2, we need three moves such as (1,1) → (2,1) → (2,2) → (3,2).

For k=3, we need six moves such as (1,1) → (2,1) → (2,2) → (3,2) → (3,3) → (3,4) → (4,4).

For k=4, it is impossible to reach any square in the fifth row from the top.

Solution in Rust (1.42.0) (judge verdict: Accepted)

#![allow(clippy::many_single_char_names)]
// ngtio {{{
#[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 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()
        }
    }
}
// }}}

fn main() {
    let mut buf = ngtio::Buffer::new();
    let h = buf.usize();
    let w = buf.usize();

    let mut map = (0..w)
        .map(|i| (i, i))
        .collect::<std::collections::BTreeMap<_, _>>();
    let mut ng = false;
    let mut ckd = vec![0; w];
    ckd[0] = w;
    let mut diffs = std::collections::BTreeSet::new();
    diffs.insert(0);

    for i in 0..h {
        if ng {
            println!("-1");
            continue;
        }
        let l = buf.usize() - 1;
        let r = buf.usize();
        let subrange = map
            .range(l..r)
            .map(|(&x, &y)| (x, y))
            .collect::<Vec<(usize, usize)>>();

        for &(key, value) in &subrange {
            map.remove(&key);
            let dif = key - value;
            ckd[dif] -= 1;
            if ckd[dif] == 0 {
                let res = diffs.remove(&dif);
                assert!(res);
            }
        }
        if let Some(&(end, start)) = subrange.last() {
            assert!((l..r).contains(&end));
            if r < w && !map.contains_key(&r) {
                map.insert(r, start);
                let dif = r - start;
                if ckd[dif] == 0 {
                    diffs.insert(dif);
                }
                ckd[dif] += 1;
            }
        }
        if let Some(ans) = diffs.iter().next() {
            println!("{}", ans + i + 1);
        } else {
            ng = true;
            println!("-1");
        }
    }
}

/*
 * 各 i, j について (0, start) -> (i, j) が到達可能である最大の start を f(i, j) としましょう。
 * これは j に関して単調増加で、i に関して単調減少です。
 * j に関して一定である区間を、左端で代表しましょう。
 * すると、更新は削除たくさん挿入一つです。
 * また j - f(i, j) のチェックリストと最大を管理しておきましょう。「
 * 答えは i + 最大です。
 */