#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <iostream>
using namespace std;

#define int long long int
#define all(x) (x).begin(), (x).end()
#define removeDuplicates(a) a.resize(unique(all(a))-a.begin())
#define endl '\n'

class segtree{
	int sz;
	vector<int>val;
	vector<int>opt;
	vector<int>cnt;
	int NOP=0;
	int NEU=0;

public:

	segtree (int n){
		sz=1;
		while(sz<n){
			sz = sz*2;
		}
		val.assign(2*sz,NEU);
		opt.assign(2*sz,0LL);
		cnt.assign(2*sz,0LL);
	}

	// void build(vector<int>&a,int n,int curr,int left,int right){
	// 	if(right-left==1){ 
	// 		if(left<n){
	// 			cnt[curr]=1;
	// 			val[curr]=a[left];
	// 		}
	// 		return;
	// 	}
	// 	int mid=(left+right)/2;
	// 	build(a,n,2*curr+1,left,mid);
	// 	build(a,n,2*curr+2,mid,right);
	// 	cnt[curr]=cnt[2*curr+1]+cnt[2*curr+2];
	// 	val[curr]=val[2*curr+1]+val[2*curr+2];
	// }
	// void build(vector<int>&a,int n){
	// 	build(a,n,0,0,sz);
	// }

	// void propogate(int curr,int left,int right){
	// 	if((right-left)==1){
	// 		return;
	// 	}
	// 	if(opt[curr]!=NOP){
	// 		opt[2*curr+1]+=opt[curr];
	// 		val[2*curr+1]+=opt[curr]*cnt[2*curr+1];
	// 		opt[2*curr+2]+=opt[curr];
	// 		val[2*curr+2]+=opt[curr]*cnt[2*curr+2];
	// 		opt[curr]=NOP;
	// 	}
	// }

	void updateRange(int l,int r,int value,int curr,int left,int right){
		if(left>=r || right<=l){
			return;
		}
		// propogate(curr,left,right);
		if(left>=l && right<=r){
			opt[curr]+=value;
			val[curr]+=value*cnt[curr];
			return;
		}
		int mid=(left+right)/2;
		updateRange(l,r,value,2*curr+1,left,mid);   
		updateRange(l,r,value,2*curr+2,mid,right);
		val[curr]=max(val[2*curr+1],val[2*curr+2]);
	}
	void updateRange(int l,int r,int value){
		updateRange(l,r,value,0,0,sz);
	}

	void updateIndex(int i,int value,int curr,int left,int right){
		if(right-left==1){
			val[curr]=max(value,val[curr]);
			return;
		}
		int mid=(left+right)/2;
		if(i<mid){
			updateIndex(i,value,2*curr+1,left,mid);
		}else{
			updateIndex(i,value,2*curr+2,mid,right);
		}   
		val[curr]=max(val[2*curr+1],val[2*curr+2]);
	}
	void updateIndex(int i,int value){
		updateIndex(i,value,0,0,sz);
	}

	// int queryIndex(int i,int curr,int left,int right){
	// 	if(right-left==1){
	// 		return val[curr];
	// 	}		
	// 	propogate(curr,left,right);
	// 	int mid=(left+right)/2;
	// 	if(i<mid){
	// 		return queryIndex(i,2*curr+1,left,mid);
	// 	}else{
	// 		return queryIndex(i,2*curr+2,mid,right);
	// 	}
	// }
	// int queryIndex(int i){
	// 	return queryIndex(i,0,0,sz);
	// }

	int queryRange(int l,int r,int curr,int left,int right){
		if(left>=r || right<=l){
			return NEU;
		}
		// propogate(curr,left,right);
		if(left>=l && right<=r){
			return val[curr];
		}
		int mid=(left+right)/2;
		int c1=queryRange(l,r,2*curr+1,left,mid);
		int c2=queryRange(l,r,2*curr+2,mid,right);
		return max(c1,c2);
	}
	int queryRange(int l,int r){
		return queryRange(l,r,0,0,sz);
	}
};

void solve(){
	int n,k;
	cin>>n>>k;
	vector<int>a(n);
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	segtree st(300001);
	int ans=1;
	for(int i=0;i<n;i++){
		int l=max(0LL,a[i]-k);
		int r=min(300000LL,a[i]+k);
		int val=st.queryRange(l,r+1);
		ans=max(ans,val+1);
		st.updateIndex(a[i],val+1);
	}
	cout<<ans<<endl;
}

int32_t main(){

	//remove for interactive problems
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	solve();
	cerr<<"Time : "<<1000*((double)clock())/(double)CLOCKS_PER_SEC<<"ms\n";

	return 0;
}

Measured memory_bytes: 30120