#![allow(unused_imports, unused_macros, dead_code)]

macro_rules! min {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        it.next().map(|z| it.fold(z, |x, y| min!(x, y)))
    }};
    ($x:expr) => ($x);
    ($x:expr, $($ys:expr),*) => {{
        let t = min!($($ys),*);
        if $x < t { $x } else { t }
    }}
}
macro_rules! max {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        it.next().map(|z| it.fold(z, |x, y| max!(x, y)))
    }};
    ($x:expr) => ($x);
    ($x:expr, $($ys:expr),*) => {{
        let t = max!($($ys),*);
        if $x > t { $x } else { t }
    }}
}
macro_rules! trace {
    ($x:expr) => {
        #[cfg(debug_assertions)]
        eprintln!(">>> {} = {:?}", stringify!($x), $x)
    };
    ($($xs:expr),*) => { trace!(($($xs),*)) }
}
macro_rules! flush {
    () => {
        std::io::stdout().flush().unwrap();
    };
}
macro_rules! put {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        if let Some(x) = it.next() { print!("{}", x); }
        for x in it { print!(" {}", x); }
        println!("");
    }};
    ($x:expr) => { println!("{}", $x) };
    ($x:expr, $($xs:expr),*) => { print!("{} ", $x); put!($($xs),*) }
}

const M: i64 = 1_000_000_007;

// @seq.segment_tree.rs
// @algebra.monoid.rs
trait Monoid: std::ops::Mul<Output = Self> + Clone + Copy {
    fn unit() -> Self;
}
impl Monoid for i64 {
    fn unit() -> Self {
        0
    }
}
impl Monoid for f64 {
    fn unit() -> Self {
        0.0
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
enum MaxInt<X> {
    Minimal,
    Val(X),
}
impl<X> MaxInt<X> {
    fn unwrap(self) -> X {
        if let Self::Val(x) = self {
            x
        } else {
            panic!();
        }
    }
}
impl<X: Ord> std::ops::Mul for MaxInt<X> {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        if self > other {
            self
        } else {
            other
        }
    }
}
impl<X: Ord + Copy> Monoid for MaxInt<X> {
    fn unit() -> Self {
        MaxInt::Minimal
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
enum MinInt<X> {
    Val(X),
    Maximal,
}
impl<X> MinInt<X> {
    fn unwrap(self) -> X {
        if let Self::Val(x) = self {
            x
        } else {
            panic!();
        }
    }
}
impl<X: Ord> std::ops::Mul for MinInt<X> {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        if self < other {
            self
        } else {
            other
        }
    }
}
impl<X: Ord + Copy> Monoid for MinInt<X> {
    fn unit() -> Self {
        MinInt::Maximal
    }
}

#[derive(Debug, Clone, Copy)]
struct MonoidProduct<M, N>(M, N)
where
    M: Monoid,
    N: Monoid;

impl<M: Monoid + Copy, N: Monoid + Copy> Monoid for MonoidProduct<M, N> {
    fn unit() -> Self {
        MonoidProduct(M::unit(), N::unit())
    }
}
impl<M: Monoid, N: Monoid> std::ops::Mul for MonoidProduct<M, N> {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        MonoidProduct(self.0 * other.0, self.1 * other.1)
    }
}

trait Act<X> {
    fn act(&self, x: X) -> X;
}

#[derive(Debug, Clone, Copy)]
enum AssignInt<X> {
    None,
    Val(X),
    Fuck,
}

impl<X: Copy> std::ops::Mul for AssignInt<X> {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        match (self, other) {
            (x, AssignInt::None) => x,
            _ => other,
        }
    }
}

impl<X: Copy> Monoid for AssignInt<X> {
    fn unit() -> Self {
        return AssignInt::None;
    }
}

impl<X: Copy> Act<MinInt<X>> for AssignInt<X> {
    fn act(&self, x: MinInt<X>) -> MinInt<X> {
        match (x, self) {
            (_, AssignInt::Fuck) => MinInt::Maximal,
            (_, AssignInt::Val(m)) => MinInt::Val(*m),
            _ => x,
        }
    }
}

impl<X: Copy> Act<MaxInt<X>> for AssignInt<X> {
    fn act(&self, x: MaxInt<X>) -> MaxInt<X> {
        match (x, self) {
            (_, AssignInt::Fuck) => MaxInt::Minimal,
            (_, AssignInt::Val(m)) => MaxInt::Val(*m),
            _ => x,
        }
    }
}

