#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int N = 3e5 + 10;
int n,k;
int v[N];
struct info{
    //Use required attributes
    int mn;

    //Default Values
    info() : mn(0) {};
};

struct SegTree{
    int N;
    vector<info> st;
    vector<bool> cLazy;
    vector<int> lazy;

    void init(int n){
        N = n;
        st.resize(4 * N + 5);
        cLazy.assign(4 * N + 5, false);
        lazy.assign(4 * N + 5, 0);
    }

    //Write reqd merge functions
    void merge(info &cur, info &l, info &r) {
        cur.mn = max(l.mn, r.mn);
    }
    
    //Handle lazy propagation appriopriately
    void propagate(int node, int L, int R){
        if(L != R){
            cLazy[node*2] = 1;
            cLazy[node*2 + 1] = 1;
            lazy[node*2] = lazy[node];
            lazy[node*2 + 1] = lazy[node]; 
        }
        st[node].mn = lazy[node];
        cLazy[node] = 0;
    }

    void build(int node, int L, int R){
        if(L==R){
            st[node].mn = 1e9;
            return;
        }
        int M=(L + R)/2;
        build(node*2, L, M);
        build(node*2 + 1, M + 1, R);
        merge(st[node], st[node*2], st[node*2+1]);
    }

    info Query(int node, int L, int R, int i, int j){
        if(cLazy[node])
            propagate(node, L, R);
        if(j<L || i>R)
            return info();
        if(i<=L && R<=j)
            return st[node];
        int M = (L + R)/2;
        info left=Query(node*2, L, M, i, j);
        info right=Query(node*2 + 1, M + 1, R, i, j);
        info cur;
        merge(cur, left, right);
        return cur;
    }

    info pQuery(int node, int L, int R, int pos){
        if(cLazy[node])
            propagate(node, L, R);
        if(L == R)
            return st[node];
        int M = (L + R)/2;
        if(pos <= M)
            return pQuery(node*2, L, M, pos);
        else
            return pQuery(node*2 + 1, M + 1, R, pos);
    }    

    void Update(int node, int L, int R, int i, int j, int val){
        if(cLazy[node])
            propagate(node, L, R);
        if(j<L || i>R)
            return;
        if(i<=L && R<=j){
            cLazy[node] = 1;
            lazy[node] = val;
            propagate(node, L, R);
            return;
        }
        int M = (L + R)/2;
        Update(node*2, L, M, i, j, val);
        Update(node*2 + 1, M + 1, R, i, j, val);
        merge(st[node], st[node*2], st[node*2 + 1]);
    }

    void pUpdate(int node, int L, int R, int pos, int val){
        if(cLazy[node])
            propagate(node, L, R);
        if(L == R){
            cLazy[node] = 1;
            lazy[node] = val;
            propagate(node, L, R);
            return;
        }
        int M = (L + R)/2;
        if(pos <= M)
            pUpdate(node*2, L, M, pos, val);
        else
            pUpdate(node*2 + 1, M + 1, R, pos, val);
        merge(st[node], st[node*2], st[node*2 + 1]);
    }

    info query(int pos){
        return pQuery(1, 1, N, pos);
    }

    info query(int l, int r){
        return Query(1, 1, N, l, r);
    }

    void update(int pos, int val){
        pUpdate(1, 1, N, pos, val);
    }

    void update(int l, int r, int val){
        Update(1, 1, N, l, r, val);
    }
};
int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> k;
    for(int i = 1;i <= n;i++){
        cin >> v[i];
    }
    SegTree st;
    int ans = 0;
    st.init(N);
    for(int i = n;i >= 1;i--){
        int aa = st.query(v[i] - k,v[i] + k).mn + 1;
        st.update(v[i],aa);
        ans = max(ans,aa);
    }
    cout << ans << "\n";
    return 0;
}
 

Measured memory_bytes: 14032