#include <bits/stdc++.h>
using namespace std;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
const long long INF =
    sizeof(long long) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const long long MOD = (long long)1e9 + 7;
const double EPS = 1e-9;
template <typename T>
struct SegmentTree {
  typedef function<T(T, T)> F;
  typedef function<bool(T)> C;
  long long sz, n;
  vector<T> seg;
  const F f;
  const T M1;
  SegmentTree(long long n, const F f, const T &M1) : f(f), M1(M1), n(n) {
    sz = 1;
    while (sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }
  void init(const vector<T> v) {
    for (long long i = 0; i < ((long long)(v).size()); i++) seg[i + sz] = v[i];
    for (long long k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }
  void update(long long k, const T &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }
  T query(long long a, long long b) {
    if (a >= b) return M1;
    T L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) L = f(L, seg[a++]);
      if (b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }
  T operator[](const long long &k) const { return seg[k + sz]; }
  long long find_subtree(long long a, const C &check, T &M, bool type) {
    while (a < sz) {
      T nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }
  long long find_first(long long a, const C &check) {
    T L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1]))) return find_subtree(1, check, L, false);
      return -1;
    }
    long long b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        T nxt = f(L, seg[a]);
        if (check(nxt)) return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }
  long long find_last(long long b, const C &check) {
    T R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R))) return find_subtree(1, check, R, true);
      return -1;
    }
    long long a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        T nxt = f(seg[--b], R);
        if (check(nxt)) return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
  void print() {
    for (long long i = 0; i < n; i++)
      if ((*this)[i] == M1)
        cout << "x ";
      else
        cout << (*this)[i] << " ";
    cout << endl;
  }
};
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  long long N, K;
  cin >> N >> K;
  auto f = [&](long long a, long long b) { return max(a, b); };
  SegmentTree<long long> st(300010, f, 0);
  long long A;
  long long ans = 0;
  for (long long i = (0), i_len = (N); i < i_len; i++) {
    cin >> A;
    A--;
    long long res = st.query(max(0LL, A - K), min(300005LL, A + K + 1)) + 1;
    chmax(ans, res);
    st.update(A, res);
  }
  cout << ans << endl;
  return 0;
}
