#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <string>
#include <vector>
#include <array>
#include <algorithm>
#include <map>
#include <list>
#include <queue>
#include <set>
#include <iostream>
#include <fstream>
#include <chrono>

using namespace std;

const int DIV = 1000000007;

struct SegmentTreeInterval {
private:
    int n;
    vector<int> tsum, tmax;

    void build(const std::vector<int> &a, int v, int tl, int tr) {
        if (tl == tr) {
            tsum[v] = a[tl];
            tmax[v] = a[tl];
        }
        else {
            int tm = (tl + tr) / 2;
            build(a, v * 2, tl, tm);
            build(a, v * 2 + 1, tm + 1, tr);
            tmax[v] = max(tmax[v * 2], tmax[v * 2 + 1]);
        }
    }

    void update(int v, int tl, int tr, int l, int r, int add) {
        if (l > r)
            return;
        if (l == tl && tr == r) {
            tsum[v] += add;
            tmax[v] += add;
        }
        else {
            int tm = (tl + tr) / 2;
            update(v * 2, tl, tm, l, min(r, tm), add);
            update(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, add);
            tmax[v] = tsum[v] + max(tmax[v * 2], tmax[v * 2 + 1]);
        }
    }

    int getElem(int v, int tl, int tr, int pos) {
        if (tl == tr)
            return tsum[v];
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            return tsum[v] + getElem(v * 2, tl, tm, pos);
        else
            return tsum[v] + getElem(v * 2 + 1, tm + 1, tr, pos);
    }

    int getMax(int v, int tl, int tr, int l, int r) {
        if (l > r)
            return -INT32_MIN;
        if (l == tl && r == tr)
            return tmax[v];
        int tm = (tl + tr) / 2;
        int t1 = getMax(v * 2, tl, tm, l, min(r, tm));
        int t2 = getMax(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r);
        return tsum[v] + max(t1, t2);
    }

public:

    SegmentTreeInterval(int n) : n(n), tsum(n * 4, 0), tmax(n * 4, INT32_MIN) {
    }

    void build(const std::vector<int> &a) {
        build(a, 1, 0, n - 1);
    }

    void update(int l, int r, int add) {
        update(1, 0, n - 1, l, r, add);
    }

    int getElem(int pos) {
        return getElem(1, 0, n - 1, pos);
    }

    int getMax(int l, int r) {
        return getMax(1, 0, n - 1, l, r);
    }
};

void solve(int test, istream &in) {
    int n, k;
    in >> n >> k;
    int MAX = 300000;
    SegmentTreeInterval tree(MAX + 1);
    std::vector<int> init(MAX + 1, 0);
    vector<int> a(n);
    tree.build(init);
    for (int i = 0; i < n; i++) {
        in >> a[i];
        int from = std::max(a[i] - k, 0);
        int to = std::min(a[i] + k, MAX);
        int cnt = tree.getMax(from, to);
        int cur = tree.getElem(a[i]);
        tree.update(a[i], a[i], cnt + 1 - cur);
    }
    int result = tree.getMax(0, MAX);
    printf("%d\n", result);
}

int main(int argc, char* argv[])
{
#ifdef VLAD_LOCAL
    ifstream f("in.txt");
    auto start = std::chrono::steady_clock::now();
#else
    istream &f = cin;
#endif
    int tests = 1;
    //f >> tests;
    for (int test = 0; test < tests; test++) {
        solve(test, f);
    }
#ifdef VLAD_LOCAL
    auto end = std::chrono::steady_clock::now();
    double seconds = (double)std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() / 1000;
    printf("%.3lf\n", seconds);
#endif
    return 0;
}


Measured memory_bytes: 15264