#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
const double pi = 3.141592653589793;
template <class T>
using V = vector<T>;
using Graph = vector<vector<int>>;
using P = pair<long long, long long>;
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline void out(T a) {
  cout << a << '\n';
}
void YN(bool ok) {
  if (ok)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}
const long long INF = 1e18;
const int mx = 200005;
long long mod_pow(long long x, long long n, long long m) {
  if (n == 0) return 1;
  long long res = mod_pow(x * x % m, n / 2, m);
  if (n & 1) res = res * x % m;
  return res;
}
long long modinv(long long n) { return mod_pow(n, 1000000007 - 2, 1000000007); }
long long dp[300005];
class Segtree {
 public:
  long long N = 1;
  V<long long> dat;
  explicit Segtree(long long sz) {
    while (N < sz) N *= 2;
    dat.reserve(2 * N);
    for (int i = 0; i < 2 * N; i++) dat[i] = 0;
  }
  void min_init() {
    for (int i = 0; i < N; i++) min_update(i, INF);
  }
  void min_update(long long k, long long a) {
    k += N - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }
  long long min_query(long long a, long long b, long long k, long long l,
                      long long r) {
    if (r <= a || b <= l) return INF;
    if (a <= l && r <= b) return dat[k];
    long long m = (l + r) / 2;
    long long u = min_query(a, b, 2 * k + 1, l, m);
    long long v = min_query(a, b, 2 * k + 2, m, r);
    return min(u, v);
  }
  long long get_min(long long l, long long r) {
    return min_query(l, r, 0, 0, N);
  }
  void max_init() {
    for (int i = 0; i < N; i++) max_update(i, -INF);
  }
  void max_update(long long k, long long a) {
    k += N - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = max(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }
  long long max_query(long long a, long long b, long long k, long long l,
                      long long r) {
    if (r <= a || b <= l) return 0;
    if (a <= l && r <= b) return dat[k];
    long long m = (l + r) / 2;
    long long u = max_query(a, b, 2 * k + 1, l, m);
    long long v = max_query(a, b, 2 * k + 2, m, r);
    return max(u, v);
  }
  long long get_max(long long l, long long r) {
    return max_query(l, r, 0, 0, N);
  }
  void sum_update(long long k, long long a) {
    k += N - 1;
    dat[k] += a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = (dat[2 * k + 1] + dat[2 * k + 2]);
    }
  }
  long long sum_query(long long a, long long b, long long k, long long l,
                      long long r) {
    if (r <= a || b <= l) return 0LL;
    if (a <= l && r <= b) return dat[k];
    long long m = (l + r) / 2;
    long long u = sum_query(a, b, 2 * k + 1, l, m);
    long long v = sum_query(a, b, 2 * k + 2, m, r);
    return (u + v);
  }
  long long get_sum(long long l, long long r) {
    return sum_query(l, r, 0, 0, N);
  }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  long long n, k;
  cin >> n >> k;
  V<long long> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  Segtree s(300002);
  s.max_update(a[0], 1);
  for (int i = 1; i < n; i++) {
    long long vl = max(1LL, a[i] - k);
    long long vr = min(300001LL, a[i] + k + 1);
    long long tmp = s.get_max(vl, vr) + 1;
    if (tmp > s.get_max(a[i], a[i] + 1)) s.max_update(a[i], tmp);
  }
  out(s.get_max(1, 300001));
}
