/*
Author- Aasav Badera
Time- Mon Sep 28 09:58:16 2020
*/
#include<bits/stdc++.h> 
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp> 
#pragma GCC optimize("-O3")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma") 
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL  
#include <sys/resource.h>
#define meminc             rlimit rlim;if (getrlimit(RLIMIT_STACK, &rlim)) return 1;rlim.rlim_cur = 268435456;if (setrlimit(RLIMIT_STACK, &rlim)) return 2;
#else
#define meminc      
#endif
#ifdef LOCAL
#define dbg(args...)       { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
#else
#define dbg(args...)
#endif
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
    cerr << *it << " = " << a << endl;
    err(++it, args...);
}
#define ll                 int
#define vi                 vector<int >
#define ordered_set        tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// -------------------Standard Traversal Moves---------------------
// vi fx = {1 ,-1 ,0, 0}, fy = {0, 0, -1, 1};
// vi fx = {2, -2, 2, -2,  1, -1, 1, -1}, fy = {1, 1, -1, -1, 2, 2, -2, -2};
// vi fx = {1, 1, 1, -1, -1 , -1, 0, 0}, fy = {1, -1, 0, 1, -1, 0, 1, -1};
// ----------------------------------------------------------------

#define rep(i, a, b)       for(int  i=a;i<b;i++)
#define all(a)             (a).begin(),(a).end()
#define sz(x)              (int )x.size()
#define yes                cout << "YES" << endl
#define no                 cout << "NO" << endl
#define endl               '\n' 
// const int hell = (int)998244353;
const int hell = (int)1e9 + 7;
const long long int inf = 3223372036854775807;
const double PI = 3.14159265;
const int N = (int) 3e5 + 5;
int n, m, k, a[N];

struct item{
    // int m, c;
    // long long int su;
    // long long int mex, pref, suf, sum;
    int val;
    // override assignment operator and default constructor and also remember to override + operator to get merge operation sorted.
    item(){
        val = 0;
    }
    item(int ok)
    {
        val = ok;
    }
    item operator+(const item &op1)
    {
        item ret;
        ret.val = max(op1.val ,val);
        return ret;
    }
};
//O(N) preprocessing time and O(logN) query time amortized.
// take care this implementation is 0 indexed!
// segtree st;
// st.init(n);
// st.build(v);
template<class itemType, class B>
struct segtree{
    int sz;
    vector<itemType> values;
    itemType NEUTRAL_ELEMENT;
    itemType merge(itemType fi, itemType se)
    {
        // if(fi.m < se.m)
        // {
        //     return fi;
        // }
        // if(fi.m > se.m)
        // {
        //     return se;
        // }
        // return {fi.m, fi.c + se.c};
        // return {min(fi.su, se.su)};
        // return {
        //     max({fi.mex ,se.mex ,fi.suf + se.pref}),
        //     max({fi.pref, fi.sum + se.pref}),
        //     max({se.suf, se.sum + fi.suf}),
        //     fi.sum + se.sum
        // };
        return {fi.val + se.val};
    }
    
    itemType single(B val)
    {
        // if(val > 0)return {val, val, val, val};
        // return {0, 0 , 0, val};
        return {val};
    }
    inline int ri(int _gg){return _gg * 2 + 2;}
    inline int le(int _gg){return _gg * 2 + 1;}
    void init(int new_size)
    {
        sz = 1;
        while(sz < new_size)sz <<= 1;
        values.resize(sz << 1);
    }
    void build(vector<B> &v, int x, int lx, int rx)
    {
        if(rx - lx == 1)
        {
            if(lx < sz(v))
            {
                values[x] = v[lx];
            }
            return ;
        }
        int mx = (lx + rx) >> 1;
        build(v, le(x), lx, mx);
        build(v, ri(x), mx, rx);
        
        values[x] = values[le(x)] + values[ri(x)];
    }
    void build(vector<B> &v)
    {
        /****************************************************************************/
        // REMEMBER TO CHANGE IT IF OUR FIRST ARGUMENT IS NOT ITEM WHICH IS RARE THO
        // initializing neutral value
        NEUTRAL_ELEMENT = item();
        /*****************************************************************************/
        int _n = v.size();
        init(_n);
        build(v, 0, 0, sz);
    }
    void set(int i, B val, int x, int lx, int rx)
    {
        if(rx - lx == 1)
        {
            values[x] = val;
            return ;
        }
        int mx = (lx + rx) >> 1;
        if(i < mx)
        {
            set(i, val, le(x), lx, mx);
        }
        else
            set(i, val, ri(x), mx, rx);
        values[x] = values[le(x)] + values[ri(x)];
    }
    void set(int i, B val)
    {
        set(i, val, 0, 0, sz);
    }
    itemType calc(int l, int r, int x, int lx, int rx)
    {
        if(lx >= r or l >= rx)return NEUTRAL_ELEMENT;
        if(lx >= l and rx <= r)return values[x];
        int mx = (lx + rx) >> 1;
        itemType f1 = calc(l ,r ,le(x), lx, mx);
        itemType f2 = calc(l ,r ,ri(x), mx, rx);
        return f1 + f2;
    }
    itemType calc(int l, int r)
    {
        return calc(l, r, 0, 0, sz);
    }
};


int32_t main()
{
    meminc;
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cerr.precision(10);
    cout.precision(25);
    cout << fixed;
    #ifdef LOCAL
    // for getting input from input.txt
    freopen("input.txt", "r", stdin);
    // for writing output to output.txt
    freopen("output.txt", "w", stdout);
    #endif
    int tests = 1;
    // cin >> tests;
    rep(test, 1, tests+1)
    {
        cin >> n;
        cin >> k;
        vector<int> v(N, 0);
        rep(i, 0, n)
        {
        	cin >> a[i];
        }
        segtree<item, int> st;
        st.build(v);
        int dp[n];
        dp[0] = 1;
        st.set(a[0], 1);
        v[a[0]] = 1;
        int ans = 1;
        rep(i, 1, n)
        {
        	int lo = a[i] - k, hi = a[i] + k;
        	lo = max(0, lo);
        	hi = min((int)3e5, hi);
        	item qr = st.calc(lo, hi + 1);
        	dp[i] = qr.val + 1;
    		ans = max(ans, dp[i]);
    		if(v[a[i]] < dp[i]){
        		st.set(a[i], dp[i]);
        		v[a[i]] = dp[i];
    		}
        }
        cout << ans;
    }
    #ifdef LOCAL
        // cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
    #endif
    return 0;
}

Measured memory_bytes: 10836