#![allow(non_snake_case)]
#![allow(unused_imports)]
use ac_library_rs::{Max, Segtree};
use ascii::AsciiChar;
use ascii::AsciiStr;
use itertools::Itertools as _;
use permutohedron::LexicalPermutation as _;
use petgraph::algo::dijkstra;
use petgraph::algo::min_spanning_tree;
use petgraph::data::FromElements;
use petgraph::graph::NodeIndex;
use petgraph::graph::UnGraph;
use petgraph::unionfind::UnionFind;
use proconio::fastout;
use proconio::input;
use proconio::marker::Chars;
use proconio::marker::Usize1;
use std::cmp::max;
use std::cmp::min;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::VecDeque;
use superslice::Ext as _;

#[fastout]
fn main() {
    input! {
        N: usize,
        K: i64,
        As: [i64; N],
    }

    // セグ木の典型らしい。

    // セグ木でできること
    // 1. 区間[a, b)におけるモノイドopの畳み込み O(log N)
    // 2. replace a_i to x O(log N)

    // Asをセグ木に登録するのは O(N logN)
    // その後、どうするんだろうか?
    // ただのAsのmax, minではないので、計算できないような…?
    // おー、添え字の0~N-1を入れるんじゃなくて、
    // 有り得る数値(Aの0~300000)を全部木に入れちゃうのか。

    // セグ木のノードで持つ値 : Seg[k] : 末尾がkであるような部分列の最長の長さ
    // ただし、その部分列は差の絶対値の条件を満たす

    const A_MAX: i64 = 300_000;

    // 各ノードの値は演算の単位元である「i64の最小値」で初期化される
    let mut segtree = Segtree::<Max<i64>>::new(A_MAX as usize + 1);

    // それだとマズいので、0をセットしておく。
    for a in 0..=A_MAX as usize {
        segtree.set(a, 0);
    }

    // ループ内でO(log N)なので全体でO(N logN)
    for &a in As.iter() {
        // 「末尾が[a-K, a+K]の範囲内での最長の長さ」に1を足したい。
        let l: usize = max(0, a - K) as usize;
        let r: usize = min(A_MAX, a + K + 1) as usize;

        let tmp = segtree.prod(l, r);
        segtree.set(a as usize, tmp + 1);
    }

    let ans = segtree.all_prod();
    println!("{}", ans);
}