#[derive(Clone)]
struct LazySegmentTree<X, M> {
    size: usize,
    size_upper: usize, // power of 2
    depth: usize,
    data: Vec<Vec<X>>,
    act: Vec<Vec<M>>,
}
impl<X: Monoid, M: Monoid + Act<X>> LazySegmentTree<X, M> {
    fn new(size: usize) -> Self {
        let mut data = vec![];
        let mut act = vec![];
        let mut i = 1;
        loop {
            data.push(vec![X::unit(); i]);
            act.push(vec![M::unit(); i]);
            if i >= size {
                break;
            }
            i *= 2;
        }
        LazySegmentTree {
            size,
            size_upper: i,
            depth: data.len(),
            data,
            act,
        }
    }
    fn from(xs: Vec<X>) -> Self {
        let mut tree = Self::new(xs.len());
        for i in 0..xs.len() {
            tree.data[tree.depth - 1][i] = xs[i];
        }
        for depth in (0..tree.depth - 1).rev() {
            for i in 0..tree.data[depth].len() {
                tree.data[depth][i] = tree.data[depth + 1][2 * i] * tree.data[depth + 1][2 * i + 1];
            }
        }
        tree
    }
    fn propagation(&mut self, depth: usize, idx: usize) {
        if depth + 1 < self.depth {
            self.act[depth + 1][idx * 2] = self.act[depth + 1][idx * 2] * self.act[depth][idx];
            self.act[depth + 1][idx * 2 + 1] =
                self.act[depth + 1][idx * 2 + 1] * self.act[depth][idx];
        }
        self.data[depth][idx] = self.act[depth][idx].act(self.data[depth][idx]);
        self.act[depth][idx] = M::unit();
    }
    fn update_sub(
        &mut self,
        range: std::ops::Range<usize>,
        m: M,
        depth: usize,
        idx: usize,
        focus: std::ops::Range<usize>,
    ) {
        self.propagation(depth, idx);
        if focus.end <= range.start || range.end <= focus.start {
            return;
        }
        if range.start <= focus.start && focus.end <= range.end {
            self.act[depth][idx] = self.act[depth][idx] * m;
            self.propagation(depth, idx);
        } else if depth + 1 < self.depth {
            let mid = (focus.start + focus.end) / 2;
            self.update_sub(range.clone(), m, depth + 1, idx * 2, focus.start..mid);
            self.update_sub(range.clone(), m, depth + 1, idx * 2 + 1, mid..focus.end);
            self.data[depth][idx] =
                self.data[depth + 1][idx * 2] * self.data[depth + 1][idx * 2 + 1];
        }
    }
    fn update(&mut self, range: std::ops::Range<usize>, m: M) {
        self.update_sub(range, m, 0, 0, 0..self.size_upper);
    }
    fn product_sub(
        &mut self,
        range: std::ops::Range<usize>,
        depth: usize,
        idx: usize,
        focus: std::ops::Range<usize>,
    ) -> X {
        self.propagation(depth, idx);
        if focus.end <= range.start || range.end <= focus.start {
            X::unit()
        } else if range.start <= focus.start && focus.end <= range.end {
            self.data[depth][idx]
        } else {
            let mid = (focus.start + focus.end) / 2;
            let a = self.product_sub(range.clone(), depth + 1, idx * 2, focus.start..mid);
            let b = self.product_sub(range.clone(), depth + 1, idx * 2 + 1, mid..focus.end);
            a * b
        }
    }
    fn product(&mut self, range: std::ops::Range<usize>) -> X {
        self.product_sub(range, 0, 0, 0..self.size_upper)
    }
    fn index(&mut self, i: usize) -> X {
        self.product(i..i + 1)
    }
    fn to_vec(&mut self) -> Vec<X> {
        (0..self.size).map(|i| self.index(i)).collect()
    }
}
impl<X: std::fmt::Debug, M: std::fmt::Debug> LazySegmentTree<X, M> {
    fn debug(&self) {
        for i in 0..self.depth {
            for j in 0..self.data[i].len() {
                eprint!("{:?} / {:?}; ", &self.data[i][j], &self.act[i][j]);
            }
            eprintln!();
        }
    }
}

// @rand.xorshift.rs
pub trait FromU64 {
    fn coerce(x: u64) -> Self;
}
impl FromU64 for u64 {
    fn coerce(x: u64) -> Self {
        x
    }
}
impl FromU64 for i64 {
    fn coerce(x: u64) -> Self {
        x as i64
    }
}
impl FromU64 for u32 {
    fn coerce(x: u64) -> Self {
        x as u32
    }
}
impl FromU64 for i32 {
    fn coerce(x: u64) -> Self {
        x as i32
    }
}
impl FromU64 for usize {
    fn coerce(x: u64) -> Self {
        x as usize
    }
}
impl FromU64 for bool {
    fn coerce(x: u64) -> Self {
        x % 2 == 0
    }
}

