#include <bits/stdc++.h>
using namespace std;

#define int long long
#define ff first
#define ss second
#define endl "\n"
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x.size())
int powmod(int a,int l, int md){a%=md; int res=1;while(l){if(l&1)res=res*a%md;l/=2;a=a*a%md;}return res;}
int binpow(int a,int l){int res=1;while(l){if(l&1)res=res*a;l/=2;a=a*a;}return res;}
int invmod(int a, int md){return powmod(a,md-2,md);}
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
typedef vector<int> vi; typedef pair<int, int> ii; typedef vector< ii > vii;
#define pb push_back
int __set(int b, int i) {return b|(1LL<<i);} //set ith bit
int __unset(int b, int i) {return b&(~(1UL<<i));}
int __check(int b, int i) {return b&(1LL<<i);} //returns 0 if ith bit is 0
int mulmod(int a, int b, int md) {return (((a%md)*(b%md))%md+md)%md;}
int addmod(int a, int b, int md) {return ((a%md+b%md)%md+md)%md;}
int submod(int a, int b, int md) {return (((a%md-b%md)%md)+md)%md;}
int divmod(int a, int b, int md) {return mulmod(a, powmod(b, md-2, md), md);} //if md is prime;
const ll inf = 0xFFFFFFFFFFFFFFFL; //very large number
priority_queue<int, vector<int>, greater<int> > pq; //for min priority_queue
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
const int MOD = 998244353; 

class SegmentTreeMax {
private:
	int n; vii st; vi lz; vi a; //In st ss contains value and ff contains the index of the value
	void merge(int node) {
		if(st[2*node].ss >= st[2*node+1].ss)
			st[node]=st[2*node];
		else
			st[node]=st[2*node+1];
	}
	void build(int node, int lo, int hi) {
		if(lo==hi) {
			st[node]={lo,a[lo]};
			return;
		}
		build(2*node,lo,(lo+hi)/2);
		build(2*node+1,(lo+hi)/2+1,hi);
		merge(node);
	}
	void propagate(int node, int l, int r) {
		if(l!=r) {
			lz[2*node] = lz[node];
			lz[2*node+1] = lz[node];
		}
		st[node].ss = lz[node];
		lz[node]=inf;
	}
	void update(int node, int l, int r, int lo, int hi, int val) {
		if(lz[node]!=inf)
			propagate(node,l,r);
		if(hi < l || lo > r)
			return;
		if(hi >= r && lo <= l) {
			lz[node]=val;
			propagate(node,l,r);
			return;
		}
		update(2*node,l,(l+r)/2,lo,hi,val);
		update(2*node+1,(l+r)/2+1,r,lo,hi,val);
		merge(node);
	}
	ii rmq(int node, int l, int r, int lo, int hi) { //ss contains value and ff contains the index of the value
		if(lz[node]!=inf)
			propagate(node,l,r);
		if(hi < l || lo > r)
			return {-1, -inf};
		if(hi >= r && lo <= l)
			return st[node];
		ii d1 = rmq(2*node, l, (l+r)/2, lo, hi);
		ii d2 = rmq(2*node+1, (l+r)/2+1, r, lo, hi);
		if(d1.ss >= d2.ss)
			return d1;
		return d2;
	}
	int lower_bound(int node, int l, int r, int x) {
		if(lz[node]!=inf)
			propagate(node,l,r);
		if(l==r) return st[node].ff;
		if(lz[2*node]!=inf) propagate(2*node,l,(l+r)/2);
		if(lz[2*node+1]!=inf) propagate(2*node+1,(l+r)/2+1,r);
		if(st[2*node].ss >= x)
			return lower_bound(2*node,l,(l+r)/2,x);
		else
			return lower_bound(2*node+1,(l+r)/2+1,r,x);
	}
public:
	SegmentTreeMax(vi& __a) {
		n = __a.size();
		a=__a;
		st.assign(4*n,{0,0});
		lz.assign(4*n,inf);
		build(1,0,n-1);
	}
	void Update(int l, int r, int val) {return update(1,0,n-1,l,r,val);}
	ii RMQ(int l, int r) {return rmq(1,0,n-1,l,r);}
	int lowerbound(int x) {return lower_bound(1,0,n-1,x);}
};


signed main(void)
{
	IOS;
	int n,k; cin>>n>>k;
	vi a(n);
	for(int i = 0; i < n; i++)
		cin>>a[i];
	vi tmp(300010,0);
	
	tmp[a[n-1]]=1;
	SegmentTreeMax st(tmp);
	for(int i = n-2; i >= 0; i--) {
		int lo = max(a[i]-k,0ll), hi = min((ll)300000, a[i]+k);
		int mx = st.RMQ(lo,hi).ss;
		// cout<<i<<" "<<lo<<" "<<hi<<" "<<mx+1<<endl;
		st.Update(a[i],a[i],mx+1);
	}
	cout<<st.RMQ(0,300000).ss<<endl;
	return 0;
}

Measured memory_bytes: 38320