#include<bits/stdc++.h>
#define all(x) (x).begin(),(x).end()
#define ll long long
#define P pair<int,int>
#define rep(i,n) for(int i = 0; i < int(n); i++)
#define vi vector<int>
using namespace std;
const int INF = 1001001001;
const int MOD = 1e9+7;
template<class T> inline bool chmax(T &a, const T &b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T &a, const T &b){ if(b<a){ a=b; return 1; } return 0; }

// segtree：[0,n-1] について、区間ごとの最小値を管理する構造体
// set(int i, T x), build(): i番目の要素をxにセット。まとめてセグ木を構築する。O(n)
// update(i,x): i 番目の要素を x に更新。O(log(n))
// query(a,b): [a,b) での最小の要素を取得。O(log(n))
// find_rightest(a,b,x): [a,b) で x以下の要素を持つ最右位置を求める。O(log(n))
// find_leftest(a,b,x): [a,b) で x以下の要素を持つ最左位置を求める。O(log(n))
template <typename T>
struct segtree{
  // const T e = numeric_limits<T>::max();
  // function<T(T, T)> fx = [](T x1, T x2) -> T { return min(x1, x2); };
  const T e = 0;
  function<T(T, T)> fx = [](T x1, T x2) -> T { return max(x1, x2); };
  int n;
  vector<T> dat;
  segtree(int n_) : n(), dat(n_*4, e){
    int x = 1;
    while(x < n_){
      x *= 2;
    }
    n = x;
  }
  void set(int i, T x){ dat[i+n-1] = x; }
  void build(){
    for(int k = n-2; 0 <= k; k--) dat[k] = fx(dat[2*k+1], dat[2*k+2]);
  }
  void update(int i, T x){
    i += n - 1;
    dat[i] = x;
    while(0 < i){
      i = (i-1)/2;  // parent
      dat[i] = fx(dat[i*2+1], dat[i*2+2]);
    }
  }
  // the minimum element of [a,b)
  T query(int a, int b){ return query_sub(a, b, 0, 0, n); }
  T query_sub(int a, int b, int k, int l, int r){
    if(r <= a || b <= l){
      return e;
    }else if(a <= l && r <= b){
      return dat[k];
    }else{
      T vl = query_sub(a, b, k*2+1, l, (l+r)/2);
      T vr = query_sub(a, b, k*2+2, (l+r)/2, r);
      return fx(vl, vr);
    }
  }
  int find_rightest(int a, int b, T x){ return find_rightest_sub(a, b, x, 0, 0, n); }
  int find_leftest(int a, int b, T x){ return find_leftest_sub(a, b, x, 0, 0, n); }
  int find_rightest_sub(int a, int b, T x, int k, int l, int r){
    if(x < dat[k] || r <= a || b <= l){  // 自分の値がxより大きい or [a,b)が[l,r)の範囲外ならreturn a-1
      return a-1;
    }else if(n-1 <= k){  // 自分が葉ならその位置をreturn
      return (k - (n-1));
    }else{
      int vr = find_rightest_sub(a, b, x, 2*k+2, (l+r)/2, r);
      if (vr != a-1){  // 右の部分木を見て a-1 以外ならreturn
        return vr;
      }else{  // 左の部分木を見て値をreturn
        return find_rightest_sub(a, b, x, 2*k+1, l, (l+r)/2);
      }
    }
  }
  int find_leftest_sub(int a, int b, T x, int k, int l, int r){
    if(x < dat[k] || r <= a || b <= l){  // 自分の値がxより大きい or [a,b)が[l,r)の範囲外ならreturn b
      return b;
    }else if(n-1 <= k){  // 自分が葉ならその位置をreturn
      return(k - (n-1));
    }else{
      int vl = find_leftest_sub(a, b, x, 2*k+1, l, (l+r)/2);
      if(vl != b){  // 左の部分木を見て b 以外ならreturn
        return vl;
      }else{  // 右の部分木を見て値をreturn
        return find_leftest_sub(a, b, x, 2*k+2, (l+r)/2, r);
      }
    }
  }
};

int main(){
  cin.tie(0), ios::sync_with_stdio(false);
  int n,k; cin >> n >> k;
  vi a(n); rep(i,n) cin >> a[i];
  segtree<int> seg(300005);
  int ans = 0;
  rep(i,n){
    int l = max(a[i]-k,0);
    int r = min(a[i]+k,300000);
    int tmp = seg.query(l,r+1)+1;
    chmax(ans,tmp);
    seg.update(a[i],tmp);
  }
  cout << ans;
  cout << endl;
  return 0;
}


Measured memory_bytes: 8996