pub trait Zero: PartialEq + Sized {
    fn zero() -> Self;
    #[inline]
    fn is_zero(&self) -> bool {
        self == &Self::zero()
    }
}
pub trait One: PartialEq + Sized {
    fn one() -> Self;
    #[inline]
    fn is_one(&self) -> bool {
        self == &Self::one()
    }
}
macro_rules ! zero_one_impls {($ ({$ Trait : ident $ method : ident $ ($ t : ty ) *, $ e : expr } ) * ) => {$ ($ (impl $ Trait for $ t {# [inline ] fn $ method () -> Self {$ e } } ) * ) * } ; }
zero_one_impls ! ({Zero zero u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 , 0 } {Zero zero f32 f64 , 0. } {One one u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 , 1 } {One one f32 f64 , 1. } );
pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Clone, Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
mod scanner_impls {
    use super::*;
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn new(s: &'a str) -> Self {
            let iter = s.split_ascii_whitespace();
            Self { iter }
        }
        #[inline]
        pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
            <T as IterScan>::scan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
            marker.mscan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
            (0..size)
                .map(|_| <T as IterScan>::scan(&mut self.iter).expect("scan error"))
                .collect()
        }
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
    macro_rules ! iter_scan_impls {($ ($ t : ty ) * ) => {$ (impl IterScan for $ t {type Output = Self ; # [inline ] fn scan <'a , I : Iterator < Item = &'a str >> (iter : & mut I ) -> Option < Self > {iter . next () ?. parse ::<$ t > () . ok () } } ) * } ; }
    iter_scan_impls ! (char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String );
    macro_rules ! iter_scan_tuple_impl {($ ($ T : ident ) * ) => {impl <$ ($ T : IterScan ) ,*> IterScan for ($ ($ T , ) * ) {type Output = ($ (<$ T as IterScan >:: Output , ) * ) ; # [inline ] fn scan <'a , It : Iterator < Item = &'a str >> (_iter : & mut It ) -> Option < Self :: Output > {Some (($ (<$ T as IterScan >:: scan (_iter ) ?, ) * ) ) } } } ; }
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl ! (A B );
    iter_scan_tuple_impl ! (A B C );
    iter_scan_tuple_impl ! (A B C D );
    iter_scan_tuple_impl ! (A B C D E );
    iter_scan_tuple_impl ! (A B C D E F );
    iter_scan_tuple_impl ! (A B C D E F G );
    iter_scan_tuple_impl ! (A B C D E F G H );
    iter_scan_tuple_impl ! (A B C D E F G H I );
    iter_scan_tuple_impl ! (A B C D E F G H I J );
    iter_scan_tuple_impl ! (A B C D E F G H I J K );
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            <T as IterScan>::scan(&mut self.inner.iter)
        }
    }
}
pub mod marker {
    use super::*;
    use std::{iter::FromIterator, marker::PhantomData};
    #[derive(Debug, Copy, Clone)]
    pub struct Usize1;
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(<usize as IterScan>::scan(iter)?.checked_sub(1)?)
        }
    }
    #[derive(Debug, Copy, Clone)]
    pub struct Chars;
    impl IterScan for Chars {
        type Output = Vec<char>;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(iter.next()?.chars().collect())
        }
    }
    #[derive(Debug, Copy, Clone)]
    pub struct CharsWithBase(pub char);
    impl MarkedIterScan for CharsWithBase {
        type Output = Vec<usize>;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                iter.next()?
                    .chars()
                    .map(|c| (c as u8 - self.0 as u8) as usize)
                    .collect(),
            )
        }
    }
    #[derive(Debug, Copy, Clone)]
    pub struct Collect<T: IterScan, B: FromIterator<<T as IterScan>::Output>> {
        size: usize,
        _marker: PhantomData<fn() -> (T, B)>,
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> Collect<T, B> {
        pub fn new(size: usize) -> Self {
            Self {
                size,
                _marker: PhantomData,
            }
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> MarkedIterScan for Collect<T, B> {
        type Output = B;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                (0..self.size)
                    .map(|_| <T as IterScan>::scan(iter).expect("scan error"))
                    .collect::<B>(),
            )
        }
    }
}
#[macro_export]
macro_rules ! min {($ e : expr ) => {$ e } ; ($ e : expr , $ ($ es : expr ) ,+ ) => {std :: cmp :: min ($ e , min ! ($ ($ es ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! chmin {($ dst : expr , $ ($ src : expr ) ,+ ) => {{let x = std :: cmp :: min ($ dst , min ! ($ ($ src ) ,+ ) ) ; $ dst = x ; } } ; }
#[macro_export]
macro_rules ! max {($ e : expr ) => {$ e } ; ($ e : expr , $ ($ es : expr ) ,+ ) => {std :: cmp :: max ($ e , max ! ($ ($ es ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! chmax {($ dst : expr , $ ($ src : expr ) ,+ ) => {{let x = std :: cmp :: max ($ dst , max ! ($ ($ src ) ,+ ) ) ; $ dst = x ; } } ; }
/// binary operaion: $T \circ T \to T$
pub trait Magma {
    /// type of operands: $T$
    type T: Clone + PartialEq;
    /// binary operaion: $\circ$
    fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T;
    #[inline]
    fn reverse_operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
        self.operate(y, x)
    }
}
/// $\forall a,\forall b,\forall c \in T, (a \circ b) \circ c = a \circ (b \circ c)$
pub trait Associative {}
/// associative binary operation
pub trait SemiGroup: Magma + Associative {}
impl<S: Magma + Associative> SemiGroup for S {}
/// $\exists e \in T, \forall a \in T, e \circ a = a \circ e = e$
pub trait Unital: Magma {
    /// identity element: $e$
    fn unit(&self) -> Self::T;
}
/// associative binary operation and an identity element
pub trait Monoid: SemiGroup + Unital {
    /// binary exponentiation: $x^n = x\circ\ddots\circ x$
    fn pow(&self, x: Self::T, n: usize) -> Self::T {
        let mut n = n;
        let mut res = self.unit();
        let mut base = x;
        while n > 0 {
            if n & 1 == 1 {
                res = self.operate(&res, &base);
            }
            base = self.operate(&base, &base);
            n >>= 1;
        }
        res
    }
}
impl<M: SemiGroup + Unital> Monoid for M {}
/// $\exists e \in T, \forall a \in T, \exists b,c \in T, b \circ a = a \circ c = e$
pub trait Invertible: Magma {
    /// $a$ where $a \circ x = e$
    fn inverse(&self, x: &Self::T) -> Self::T;
    #[inline]
    fn rinv_operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
        self.operate(x, &self.inverse(y))
    }
}
/// associative binary operation and an identity element and inverse elements
pub trait Group: Monoid + Invertible {}
impl<G: Monoid + Invertible> Group for G {}
/// $\forall a,\forall b \in T, a \circ b = b \circ a$
pub trait Commutative {}
/// commutative monoid
pub trait AbelianMonoid: Monoid + Commutative {}
impl<M: Monoid + Commutative> AbelianMonoid for M {}
/// commutative group
pub trait AbelianGroup: Group + Commutative {}
impl<G: Group + Commutative> AbelianGroup for G {}
/// $\forall a \in T, a \circ a = a$
pub trait Idempotent {}
/// idempotent monoid
pub trait IdempotentMonoid: Monoid + Idempotent {}
impl<M: Monoid + Idempotent> IdempotentMonoid for M {}
#[derive(Clone, Debug)]
pub struct SegmentTree<M: Monoid> {
    n: usize,
    seg: Vec<M::T>,
    m: M,
}
impl<M: Monoid> SegmentTree<M> {
    pub fn new(n: usize, m: M) -> Self {
        let n = 1 << format!("{:b}", n - 1).len();
        let seg = vec![m.unit(); 2 * n];
        Self { n, seg, m }
    }
    pub fn from_vec(v: Vec<M::T>, m: M) -> Self {
        let n = 1 << format!("{:b}", v.len() - 1).len();
        let mut seg = vec![m.unit(); 2 * n];
        for (i, x) in v.into_iter().enumerate() {
            seg[n + i] = x;
        }
        for i in (1..n).rev() {
            seg[i] = m.operate(&seg[2 * i], &seg[2 * i + 1]);
        }
        Self { n, seg, m }
    }
    pub fn set(&mut self, k: usize, x: M::T) {
        debug_assert!(k < self.n);
        let mut k = k + self.n;
        self.seg[k] = x;
        k /= 2;
        while k > 0 {
            self.seg[k] = self.m.operate(&self.seg[2 * k], &self.seg[2 * k + 1]);
            k /= 2;
        }
    }
    pub fn update(&mut self, k: usize, x: M::T) {
        debug_assert!(k < self.n);
        let mut k = k + self.n;
        self.seg[k] = self.m.operate(&self.seg[k], &x);
        k /= 2;
        while k > 0 {
            self.seg[k] = self.m.operate(&self.seg[2 * k], &self.seg[2 * k + 1]);
            k /= 2;
        }
    }
    pub fn get(&self, k: usize) -> M::T {
        debug_assert!(k < self.n);
        self.seg[k + self.n].clone()
    }
    pub fn fold(&self, l: usize, r: usize) -> M::T {
        debug_assert!(l < self.n);
        debug_assert!(r <= self.n);
        let mut l = l + self.n;
        let mut r = r + self.n;
        let mut vl = self.m.unit();
        let mut vr = self.m.unit();
        while l < r {
            if l & 1 != 0 {
                vl = self.m.operate(&vl, &self.seg[l]);
                l += 1;
            }
            if r & 1 != 0 {
                r -= 1;
                vr = self.m.operate(&self.seg[r], &vr);
            }
            l /= 2;
            r /= 2;
        }
        self.m.operate(&vl, &vr)
    }
    pub fn fold_all(&self) -> M::T {
        self.seg[1].clone()
    }
    /// left most index [0, r) that satisfies monotonic condition
    pub fn lower_bound_all<F: Fn(&M::T) -> bool>(&self, f: F, r: usize) -> usize {
        if !f(&self.seg[1]) {
            return r;
        }
        let mut acc = self.m.unit();
        let mut pos = 1;
        while pos < self.n {
            pos *= 2;
            let y = self.m.operate(&acc, &self.seg[pos]);
            if !f(&y) {
                acc = y;
                pos += 1;
            }
        }
        std::cmp::min(pos - self.n, r)
    }
    /// left most index [l, r) that satisfies monotonic condition
    pub fn lower_bound<F: Fn(&M::T) -> bool>(&self, f: F, l: usize, r: usize) -> usize {
        let mut acc = self.m.unit();
        let mut pos = l + self.n;
        let mut lim = r + self.n;
        loop {
            let y = self.m.operate(&acc, &self.seg[pos]);
            if f(&y) {
                while pos < self.n {
                    pos *= 2;
                    let y = self.m.operate(&acc, &self.seg[pos]);
                    if !f(&y) {
                        acc = y;
                        pos += 1;
                    }
                }
                return std::cmp::min(pos - self.n, r);
            }
            let is_right = pos & 1 == 1;
            if pos == lim {
                return r;
            }
            pos /= 2;
            lim /= 2;
            if is_right {
                acc = y;
                pos += 1;
            }
        }
    }
    pub fn as_slice(&self) -> &[M::T] {
        &self.seg[self.n..]
    }
}
/// binary operation to select larger element
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct MaxOperation<T: Clone + Ord + MinimumBounded> {
    _marker: std::marker::PhantomData<fn() -> T>,
}
pub trait MinimumBounded {
    fn minimum() -> Self;
}
mod max_operation_impl {
    use super::*;
    macro_rules! impl_minimum_with_min {
        ($ t : ty , $ min : expr ) => {
            impl MinimumBounded for $t {
                #[inline]
                fn minimum() -> Self {
                    $min
                }
            }
        };
    }
    impl_minimum_with_min!(usize, std::usize::MIN);
    impl_minimum_with_min!(u8, std::u8::MIN);
    impl_minimum_with_min!(u16, std::u16::MIN);
    impl_minimum_with_min!(u32, std::u32::MIN);
    impl_minimum_with_min!(u64, std::u64::MIN);
    impl_minimum_with_min!(isize, std::isize::MIN);
    impl_minimum_with_min!(i8, std::i8::MIN);
    impl_minimum_with_min!(i16, std::i16::MIN);
    impl_minimum_with_min!(i32, std::i32::MIN);
    impl_minimum_with_min!(i64, std::i64::MIN);
    macro_rules ! impl_minimum_tuple {($ ($ T : ident ) * ) => {impl <$ ($ T : MinimumBounded ) ,*> MinimumBounded for ($ ($ T , ) * ) {# [inline ] fn minimum () -> Self {($ (<$ T as MinimumBounded >:: minimum () , ) * ) } } } ; }
    impl_minimum_tuple!();
    impl_minimum_tuple!(A);
    impl_minimum_tuple ! (A B );
    impl_minimum_tuple ! (A B C );
    impl_minimum_tuple ! (A B C D );
    impl_minimum_tuple ! (A B C D E );
    impl_minimum_tuple ! (A B C D E F );
    impl_minimum_tuple ! (A B C D E F G );
    impl_minimum_tuple ! (A B C D E F G H );
    impl_minimum_tuple ! (A B C D E F G H I );
    impl_minimum_tuple ! (A B C D E F G H I J );
    impl_minimum_tuple ! (A B C D E F G H I J K );
    impl<T: Clone + Ord + MinimumBounded> MaxOperation<T> {
        pub fn new() -> Self {
            Self {
                _marker: std::marker::PhantomData,
            }
        }
    }
    impl<T: Clone + Ord + MinimumBounded> Magma for MaxOperation<T> {
        type T = T;
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            x.max(y).clone()
        }
    }
    impl<T: Clone + Ord + MinimumBounded> Unital for MaxOperation<T> {
        #[inline]
        fn unit(&self) -> Self::T {
            MinimumBounded::minimum()
        }
    }
    impl<T: Clone + Ord + MinimumBounded> Associative for MaxOperation<T> {}
    impl<T: Clone + Ord + MinimumBounded> Commutative for MaxOperation<T> {}
    impl<T: Clone + Ord + MinimumBounded> Idempotent for MaxOperation<T> {}
}
/// binary operation to select smaller element
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct MinOperation<T: Clone + Ord + MaximumBounded> {
    _marker: std::marker::PhantomData<fn() -> T>,
}
pub trait MaximumBounded {
    fn maximum() -> Self;
}
mod min_operation_impl {
    use super::*;
    macro_rules! impl_maximum_with_max {
        ($ t : ty , $ max : expr ) => {
            impl MaximumBounded for $t {
                #[inline]
                fn maximum() -> Self {
                    $max
                }
            }
        };
    }
    impl_maximum_with_max!(usize, std::usize::MAX);
    impl_maximum_with_max!(u8, std::u8::MAX);
    impl_maximum_with_max!(u16, std::u16::MAX);
    impl_maximum_with_max!(u32, std::u32::MAX);
    impl_maximum_with_max!(u64, std::u64::MAX);
    impl_maximum_with_max!(isize, std::isize::MAX);
    impl_maximum_with_max!(i8, std::i8::MAX);
    impl_maximum_with_max!(i16, std::i16::MAX);
    impl_maximum_with_max!(i32, std::i32::MAX);
    impl_maximum_with_max!(i64, std::i64::MAX);
    macro_rules ! impl_maximum_tuple {($ ($ T : ident ) * ) => {impl <$ ($ T : MaximumBounded ) ,*> MaximumBounded for ($ ($ T , ) * ) {# [inline ] fn maximum () -> Self {($ (<$ T as MaximumBounded >:: maximum () , ) * ) } } } ; }
    impl_maximum_tuple!();
    impl_maximum_tuple!(A);
    impl_maximum_tuple ! (A B );
    impl_maximum_tuple ! (A B C );
    impl_maximum_tuple ! (A B C D );
    impl_maximum_tuple ! (A B C D E );
    impl_maximum_tuple ! (A B C D E F );
    impl_maximum_tuple ! (A B C D E F G );
    impl_maximum_tuple ! (A B C D E F G H );
    impl_maximum_tuple ! (A B C D E F G H I );
    impl_maximum_tuple ! (A B C D E F G H I J );
    impl_maximum_tuple ! (A B C D E F G H I J K );
    impl<T: Clone + Ord + MaximumBounded> MinOperation<T> {
        pub fn new() -> Self {
            Self {
                _marker: std::marker::PhantomData,
            }
        }
    }
    impl<T: Clone + Ord + MaximumBounded> Magma for MinOperation<T> {
        type T = T;
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            x.min(y).clone()
        }
    }
    impl<T: Clone + Ord + MaximumBounded> Unital for MinOperation<T> {
        #[inline]
        fn unit(&self) -> Self::T {
            MaximumBounded::maximum()
        }
    }
    impl<T: Clone + Ord + MaximumBounded> Associative for MinOperation<T> {}
    impl<T: Clone + Ord + MaximumBounded> Commutative for MinOperation<T> {}
    impl<T: Clone + Ord + MaximumBounded> Idempotent for MinOperation<T> {}
}
/// $(M_1, M_2)$
#[derive(Clone, Debug)]
pub struct CartesianOperation<M1, M2> {
    m1: M1,
    m2: M2,
}
mod cartesian_operation_impl {
    use super::*;
    impl<M1, M2> CartesianOperation<M1, M2> {
        pub fn new(m1: M1, m2: M2) -> Self {
            Self { m1, m2 }
        }
    }
    impl<M1: Magma, M2: Magma> Magma for CartesianOperation<M1, M2> {
        type T = (M1::T, M2::T);
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            (self.m1.operate(&x.0, &y.0), self.m2.operate(&x.1, &y.1))
        }
    }
    impl<M1: Unital, M2: Unital> Unital for CartesianOperation<M1, M2> {
        #[inline]
        fn unit(&self) -> Self::T {
            (self.m1.unit(), self.m2.unit())
        }
    }
    impl<M1: Associative, M2: Associative> Associative for CartesianOperation<M1, M2> {}
    impl<M1: Commutative, M2: Commutative> Commutative for CartesianOperation<M1, M2> {}
    impl<M1: Invertible, M2: Invertible> Invertible for CartesianOperation<M1, M2> {
        #[inline]
        fn inverse(&self, x: &Self::T) -> Self::T {
            (self.m1.inverse(&x.0), self.m2.inverse(&x.1))
        }
    }
}
fn main() {
    #![allow(unused_imports, unused_macros)]
    use std::io::{stdin, stdout, BufWriter, Read as _, Write as _};
    let mut _in_buf = Vec::new();
    stdin().read_to_end(&mut _in_buf).expect("io error");
    let _in_buf = unsafe { String::from_utf8_unchecked(_in_buf) };
    let mut scanner = Scanner::new(&_in_buf);
    macro_rules ! scan {() => {scan ! (usize ) } ; (($ ($ t : tt ) ,* ) ) => {($ (scan ! ($ t ) ) ,* ) } ; ([$ t : tt ; $ len : expr ] ) => {(0 ..$ len ) . map (| _ | scan ! ($ t ) ) . collect ::< Vec < _ >> () } ; ([$ t : ty ; $ len : expr ] ) => {scanner . scan_vec ::<$ t > ($ len ) } ; ([$ t : ty ] ) => {scanner . iter ::<$ t > () } ; ({$ e : expr } ) => {scanner . mscan ($ e ) } ; ($ t : ty ) => {scanner . scan ::<$ t > () } ; }
    let _out = stdout();
    let mut _out = BufWriter::new(_out.lock());
    macro_rules ! print {($ ($ arg : tt ) * ) => (:: std :: write ! (_out , $ ($ arg ) * ) . expect ("io error" ) ) }
    macro_rules ! println {($ ($ arg : tt ) * ) => (:: std :: writeln ! (_out , $ ($ arg ) * ) . expect ("io error" ) ) }
    macro_rules! echo {
        ($ iter : expr ) => {
            echo!($iter, '\n')
        };
        ($ iter : expr , $ sep : expr ) => {
            let mut iter = $iter.into_iter();
            if let Some(item) = iter.next() {
                print!("{}", item);
            }
            for item in iter {
                print!("{}{}", $sep, item);
            }
            println!();
        };
    }
    let n = scan!();
    let k = scan!();
    let a = scan!([usize; n]);
    let mut seg1 = SegmentTree::from_vec(vec![0; 300_005], MaxOperation::new());
    let mut seg2 = SegmentTree::from_vec(vec![0; 300_005], MaxOperation::new());
    for a in a {
        let x = seg1.fold(a.saturating_sub(k), (a + k + 1).min(300_005));
        let y = seg2.fold(a.saturating_sub(k), (a + k + 1).min(300_005));
        let z = max!(seg1.get(a), seg2.get(a), x + 1, y + 1);
        seg1.set(a, z);
        seg2.set(a, z);
    }
    println!("{}", max!(seg1.fold_all(), seg2.fold_all()));
}


Measured memory_bytes: 14740