#include <bits/stdc++.h>
using namespace std;
const int64_t MAXN = (int64_t)3e5 + 2;
const int64_t INF = numeric_limits<int64_t>::max() >> 1;
const int64_t MOD = (int64_t)1000000007;
struct lazy_segment_tree {
  using it_type = long long;
  int64_t n;
  vector<it_type> it;
  vector<long long> lz;
  const it_type FAILED_STAGE = -INF;
  void init(int64_t _) {
    n = _;
    it.resize((n << 2) | 1, -INF);
    lz.resize((n << 2) | 1, -INF);
  }
  it_type merge(it_type a, it_type b) { return max(a, b); }
  void lazy(int64_t u, int64_t l, int64_t r) {
    if (lz[u] == -INF) return;
    it[u] = max(it[u], lz[u]);
    if (l != r) {
      lz[u << 1] = max(lz[u << 1], lz[u]);
      lz[(u << 1) | 1] = max(lz[(u << 1) | 1], lz[u]);
    }
    lz[u] = -INF;
  }
  void update(int64_t u, int64_t l, int64_t r, int64_t L, int64_t R,
              int64_t val) {
    if (R < L) return;
    lazy(u, l, r);
    if (l > R || r < L) return;
    if (L <= l && r <= R) {
      lz[u] = val;
      lazy(u, l, r);
      return;
    }
    update(u << 1, l, ((l + r) >> 1), L, R, val);
    update((u << 1) | 1, ((l + r) >> 1) + 1, r, L, R, val);
    it[u] = merge(it[u << 1], it[(u << 1) | 1]);
  }
  it_type get(int64_t u, int64_t l, int64_t r, int64_t L, int64_t R) {
    if (l > R || r < L) return FAILED_STAGE;
    lazy(u, l, r);
    if (L <= l && r <= R) return it[u];
    return merge(get(u << 1, l, ((l + r) >> 1), L, R),
                 get((u << 1) | 1, ((l + r) >> 1) + 1, r, L, R));
  }
};
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  lazy_segment_tree tr;
  int64_t n, k;
  cin >> n >> k;
  tr.init(300000);
  vector<int64_t> a(n + 1);
  for (int64_t i = 1; i <= n; i++) cin >> a[i];
  for (int64_t i = n; i >= 1; i--) {
    int64_t lf = a[i] - k;
    if (lf < 0) lf = 0;
    int64_t rt = a[i] + k;
    if (rt > 300000) rt = 300000;
    int64_t d = tr.get(1, 1, n, lf, rt);
    if (d < 0) d = 0;
    d++;
    tr.update(1, 1, n, a[i], a[i], d);
  }
  cout << tr.get(1, 1, 300000, 0, 300000);
}
