#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define FOR(i, a, b) for (int i = (a), i##_len = (b); i < i##_len; i++)
#define ALL(x) (x).begin(), (x).end()  // sortなどの引数を省略したい
#ifdef _DEBUG
#define PRE_COMMAND             \
    std::cin.rdbuf(in.rdbuf()); \
    std::cout << fixed << setprecision(15);
#else
#define PRE_COMMAND cout << fixed << setprecision(15);
#endif
const double EPS = 1e-10, PI = acos(-1.0);
template <class T> auto MAX(T& seq) {
    return *max_element(seq.begin(), seq.end());
}
template <class T> auto MIN(T& seq) {
    return *min_element(seq.begin(), seq.end());
}
template <class T> auto SUM(T& seq) {
    T temp{0};
    auto& temp2 = temp[0];
    return accumulate(seq.begin(), seq.end(), temp2);
}
template <class T> void SORT(T& seq) { sort(seq.begin(), seq.end()); }
template <class T, class S> void SORT(T& seq, S& sort_order) {
    sort(seq.begin(), seq.end(), sort_order);
}
template <class T> void SORTR(vector<T>& seq) {
    sort(seq.begin(), seq.end(), greater<T>());
}
template <class T, class S, class R> long long pow(T n_0, S k_0, R mod_0) {
    long long n = n_0 % mod_0, k = k_0, mod = mod_0, now = 1;
    while (k) {
        if (k & 1) now = (now * n) % mod;
        n = (n * n) % mod;
        k >>= 1;
    }
    return now;
}
template <typename T> istream& operator>>(istream& is, vector<T>& vec) {
    for (T& x : vec) is >> x;
    return is;
}

// e：単位元, base：元の配列, op：モノイド, tree：セグ木, depth：treeの深さ,
// basesize：baseの要素数, treesize：treeの要素数, num：treesize-basesize
// 初期値（上限とか下限）を決定
template <class S> struct segtree {
    int num, depth, basesize, treesize;
    vector<S> tree;
    using f_type = S(S, S);
    S (*op)(S a, S b);
    S e;
    // 元の配列, モノイド, 初期値
    segtree(vector<S>& base, f_type tmp2, S tmp3) : op(tmp2), e(tmp3) {
        basesize = (int)base.size(), num = 1, depth = 1;
        for (; num < basesize; num <<= 1, depth++) {}
        treesize = (--num << 1) + 1;
        tree.assign(treesize, e);
        for (int i = 0; i < basesize; ++i) { tree[i + num] = base[i]; }
        for (int i = num + basesize; i < treesize; ++i) { tree[i] = e; }
        for (int i = num - 1; i > -1; --i) {
            tree[i] = op(tree[(i << 1) + 1], tree[(i << 1) + 2]);
        }
    }
    // base[i]をsに更新してセグ木全体を更新する関数
    void set(int index, S new_value) {
        int i = index + num;
        tree[i] = new_value;
        S tmp;
        while (i) {
            if (i & 1) {
                tmp = op(tree[i], tree[i + 1]);
            } else {
                tmp = op(tree[i - 1], tree[i]);
            }
            --i >>= 1;
            if (tree[i] != tmp) {
                tree[i] = tmp;
                continue;
            }
            break;
        }
    }
    // base[i]を取得する関数
    S get(int index) { return tree[num + index]; }
    // 半開区間[lower,upper)の最小値（とか）を探す関数
    S prod(int lower, int upper) {
        S ret = e;
        int l = lower + num, r = upper + num;
        while (l < r) {
            if (!(r & 1)) ret = op(ret, tree[--r]);
            if (!(l & 1)) ret = op(ret, tree[l++]);
            l >>= 1, r >>= 1;
        }
        return ret;
    }
    // prod[0, n)を計算する関数
    S all_prod() { return tree[0]; }
    // f(op(a[l], a[l + 1], ..., a[r - 1]))を満たす最大のrを返す関数
    template <class f_type2> int max_right(f_type2 index_func, int l) {
        int pos = l + num;
        if (!index_func(tree[pos])) return l;
        S now = tree[pos];
        while (pos) {
            if (pos & 1) {
                if (!index_func(op(now, tree[pos + 1]))) {
                    pos++;
                    break;
                } else {
                    now = op(now, tree[pos + 1]);
                }
            }
            --pos >>= 1;
        }
        if (!pos) return basesize;
        while (true) {
            int tmp = (pos << 1) + 1;
            if (tmp < treesize) {
                pos = tmp;
                if (index_func(op(now, tree[pos]))) {
                    now = op(now, tree[pos++]);
                }
            } else {
                break;
            }
        }
        return pos - num;
    }
    // f(op(a[l], a[l + 1], ..., a[r - 1]))を満たす最小のlを返す関数
    template <class f_type2> int min_left(f_type2 index_func, int r) {
        int pos = r + num - 1;
        if (!index_func(tree[pos])) return r;
        S now = tree[pos];
        while (pos) {
            if (!(pos & 1)) {
                if (!index_func(op(now, tree[pos - 1]))) {
                    pos--;
                    break;
                } else {
                    now = op(now, tree[pos - 1]);
                }
            }
            --pos >>= 1;
        }
        if (!pos) return 0;
        while (true) {
            int tmp = (pos << 1) + 2;
            if (tmp < treesize) {
                pos = tmp;
                if (index_func(op(now, tree[pos]))) {
                    now = op(now, tree[pos--]);
                }
            } else {
                break;
            }
        }
        return pos - num + 1;
    }
};

int func(int a, int b) { return max(a, b); }

int main() {
    PRE_COMMAND
    int n, k;
    cin >> n >> k;
    vector<int> a(300001);
    cin >> a;
    vector<int> base(300001, 0);
    segtree<int> seg(base, func, -1);
    for (int i = 0; i < n; i++) {
        seg.set(a[i],
                seg.prod(max(a[i] - k, 0), min(a[i] + k + 1, 300001)) + 1);
    }
    cout << seg.all_prod() << endl;
}

Measured memory_bytes: 9608