/*
* @author:  codancer
* @createTime:  2020-09-27, 23:09:45
*/

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const ll mod = 1e9+7;
#define pb push_back
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define fep(i,a,b) for(int i=(a);i>=(b);i--)
#define deb(x) cerr<<#x<<" = "<<(x)<<"\n"
typedef vector<int> VI;
typedef vector<ll> VII;
typedef pair<int,int> pii;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll Rand(ll B) {
	return (ull)rng() % B;
}
const int N = 1e6;
const int INF = 1e9;
struct Seg{
    ll minn[N<<1],maxx[N<<1],sum[N<<1],add[N<<1];
    inline void pushup(ll rt){
        minn[rt]=min(minn[rt<<1|1],minn[rt<<1]);
        maxx[rt]=max(maxx[rt<<1|1],maxx[rt<<1]);
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    inline void pushdown(ll rt,ll l,ll r){
        if(add[rt]){
            ll mid=(l+r)>>1;
            sum[rt<<1]=sum[rt<<1]+add[rt]*(mid-l+1);
            sum[rt<<1|1]=sum[rt<<1|1]+add[rt]*(r-mid);

            maxx[rt<<1]=maxx[rt<<1]+add[rt];
            maxx[rt<<1|1]=maxx[rt<<1|1]+add[rt];

            minn[rt<<1]=minn[rt<<1]+add[rt];
            minn[rt<<1|1]=minn[rt<<1|1]+add[rt];

            add[rt<<1]+=add[rt];
            add[rt<<1|1]+=add[rt];

            add[rt]=0;
        }
        return ;
    }
    inline void buildtree(ll rt,ll l,ll r){
        add[rt]=0;
        if(l==r){
            minn[rt]=maxx[rt]=sum[rt]=0;
            return ;
        }
        ll mid=(l+r)>>1;
        buildtree(rt<<1,l,mid);
        buildtree(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    inline void modify(ll rt,ll l,ll r,ll nl,ll nr,ll k){//区间[nl,nr]+k
        if(nl<=l&&r<=nr){
            add[rt]+=k;
            maxx[rt]+=k;
            minn[rt]+=k;
            sum[rt]+=k*(r-l+1);
            return ;
        }
        ll mid=(l+r)>>1;
        pushdown(rt,l,r);
        if(nl<=mid) modify(rt<<1,l,mid,nl,nr,k);
        if(nr>mid) modify(rt<<1|1,mid+1,r,nl,nr,k);
        pushup(rt);
    }
    inline ll querymaxx(ll rt,ll l,ll r,ll nl,ll nr){
        if(nl<=l&&r<=nr){
            return maxx[rt];
        }
        ll ans=0;
        ll mid=(l+r)>>1;
        pushdown(rt,l,r);
        if(nl<=mid) ans=max(ans,querymaxx(rt<<1,l,mid,nl,nr));
        if(nr>mid) ans=max(ans,querymaxx(rt<<1|1,mid+1,r,nl,nr));
        return ans;
    }
    inline ll queryminn(ll rt,ll l,ll r,ll nl,ll nr){
        if(nl<=l&&r<=nr){
            return minn[rt];
        }
        ll ans=INF;
        ll mid=(l+r)>>1;
        pushdown(rt,l,r);
        if(nl<=mid) ans=min(ans,queryminn(rt<<1,l,mid,nl,nr));
        if(nr>mid) ans=min(ans,queryminn(rt<<1|1,mid+1,r,nl,nr));
        return ans;
    }
    inline ll querysum(ll rt,ll l,ll r,ll nl,ll nr){
         if(nl<=l&&r<=nr){
            return sum[rt];
        }
        ll ans=0;
        ll mid=(l+r)>>1;
        pushdown(rt,l,r);
        if(nl<=mid) ans+=querysum(rt<<1,l,mid,nl,nr);
        if(nr>mid) ans+=querysum(rt<<1|1,mid+1,r,nl,nr);
        return ans;       
    }
}tree;
ll dp[400000];
int main(){
	int n,k;
	cin>>n>>k;
	ll ans=0;
	vector<int> a(n+1);
	rep(i,1,n){
		 cin>>a[i],a[i]++;
	}
	tree.buildtree(1,1,300001);
	rep(i,1,n){
		int l=max(1,a[i]-k);
		int r=min(300001,a[i]+k);
		int tp=dp[a[i]];
		//cout<<"now: "<<tree.querymaxx(1,1,300001,l,r)<<endl;
		dp[a[i]]=max(dp[a[i]],tree.querymaxx(1,1,300001,l,r)+1);
		//cout<<i<<' '<<a[i]<<' '<<dp[a[i]]<<endl;
		tree.modify(1,1,300001,a[i],a[i],dp[a[i]]-tp);
		ans=max(ans,dp[a[i]]);
	}
	cout<<ans<<endl;
	return 0;
}

Measured memory_bytes: 39572