#[allow(unused_imports)]
use {
    itertools::Itertools,
    proconio::{fastout, input, marker::*},
    std::cmp::*,
    std::collections::*,
    std::io::Write,
    std::ops::*,
};

#[allow(unused_macros)]
macro_rules! debug { ($($e:expr),*) => { #[cfg(debug_assertions)] $({ let (e, mut err) = (stringify!($e), std::io::stderr()); writeln!(err, "{} = {:?}", e, $e).unwrap() })* }; }

struct SegmentTree<T, F: Fn(&T, &T) -> T> {
    width: usize,
    node: Vec<T>,
    id: T,
    op: F,
}
#[allow(dead_code)]
impl<T: Add<Output = T> + Copy + Clone, F: Fn(&T, &T) -> T> SegmentTree<T, F> {
    fn new(n: usize, id: T, op: F) -> Self {
        let width = n.next_power_of_two();
        Self {
            width,
            node: vec![id; width << 1],
            id,
            op,
        }
    }
    fn from_vec(a: &[T], id: T, op: F) -> Self {
        let width = a.len().next_power_of_two();
        let mut node = vec![id; width << 1];
        for i in 0..a.len() {
            node[i + width] = a[i];
        }
        for i in (1..width).rev() {
            node[i] = op(&node[i << 1], &node[1 + (i << 1)]);
        }
        Self {
            width,
            node,
            id,
            op,
        }
    }
    fn update(&mut self, idx: usize, v: T) {
        let mut now = idx + self.width;
        self.node[now] = v;
        now = now >> 1;
        while now > 0 {
            self.node[now] = (self.op)(&self.node[now << 1], &self.node[1 + (now << 1)]);
            now = now >> 1;
        }
    }
    fn get(&self, idx: usize) -> T {
        self.node[idx + self.width]
    }
    fn __prod(&self, idx: usize, lc: usize, rc: usize, l: usize, r: usize) -> T {
        if rc <= l || r <= lc {
            self.id
        } else if l <= lc && rc <= r {
            self.node[idx]
        } else {
            (self.op)(
                &self.__prod(idx << 1, lc, (lc + rc) / 2, l, r),
                &self.__prod(1 + (idx << 1), (lc + rc) / 2, rc, l, r),
            )
        }
    }
    fn prod<R>(&self, range: R) -> T
    where
        R: std::ops::RangeBounds<usize>,
    {
        let l = match range.start_bound() {
            std::ops::Bound::Included(&a) => a,
            _ => 0,
        };
        let r = match range.end_bound() {
            std::ops::Bound::Excluded(&a) => a,
            std::ops::Bound::Included(&a) => a + 1,
            _ => self.width,
        };
        self.__prod(1, 0, self.width, l, r)
    }
    /// return Some(r): Max f(l..r) == true && f(l..=r) == false
    fn max_right(&self, l: usize, f: fn(T) -> bool) -> Option<usize> {
        if !f(self.get(l)) {
            None
        } else {
            let mut low = l;
            let mut high = self.width;
            while high - low > 1 {
                let mid = (low + high) / 2;
                if f(self.prod(l..=mid)) {
                    low = mid;
                } else {
                    high = mid;
                }
            }
            Some(low)
        }
    }
    /// return l: Min f(self.prod(l, r)) == true
    fn min_left(&self, r: usize, f: fn(T) -> bool) -> Option<usize> {
        if !f(self.get(r)) {
            None
        } else {
            let mut low = 0;
            let mut high = r;
            while high - low > 1 {
                let mid = (low + high) / 2;
                if f(self.prod(mid..=r)) {
                    high = mid;
                } else {
                    low = mid;
                }
            }
            Some(high)
        }
    }
}

#[fastout]
fn main() {
    input! {
        n: usize,
        k: usize,
        a: [usize; n]
    }
    let mut seg = SegmentTree::new(300001, 0i64, |a, b| max(*a, *b));
    for a in a {
        let now = seg.prod(max(a, k) - k..=min(300000, a + k));
        seg.update(a, now + 1);
    }
    let ans = seg.prod(..);
    println!("{}", ans);
}


Measured memory_bytes: 11128