#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <utility>
#include <set>
#include <stack>
#include <climits>
#include <cmath>
#include <iomanip>
#include <unordered_map>
#include <map>
#include <boost/multiprecision/cpp_int.hpp>

#define rep(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define rep1(i,n) for(int i=1, i##_len=(n); i<=i##_len; ++i)
#define reps(i,s,n) for(int i=s, i##_len=(n); i<i##_len; ++i)
#define all(x) (x).begin(),(x).end()
#define MEMSET(v, h) memset((v), h, sizeof(v))
typedef long long ll;
typedef long double ld;
const char sp = ' ';

using namespace boost::multiprecision;
using namespace std;

/* segtree：モノイドを管理する
    update(index,val):index番目の要素をvalに更新 O(log(n))
    query(inf,sup):[inf,sup)での最小の要素を取得 O(log(n))
    演算に合わせて以下を指定せよ:
    T_seg: モノイドの型       binary_op: 目的の二項演算
    init: 要素の初期値
*/
template <typename T_seg>
struct segtree{
    ll init;
    ll leaves;         // 葉の数
    vector<T_seg> tree; // 完全二分木の配列
    segtree(ll size_, T_seg init_) : leaves(), tree(size_*4, init_){
        //全要素を葉に持てるような完全分木の葉の数
        //leaves=Min{2^{m} | 2^{m}>size_ && m in N}
        init=init_;
        int sup_=1;
        while(size_>sup_) {
            sup_*=2;
        }
        leaves=sup_;
    }

    void update(ll index,T_seg val){
        //木全体の大きさはleaves*2-1なので
        //葉でない部分の大きさはleaves-1
        index+=leaves-1;
        tree[index]=val;
        while(index>0) {
            //親ノードの参照
            index=(index-1)/2;
            //親ノードの更新(index*2+1 or 2は逆演算を考えよ)
            tree[index]=binary_op(tree[index*2+1], tree[index*2+2]);
        }
    }
    
    //full result of [a,b)
    T_seg query(ll inf, ll sup){
        return query_sub(inf, sup, 0, 0, leaves);
    }
    //inf, supは探索区間の保持、thisnodeは完全二分木中のノード
    //right, leftはそのノードの担当する区間
    T_seg query_sub(ll inf, ll sup, ll thisnode, ll left, ll right){
        //全く含まれない区間は無いも同然
        if (right<=inf || sup<=left) return init;
        //完全に含まれる区間はそのノードでOK
        else if(inf<=left && right<=sup) return tree[thisnode];
        else{
            T_seg val_l=query_sub(inf, sup, thisnode*2+1, left, (left+right)/2);
            T_seg val_r = query_sub(inf, sup, thisnode*2+2, (left+right)/2, right);
            return binary_op(val_l, val_r);
        }
    }
    //binarey_opは型に対してモノイドをなす二項演算ならば良い
    T_seg binary_op(T_seg left, T_seg right){
        T_seg ans;
        //insert binary operation
        ans=max(left, right);
        return ans;
    }
};

int main(void){
    ll A, last=0;
    ll N, K;
    cin>>N>>K;
    segtree<ll> seg(N,0);
    rep(i, N){
        cin>>A;
        ll MAXNU=seg.query(max(A-1-K, (ll)0), min(A+K, N));
        seg.update(A-1,MAXNU+1);
        last=max(MAXNU+1, last);
    }
    cout<<last<<endl;
    return 0;
}
