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

use itertools::Itertools;

const U_INF: usize = 1 << 60;
const I_INF: isize = 1 << 60;

struct RMQ;
impl Monoid for RMQ {
    type Item = usize;

    fn id() -> Self::Item {
        0
    }

    fn op(a: &Self::Item, b: &Self::Item) -> Self::Item {
        *a.max(b)
    }
}

fn main() {
    let mut sc = Scanner::new();
    let n = sc.next_usize();
    let k = sc.next_usize();
    let mut a = Vec::with_capacity(n);
    for _ in 0..n {
        let ai = sc.next_usize();
        a.push(ai);
    }

    let mut sg = SegmentTree::<RMQ>::from_slice(&(0..=300_000).map(|_| 0).collect_vec());
    sg.set(a[0], 1);

    let mut dp = vec![0; n + 1];
    dp[1] = 1;

    for i in 1..=n {
        let l = a[i - 1].saturating_sub(k);
        let r = 300_000.min(a[i - 1] + k + 1);
        dp[i] = sg.fold(l, r) + 1;
        sg.set(a[i - 1], dp[i]);
    }

    let mut max = 0;
    for i in 0..n {
        max = (max).max(dp[i]);
    }

    println!("{}", max);
}

/// セグメント木に乗せるMonoid
///
/// 以下の性質を満たさないといけない
/// - op(a, id()) == op(id(), a) == a
/// - op(op(a, b), c) == op(a, op(b,c))
pub trait Monoid {
    type Item: Sized + Clone + std::fmt::Debug;
    fn id() -> Self::Item;
    fn op(a: &Self::Item, b: &Self::Item) -> Self::Item;
}

pub enum SegmentTree<M: Monoid> {
    Leaf {
        value: M::Item,
    },
    Node {
        value: M::Item,
        len: usize,
        left: Box<SegmentTree<M>>,
        right: Box<SegmentTree<M>>,
    },
}

impl<M: Monoid> SegmentTree<M> {
    /// そのNodeの持つ要素の長さを返す
    pub fn len(&self) -> usize {
        match self {
            SegmentTree::Leaf { .. } => 1,
            SegmentTree::Node { len, .. } => *len,
        }
    }

    /// そのNodeの値を返す
    pub fn val(&self) -> &M::Item {
        match self {
            SegmentTree::Leaf { value } => value,
            SegmentTree::Node { value, .. } => value,
        }
    }

    /// スライスからセグメント木を作る
    pub fn from_slice(slice: &[M::Item]) -> Self {
        assert!(!slice.is_empty());

        if slice.len() == 1 {
            Self::Leaf {
                value: slice[0].clone(),
            }
        } else {
            let mid = slice.len() / 2;
            let left = Self::from_slice(&slice[..mid]);
            let right = Self::from_slice(&slice[mid..]);
            Self::Node {
                value: M::op(left.val(), right.val()),
                len: slice.len(),
                left: Box::new(left),
                right: Box::new(right),
            }
        }
    }

    /// 0-indexedでその要素を得る
    pub fn get(&self, i: usize) -> &M::Item {
        assert!(i < self.len());

        match self {
            SegmentTree::Leaf { value, .. } => value,
            SegmentTree::Node { left, right, .. } => {
                let l = left.len();

                if i < l {
                    left.get(i)
                } else {
                    right.get(i - l)
                }
            }
        }
    }

    /// 0-indexedで一点更新
    pub fn set(&mut self, i: usize, item: M::Item) {
        assert!(i < self.len());

        match self {
            SegmentTree::Leaf { value } => *value = item,
            SegmentTree::Node {
                left, right, value, ..
            } => {
                let l = left.len();

                if i < l {
                    left.set(i, item);
                } else {
                    right.set(i - l, item);
                }

                *value = M::op(left.val(), right.val());
            }
        }
    }

    /// sg[start..end]の値を返す
    pub fn fold(&self, start: usize, end: usize) -> M::Item {
        assert!(start <= end);
        assert!(end <= self.len());

        let len = end - start;
        if len == 0 {
            return M::id();
        } else if len == self.len() {
            return self.val().clone();
        }

        match self {
            SegmentTree::Leaf { .. } => unreachable!(),
            SegmentTree::Node { left, right, .. } => {
                let l = left.len();

                if end <= l {
                    left.fold(start, end)
                } else if l <= start {
                    right.fold(start - l, end - l)
                } else {
                    M::op(&left.fold(start, l), &right.fold(0, end - l))
                }
            }
        }
    }
}

impl<M: Monoid> From<&[M::Item]> for SegmentTree<M> {
    fn from(slice: &[<M as Monoid>::Item]) -> Self {
        SegmentTree::from_slice(slice)
    }
}

pub struct Scanner {
    buf: std::collections::VecDeque<String>,
}

impl Scanner {
    pub fn new() -> Self {
        Self {
            buf: std::collections::VecDeque::new(),
        }
    }

    fn scan_line(&mut self) {
        let mut flag = 0;
        while self.buf.is_empty() {
            let mut s = String::new();
            std::io::stdin().read_line(&mut s).unwrap();
            let mut iter = s.split_whitespace().peekable();
            if iter.peek().is_none() {
                if flag >= 5 {
                    panic!("There is no input!");
                }
                flag += 1;
                continue;
            }

            for si in iter {
                self.buf.push_back(si.to_string());
            }
        }
    }

    pub fn next<T: std::str::FromStr>(&mut self) -> T {
        self.scan_line();
        self.buf
            .pop_front()
            .unwrap()
            .parse()
            .unwrap_or_else(|_| panic!("Couldn't parse!"))
    }

    pub fn next_usize(&mut self) -> usize {
        self.next()
    }

    pub fn next_isize(&mut self) -> isize {
        self.next()
    }

    pub fn next_chars(&mut self) -> Vec<char> {
        self.next::<String>().chars().collect()
    }

    pub fn next_string(&mut self) -> String {
        self.next()
    }

    pub fn next_char(&mut self) -> char {
        self.next()
    }

    pub fn next_float(&mut self) -> f64 {
        self.next()
    }
}
