#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
using namespace std;
using namespace __gnu_pbds;
auto random_address = [] { char *p = new char; delete p; return uint64_t(p); };
const uint64_t SEED = chrono::steady_clock::now().time_since_epoch().count() * (random_address() | 1);
mt19937_64 rng(SEED);
typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll arb[1000001],x,n,k,ans;
void update(int nod,int st,int dr,int poz,int val)
{
    if(poz<st||poz>dr)
        return;
    if(poz>=st&&poz<=dr)
        arb[nod]=val;
    if(st!=dr)
    {
        int mij=(st+dr)/2;
        if(poz<=mij)
            update(nod*2,st,mij,poz,val);
        if(poz>mij)
            update(nod*2+1,mij+1,dr,poz,val);
        arb[nod]=max(arb[2*nod],arb[2*nod+1]);
    }
}
int query(int nod, int st, int dr, int a, int b)
{
    if(a<=st&&b>=dr)
        return arb[nod];
    else
    {
        int mij=(st+dr)/2;
        int ans=0;
        if(a<=mij)
            ans=max(ans,query(nod*2,st,mij,a,b));
        if(b>mij)
            ans=max(ans,query(nod*2+1,mij+1,dr,a,b));
        return ans;
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>x;
        ll st=max(0LL,x-k);
        ll dr=min(300000LL,x+k);
        ll val=query(1,0,300000,st,dr)+1;
        update(1,0,300000,x,val);
        ans=max(ans,val);
    }
    cout<<ans;
    return 0;
}
