#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
using namespace std;

#pragma region Macros
using ll = long long;
#define int ll
using pii = pair<int, int>;
using tiii = tuple<int, int, int>;
template<class T = ll> using V = vector<T>;
template<class T = ll> using VV = V<V<T>>;
#define IOS\
    ios::sync_with_stdio(false);\
    cin.tie(0);\
    cout.tie(0);
#define FOR(i,l,r) for(ll i=(l);i<(r);++i)
#define REP(i,n) FOR(i,0,n)
#define REPS(i,n) FOR(i,1,n+1)
#define RFOR(i,l,r) for(ll i=(l);i>=(r);--i)
#define RREP(i,n) RFOR(i,n-1,0)
#define RREPS(i,n) RFOR(i,n,1)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(),(x).end()
#define SORT(name) sort(name.begin(), name.end())
#define RSORT(name)\
    SORT(name);\
    reverse(all(name));
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
inline void Yes(bool b = true) {cout << (b ? "Yes" : "No") << '\n';}
inline void YES(bool b = true) {cout << (b ? "YES" : "NO") << '\n';}
template <class T> inline void print(T x){ cout << x << '\n';}
template<typename T1,typename T2> inline void chmin(T1 &a, T2 b){ if(a > b) a = b; }
template<typename T1,typename T2> inline void chmax(T1 &a, T2 b){ if(a < b) a = b; }

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
#pragma endregion

#if 1
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const int MOD = 1000000007;
const int MAX_N = 300010;

// 配列 [0, N) について、ある範囲 [lb, ub) のうち
// まだ利用していない要素があるなら、その要素のうち
// 一番インデックスが小さいものを返す
// 愚直に実装すると O(N) だが、このクラスなら O(log N) で発見できる
class UsedChecker {
    private:
        class BITreeImpl {
            public:
                BITreeImpl() {}
                BITreeImpl(int n) { Init(n); }
                void Init(int n) {
                    m_N = n + 1;
                    m_Tree.assign(m_N, 0);
                }
                int Sum(int i) {
                    int s = 0;
                    while(i > 0) { s += m_Tree[i]; i -= i & -i; }
                    return s;
                }
                int Sum(int i, int j) { return Sum(j) - Sum(i-1); }
                void Add(int i, int x){ while(i < m_N) { m_Tree[i] += x; i += i & -i; } }
            private:
                int m_N;
                vector<int> m_Tree;
        };

    public:
        UsedChecker(){}
        UsedChecker(int n) { Init(n); }
        void Init(int n) {
            bitree.Init(n);
            for(int i = 1; i <= n; ++i) { bitree.Add(i, 1); }
        }

        // [lb, ub] 内のまだ使われていない要素で
        // 一番インデックスが小さいものを返す
        // ない場合は -1 を返す
        // O(log log N)
        int GetUnUsed(int lb, int ub) {
            if(lb > ub) { return -1; }
            if(bitree.Sum(lb+1, ub+1) <= 0) { return -1; }
            while(ub - lb > 1) {
                int mid = (lb + ub) / 2;
                if(bitree.Sum(lb+1, mid+1) > 0) { ub = mid; }
                else { lb = mid; }
            }
            if(bitree.Sum(lb+1, lb+1) > 0) { return lb; }
            return ub;
        }

        // インデックス ind を使用済みとしてマークします
        // O(log N)
        void SetToUsed(int ind) {
            int val = bitree.Sum(ind+1, ind+1);
            assert(val == 0 || val == 1);
            if(val == 1) { bitree.Add(ind+1, -1); }
        }

        // インデックス ind を未使用としてマークします
        // O(log N)
        void SetToUnUsed(int ind) {
            int val = bitree.Sum(ind+1, ind+1);
            assert(val == 0 || val == 1);
            if(val == 0) { bitree.Add(ind+1, 1); }
        }

    private:
        BITreeImpl bitree;
};

int N, K;
V<> A;

UsedChecker uc;
int dp[MAX_N];

int dfs(int i) {
    uc.SetToUsed(i);
    if(i >= N) { return 1; }
    int& ret = dp[i];
    if(~ret) { return ret; }
    ret = 0;
    for(int j = i + 1; j < N;) {
        int next_j = uc.GetUnUsed(j, N - 1);
        if(next_j < 0) { break; }
        if(abs(A[i] - A[next_j]) <= K) {
            chmax(ret, dfs(next_j) + 1);
        }
        j = next_j;
    }
    return ret;
}

signed main() {
    IOS;


    cin >> N >> K;
    A.resize(N);
    REP(i, N) {
        cin >> A[i];
    }

    uc.Init(N);

    MINUS(dp);
    int ans = 0;
    for(int i = 0; i < N;) {
        chmax(ans, dfs(i) + 1);
        int next_i = uc.GetUnUsed(i + 1, N - 1);
        if(next_i < 0) { break; }
        i = next_i;
    }
    print(ans);

    return 0;
}
