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)

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.")
    }
}

struct LazySegmentTree<T, F, U, G, H> {
    n: usize,
    dat: Vec<T>,
    e_t: T,
    multiply: F,
    laz: Vec<U>,
    e_u: U,
    composite: G,
    apply: H,
}

impl<T, F, U, G, H> LazySegmentTree<T, F, U, G, H>
where
    T: Copy + std::fmt::Debug,
    F: Fn(T, T) -> T,
    U: Copy + std::fmt::Debug,
    G: Fn(U, U) -> U,
    H: Fn(U, T) -> T,
{
    fn new(a: &Vec<T>, e_t: T, multiply: F, e_u: U, composite: G, apply: H) -> Self {
        let len = a.len();
        let n = len.next_power_of_two();
        let mut dat = vec![e_t; n * 2 - 1];
        for i in 0..len {
            dat[i + n - 1] = a[i];
        }
        for i in (0..(n - 1)).rev() {
            dat[i] = (multiply)(dat[i * 2 + 1], dat[i * 2 + 2]);
        }
        Self {
            n,
            dat,
            e_t,
            multiply,
            laz: vec![e_u; n * 2 - 1],
            e_u,
            composite,
            apply,
        }
    }
    fn update_node(&mut self, i: usize, u: U) {
        self.dat[i] = (self.apply)(u, self.dat[i]);
        self.laz[i] = (self.composite)(u, self.laz[i]);
    }
    fn update_range(
        &mut self,
        range: &std::ops::Range<usize>,
        i: usize,
        i_range: std::ops::Range<usize>,
        u: U,
    ) {
        if range.end <= i_range.start || i_range.end <= range.start {
            return;
        }
        if range.start <= i_range.start && i_range.end <= range.end {
            self.update_node(i, u);
            return;
        }
        let left_child = i * 2 + 1;
        let right_child = i * 2 + 2;
        self.update_node(left_child, self.laz[i]);
        self.update_node(right_child, self.laz[i]);
        self.laz[i] = self.e_u;
        let m = (i_range.start + i_range.end) / 2;
        self.update_range(range, left_child, i_range.start..m, u);
        self.update_range(range, right_child, m..i_range.end, u);
        self.dat[i] = (self.multiply)(self.dat[left_child], self.dat[right_child]);
    }
    fn update(&mut self, range: std::ops::Range<usize>, u: U) {
        self.update_range(&range, 0, 0..self.n, u);
    }
    fn _fold(
        &self,
        range: &std::ops::Range<usize>,
        i: usize,
        i_range: std::ops::Range<usize>,
    ) -> T {
        if range.end <= i_range.start || i_range.end <= range.start {
            return self.e_t;
        }
        if range.start <= i_range.start && i_range.end <= range.end {
            return self.dat[i];
        }
        let m = (i_range.start + i_range.end) / 2;
        let left_result = self._fold(range, i * 2 + 1, i_range.start..m);
        let right_result = self._fold(range, i * 2 + 2, m..i_range.end);
        (self.apply)(self.laz[i], (self.multiply)(left_result, right_result))
    }
    fn fold(&self, range: std::ops::Range<usize>) -> T {
        self._fold(&range, 0, 0..self.n)
    }
    fn get(&self, i: usize) -> T {
        let mut i = i + self.n - 1;
        let mut res = (self.apply)(self.laz[i], self.dat[i]);
        while i > 0 {
            i = (i - 1) / 2;
            res = (self.apply)(self.laz[i], res);
        }
        res
    }
    #[allow(dead_code)]
    fn debug_tree(&self) {
        let mut que = std::collections::VecDeque::new();
        que.push_back(0);
        let mut cnt: usize = 0;
        while let Some(i) = que.pop_front() {
            print!("{:?} ", self.laz[i]);
            cnt += 1;
            if (cnt + 1).is_power_of_two() {
                print!("\n");
            }
            if i * 2 + 2 < self.laz.len() {
                que.push_back(i * 2 + 1);
                que.push_back(i * 2 + 2);
            }
        }
    }
}

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

    let h: usize = rd.get();
    let w: usize = rd.get();
    let ab: Vec<(usize, usize)> = (0..h)
        .map(|_| {
            let a: usize = rd.get();
            let b: usize = rd.get();
            (a - 1, b - 1)
        })
        .collect();
    let inf = w + 1;
    let e_u = std::usize::MAX;
    let composite = |u, v| if u == e_u { v } else { u };
    let apply = |u, (a, i)| {
        if u == e_u {
            (a, i)
        } else {
            (u, i)
        }
    };
    let mut seg1 = LazySegmentTree::new(
        &(vec![0; w].into_iter().zip(0..w).collect::<Vec<_>>()),
        (inf, 0),
        |(a, i), (b, j)| {
            // a - i < b - j
            if a + j < b + i {
                (a, i)
            } else {
                (b, j)
            }
        },
        e_u,
        composite,
        apply,
    );
    let mut seg2 = LazySegmentTree::new(
        &(vec![0; w].into_iter().zip(0..w).collect::<Vec<_>>()),
        (inf, 0),
        |(a, i), (b, j)| std::cmp::min((a, i), (b, j)),
        e_u,
        composite,
        apply,
    );
    for (i, &(a, b)) in ab.iter().enumerate() {
        // println!("{:?}", (0..w).map(|j| seg.get(j).0).collect::<Vec<_>>());
        let (x, j) = seg1.fold(a..(b + 1));
        // println!("{:?}", (x, j));
        if x < w && b + 1 < w {
            let (y, _) = seg1.get(b + 1);
            seg1.update((b + 1)..(b + 2), std::cmp::min(y, x + b + 1 - j));
            seg2.update((b + 1)..(b + 2), std::cmp::min(y, x + b + 1 - j));
        }
        seg1.update(a..(b + 1), inf);
        seg2.update(a..(b + 1), inf);
        // println!("{:?}", (0..w).map(|j| seg.get(j).0).collect::<Vec<_>>());
        let (ans, _) = seg2.fold(0..w);
        if ans >= w {
            println!("{}", -1);
        } else {
            println!("{}", ans + i + 1);
        }
    }
}