#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
#ifdef __LOCAL
#define debug(x) cerr << __LINE__ << ": " << #x << " = " << (x) << '\n'
#define debugArray(x, n)                                      \
  cerr << __LINE__ << ": " << #x << " = {";                   \
  for (long long hoge = 0; (hoge) < (long long)(n); ++(hoge)) \
    cerr << ((hoge) ? "," : "") << x[hoge];                   \
  cerr << "}" << '\n'
#define debugMatrix(x, h, w)                                         \
  cerr << __LINE__ << ": " << #x << " =\n";                          \
  for (long long hoge = 0; (hoge) < (long long)(h); ++(hoge)) {      \
    cerr << ((hoge ? " {" : "{{"));                                  \
    for (long long fuga = 0; (fuga) < (long long)(w); ++(fuga))      \
      cerr << ((fuga ? ", " : "")) << x[hoge][fuga];                 \
    cerr << "}" << (hoge + 1 == (long long)(h) ? "}" : ",") << '\n'; \
  }
#else
#define debug(x) (void(0))
#define debugArray(x, n) (void(0))
#define debugMatrix(x, h, w) (void(0))
#endif

template <typename M>
struct SegmentTree {
  using T = typename M::T;

 private:
  const int n;
  vector<T> dat;

 public:
  SegmentTree() {}
  SegmentTree(int n_) : n(n_), dat(n << 1, M::ti()) {}
  SegmentTree(int n_, T v) : SegmentTree(vector<T>(n_, v)) {}
  SegmentTree(const vector<T> &v) : n(v.size()), dat(n << 1, M::ti()) {
    for (int i = 0; i < (int)v.size(); i++) dat[i + n] = v[i];
    rebuild();
  }
  void set_val(int k, T x) {
    for (dat[k += n] = x; k >>= 1;)
      dat[k] = M::f(dat[(k << 1) | 0], dat[(k << 1) | 1]);
  }
  void unsafe_set(int k, T x) { dat[k + n] = x; }
  void rebuild() {
    for (int i = n - 1; i >= 1; i--)
      dat[i] = M::f(dat[i << 1 | 0], dat[i << 1 | 1]);
  }
  void clear() { fill(dat.begin(), dat.end(), M::ti()); }
  //[l,r)
  inline T query(int l, int r) {
    T vl = M::ti(), vr = M::ti();
    for (int a = l + n, b = r + n; a < b; a >>= 1, b >>= 1) {
      if (a & 1) vl = M::f(vl, dat[a++]);
      if (b & 1) vr = M::f(dat[--b], vr);
    }
    return M::f(vl, vr);
  }
  T operator[](const int &k) const { return dat[k + n]; }

  // max{ i : check(query(l,i+1)) = true}
  template <class C>
  int find_right(const C &check, int l = 0) {
    assert(check(M::ti()));
    if (l == n) return n;
    vector<int> idl, idr;
    for (int a = l + n, b = 2 * n; a < b; a >>= 1, b >>= 1) {
      if (a & 1) idl.push_back(a++);
      if (b & 1) idr.push_back(--b);
    }
    for (auto itr = idr.rbegin(); itr != idr.rend(); itr++) idl.push_back(*itr);
    T val = M::ti();
    for (int i : idl) {
      if (!check(M::f(val, dat[i]))) {
        while (i < n) {
          i = i << 1 | 0;
          if (check(M::f(val, dat[i]))) val = M::f(val, dat[i++]);
        }
        return i - n;
      }
      val = M::f(val, dat[i]);
    }
    return n;
  }
  //   min { i : check(query(i,r)) = true }
  template <class C>
  int find_left(const C &check, int r = -1) {
    if (r < 0) r = n;
    assert(check(M::ti()));
    if (r == 0) return 0;
    vector<int> idl, idr;
    for (int a = n, b = r + n; a < b; a >>= 1, b >>= 1) {
      if (a & 1) idl.push_back(a++);
      if (b & 1) idr.push_back(--b);
    }
    for (auto itr = idl.rbegin(); itr != idl.rend(); itr++) idr.push_back(*itr);
    T val = M::ti();
    for (int i : idr) {
      if (!check(M::f(dat[i], val))) {
        while (i < n) {
          i = i << 1 | 1;
          if (check(M::f(dat[i], val))) val = M::f(dat[i--], val);
        }
        return i + 1 - n;
      }
      val = M::f(dat[i], val);
    }
    return 0;
  }
};

struct Mono {
  using T = int;
  static T ti() { return 0; }
  static T f(T vl, T vr) { return max(vl, vr); }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int N, K;
  cin >> N >> K;
  int A[N];
  for (int i = 0; i < N; i++) cin >> A[i];
  const int M = 312345;
  SegmentTree<Mono> seg(M);
  int ans = 0;
  for (int i = 0; i < N; i++) {
    int L = max(0, A[i] - K);
    int R = min(M - 1, A[i] + K);
    seg.set_val(A[i], seg.query(L, R + 1) + 1);
  }
  cout << seg.query(0, M) << '\n';
  return 0;
}


Measured memory_bytes: 6896