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

using namespace std;
using namespace __gnu_pbds; 
  
#define ll long long
#define X first
#define Y second
#define all(x) x.begin(), x.end()
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
	enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
	ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
	*this << "[";
	for (auto it = d.b; it != d.e; ++it)
		*this << ", " + 2 * (it == d.b) << *it;
	ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

const int MOD = 998244353;
const int MX = (int)3e5 + 10;

void add_self(int &x, int y, int md = MOD){x += y; if(x >= md) x -= md;}
void sub_self(int &x, int y, int md = MOD){x -= y; if(x < 0) x += md;}
void mul_self(int &x, int y, int md = MOD){x = x * 1LL * y % md;}
inline int mul(int x, int y, int md = MOD){return x * 1LL * y % md;}
inline int add(int x, int y, int md = MOD){x += y; if(x >= md) x -= md; return x;}
inline int sub(int x, int y, int md = MOD){x -= y; if(x < 0) x += md; return x;}

const int dx[] = {0, 0, -1, 1};
const int dy[] = {1, -1, 0, 0};

vector<int> read(int n, int k){
	vector<int> vec(n);
	for(int i = 0; i < k; ++i) cin >> vec[i];
	int a, b, c, d;
	cin >> a >> b >> c >> d;
	for(int i = k; i < n; ++i)
		vec[i] = (a * 1ll * vec[i - 2] + b * 1ll * vec[i - 1] + c) % d;
	return vec;
}

// Segment Tree

struct segmentTree{

  int lgn;
  std::vector<int> tree, lazy;

  segmentTree(){
    lgn = 31 - __builtin_clz(MX) + 2;
    tree.assign(1 << lgn, 0);
    lazy.assign(1 << lgn, 0);
  }

  inline void propagate_lazy(int pos, int l, int r){

      if(lazy[pos] != 0){ //get_prev_lazy_updates
      
          tree[pos] += lazy[pos];
          
          if(l != r){ // not a leaf
              lazy[2 * pos + 1] += lazy[pos];
              lazy[2 * pos + 2] += lazy[pos];
          }
          
          lazy[pos] = 0;
      }  
  }

  void update(int lx, int rx, int val, int l = 0, int r = MX - 1, int pos = 0){
      
      propagate_lazy(pos, l, r);

      if(l > r || l > rx || r < lx) return;
    
      if(l >= lx && r <= rx){ //lazy_update

          tree[pos] += val;
          
          if(l != r){
              lazy[2 * pos + 1] += val;
              lazy[2 * pos + 2] += val;
          }
          
          return;
      }

      int mid = (l + r) / 2;
      update(lx, rx, val, l, mid, 2 * pos + 1);
      update(lx, rx, val, mid + 1, r, 2 * pos + 2);
    
      tree[pos] = max(tree[2 * pos + 1], tree[2 * pos + 2]);
  }
  
  int query(int lx, int rx, int l = 0, int r = MX - 1, int pos = 0){
          
      propagate_lazy(pos, l, r);
     
      if(l > r || l > rx || r < lx) return -1; //outside
 
      if(l >= lx && r <= rx){
          return tree[pos];
      }

      int mid = (l + r) / 2;
      int lll = query(lx, rx, l, mid, 2 * pos + 1);
      int rrr = query(lx, rx, mid + 1, r, 2 * pos + 2);
    
      return max(lll, rrr);
  }
      
};
/////////////////////////////////////

void solve(){
	int n, k;
	cin >> n >> k;
	vector<int> vec(n);
	int res = 1;
	segmentTree seg;
	for(auto &x : vec){
		cin >> x;
		int best = seg.query(max(x - k, 0), min(x + k, MX - 1)) + 1;
		res = max(res, best);
		seg.update(x, x, best);
	}

	cout << res << '\n';

	return;
}

int main(){

	cin.tie(0); cout.tie(0);
	ios_base::sync_with_stdio(0);

	// freopen("input.in", "r", stdin);
	// freopen("output.out", "w", stdout);

	int t;
	t = 1;
	// cin >> t;
	// pre();
	for(int i = 1; i <= t; ++i){
		// cout << "Case #" << i << ": ";
		solve();
		// cout << '\n';
		// cout << endl;
	}

	return 0;
}