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: Time Limit Exceeded)

use std::collections::{BTreeMap, BTreeSet};
use std::ops::Range;

use proconio::input;
use proconio::marker::Usize1;

fn main() {
    input! {
        h: usize,
        w: usize,
        ab: [(Usize1, Usize1); h],
    }

    let mut go = BTreeMap::new();

    let mut neko = NekoTree::new(w, h);
    for i in (0..h).rev() {
        let (a, b) = ab[i];
        neko.set(a..b + 1, i);
        if b + 1 < w {
            go.insert((i, b + 1), neko.get(b + 1));
        }
    }

    for i in (0..h) {
        let (a, b) = ab[i];
        if a >= 1 {
            go.insert((0, a - 1), neko.get(a - 1));
        }
        if b + 1 < w {
            go.insert((0, b + 1), neko.get(b + 1));
        }
    }
    go.insert((0, 0), neko.get(0));

    let mut start = vec![0usize, w - 1];
    for &(a, b) in &ab {
        if a >= 1 {
            start.push(a - 1);
        }
        if b + 1 < w {
            start.push(b + 1);
        }
    }
    start.sort();
    start.reverse();
    let start: BTreeSet<usize> = start.into_iter().collect();
    let mut start: Vec<usize> = start.into_iter().collect();
    start.reverse();
    let start = start;

    let mut dp = BTreeMap::<(usize, usize), usize>::new();
    for j in start {
        let mut i = 0;
        let mut j = j;
        let mut d = 0;
        while i < h {
            if !go.contains_key(&(i, j)) {
                break;
            }
            d += go[&(i, j)] - i;
            i = go[&(i, j)];
            dp.entry((i, j)).or_insert(d);
            if i == h {
                break;
            }
            d += (ab[i].1 + 1) - j;
            j = ab[i].1 + 1;
            if dp.contains_key(&(i, j)) {
                break;
            }
        }
        if i == h {
            dp.entry((h, j)).or_insert(d);
        }
    }

    let mut dis = vec![std::usize::MAX; h + 1];
    for (&(i, _j), &v) in &dp {
        dis[i] = v;
    }

    for i in (1..h).rev() {
        if dis[i + 1] < std::usize::MAX {
            dis[i] = dis[i].min(dis[i + 1] - 1);
        }
    }

    for i in 1..=h {
        if dis[i] < std::usize::MAX {
            println!("{}", dis[i]);
        } else {
            println!("-1");
        }
    }
}

struct NekoTree {
    buf: Vec<usize>,
    len: usize,
}

impl NekoTree {
    fn new(n: usize, x: usize) -> NekoTree {
        NekoTree {
            buf: vec![x; n + n],
            len: n,
        }
    }
    fn set(&mut self, lr: Range<usize>, x: usize) {
        let mut l = lr.start + self.len;
        let mut r = lr.end + self.len;
        while l < r {
            if l & 1 == 1 {
                self.buf[l] = self.buf[l].min(x);
                l += 1;
            }
            if r & 1 == 1 {
                r -= 1;
                self.buf[r] = self.buf[r].min(x);
            }
            l >>= 1;
            r >>= 1;
        }
    }
    fn get(&self, i: usize) -> usize {
        let mut res = std::usize::MAX;
        let mut i = i + self.len;
        while i >= 1 {
            res = res.min(self.buf[i]);
            i >>= 1;
        }
        res
    }
}