#include <bits/stdc++.h>
template <typename T, typename E>
struct LazySegmentTree {
 private:
  typedef std::function<T(T, T)> F;
  typedef std::function<T(T, E)> G;
  typedef std::function<E(E, E)> H;
  typedef std::function<E(E, int)> P;
  int n;
  F cal;
  G upd;
  H ecal;
  P rcal;
  std::vector<T> init;
  T initv;
  E opinit;
  std::vector<T> node;
  std::vector<E> lazy;

 public:
  explicit LazySegmentTree(
      int sz, F cal, G upd, H ecal, P rcal = [](T a, int b) { return a; },
      std::vector<T> init = std::vector<T>(1, 0), E opinit = 0)
      : cal(cal), upd(upd), ecal(ecal), rcal(rcal), init(init), opinit(opinit) {
    n = 1;
    initv = init[0];
    while (n < sz) n = n * 2;
    node.resize(static_cast<unsigned int>(2 * n - 1), init[0]);
    for (int i = 0; i < sz; ++i) node[i + n - 1] = init[i + 1];
    for (int i = n - 2; i >= 0; --i)
      node[i] = cal(node[2 * i + 1], node[2 * i + 2]);
    lazy.resize(static_cast<unsigned int>(2 * n - 1), opinit);
    for (int i = 0; i < sz; ++i) lazy[i + n - 1] = opinit;
    for (int i = n - 2; i >= 0; --i)
      lazy[i] = ecal(lazy[2 * i + 1], lazy[2 * i + 2]);
  }
  explicit LazySegmentTree(
      int sz, F cal, G upd, H ecal, P rcal = [](T a, int b) { return a; },
      T initv = 0, E opinit = 0)
      : cal(cal),
        upd(upd),
        ecal(ecal),
        rcal(rcal),
        initv(initv),
        opinit(opinit) {
    n = 1;
    while (n < sz) n = n * 2;
    node.resize(static_cast<unsigned int>(2 * n - 1), initv);
    for (int i = 0; i < sz; ++i) node[i + n - 1] = initv;
    for (int i = n - 2; i >= 0; --i)
      node[i] = cal(node[2 * i + 1], node[2 * i + 2]);
    lazy.resize(static_cast<unsigned int>(2 * n - 1), opinit);
    for (int i = 0; i < sz; ++i) lazy[i + n - 1] = opinit;
    for (int i = n - 2; i >= 0; --i)
      lazy[i] = ecal(lazy[2 * i + 1], lazy[2 * i + 2]);
  }
  void update(int p, int q, E val, int k = 0, int l = 0, int r = -1) {
    if (r < 0) r = n;
    eval(k, r - l);
    if (r <= p || l >= q) return;
    if (p <= l && r <= q) {
      lazy[k] = ecal(lazy[k], val);
      eval(k, r - l);
    } else {
      update(p, q, val, 2 * k + 1, l, (l + r) / 2);
      update(p, q, val, 2 * k + 2, (l + r) / 2, r);
      node[k] = cal(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  T query(int p, int q, int k = 0, int l = 0, int r = -1) {
    if (r < 0) r = n;
    if (r <= p || l >= q) return initv;
    eval(k, r - l);
    if (p <= l && r <= q) return node[k];
    T vl = query(p, q, 2 * k + 1, l, (l + r) / 2);
    T vr = query(p, q, 2 * k + 2, (l + r) / 2, r);
    return cal(vl, vr);
  }
  void eval(int k, int len) {
    if (lazy[k] == opinit) return;
    node[k] = upd(node[k], rcal(lazy[k], len));
    if (k < n - 1) {
      lazy[2 * k + 1] = ecal(lazy[2 * k + 1], lazy[k]);
      lazy[2 * k + 2] = ecal(lazy[2 * k + 2], lazy[k]);
    }
    lazy[k] = opinit;
  }
};
using namespace std;
using ll = long long;
int main() {
  int n, k;
  cin >> n >> k;
  LazySegmentTree<int, int> st(
      300001 + k, [](int a, int b) { return max(a, b); },
      [](int a, int b) { return a + b; }, [](int a, int b) { return a + b; },
      [](int a, int b) { return a; }, 0, 0);
  for (int i = 0; i < n; ++i) {
    int a;
    cin >> a;
    int t = st.query(max(0, a - k), a + k);
    st.update(a, a + 1, t + 1);
  }
  cout << st.query(0, 300001 + k) << endl;
  return 0;
}
