#include <bits/stdc++.h>
using namespace std;

#pragma region Macros
using ll = long long;
#define int ll
using pii = pair<int, int>;
using tiii = tuple<int, int, int>;
template<class T = ll> using V = vector<T>;
template<class T = ll> using VV = V<V<T>>;
#define IOS\
    ios::sync_with_stdio(false);\
    cin.tie(0);\
    cout.tie(0);
#define FOR(i,l,r) for(ll i=(l);i<(r);++i)
#define REP(i,n) FOR(i,0,n)
#define REPS(i,n) FOR(i,1,n+1)
#define RFOR(i,l,r) for(ll i=(l);i>=(r);--i)
#define RREP(i,n) RFOR(i,n-1,0)
#define RREPS(i,n) RFOR(i,n,1)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(),(x).end()
#define SORT(name) sort(name.begin(), name.end())
#define RSORT(name)\
    SORT(name);\
    reverse(all(name));
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
inline void Yes(bool b = true) {cout << (b ? "Yes" : "No") << '\n';}
inline void YES(bool b = true) {cout << (b ? "YES" : "NO") << '\n';}
template <class T> inline void print(T x){ cout << x << '\n';}
template<typename T1,typename T2> inline void chmin(T1 &a, T2 b){ if(a > b) a = b; }
template<typename T1,typename T2> inline void chmax(T1 &a, T2 b){ if(a < b) a = b; }

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
#pragma endregion

#if 0
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const int MOD = 1000000007;
const int MAX_N = 100010;

template< typename SType>
class SegmentTree
{
    public:
        // 集合の要素 2 つを引数に取リ、その二項演算結果を返す関数
        using Func = function< SType(SType, SType) >;

    public:
        SegmentTree() {}
        SegmentTree(int n, const Func f, const SType &e) { Init(n, f, e); }
        // セグ木を初期化します。
        // サイズは 10^6 くらいまでならいけそう
        // n  : セグ木のサイズ
        // f  : セグ木で判定する関数
        // e : 初期値(単位元)
        void Init(int n, const Func f, const SType &e) {
            m_F = f; m_E = e;
            // 要素数は 2 のべき乗じゃないといけないのでそうする
            m_Size = 1;
            while(m_Size < n) { m_Size <<= 1; }
            m_Seg.assign(2 * m_Size, m_E);
        }

        // k 番目の要素に x をセット (0-indexed)
        void Set(int k, const SType &x) { m_Seg[k + m_Size] = x; }

        // セグ木構築 O(N)
        void Build() {
            for(int k = m_Size - 1; k > 0; k--) {
                // 子ノードに対しての演算結果を親ノードに格納
                m_Seg[k] = m_F(m_Seg[2 * k + 0], m_Seg[2 * k + 1]);
            }
        }

        // k 番目の要素を x に変更する O(log N) (0-indexed)
        // Build 後も利用可能
        void Update(int k, const SType &x) {
            k += m_Size;
            m_Seg[k] = x;
            while(k >>= 1) {
                m_Seg[k] = m_F(m_Seg[2 * k + 0], m_Seg[2 * k + 1]);
            }
        }

        // 区間 [a, b) に対して初期設定した関数をした結果を返す O(log N)
        // 開区間なので b は含まれないので注意
        // 0-indexed
        SType Query(int a, int b) {
            SType l = m_E, r = m_E;
            for(a += m_Size, b += m_Size; a < b; a >>= 1, b >>= 1) {
                if(a & 1) l = m_F(l, m_Seg[a++]);
                if(b & 1) r = m_F(m_Seg[--b], r);
            }
            return m_F(l, r);
        }

        SType operator[](const int &k) const
        {
            return m_Seg[k + m_Size];
        }
    public:
        Func m_F;               // このセグ木で処理する関数（二項演算）
        SType m_E;              // 初期値(単位元)

        int m_Size;             // セグ木の要素数
        vector< SType > m_Seg;  // セグ木本体。一次元で管理する
};

int H, W;
V<> A, B;

signed main() {
    IOS;

    cin >> H >> W;
    A.resize(H);
    B.resize(H);
    REP(i, H) {
        cin >> A[i] >> B[i];
        A[i]--; B[i]--;
    }

    auto Rmq = [](int a, int b) -> int {
        return min(a, b);
    };
    SegmentTree<int> seg(W, Rmq, LLINF);
    map<int, int> pos;  // key: 現在地 value: 最初の位置
    REP(i, W) {
        seg.Set(i, 0);
        pos[i] = i;
    }
    seg.Build();

    REP(i, H) {
        // 現在地が [A[i], B[i]] のものを見つける
        // 一番右のもの以外は削除
        auto it = pos.lower_bound(A[i]);    // A[i] 以降の最初の値
        V<pii> survive;
        while(it != pos.end() && it->first <= B[i] + 1) {
            survive.pb(*it);
            seg.Update(it->second, LLINF);
            it++;
        }
        // 生き残りの中で一番右にあるものを残す
        if(survive.size() > 0) {
            for(auto tmp : survive) {
                pos.erase(tmp.first);
            }
            pii cand = survive[survive.size() - 1];
            if(B[i] + 1 < W) {
                pos[B[i] + 1] = cand.second;
                // 移動期間の更新
                seg.Update(cand.second, B[i] + 1 - cand.second);
            }
        }
        int ans = seg.Query(0, W) + i + 1;
        if(ans >= LLINF) { print(-1); }
        else { print(ans); }
    }

    return 0;
}


Measured memory_bytes: 23184