#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 

using namespace __gnu_pbds; 
using namespace std;

#define int           long long
#define S             second
#define F             first
#define pb            push_back
#define all(c)        (c).begin(),(c).end()
#define rall(c)       (c).rbegin(),(c).rend() 
#define lb            lower_bound
#define ub            upper_bound
#define si(c)         (int)((c).size())
#define lcm(a, b)      (a * (b / __gcd(a,b)))  
#define inf           (int)(4e18)
#define endl          '\n'
#define mp            make_pair
#define time(s)       (double(clock()-s)/double(CLOCKS_PER_SEC))
#define debug(args...)    _F(#args, args)
#define vi            std::vector<int>
#define pii           pair<int, int> 
#define vpi           vector<pii>
#define ordered_set   tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 

clock_t start;
mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());

template<typename T> void _F(const char *name, T arg1){ cerr << name << " = " << arg1 << endl;}
template<typename T, typename... Args> void _F(const char *names, T arg1, Args... args)
{ const char *name = strchr(names, ',');cerr.write(names, name-names) << " = " << arg1 << endl;_F(name+2, args...);}

template< typename T1, typename T2 > istream& operator>>(istream& in, pair<T1, T2> &q){ in >> q.F >> q.S; return in;}
template< typename T1, typename T2 > ostream& operator<<(ostream& out, pair<T1, T2> &q){ out << q.F << " " << q.S; return out;}
template< typename T1, typename T2 > pair<T1, T2> operator+(pair<T1, T2> p1, pair<T1, T2> p2){ return {p1.F+p2.F, p1.S+p2.S};}
template< typename T1, typename T2 > pair<T1, T2> operator-(pair<T1, T2> p1, pair<T1, T2> p2){ return {p1.F-p2.F, p1.S-p2.S};}
template< typename T1, typename T2 > bool operator<(pair<T1, T2> p1, pair<T1, T2> p2){ return p1 < p2 ;}

template<typename T> void Unique(vector<T> &v) {
    sort(all(v)), v.resize(distance(v.begin(), unique(all(v))));
}

const int N = 3e5+1;

struct SegNorm {
	std::vector<int> t;
	int s, e;
	SegNorm(int n) {
		s = 0, e = n-1; // want start from 1 set s = 1;
		t.resize(n*4+1);
	}
	int combine(int x, int y) {
		return max(x, y); // write your condition
	}
	void build(int 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] = combine(t[v*2], t[v*2+1]);
	    }
	}
	int query(int v, int tl, int tr, int l, int r) {
		if(l > r) return 0; // write your own
	    if (l == tl && r == tr) return t[v];
	    int tm = (tl + tr) / 2;
	    return combine(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, int new_val) {
	    if (tl == tr) t[v] = max(new_val, t[v]);
	    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] = combine(t[v*2], t[v*2+1]);
	    }
	}
	int last(int v, int tl, int tr, int l, int r) {
	    if(t[v] == 0) return -1;// write your condition
	    if (tr == tl) return tl;
	    int tm = (tl + tr) / 2;
	    int ll = last(v*2+1, tm+1, tr, max(l, tm+1), r);
	    if(ll != -1) return ll;
	    return last(v*2, tl, tm, l, min(r, tm));
	}
	int first(int v, int tl, int tr, int l, int r) {
	    if(t[v] == 0) return -1; // write your condition 
	    if (tr == tl) return tl;
	    int tm = (tl + tr) / 2;
	    int ll = first(v*2, tl, tm, l, min(r, tm));
	    if(ll != -1) return ll;
	    return first(v*2+1, tm+1, tr, max(l, tm+1), r);
	}
	int query(int l, int r) {
		if(l > r) return 0; // write your own
		assert(l >= s && r <= e);
		return query(1, s, e, l, r); // 0 base indexing
	}
	int last(int l, int r) {
		if(l > r) return -1; // write your own
		assert(l >= s && r <= e);
		return last(1, s, e, l, r); // 0 base indexing
	}
	int first(int l, int r) {
		if(l > r) return -1; // write your own
		assert(l >= s && r <= e);
		return first(1, s, e, l, r); // 0 base indexing
	}
	void update(int pos, int x) {
		assert(pos >= s && pos <= e);
		update(1, s, e, pos, x);// 0 base indexing
	}
};


void solve() {
	int n, k;
	cin >> n >> k;

	int dp[n], ans = 0;
	SegNorm sg(N);

	for(int i = 0; i < n; i++) {
		int x;
		cin >> x;
		dp[i] = sg.query(max(x-k, 0LL), x);
		dp[i] = max(dp[i], sg.query(x, min(x+k, N-1)));
		dp[i]++;
		sg.update(x, dp[i]);
		ans = max(ans, dp[i]);
	}

	cout << ans << endl;
}

signed main(){

    ios_base::sync_with_stdio(0); 
    cin.tie(0); cout.tie(0);   
    start = clock(); 


    int test = 1;
    // cin >> test;
    
    cout << fixed << setprecision(2);
     
    for(int i = 1; i <= test; ++i){
    	solve();
    }

    cerr << time(start);
    return 0;
}


Measured memory_bytes: 15152