#include <bits/stdc++.h>
// #include <boost/multiprecision/cpp_ll.hpp>

#define rep(i,a,b) for(ll i=a;i<b;i++)
#define rrep(i,b,a) for(ll i=b;i>=a;i--)
#define fori(a) for(auto i : a )
#define all(a) begin(a), end(a)
#define set(a,b) memset(a,b,sizeof(a))
#define sz(a) a.size()
double pi=acos(-1);
#define ll long long
#define ull unsigned long long
#define pb push_back
#define PF push_front //deque
// #define mp make_pair
#define pq priority_queue
const ll mod=1000000007;
#define f first
#define s second
#define pii pair< ll, ll >
#define vi vector<ll>
#define vpii vector<pii>
#define debug(v) for(auto i:v) cout<<i<<" ";
#define tc ll t; cin >> t; while(t--)

// using namespace boost::multiprecision;
using namespace std;
void optimizeIO(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
}
//
//
// const ll N=1000005;
// ll fact[N],invfact[N];
// ll power(ll x,ll y){
//   if(y<=0) return 1LL;
//   ll z=power(x,y/2);
//   if(y%2) return (((z*z)%mod)*x)%mod;
//   return (z*z)%mod;
// }
//
// void pre(){
//   fact[0]=invfact[0]=invfact[1]=fact[1]=1;
//   rep(i,2,N) fact[i]=(i*fact[i-1])%mod;
//   rep(i,2,N) invfact[i]=(invfact[i-1]*power(i,mod-2))%mod;
// }
// ll nCr(ll n,ll k){ return (((fact[n]*invfact[n-k])%mod)*invfact[k])%mod; }
//
//
//
// const ll N1=1e6+1;
// vector<ll> isprime(N1,1),prime;
// void seive(){
//   rep(i,2,sqrt(N1)+1){
//       if(isprime[i]){
//         for(ll j=i*i;j<N1;j+=i) isprime[j]=0;
//         prime.pb(i);
//       }
//   }
//   rep(i,sqrt(N1)+1,N1) if(isprime[i]) prime.pb(i);
// }
//
//
//
// struct dsu {
//     vector<ll> par, rank;
//     dsu(ll n): par(n+1), rank(n+1) {
//         for (ll i = 0; i <= n; i++) {
//             par[i] = i;
//             rank[i]= 1;
//         }
//     }
//     ll root(ll a) {
//         if (a == par[a]) return a;
//         return par[a] = root(par[a]);
//     }
//     void merge(ll a, ll b) {
//         a = root(a);
//         b = root(b);
//         if (a == b) return;
//         if (rank[a] > rank[b]) swap(a, b);
//         par[b] = a;
//     }
//     set<ll> parent(ll n){
//         set<ll> s;
//         for(ll i=1;i<=n;i++){
//             s.insert(root(i));
//         }
//         return s;
//     }
// };

struct tree_node{
    ll mx;
};
const ll N2=300005;
ll A[N2];
tree_node tree[N2*4];
tree_node merge(tree_node &l,tree_node &r){
    tree_node result;
    result.mx=max(l.mx,r.mx);
    return result;
}
void build_tree(ll node,ll l,ll r){
    if(l==r) {tree[node].mx=A[l]; return;}
    build_tree(node*2, l, (l+r)/2);
    build_tree(node*2+1, 1+(l+r)/2, r);
    tree[node]=merge(tree[2*node],tree[node*2+1]);
}

tree_node query(ll node,ll l,ll r,ll x,ll y){
    if(l==x && r==y) return tree[node];
    ll mid=(l+r)/2;
    if(x>mid) return query(2*node+1,mid+1,r,x,y);
    if(y<=mid) return query(2*node,l,mid,x,y);

    tree_node w=query(2*node,l,mid,x,mid);
    tree_node z=query(2*node+1,mid+1,r,mid+1,y);
    tree_node result=merge(w,z);
    return result;
}
void update(ll node,ll l,ll r,ll x,ll val){
    if(l==r) {tree[node].mx=val; return;}
    if (x <= (l+r)/2LL)
        update(2*node, l, (l+r)/2LL, x, val);
    else
        update(2*node+1, (l+r)/2LL+1, r, x, val);
    tree[node].mx=max(tree[2*node].mx,tree[node*2+1].mx);
    // cout<<node<<" "<<tree[node].mx<<endl;
}
void solve(){
  ll n,k;
  cin>>n>>k;
  ll x;
  build_tree(1,0,N2-1);
  rep(i,0,n){
    cin>>x;
    ll l=max(0LL,x-k),r=min(N2-1,x+k);
    ll z=query(1,0,N2-1,l,r).mx;
    // cout<<z<<endl;
    update(1,0,N2-1,x,z+1);
    ll z1=query(1,0,N2-1,l,r).mx;
  }
  ll mx=0;
  rep(i,0,4*N2) mx=max(mx,tree[i].mx);
  cout<<mx<<endl;
}

int main(){
    optimizeIO();
    {solve();}
}


Measured memory_bytes: 11852