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

#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define pb push_back
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define S(x) (int)(x).size()
#define L(x) (int)(x).length()
#define ld long double
#define mem(x,y) memset(x,y,sizeof x)

#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int , null_type , less<int> , rb_tree_tag , tree_order_statistics_node_update> ordered_set;

const int mod = 1e9+7;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;

template<class T>
struct segtree_max
{
	vector<T> t;
	T bound;
	
	segtree_max(int a, T val)
	{
		this->bound = val;
		t.assign(4*a,bound);
	}
	
	void build(T a[], int v, int tl, int tr) 
	{
		if (tl == tr) t[v] = a[tl];
		else 
        {
			int tm = (tl + tr) / 2;
			build(a, v*2, tl, tm);
			build(a, v*2+1, tm+1, tr);
			t[v] = max(t[v*2], t[v*2+1]);
		}
	}
	
	T query(int v, int tl, int tr, int l, int r) 
	{
		if (l > r) return bound;
		if (l == tl && r == tr) return t[v];
		int tm = (tl + tr) / 2;
		return max(query(v*2, tl, tm, l, min(r, tm)), query(v*2+1, tm+1, tr, max(l, tm+1), r));
	}
	
	void update(int v, int tl, int tr, int pos, T new_val) 
	{
		if (tl == tr) t[v] = new_val;
		else 
		{	
			int tm = (tl + tr) / 2;
			if (pos <= tm) update(v*2, tl, tm, pos, new_val);
			else update(v*2+1, tm+1, tr, pos, new_val);
			t[v] = max(t[v*2], t[v*2+1]);
		}
	}
	
};
segtree_max<int> T(300009,0);
int a[300009];
int dp[300009];

void solve()
{
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i];
	int ans=0;
	for(int i=n;i>0;i--)
	{
		int l=max(1,a[i]-k);
		int r=min(n,a[i]+k);
		dp[i]=1+T.query(1,1,n,l,r);
		T.update(1,1,n,a[i],dp[i]);
		ans = max(ans,dp[i]);
	}
	cout<<ans<<'\n';
}

int main()
{
	IOS
	int t=1;
	//cin>>t;
	while(t--)
	{
		solve();
	}
}
