#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, typename E>
struct LazySegmentTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  typedef function<E(E, E)> H;
  typedef function<E(E, long long)> P;
  vector<T> dat;
  vector<E> laz;
  long long n;
  F f;
  G g;
  H h;
  P p;
  T d1;
  E d0;
  LazySegmentTree(long long m, F f, G g, H h, P p, T d1, E d0)
      : f(f), g(g), h(h), p(p), d1(d1), d0(d0) {
    n = 1;
    while (n < m) n *= 2;
    dat.assign(2 * n - 1, d1);
    laz.assign(2 * n - 1, d0);
  }
  void init(const vector<T> v) {
    for (long long i = 0; i < ((long long)(v).size()); i++)
      dat[i + n - 1] = v[i];
    for (long long i = n - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  inline void eval(long long len, long long k) {
    if (laz[k] == d0) return;
    if (k * 2 + 1 < n * 2 - 1) {
      laz[k * 2 + 1] = h(laz[k * 2 + 1], laz[k]);
      laz[k * 2 + 2] = h(laz[k * 2 + 2], laz[k]);
    }
    dat[k] = g(dat[k], p(laz[k], len));
    laz[k] = d0;
  }
  void update(long long a, long long b, E x, long long k, long long l,
              long long r) {
    eval(r - l, k);
    if (a <= l && r <= b) {
      laz[k] = h(laz[k], x);
      eval(r - l, k);
    } else if (a < r && l < b) {
      update(a, b, x, k * 2 + 1, l, (l + r) / 2);
      update(a, b, x, k * 2 + 2, (l + r) / 2, r);
      dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  T query(long long a, long long b, long long k, long long l, long long r) {
    eval(r - l, k);
    if (r <= a || b <= l) return d1;
    if (a <= l && r <= b) return dat[k];
    T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return f(vl, vr);
  }
  void update(long long a, long long b, E x) { update(a, b, x, 0, 0, n); }
  T query(long long a, long long b) { return query(a, b, 0, 0, n); }
  T operator[](const long long &k) const { return dat[k + n - 1]; }
};
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 a; };
  auto g = [&](long long a, long long b) { return max(a, b); };
  auto h = [&](long long a, long long b) { return max(a, b); };
  auto p = [&](long long a, long long b) { return a; };
  LazySegmentTree<long long, long long> st(300010, f, g, h, p, 0, 0);
  long long ans = 0;
  long long A;
  for (long long i = (0), i_len = (N); i < i_len; i++) {
    cin >> A;
    A--;
    st.query(A, A + 1);
    long long res = st[A] + 1;
    chmax(ans, res);
    st.update(max(0LL, A - K), min(300005LL, A + K + 1), res);
  }
  cout << ans << endl;
  return 0;
}
