#include <bits/stdc++.h>
//#include <chrono>
//#pragma GCC optimize("Ofast")
using namespace std;
#define reps(i,s,n) for(int i = s; i < n; i++)
#define rep(i,n) reps(i,0,n)
#define Rreps(i,n,e) for(int i = n - 1; i >= e; --i)
#define Rrep(i,n) Rreps(i,n,0)
#define ALL(a) a.begin(), a.end()
#define fi first
#define se second

using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;

ll N,M,H,W,Q,K,A,B;
string S;
typedef pair<ll, ll> P;
const ll INF = (1LL<<58);

template <class T> class SEGTREE {
    unsigned int n;
    T dflt, cmp;
    vector<T> dat;

    static T op(const T a, const T b) {
        return max(a, b);
    }

    bool f(const T &a){
        return a >= cmp;
    }

public:
    SEGTREE(unsigned long _n, T _a) : n(1), dflt(_a) {
        while (n < _n) {n *= 2;}
        dat.resize(n * 2, dflt);
    }

    void update(unsigned int k, T a) {
        k += n;
        dat[k] = a;
        while (k > 0) {
            k >>= 1;
            dat[k] = op(dat[k<<1], dat[(k<<1)|1]);
        }
    }

    void init(vector<T> &v) {
        for (int i = 0; i < (int)v.size(); ++i) dat[i + n] = v[i];
        for (int i = n - 1; i >= 1; --i) {
            dat[i] = op(dat[i * 2], dat[i * 2 + 1]);
        }
    }

    T query(unsigned int l, unsigned int r) {
        T res_left = dflt, res_right = dflt;
        l += n; r += n;
        for ( ; l < r; l >>= 1, r >>= 1){
            if(l&1){
                res_left = op(res_left, dat[l]);
                if((++l) == r) break;
            }
            if(r&1){
                res_right = op(dat[r ^ 1], res_right);
            }
        }
        return op(res_left, res_right);
    }

    unsigned int max_right_search(unsigned int id, T &total){
        while(id < n) {
            id <<= 1;
            if(!f(op(total, dat[id]))){
                total = op(total, dat[id]);
                id |= 1;
            }
        }
        return id - n;
    }

    unsigned int max_right(unsigned int l, unsigned int r, T &a){
        //定義：op( dat[i], ..., dat[j - 1] ) = false
        //      op( dat[i], ..., dat[j] ) = true      となるjを返す(単調性を仮定)
        //op = maxの場合、[l, r)内のindexであるjであって、query(l, j) < a <= query(l, j + 1)なるものを求める
        //つまり、j >= l かつ dat[j] >= a である最小の数jを求める
        cmp = a;
        l += n;
        vector<unsigned int> right_id(0);
        T total(dflt);
        for (unsigned int tr = r + n ; l < tr; l >>= 1, tr >>= 1){
            if(l&1){
                if(f(op(total, dat[l]))) return max_right_search(l, total);
                total = op(total, dat[l]);
                if((++l) == tr) break;
            }
            if(tr&1) right_id.push_back(tr ^ 1);
        }
        for(auto ite = right_id.rbegin(); ite != right_id.rend(); ++ite){
            if(f(op(total, dat[*ite]))) return max_right_search(*ite, total);
            total = op(total, dat[*ite]);
        }
        return r;
    }

    //単項にアクセスする[]だが、書き換え厳禁
    //一応後でinitすれば書き換えてもよさそうだが…
    ll &operator[](int k) { return dat[k + n]; }
};

int main() {
    cin>>N>>K;
    vec a(N);
    rep(i,N) cin>>a[i];
    SEGTREE<ll> seg(300010, 0);
    rep(i, N){
        int l = max(0LL, a[i] - K), r = min(300000LL, a[i] + K);
        ll cmp = seg[a[i]];
        ll temp = seg.query(l, r + 1) + 1;
        if(cmp < temp) seg.update(a[i], temp);
        /*
        cout<<a[i]<<"  ";
        reps(j, 1, 10) cout<<seg[j]<<" \n"[j == 9];
         */
    }
    cout<<seg.query(0, 300010)<<endl;
}


Measured memory_bytes: 13764