macro_rules! read_line_to_tuple {
    ( $( $t:ty ),* ) => {{
        let mut input = String::new();
        std::io::stdin().read_line(&mut input).unwrap();
        let mut iter = input.split_whitespace();
        ( $( iter.next().unwrap().parse::<$t>().unwrap() ),* )
    }};
}

struct SegmentTree<T> {
    n: usize,
    len: usize,
    height: usize,
    op: fn(T, T) -> T,
    e: fn() -> T,
    node: Vec<T>,
}

impl<T: Clone + Copy> SegmentTree<T> {
    fn new(n: usize, op: fn(T, T) -> T, e: fn() -> T) -> SegmentTree<T> {
        let (mut len, mut height) = (1, 1);
        while len < n {
            len *= 2;
            height += 1;
        }
        let node = vec![e(); 2 * len];
        SegmentTree { n, len, height, op, e, node }
    }

    fn _from(v: Vec<T>, op: fn(T, T) -> T, e: fn() -> T) -> SegmentTree<T> {
        let mut st = SegmentTree::new(v.len(), op, e);
        for i in 0..v.len() { st.node[i + st.len] = v[i]; }
        for i in (1..st.len).rev() {
            st.update(i);
        }
        st
    }

    fn update(&mut self, k: usize) {
        self.node[k] = (self.op)(self.node[2 * k], self.node[2 * k + 1]);
    }

    fn set(&mut self, mut p: usize, x: T) {
        assert!(p < self.n);
        p += self.len;
        self.node[p] = x;
        for i in 1..self.height { self.update(p >> i) };
    }

    fn prod(&self, mut l: usize, mut r: usize) -> T {
        assert!(l <= r && r <= self.n);
        let (mut sml, mut smr) = ((self.e)(), (self.e)());
        l += self.len;
        r += self.len;

        while l < r {
            if l & 1 != 0 {
                sml = (self.op)(sml, self.node[l]);
                l += 1;
            }
            if r & 1 != 0 {
                r -= 1;
                smr = (self.op)(self.node[r], smr);
            }
            l >>= 1;
            r >>= 1;
        }

        (self.op)(sml, smr)
    }

    fn _max_right<F: Fn(T) -> bool>(&self, mut l: usize, f: F) -> usize {
        assert!(l <= self.n);
        assert!(f((self.e)()));
        if l == self.n { return self.n; }
        l += self.len;
        let mut sm = (self.e)();
        while {
            while l % 2 == 0 { l >>= 1; }
            if !f((self.op)(sm, self.node[l])) {
                while l < self.len {
                    l = 2 * l;
                    if f((self.op)(sm, self.node[l])) {
                        sm = (self.op)(sm, self.node[l]);
                        l += 1;
                    }
                }
                return l - self.len;
            }
            sm = (self.op)(sm, self.node[l]);
            l += 1;
            (l & (!l + 1)) != l
        } {}
        self.n
    }

    fn _min_left<F: Fn(T) -> bool>(&self, mut r: usize, f: F) -> usize {
        assert!(r <= self.n);
        assert!(f((self.e)()));
        if r == 0 { return 0; }
        r += self.len;
        let mut sm = (self.e)();
        while {
            r -= 1;
            while r > 1 && r % 2 != 0 { r >>= 1; }
            if !f((self.op)(self.node[r], sm)) {
                while r < self.len {
                    r = 2 * r + 1;
                    if f((self.op)(self.node[r], sm)) {
                        sm = (self.op)(self.node[r], sm);
                        r -= 1;
                    }
                }
                return r + 1 - self.len;
            }
            sm = (self.op)(self.node[r], sm);
            (r & (!r + 1)) != r
        } {}
        0
    }
}

fn op(v1: i32, v2: i32) -> i32 {
    std::cmp::max(v1, v2)
}

fn e() -> i32 {
    0
}

fn main() {
    let (n, k) = read_line_to_tuple!(usize, usize);

    let mut st = SegmentTree::new(900_010, op, e);
    for _ in 0..n {
        let a = read_line_to_tuple!(usize);
        let m = st.prod(a, a + 2 * k + 1);
        st.set(a + k, m + 1);
    }

    println!("{}", st.node[1]);
}

Measured memory_bytes: 4484