// returns [0, 1]
impl FromU64 for f64 {
    fn coerce(x: u64) -> Self {
        (x as f64) / (std::u64::MAX as f64)
    }
}
impl FromU64 for f32 {
    fn coerce(x: u64) -> Self {
        (x as f32) / (std::u64::MAX as f32)
    }
}

struct XorShift(u64);
impl XorShift {
    fn new() -> Self {
        XorShift(88172645463325252)
    }
    fn next(&mut self) -> u64 {
        let mut x = self.0;
        x = x ^ (x << 13);
        x = x ^ (x >> 7);
        x = x ^ (x << 17);
        self.0 = x;
        x
    }
    fn gen<T: FromU64>(&mut self) -> T {
        FromU64::coerce(self.next())
    }
}

fn main() {
    // {
    //     let n = 12;
    //     let mut st = LazySegmentTree::<MaxInt<usize>, AssignInt<usize>>::from(
    //         (0..n).map(|_| MaxInt::Val(0)).collect(),
    //     );
    //     let mut rand = XorShift::new();
    //     let mut ar = vec![0; n];
    //     for _ in 0..1000 {
    //         for __ in 0..2 {
    //             let i = rand.gen::<usize>() % n;
    //             let j = rand.gen::<usize>() % n;
    //             if i < j {
    //                 let x = rand.gen::<usize>() % 1000;
    //                 st.update(i..j, AssignInt::Val(x));
    //                 for k in i..j {
    //                     ar[k] = x;
    //                 }
    //                 // trace!("update", i..j, x);
    //                 // trace!(&ar);
    //                 // st.debug();
    //                 // trace!("---");
    //             }
    //         }
    //         for i in 0..n {
    //             for j in i + 1..n {
    //                 let truth = (i..j).map(|k| ar[k]).max().unwrap();
    //                 if MaxInt::Val(truth) != st.product(i..j) {
    //                     trace!(&ar);
    //                     st.debug();
    //                     trace!(i, j);
    //                     trace!(truth);
    //                     trace!(st.product(i..j));
    //                 }
    //                 assert!(MaxInt::Val(truth) == st.product(i..j));
    //             }
    //         }
    //     }
    //     trace!("Pass");
    // }

    let mut sc = Scanner::new();
    let h: usize = sc.cin();
    let w: usize = sc.cin();

    // 到達可能な最右点, 右移動距離
    let mut start = LazySegmentTree::<MaxInt<usize>, AssignInt<usize>>::from(
        (0..w).map(|i| MaxInt::Val(i)).collect(),
    );
    // 右移動距離
    let mut right = LazySegmentTree::<MinInt<usize>, AssignInt<usize>>::from(
        (0..w).map(|_| MinInt::Val(0)).collect(),
    );

    for k in 0..h {
        let l = sc.cin::<usize>() - 1;
        let r = sc.cin::<usize>();
        // trace!(l, r);

        if r < w {
            if let MaxInt::Val(i) = start.product(l..r + 1) {
                right.update(r..r + 1, AssignInt::Val(r - i));
                start.update(r..r + 1, AssignInt::Val(i));
            }
        }

        {
            if let MaxInt::Val(i) = start.product(0..l) {
                start.update(l..r, AssignInt::Val(i));
            } else {
                start.update(l..r, AssignInt::Fuck);
            }
        }

        right.update(l..r, AssignInt::Fuck);

        // trace!(start.to_vec());
        // trace!(right.to_vec());

        if let MinInt::Val(x) = right.product(0..w) {
            put!(x + k + 1);
        } else {
            put!(-1);
        }
    }
}

use std::collections::VecDeque;
use std::io::{self, Write};
use std::str::FromStr;

struct Scanner {
    stdin: io::Stdin,
    buffer: VecDeque<String>,
}
impl Scanner {
    fn new() -> Self {
        Scanner {
            stdin: io::stdin(),
            buffer: VecDeque::new(),
        }
    }
    fn cin<T: FromStr>(&mut self) -> T {
        while self.buffer.is_empty() {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
        self.buffer.pop_front().unwrap().parse::<T>().ok().unwrap()
    }
    fn chars(&mut self) -> Vec<char> {
        self.cin::<String>().chars().collect()
    }
    fn vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.cin()).collect()
    }
}


Measured memory_bytes: 37784