#include <bits/stdc++.h>
#include <unistd.h>

#define fi first
#define se second
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rep1(i, n) for (ll i = 1; i <= (n); ++i)
#define rrep(i, n) for (ll i = (n)-1; i >= 0; --i)
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define dame                                                                   \\
  {                                                                            \\
    puts("-1");                                                                \\
    return 0;                                                                  \\
  }
#define show(x) cerr << #x << " = " << x << endl;

using namespace std;
using ll = long long;
using ld = long double;
using pl = pair<ll, ll>;
ll LINF = 1000000000000000000;

typedef vector<ll> vl;
typedef vector<pl> vp;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

struct UnionFind {
  vector<int> d;
  UnionFind(int n = 0) : d(n, -1) {}
  int root(int x) {
    if (d[x] < 0)
      return x;
    return d[x] = root(d[x]);
  }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (d[x] > d[y])
      swap(x, y);
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int size(int x) { return -d[root(x)]; }
  int factor_size() {
    int ans = 0;
    rep(i, d.size()) {
      if (d[i] < 0) {
        ans++;
      }
    }
    return ans;
  }
};

ll d[100][100];

void warshall_floyd(ll n) {
  rep(k, n) {
    rep(i, n) {
      rep(j, n) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); }
    }
  }
}

struct edge {
  ll to, cost;
};

struct dijkstra {
  ll V;
  vector<vector<edge>> G;
  vector<ll> d;

  dijkstra(ll n) { init(n); }

  void init(ll n) {
    V = n;
    G.resize(V);
    d.resize(V);
    rep(i, V) { d[i] = LINF; }
  }

  void add_edge(ll s, ll t, ll cost) {
    edge e;
    e.to = t, e.cost = cost;
    G[s].push_back(e);
  }

  void run(ll s) {
    rep(i, V) { d[i] = LINF; }
    d[s] = 0;
    priority_queue<pl, vector<pl>, greater<pl>> que;
    que.push(pl(0, s));
    while (!que.empty()) {
      pl p = que.top();
      que.pop();
      ll v = p.second;
      if (d[v] < p.first)
        continue;
      for (auto e : G[v]) {
        if (d[e.to] > d[v] + e.cost) {
          d[e.to] = d[v] + e.cost;
          que.push(pl(d[e.to], e.to));
        }
      }
    }
  }
};
// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
const ll mod = 1000000007;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x = 0) : x((x % mod + mod) % mod) {}
  mint operator-() const { return mint(-x); }
  mint &operator+=(const mint a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const { return mint(*this) += a; }
  mint operator-(const mint a) const { return mint(*this) -= a; }
  mint operator*(const mint a) const { return mint(*this) *= a; }
  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return *this *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream &operator>>(istream &is, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }
// combination mod prime
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&feature=youtu.be&t=1619
struct combination {
  vector<mint> fact, ifact;
  combination(int n) : fact(n + 1), ifact(n + 1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i)
      fact[i] = fact[i - 1] * i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i)
      ifact[i - 1] = ifact[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n)
      return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
} comb(200005);

// Sieve of Eratosthenes
// https://youtu.be/UTVg7wzMWQc?t=2774
struct Sieve {
  int n;
  vector<int> f, primes;
  Sieve(int n = 1) : n(n), f(n + 1) {
    f[0] = f[1] = -1;
    for (ll i = 2; i <= n; ++i) {
      if (f[i])
        continue;
      primes.push_back(i);
      f[i] = i;
      for (ll j = i * i; j <= n; j += i) {
        if (!f[j])
          f[j] = i;
      }
    }
  }
  bool isPrime(int x) { return f[x] == x; }
  vector<int> factorList(int x) {
    vector<int> res;
    while (x != 1) {
      res.push_back(f[x]);
      x /= f[x];
    }
    return res;
  }
  vector<pl> factor(int x) {
    vector<int> fl = factorList(x);
    if (fl.size() == 0)
      return {};
    vector<pl> res(1, pl(fl[0], 0));
    for (int p : fl) {
      if (res.back().first == p) {
        res.back().second++;
      } else {
        res.emplace_back(p, 1);
      }
    }
    return res;
  }
  vector<pair<ll, int>> factor(ll x) {
    vector<pair<ll, int>> res;
    for (int p : primes) {
      int y = 0;
      while (x % p == 0)
        x /= p, ++y;
      if (y != 0)
        res.emplace_back(p, y);
    }
    if (x != 1)
      res.emplace_back(x, 1);
    return res;
  }
};

int main() {
  ll n, k;
  cin >> n >> k;

  vector<ll> a(n);
  rep(i, n) { cin >> a[i]; }

  vector<pl> v;

  ll ans = 1;
  v.pb({1, a[0]});
  rep1(i, n - 1) {
    sort(ALL(v));
    // rep(j, v.size()) { show(v[j].se); }
    bool fl = true;
    rrep(j, v.size()) {
      if (v[j].se <= a[i] + k and v[j].se >= a[i] - k) {
        //	show(i);
        v.pb({v[j].fi + 1, a[i]});
        chmax(ans, v[j].fi + 1);
        fl = false;
        break;
      }
    }
    if (fl)
      v.pb({1, a[i]});
  }

  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>
#include <unistd.h>

#define fi first
#define se second
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rep1(i, n) for (ll i = 1; i <= (n); ++i)
#define rrep(i, n) for (ll i = (n)-1; i >= 0; --i)
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define dame                                                                   \\
  {                                                                            \\
    puts("-1");                                                                \\
    return 0;                                                                  \\
  }
#define show(x) cerr << #x << " = " << x << endl;

using namespace std;
using ll = long long;
using ld = long double;
using pl = pair<ll, ll>;
ll LINF = 1000000000000000000;

typedef vector<ll> vl;
typedef vector<pl> vp;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

struct UnionFind {
  vector<int> d;
  UnionFind(int n = 0) : d(n, -1) {}
  int root(int x) {
    if (d[x] < 0)
      return x;
    return d[x] = root(d[x]);
  }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (d[x] > d[y])
      swap(x, y);
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int size(int x) { return -d[root(x)]; }
  int factor_size() {
    int ans = 0;
    rep(i, d.size()) {
      if (d[i] < 0) {
        ans++;
      }
    }
    return ans;
  }
};

ll d[100][100];

void warshall_floyd(ll n) {
  rep(k, n) {
    rep(i, n) {
      rep(j, n) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); }
    }
  }
}

struct edge {
  ll to, cost;
};

struct dijkstra {
  ll V;
  vector<vector<edge>> G;
  vector<ll> d;

  dijkstra(ll n) { init(n); }

  void init(ll n) {
    V = n;
    G.resize(V);
    d.resize(V);
    rep(i, V) { d[i] = LINF; }
  }

  void add_edge(ll s, ll t, ll cost) {
    edge e;
    e.to = t, e.cost = cost;
    G[s].push_back(e);
  }

  void run(ll s) {
    rep(i, V) { d[i] = LINF; }
    d[s] = 0;
    priority_queue<pl, vector<pl>, greater<pl>> que;
    que.push(pl(0, s));
    while (!que.empty()) {
      pl p = que.top();
      que.pop();
      ll v = p.second;
      if (d[v] < p.first)
        continue;
      for (auto e : G[v]) {
        if (d[e.to] > d[v] + e.cost) {
          d[e.to] = d[v] + e.cost;
          que.push(pl(d[e.to], e.to));
        }
      }
    }
  }
};
// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
const ll mod = 1000000007;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x = 0) : x((x % mod + mod) % mod) {}
  mint operator-() const { return mint(-x); }
  mint &operator+=(const mint a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const { return mint(*this) += a; }
  mint operator-(const mint a) const { return mint(*this) -= a; }
  mint operator*(const mint a) const { return mint(*this) *= a; }
  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return *this *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream &operator>>(istream &is, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }
// combination mod prime
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&feature=youtu.be&t=1619
struct combination {
  vector<mint> fact, ifact;
  combination(int n) : fact(n + 1), ifact(n + 1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i)
      fact[i] = fact[i - 1] * i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i)
      ifact[i - 1] = ifact[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n)
      return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
} comb(200005);

// Sieve of Eratosthenes
// https://youtu.be/UTVg7wzMWQc?t=2774
struct Sieve {
  int n;
  vector<int> f, primes;
  Sieve(int n = 1) : n(n), f(n + 1) {
    f[0] = f[1] = -1;
    for (ll i = 2; i <= n; ++i) {
      if (f[i])
        continue;
      primes.push_back(i);
      f[i] = i;
      for (ll j = i * i; j <= n; j += i) {
        if (!f[j])
          f[j] = i;
      }
    }
  }
  bool isPrime(int x) { return f[x] == x; }
  vector<int> factorList(int x) {
    vector<int> res;
    while (x != 1) {
      res.push_back(f[x]);
      x /= f[x];
    }
    return res;
  }
  vector<pl> factor(int x) {
    vector<int> fl = factorList(x);
    if (fl.size() == 0)
      return {};
    vector<pl> res(1, pl(fl[0], 0));
    for (int p : fl) {
      if (res.back().first == p) {
        res.back().second++;
      } else {
        res.emplace_back(p, 1);
      }
    }
    return res;
  }
  vector<pair<ll, int>> factor(ll x) {
    vector<pair<ll, int>> res;
    for (int p : primes) {
      int y = 0;
      while (x % p == 0)
        x /= p, ++y;
      if (y != 0)
        res.emplace_back(p, y);
    }
    if (x != 1)
      res.emplace_back(x, 1);
    return res;
  }
};

int main() {
  ll n, k;
  cin >> n >> k;

  vector<ll> a(n);
  rep(i, n) { cin >> a[i]; }

  // vector<pl> v;
  priority_queue<pl> v;

  ll ans = 1;
  v.push({1, a[0]});

  rep1(i, n - 1) {
    bool fl = true;
    vector<pl> tmp;

    while (!v.empty()) {
      pl x = v.top();
      // show(i);
      // show(x.fi);
      // show(x.se)
      v.pop();
      tmp.pb(x);
      if (x.se <= a[i] + k and x.se >= a[i] - k) {
        //	show(i);
        v.push({x.fi + 1, a[i]});
        chmax(ans, x.fi + 1);
        fl = false;
        break;
      }
    }
    rep(kk, tmp.size()) v.push(tmp[kk]);
    if (fl)
      v.push({1, a[i]});
  }

  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i, a, b) for (ll i = (a); i <= (b); ++i)
#define req(i, a, b) for (ll i = (a); i >= (b); --i)
#define name "a"
#define pb push_back
#define sz size()
#define ff first
#define ss second
#define xd '\\n'
#define dc " "
typedef pair<ll, ll> ii;
const ll maxn = 3e5 + 7, oo = 1e18, base = 311, mod = 1e9 + 7;
const double PI = 3.141592654;
ll t, n, a[maxn], res, f[maxn], k;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  // freopen(name".inp","r",stdin);
  // freopen(name".out","w",stdout);
  cin >> n >> k;
  rep(i, 1, n) cin >> a[i];
  f[1] = 1;
  rep(i, 2, n) rep(j, 1, i - 1) if (abs(a[i] - a[j]) <= k) f[i] =
      max(f[i], f[j] + 1);
  rep(i, 1, n) res = max(res, f[i]);
  cout << res;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i, a, b) for (ll i = (a); i <= (b); ++i)
#define req(i, a, b) for (ll i = (a); i >= (b); --i)
#define name "a"
#define pb push_back
#define sz size()
#define ff first
#define ss second
#define xd '\\n'
#define dc " "
typedef pair<ll, ll> ii;
const ll maxn = 3e5 + 7, oo = 1e18, base = 311, mod = 1e9 + 7;
const double PI = 3.141592654;
ll t, n, a[maxn], res, f[maxn], k, st[maxn << 2];
ll get(int i, int l, int r, int x, int y) {
  if (l > y || r < x)
    return 0;
  if (x <= l && r <= y)
    return st[i];
  int m = (l + r) / 2;
  return max(get(2 * i, l, m, x, y), get(2 * i + 1, m + 1, r, x, y));
}
void update(int i, int l, int r, int x, int v) {
  if (l > x || r < x)
    return;
  if (l == r) {
    st[i] = v;
    return;
  }
  int m = (l + r) / 2;
  update(2 * i, l, m, x, v);
  update(2 * i + 1, m + 1, r, x, v);
  st[i] = max(st[2 * i], st[2 * i + 1]);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  // freopen(name".inp","r",stdin);
  // freopen(name".out","w",stdout);
  cin >> n >> k;
  rep(i, 1, n) cin >> a[i];
  rep(i, 1, n) {
    f[i] = get(1, 0, 300000, max(0ll, a[i] - k), a[i] + k) + 1;
    update(1, 0, 300000, a[i], f[i]);
  }
  rep(i, 1, n) res = max(res, f[i]);
  cout << res;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using ld = long double;
const int MOD = 1e9 + 7;

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> values(n);
  vector<int> dp(n);
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    values[i] = a;
    dp[i] = 1;
    for (int j = 0; j < i; j++) {
      if (abs(values[j] - a) <= k) {
        dp[i] = max(dp[i], dp[j] + 1);
      }
    }
  }
  cout << dp[n - 1] << endl;
}

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using ld = long double;
const int MOD = 1e9 + 7;

int main() {
  int n, k;
  cin >> n >> k;
  auto cmp = [](pair<int, int> a, pair<int, int> b) {
    return a.second < b.second;
  };
  priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> pq(
      cmp); // value, longestLength;
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    pair<int, int> n = {a, 1};
    vector<pair<int, int>> others;
    bool inserted = false;
    while (!pq.empty()) {
      if (abs(pq.top().first - a) <= k) {
        n.second = pq.top().second + 1;
        pq.push(n);
        inserted = true;
        break;
      } else {
        others.push_back(pq.top());
        pq.pop();
      }
    }
    if (!inserted) {
      pq.push(n);
    }
    for (auto other : others) {
      pq.push(other);
    }
  }
  cout << pq.top().second << endl;
}


#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#pragma warning(disable : 4996)
using namespace std;

#define debug(i) cout << "<debug> " << #i << " " << i << " <\\\\debug>" << endl
#define mfor(i, a, b) for (int i = (a); i <= (b); i++)
#define mrep(i, a, b) for (int i = (a); i >= (b); i--)
#define lll __int128
#define Re register
#define mem(a, b) memset(a, (b), sizeof(a))
#define Design ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define endl '\\n'
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> intpair;
typedef pair<ll, ll> llpair;
typedef long double ld;
const double pi = acos(-1);
const double eps = 1e-5;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

int a[300010];
int b[300010];

struct STtree {
  // 默认min add功能
  // query功能修改push_up cmp
  // update功能修改push_down update
  // greater功能修改greater
#define lc(x) x << 1
#define rc(x) x << 1 | 1
  struct tree {
    int a;
    int l, r;
    tree() {}
  } node[(int)300010 << 2];

  STtree() {}

  STtree(int l, int r, int *a) { build(1, l, r, a); }

  inline void push_up(int x) {
    // query功能
    node[x].a = max(node[lc(x)].a, node[rc(x)].a);
  }

  inline int cmp(int a, int b) {
    // query功能
    return (a > b ? a : b);
  }

  void build(int x, int l, int r, int *a) {
    node[x].l = l;
    node[x].r = r;
    if (l == r) {
      node[x].a = 0;
      return;
    }
    int mid = (l + r) >> 1;
    build(lc(x), l, mid, a);
    build(rc(x), mid + 1, r, a);
    push_up(x);
  }
  void update(int left, int right, int x, int k) {
    if (left <= node[x].l && node[x].r <= right) {
      node[x].a = k;
      return;
    }
    int mid = (node[x].l + node[x].r) >> 1;
    if (left <= mid)
      update(left, right, lc(x), k);
    if (right > mid)
      update(left, right, rc(x), k);
    push_up(x);
  }
  int query(int left, int right, int x) {
    int res = 0;
    if (left <= node[x].l && node[x].r <= right)
      return node[x].a;
    int mid = (node[x].l + node[x].r) >> 1;
    if (left <= mid)
      res = max(res, query(left, right, lc(x)));
    if (right > mid)
      res = max(res, query(left, right, rc(x)));
    return res;
  }
} st;

int main() {
  Design;
  int n, k;
  cin >> n >> k;
  mfor(i, 1, n) cin >> a[i], b[i] = a[i];
  sort(a + 1, a + 1 + n);
  int m = unique(a + 1, a + 1 + n) - a;
  st.build(1, 1, m, 0);
  int ans = 0;
  mfor(i, 1, n) {
    int l = lower_bound(a + 1, a + 1 + m, b[i] - k) - a;
    int r = upper_bound(a + 1, a + 1 + m, b[i] + k) - a - 1;
    int t = st.query(l, r, 1);
    ans = max(ans, t + 1);
    int x = lower_bound(a + 1, a + 1 + m, b[i]) - a;
    st.update(x, x, 1, t + 1);
  }
  cout << ans;
}

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#pragma warning(disable : 4996)
using namespace std;

#define debug(i) cout << "<debug> " << #i << " " << i << " <\\\\debug>" << endl
#define mfor(i, a, b) for (int i = (a); i <= (b); i++)
#define mrep(i, a, b) for (int i = (a); i >= (b); i--)
#define lll __int128
#define Re register
#define mem(a, b) memset(a, (b), sizeof(a))
#define Design ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define endl '\\n'
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> intpair;
typedef pair<ll, ll> llpair;
typedef long double ld;
const double pi = acos(-1);
const double eps = 1e-5;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

int a[300010];
int b[300010];

struct STtree {
  // 默认min add功能
  // query功能修改push_up cmp
  // update功能修改push_down update
  // greater功能修改greater
#define lc(x) x << 1
#define rc(x) x << 1 | 1
  struct tree {
    int a;
    int l, r;
    tree() : l(0), r(0), a(0) {}
  } node[(int)300010 << 2];

  STtree() {}

  STtree(int l, int r, int *a) { build(1, l, r, a); }

  inline void push_up(int x) {
    // query功能
    node[x].a = max(node[lc(x)].a, node[rc(x)].a);
  }

  inline int cmp(int a, int b) {
    // query功能
    return (a > b ? a : b);
  }

  void build(int x, int l, int r, int *a) {
    node[x].l = l;
    node[x].r = r;
    if (l == r) {
      node[x].a = 0;
      return;
    }
    int mid = (l + r) >> 1;
    build(lc(x), l, mid, a);
    build(rc(x), mid + 1, r, a);
    push_up(x);
  }
  void update(int left, int right, int x, int k) {
    if (left <= node[x].l && node[x].r <= right) {
      node[x].a = k;
      return;
    }
    int mid = (node[x].l + node[x].r) >> 1;
    if (left <= mid)
      update(left, right, lc(x), k);
    if (right > mid)
      update(left, right, rc(x), k);
    push_up(x);
  }
  int query(int left, int right, int x) {
    int res = 0;
    if (left <= node[x].l && node[x].r <= right)
      return node[x].a;
    int mid = (node[x].l + node[x].r) >> 1;
    if (left <= mid)
      res = max(res, query(left, right, lc(x)));
    if (right > mid)
      res = max(res, query(left, right, rc(x)));
    return res;
  }
} st;

int main() {
  Design;
  int n, k;
  cin >> n >> k;
  mfor(i, 1, n) {
    cin >> a[i];
    a[i]++;
  }
  st.build(1, 1, 300001, 0);
  int ans = 0;
  mfor(i, 1, n) {
    int t = st.query(max(a[i] - k, 1), min(a[i] + k, 300001), 1);
    ans = max(ans, t + 1);
    st.update(a[i], a[i], 1, t + 1);
  }
  cout << ans;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define sz(a) a.size()
#define all(a) a.begin(), a.end()
#define lb lower_bound
#define ub upper_bound
#define owo                                                                    \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);
#define MOD (ll)(1e8)
#define INF (ll)(1e18)
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#define time__(d)                                                              \\
  for (long blockTime = 0;                                                     \\
       (blockTime == 0 ? (blockTime = clock()) != 0 : false);                  \\
       debug("%s time : %.4fs\\n", d,                                           \\
             (double)(clock() - blockTime) / CLOCKS_PER_SEC))
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> PII;
typedef pair<int, int> pii;
typedef vector<vector<int>> vii;
typedef vector<vector<ll>> VII;
ll gcd(ll a, ll b) {
  if (!b)
    return a;
  else
    return gcd(b, a % b);
}
class pointseg {
private:
  int n;
  vector<ll> t, a;
  void upd(int v, int tl, int tr, int pos, ll val) {
    if (tl == tr) {
      t[v] = val;
      return;
    }
    int tm = (tl + tr) / 2;
    if (pos <= tm) {
      upd(2 * v, tl, tm, pos, val);
    } else {
      upd(2 * v + 1, tm + 1, tr, pos, val);
    }
    t[v] = merge(t[2 * v], t[2 * v + 1]);
  }
  ll query(int v, int l, int r, int tl, int tr) {
    if (l > r)
      return 0;
    if (l == tl && r == tr) {
      return t[v];
    }
    int tm = (tl + tr) / 2;
    return merge(query(2 * v, l, min(r, tm), tl, tm),
                 query(2 * v + 1, max(l, tm + 1), r, tm + 1, tr));
  }
  void build(int v, int tl, int tr) {
    if (tl == tr) {
      t[v] = a[tl];
      return;
    }
    int tm = (tl + tr) / 2;
    build(2 * v, tl, tm);
    build(2 * v + 1, tm + 1, tr);
    t[v] = merge(t[2 * v], t[2 * v + 1]);
  }

public:
  ll merge(ll a, ll b) { return max(a, b); }
  void upd(int pos, ll val) { upd(1, 1, n, pos, val); }
  ll query(int l, int r) { return query(1, l, r, 1, n); }
  void build() { build(1, 1, n); }
  pointseg(int _n, vector<ll> _a = {}) {
    n = _n;
    t.assign(4 * (n + 4), 0);
    a = _a;
  }
  pointseg() {}
  void reset(int _n, vector<ll> _a = {}) {
    n = _n;
    t.clear();
    t.assign(4 * (_n + 4), 0);
    a.clear();
    a = _a;
  }
};
int main() {
  owo ll n, k;
  cin >> n >> k;
  vector<ll> a(n + 1);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    a[i]++;
  }
  ll ans = 1;
  pointseg s(400000);
  for (int i = 0; i < n; i++) {
    ll l = max(1LL, a[i] - k);
    ll r = a[i] + k;
    ll res = s.query(l, r);
    ll now = s.query(a[i], a[i]);
    if (res + 1 > now)
      s.upd(a[i], res + 1);
    ans = max(ans, now);
    ans = max(ans, res + 1);
  }
  cout << ans;
}

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define sz(a) a.size()
#define all(a) a.begin(), a.end()
#define lb lower_bound
#define ub upper_bound
#define owo                                                                    \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);
#define MOD (ll)(1e8)
#define INF (ll)(1e18)
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#define time__(d)                                                              \\
  for (long blockTime = 0;                                                     \\
       (blockTime == 0 ? (blockTime = clock()) != 0 : false);                  \\
       debug("%s time : %.4fs\\n", d,                                           \\
             (double)(clock() - blockTime) / CLOCKS_PER_SEC))
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> PII;
typedef pair<int, int> pii;
typedef vector<vector<int>> vii;
typedef vector<vector<ll>> VII;
ll gcd(ll a, ll b) {
  if (!b)
    return a;
  else
    return gcd(b, a % b);
}
class pointseg {
private:
  int n;
  vector<ll> t, a;
  void upd(int v, int tl, int tr, int pos, ll val) {
    if (tl == tr) {
      t[v] = val;
      return;
    }
    int tm = (tl + tr) / 2;
    if (pos <= tm) {
      upd(2 * v, tl, tm, pos, val);
    } else {
      upd(2 * v + 1, tm + 1, tr, pos, val);
    }
    t[v] = merge(t[2 * v], t[2 * v + 1]);
  }
  ll query(int v, int l, int r, int tl, int tr) {
    if (l > r)
      return 0;
    if (l == tl && r == tr) {
      return t[v];
    }
    int tm = (tl + tr) / 2;
    return merge(query(2 * v, l, min(r, tm), tl, tm),
                 query(2 * v + 1, max(l, tm + 1), r, tm + 1, tr));
  }
  void build(int v, int tl, int tr) {
    if (tl == tr) {
      t[v] = a[tl];
      return;
    }
    int tm = (tl + tr) / 2;
    build(2 * v, tl, tm);
    build(2 * v + 1, tm + 1, tr);
    t[v] = merge(t[2 * v], t[2 * v + 1]);
  }

public:
  ll merge(ll a, ll b) { return max(a, b); }
  void upd(int pos, ll val) { upd(1, 1, n, pos, val); }
  ll query(int l, int r) { return query(1, l, r, 1, n); }
  void build() { build(1, 1, n); }
  pointseg(int _n, vector<ll> _a = {}) {
    n = _n;
    t.assign(4 * (n + 4), 0);
    a = _a;
  }
  pointseg() {}
  void reset(int _n, vector<ll> _a = {}) {
    n = _n;
    t.clear();
    t.assign(4 * (_n + 4), 0);
    a.clear();
    a = _a;
  }
};
int main() {
  owo ll n, k;
  cin >> n >> k;
  vector<ll> a(n + 1);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    a[i]++;
  }
  ll ans = 1;
  pointseg s(400000);
  for (int i = 0; i < n; i++) {
    ll l = max(1LL, a[i] - k);
    ll r = min(ll(300001), a[i] + k);
    ll res = s.query(l, r);
    ll now = s.query(a[i], a[i]);
    if (res + 1 > now)
      s.upd(a[i], res + 1);
    ans = max(ans, now);
    ans = max(ans, res + 1);
  }
  cout << ans;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long LL;

#define N 100010

struct Data {
  LL val, idx;
};

LL a[N], c[N], q[N];
LL Maxn[N * 4];
Data b[N];
int n;
LL ans, d;

bool cmp(Data x, Data y) { return (x.val < y.val); }

void update(int o, int l, int r, int x, LL v) {
  if (l == x && r == x) {
    Maxn[o] = v;
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    update(o * 2, l, mid, x, v);
  if (x > mid)
    update(o * 2 + 1, mid + 1, r, x, v);
  Maxn[o] = max(Maxn[o * 2], Maxn[o * 2 + 1]);
}

void query(int o, int l, int r, int x, int y) {
  if (x <= l && r <= y) {
    ans = max(Maxn[o], ans);
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    query(o * 2, l, mid, x, y);
  if (y > mid)
    query(o * 2 + 1, mid + 1, r, x, y);
}

int main() {
  cin >> n >> d;
  memset(Maxn, 0, sizeof(Maxn));
  memset(q, 0, sizeof(q));
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    b[i].val = a[i];
    b[i].idx = i;
  }

  sort(b, b + n, cmp);

  for (int i = 0; i < n; i++) {
    c[i] = b[i].val;
    q[b[i].idx] = i;
  }
  LL tot = 1;
  for (int i = 0; i < n; i++) {
    LL l = a[i] - d, r = a[i] + d;
    int ll = lower_bound(c, c + n, l) - c;
    int rr = upper_bound(c, c + n, r) - c - 1;
    ans = 0;
    query(1, 0, n - 1, ll, rr);
    if (ans == 0)
      update(1, 0, n - 1, q[i], 1);
    else {
      update(1, 0, n - 1, q[i], ans + 1);
      if (ans + 1 > tot)
        tot = ans + 1;
    }
  }
  cout << tot << endl;
  return 0;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long LL;

#define N 1000010

struct Data {
  LL val, idx;
};

LL a[N], c[N], q[N];
LL Maxn[N * 4];
Data b[N];
int n;
LL ans, d;

bool cmp(Data x, Data y) { return (x.val < y.val); }

void update(int o, int l, int r, int x, LL v) {
  if (l == x && r == x) {
    Maxn[o] = v;
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    update(o * 2, l, mid, x, v);
  if (x > mid)
    update(o * 2 + 1, mid + 1, r, x, v);
  Maxn[o] = max(Maxn[o * 2], Maxn[o * 2 + 1]);
}

void query(int o, int l, int r, int x, int y) {
  if (x <= l && r <= y) {
    ans = max(Maxn[o], ans);
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    query(o * 2, l, mid, x, y);
  if (y > mid)
    query(o * 2 + 1, mid + 1, r, x, y);
}

int main() {
  cin >> n >> d;
  memset(Maxn, 0, sizeof(Maxn));
  memset(q, 0, sizeof(q));
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    b[i].val = a[i];
    b[i].idx = i;
  }

  sort(b, b + n, cmp);

  for (int i = 0; i < n; i++) {
    c[i] = b[i].val;
    q[b[i].idx] = i;
  }
  LL tot = 1;
  for (int i = 0; i < n; i++) {
    LL l = a[i] - d, r = a[i] + d;
    int ll = lower_bound(c, c + n, l) - c;
    int rr = upper_bound(c, c + n, r) - c - 1;
    ans = 0;
    query(1, 0, n - 1, ll, rr);
    if (ans == 0)
      update(1, 0, n - 1, q[i], 1);
    else {
      update(1, 0, n - 1, q[i], ans + 1);
      if (ans + 1 > tot)
        tot = ans + 1;
    }
  }
  cout << tot << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int NMAX = 3e5 + 10;
const int MOD = 1e9 + 7;

int a[NMAX], Max[NMAX << 3];

void push_up(int rt) { Max[rt] = max(Max[rt << 1], Max[rt << 1 | 1]); }

void update(int pos, int c, int l, int r, int rt) {
  if (l == r) {
    Max[rt] = c;
    return;
  }

  int mid = (l + r) >> 1;
  if (pos <= mid)
    update(pos, c, l, mid, rt << 1);
  else
    update(pos, c, mid + 1, r, rt << 1 | 1);
  push_up(rt);
}

int queryMax(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R)
    return Max[rt];

  int mid = (l + r) >> 1;
  int ans = 0;
  if (L <= mid)
    ans = max(ans, queryMax(L, R, l, mid, rt << 1));
  if (R > mid)
    ans = max(ans, queryMax(L, R, mid + 1, r, rt << 1 | 1));
  return ans;
}

int maxx[NMAX * 2];
int main(int argc, char const *argv[]) {
  int n, k;
  scanf("%d%d", &n, &k);
  for (register int i = 1; i <= n; i++)
    scanf("%d", a + i), a[i]++;
  int ans = 0, ant;
  for (register int i = 1; i <= n; i++) {
    ant = 1 + queryMax(max(1, a[i] - k), a[i] + k, 1, n + k + 1, 1);
    if (maxx[a[i]] < ant) {
      maxx[a[i]] = ant;
      update(a[i], ant, 1, n + k + 1, 1);
    }
    ans = max(ans, ant);
  }
  printf("%d\\n", ans);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int NMAX = 3e5 + 10;
const int MOD = 1e9 + 7;

int Max[NMAX << 3];
int maxx[NMAX], a[NMAX];

void push_up(int rt) { Max[rt] = max(Max[rt << 1], Max[rt << 1 | 1]); }

void update(int pos, int c, int l, int r, int rt) {
  if (l == r) {
    Max[rt] = c;
    return;
  }

  int mid = (l + r) >> 1;
  if (pos <= mid)
    update(pos, c, l, mid, rt << 1);
  else
    update(pos, c, mid + 1, r, rt << 1 | 1);
  push_up(rt);
}

int queryMax(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R)
    return Max[rt];

  int mid = (l + r) >> 1;
  int ans = 0;
  if (L <= mid)
    ans = max(ans, queryMax(L, R, l, mid, rt << 1));
  if (R > mid)
    ans = max(ans, queryMax(L, R, mid + 1, r, rt << 1 | 1));
  return ans;
}

int main(int argc, char const *argv[]) {
  int n, k, N = 0;
  scanf("%d%d", &n, &k);
  for (register int i = 1; i <= n; i++)
    scanf("%d", a + i), a[i]++, N = max(N, a[i] + k);
  int ans = 0, ant;
  for (register int i = 1; i <= n; i++) {
    ant = 1 + queryMax(max(1, a[i] - k), min(a[i] + k, N), 1, N, 1);
    if (maxx[a[i]] < ant) {
      maxx[a[i]] = ant;
      update(a[i], ant, 1, N, 1);
    }
    ans = max(ans, ant);
  }
  printf("%d\\n", ans);
  return 0;
}


// g++ -std=c++14 test.cpp -o test.out

#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string.h>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

#define LL long long int
const LL INF = (1LL << 60);
const int INF_INT = 2147483647 - 1e6 - 1;
const LL mod = 1000000007ll;
const int mod_int = 1000000007;

// 引用元：https://drken1215.hatenablog.com/entry/2020/09/27/080300
template <class Monoid> struct SegmentTree {
  using Func = function<Monoid(Monoid, Monoid)>;
  const Func F;
  const Monoid UNITY;
  int SIZE_R;
  vector<Monoid> dat;

  SegmentTree(int n, const Func f, const Monoid &unity) : F(f), UNITY(unity) {
    init(n);
  }
  void init(int n) {
    SIZE_R = 1;
    while (SIZE_R < n)
      SIZE_R *= 2;
    dat.assign(SIZE_R * 2, UNITY);
  }

  /* set, a is 0-indexed */
  void set(int a, const Monoid &v) { dat[a + SIZE_R] = v; }
  void build() {
    for (int k = SIZE_R - 1; k > 0; --k)
      dat[k] = F(dat[k * 2], dat[k * 2 + 1]);
  }

  /* update a, a is 0-indexed */
  void update(int a, const Monoid &v) {
    // まず最下段の、元の配列に相当する箇所を更新
    int k = a + SIZE_R;
    dat[k] = v;
    // 登りながら更新
    while (k >>= 1)
      dat[k] = F(dat[k * 2], dat[k * 2 + 1]);
  }

  /* query [a, b), a and b are 0-indexed */
  Monoid query(int a, int b) {
    Monoid vleft = UNITY, vright = UNITY;
    for (int left = a + SIZE_R, right = b + SIZE_R; left < right;
         left >>= 1, right >>= 1) {
      if (left & 1)
        vleft = F(vleft, dat[left++]);
      if (right & 1)
        vright = F(dat[--right], vright);
    }
    return F(vleft, vright);
  }
  inline Monoid operator[](int a) { return dat[a + SIZE_R]; }

  /* debug */
  void print() {
    for (int i = 0; i < SIZE_R; ++i) {
      cout << (*this)[i];
      if (i != SIZE_R - 1)
        cout << ",";
    }
    cout << endl;
  }
};

LL N, K;
LL A[300000];

LL ans;

void solve() {
  // ラストがiで終わるような数列の最大の長さをdp[i]とする
  auto func = [&](LL a, LL b) { return max(a, b); };
  SegmentTree<LL> st(N + 2, func, 0);
  for (int i = 0; i < N; i++) {
    LL left = max(0LL, A[i] - K);
    LL right = min(N, A[i] + K);
    LL cand = st.query(left, right + 1);
    st.update(A[i], cand + 1);
  }
  ans = st.query(1, N + 1);
}

int main() {
  cin >> N >> K;
  for (int i = 0; i < N; i++)
    cin >> A[i];

  solve();

  cout << ans << endl;
  return 0;
}

// g++ -std=c++14 test.cpp -o test.out

#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string.h>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

#define LL long long int
const LL INF = (1LL << 60);
const int INF_INT = 2147483647 - 1e6 - 1;
const LL mod = 1000000007ll;
const int mod_int = 1000000007;

// 引用元：https://drken1215.hatenablog.com/entry/2020/09/27/080300
template <class Monoid> struct SegmentTree {
  using Func = function<Monoid(Monoid, Monoid)>;
  const Func F;
  const Monoid UNITY;
  int SIZE_R;
  vector<Monoid> dat;

  SegmentTree(int n, const Func f, const Monoid &unity) : F(f), UNITY(unity) {
    init(n);
  }
  void init(int n) {
    SIZE_R = 1;
    while (SIZE_R < n)
      SIZE_R *= 2;
    dat.assign(SIZE_R * 2, UNITY);
  }

  /* set, a is 0-indexed */
  void set(int a, const Monoid &v) { dat[a + SIZE_R] = v; }
  void build() {
    for (int k = SIZE_R - 1; k > 0; --k)
      dat[k] = F(dat[k * 2], dat[k * 2 + 1]);
  }

  /* update a, a is 0-indexed */
  void update(int a, const Monoid &v) {
    // まず最下段の、元の配列に相当する箇所を更新
    int k = a + SIZE_R;
    dat[k] = v;
    // 登りながら更新
    while (k >>= 1)
      dat[k] = F(dat[k * 2], dat[k * 2 + 1]);
  }

  /* query [a, b), a and b are 0-indexed */
  Monoid query(int a, int b) {
    Monoid vleft = UNITY, vright = UNITY;
    for (int left = a + SIZE_R, right = b + SIZE_R; left < right;
         left >>= 1, right >>= 1) {
      if (left & 1)
        vleft = F(vleft, dat[left++]);
      if (right & 1)
        vright = F(dat[--right], vright);
    }
    return F(vleft, vright);
  }
  inline Monoid operator[](int a) { return dat[a + SIZE_R]; }

  /* debug */
  void print() {
    for (int i = 0; i < SIZE_R; ++i) {
      cout << (*this)[i];
      if (i != SIZE_R - 1)
        cout << ",";
    }
    cout << endl;
  }
};

LL N, K;
LL A[300000];

LL ans;

void solve() {
  // ラストがiで終わるような数列の最大の長さをdp[i]とする
  const LL MAX_A =　300000;
  auto func = [&](LL a, LL b) { return max(a, b); };
  SegmentTree<LL> st(MAX_A + 1, func, 0);
  for (int i = 0; i < N; i++) {
    LL left = max(0LL, A[i] - K);
    LL right = min(MAX_A, A[i] + K);
    LL cand = st.query(left, right + 1);
    st.update(A[i], cand + 1);
  }
  ans = st.query(1, MAX_A + 1);
}

int main() {
  cin >> N >> K;
  for (int i = 0; i < N; i++)
    cin >> A[i];

  solve();

  cout << ans << endl;
  return 0;
}


#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <ctime>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

// #include "atcoder/segtree.hpp"
using namespace std;

/*
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
*/
/*
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
*/
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define int long long
#define endl "\\n"
#define ALL(v) v.begin(), v.end()
#define m_p make_pair
#define m_t make_tuple
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using P = pair<int, int>;
using ld = long double;
using ll = long long;
using VI = vector<int>;
using VVI = vector<vector<int>>;
using VVC = vector<vector<char>>;
template <class T> using PQ_inv = priority_queue<T, vector<T>, greater<T>>;

const double pai = 3.1415926535897;
const int INF = 1000000021;
const ll LINF = 2000000000000000000;
const ll mod = 1000000007;
const int MAX = 2010000;
const ll MOD = 1000000007;
long long fac[MAX], finv[MAX], inv[MAX];

struct edge {
  int to, cost;
};
edge m_e(int xx, int yy) {
  edge ed;
  ed.to = xx;
  ed.cost = yy;
  return ed;
}

const auto identify_element = 0;      // 単位元
template <class T> T op(T xx, T yy) { // セグ木、BITで扱う関数
  return max(xx, yy);
}
template <class T> class segment_tree {
  int root_size; // 根の大きさ root_size+i-1でv[i]に対応する添え字を取得
  vector<T> data;

public:
  segment_tree(vector<T> v) {
    int a = 0;
    while (v.size() > (1ll << a))
      a++;
    root_size = 1ll << a;
    data.resize((root_size << 1) - 1, identify_element);
    rep(i, v.size()) { data[i + root_size - 1] = v[i]; }
    for (int i = root_size - 2; i >= 0; i--) {
      data[i] = op(data[i * 2 + 1], data[i * 2 + 2]);
    }
  }
  segment_tree(int xx) {
    int a = 0;
    while (xx > (1ll << a))
      a++;
    root_size = 1ll << a;
    data.resize((root_size << 1) - 1, identify_element);
    rep(i, xx) { data[i + root_size - 1] = 0; }
    for (int i = root_size - 2; i >= 0; i--) {
      data[i] = op(data[i * 2 + 1], data[i * 2 + 2]);
    }
  }

  // seg[p]=xxにする
  void update(int p, T xx) {
    int a = p + root_size - 1;
    data[a] = xx;
    while (a != 0) {
      a = (a - 1) / 2;
      data[a] = op(data[a * 2 + 2], data[a * 2 + 1]);
    }
  }
  // 0-indexedでxx番目の値を返す
  T get(int xx) { return data[root_size + xx - 1]; }
  // 0-indexed 閉区間でlからrのopの和
  T get_sum(int l, int r) { // 0-indexed
    int a = 1 /*2乗*/, p = l + root_size - 1 /*足す場所の添え字*/;
    T ret = identify_element; /*答え*/
    bool bo = 1;
    while (r + 1 > l) {
      if (a > r - l + 1) {
        bo = 0;
        a >>= 1;
        p = p * 2 + 1;
        continue;
      }
      if (bo) {
        if (l & a) {
          ret = op(ret, data[p]);
          l += a;
          p++;
        }
        a <<= 1;
        p = (p - 1) / 2;
      } else {
        if (r - l + 1 & a) {
          ret = op(ret, data[p]);
          l += a;
          p++;
        }
        a >>= 1;
        p = p * 2 + 1;
      }
    }
    return ret;
  }
  // 全体和
  T all() { return data[0]; }
  void debug() {
    for (int i = root_size - 1; i < root_size * 2 - 1; i++) {
      cout << data[i] << " ";
    }
    cout << endl;
  }
};

class BIT { // 0-indexedで与える opは群
  vector<int> data;

public:
  ;
  BIT(vector<int> v) {
    data.resize(v.size(), identify_element);
    rep(i, v.size()) { add(i, v[i]); }
  }
  // data[p]にxxを加算
  void add(int p, int xx) {
    for (int i = p + 1; i <= (int)data.size(); i += (i & -i)) {
      data[i - 1] += xx;
    }
  }
  // 0からrまでの総和
  int get_sum(int r) {
    int ret = identify_element;
    for (int i = r + 1; i > 0; i -= (i & -i)) {
      ret += data[i - 1];
    }
    return ret;
  }
};

class union_find { // 0-indexedで与える
  VI union_size;

public:
  ;
  VI table;
  union_find(int xx) {
    table.resize(xx);
    rep(i, xx) table[i] = i;
    union_size.resize(xx, 1);
  }

  int leader(int xx) {
    if (table[xx] == xx)
      return xx;
    return table[xx] = leader(table[xx]);
  }
  void marge(int xx, int yy) {
    int a = leader(xx), b = leader(yy);
    if (union_size[a] > union_size[b]) {
      table[b] = a;
      union_size[a] += union_size[b];
    } else {
      table[a] = b;
      union_size[b] += union_size[a];
    }
  }
  int same(int xx, int yy) {
    if (leader(xx) == leader(yy))
      return true;
    else
      return false;
  }
  int size(int xx) { return union_size[leader(xx)]; }
};

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}
// n個を1個以上のx組のグループに分ける重複組み合わせはcom(n-1,x-1)
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
ll PER(int n, int k) {
  if (n < 0 || k < 0)
    return 0;
  if (n < k)
    return fac[n];
  return fac[n] * finv[n - k] % mod;
}

long long modinv(long long a, long long m) {
  long long b = m, u = 1, v = 0;
  while (b) {
    long long t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= m;
  if (u < 0)
    u += m;
  return u;
}
long long modpow(int a, int n) {
  int res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}
long long fix_mod(int &xx) {
  if (xx >= mod * 2 || xx < -mod * 2) {
    xx %= mod;
  }
  if (xx >= mod)
    xx -= mod;
  // if (xx < 0)xx += mod;
  return xx;
}
// ax + by = gcd(a,b)を満たすx,yにする
long long extGCD(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  long long d = extGCD(b, a % b, y, x);
  y -= a / b * x;
  return d;
}

template <class T> void vecout(vector<T> &vec) {
  for (T t : vec)
    cout << t << " ";
  cout << endl;
}
template <class T> void vecout(vector<vector<T>> &vec) {
  for (vector<T> tvec : vec) {
    for (T t : tvec)
      cout << t << " ";
    cout << endl;
  }
}
template <class T> void vecout(vector<pair<T, T>> &vec) {
  for (pair<T, T> p : vec) {
    cout << p.first << " " << p.second << endl;
  }
}
template <class T> void vecin(vector<T> &vec) {
  for (int i = 0; i < (int)vec.size(); i++)
    cin >> vec[i];
}
bool chmax(int &xx, int yy) {
  if (xx < yy) {
    xx = yy;
    return true;
  }
  return false;
}
bool chmin(int &xx, int yy) {
  if (xx > yy) {
    xx = yy;
    return true;
  }
  return false;
}
// x未満の要素数を返す二分探索関数
int b_s(vector<int> &vec, int xx) {
  return lower_bound(ALL(vec), xx) - vec.begin();
}
int gcd(int xx, int yy) {
  if (yy > xx)
    swap(xx, yy);
  while (xx % yy != 0) {
    xx %= yy;
    swap(xx, yy);
  }
  return yy;
}
int lcm(int xx, int yy) { return (xx / gcd(xx, yy)) * yy; }
bool prime(int xx) {
  if (xx <= 1)
    return 0;
  if (xx == 2)
    return 1;
  for (int i = 3; i * i <= xx; i += 2) {
    if (xx % i == 0) {
      return 0;
    }
  }
  return 1;
}

signed main() {
  int n, k;
  cin >> n >> k;
  VI vec(n);
  vecin(vec);
  segment_tree<int> seg(300100);
  rep(i, n) {
    seg.update(vec[i], seg.get_sum(max(vec[i] - k, 0ll), vec[i] + k) + 1);
  }
  cout << seg.all() << endl;
}

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <ctime>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

// #include "atcoder/segtree.hpp"
using namespace std;

/*
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
*/
/*
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
*/
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define int long long
#define endl "\\n"
#define ALL(v) v.begin(), v.end()
#define m_p make_pair
#define m_t make_tuple
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using P = pair<int, int>;
using ld = long double;
using ll = long long;
using VI = vector<int>;
using VVI = vector<vector<int>>;
using VVC = vector<vector<char>>;
template <class T> using PQ_inv = priority_queue<T, vector<T>, greater<T>>;

const double pai = 3.1415926535897;
const int INF = 1000000021;
const ll LINF = 2000000000000000000;
const ll mod = 1000000007;
const int MAX = 2010000;
const ll MOD = 1000000007;
long long fac[MAX], finv[MAX], inv[MAX];

struct edge {
  int to, cost;
};
edge m_e(int xx, int yy) {
  edge ed;
  ed.to = xx;
  ed.cost = yy;
  return ed;
}

const auto identify_element = 0;      // 単位元
template <class T> T op(T xx, T yy) { // セグ木、BITで扱う関数
  return max(xx, yy);
}
template <class T> class segment_tree {
  int root_size; // 根の大きさ root_size+i-1でv[i]に対応する添え字を取得
  vector<T> data;

public:
  segment_tree(vector<T> v) {
    int a = 0;
    while (v.size() > (1ll << a))
      a++;
    root_size = 1ll << a;
    data.resize((root_size << 1) - 1, identify_element);
    rep(i, v.size()) { data[i + root_size - 1] = v[i]; }
    for (int i = root_size - 2; i >= 0; i--) {
      data[i] = op(data[i * 2 + 1], data[i * 2 + 2]);
    }
  }
  segment_tree(int xx) {
    int a = 0;
    while (xx > (1ll << a))
      a++;
    root_size = 1ll << a;
    data.resize((root_size << 1) - 1, identify_element);
    rep(i, xx) { data[i + root_size - 1] = identify_element; }
    for (int i = root_size - 2; i >= 0; i--) {
      data[i] = op(data[i * 2 + 1], data[i * 2 + 2]);
    }
  }

  // seg[p]=xxにする
  void update(int p, T xx) {
    int a = p + root_size - 1;
    data[a] = xx;
    while (a != 0) {
      a = (a - 1) / 2;
      data[a] = op(data[a * 2 + 2], data[a * 2 + 1]);
    }
  }
  // 0-indexedでxx番目の値を返す
  T get(int xx) { return data[root_size + xx - 1]; }
  // 0-indexed 閉区間でlからrのopの和
  T get_sum(int l, int r) { // 0-indexed
    int a = 1 /*2乗*/, p = l + root_size - 1 /*足す場所の添え字*/;
    T ret = identify_element; /*答え*/
    bool bo = 1;
    while (r + 1 > l) {
      if (a > r - l + 1) {
        bo = 0;
        a >>= 1;
        p = p * 2 + 1;
        continue;
      }
      if (bo) {
        if (l & a) {
          ret = op(ret, data[p]);
          l += a;
          p++;
        }
        a <<= 1;
        p = (p - 1) / 2;
      } else {
        if (r - l + 1 & a) {
          ret = op(ret, data[p]);
          l += a;
          p++;
        }
        a >>= 1;
        p = p * 2 + 1;
      }
    }
    return ret;
  }
  // 全体和
  T all() { return data[0]; }
};

class BIT { // 0-indexedで与える opは群
  vector<int> data;

public:
  ;
  BIT(vector<int> v) {
    data.resize(v.size(), identify_element);
    rep(i, v.size()) { add(i, v[i]); }
  }
  // data[p]にxxを加算
  void add(int p, int xx) {
    for (int i = p + 1; i <= (int)data.size(); i += (i & -i)) {
      data[i - 1] += xx;
    }
  }
  // 0からrまでの総和
  int get_sum(int r) {
    int ret = identify_element;
    for (int i = r + 1; i > 0; i -= (i & -i)) {
      ret += data[i - 1];
    }
    return ret;
  }
};

class union_find { // 0-indexedで与える
  VI union_size;

public:
  ;
  VI table;
  union_find(int xx) {
    table.resize(xx);
    rep(i, xx) table[i] = i;
    union_size.resize(xx, 1);
  }

  int leader(int xx) {
    if (table[xx] == xx)
      return xx;
    return table[xx] = leader(table[xx]);
  }
  void marge(int xx, int yy) {
    int a = leader(xx), b = leader(yy);
    if (union_size[a] > union_size[b]) {
      table[b] = a;
      union_size[a] += union_size[b];
    } else {
      table[a] = b;
      union_size[b] += union_size[a];
    }
  }
  int same(int xx, int yy) {
    if (leader(xx) == leader(yy))
      return true;
    else
      return false;
  }
  int size(int xx) { return union_size[leader(xx)]; }
};

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}
// n個を1個以上のx組のグループに分ける重複組み合わせはcom(n-1,x-1)
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
ll PER(int n, int k) {
  if (n < 0 || k < 0)
    return 0;
  if (n < k)
    return fac[n];
  return fac[n] * finv[n - k] % mod;
}

long long modinv(long long a, long long m) {
  long long b = m, u = 1, v = 0;
  while (b) {
    long long t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= m;
  if (u < 0)
    u += m;
  return u;
}
long long modpow(int a, int n) {
  int res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}
long long fix_mod(int &xx) {
  if (xx >= mod * 2 || xx < -mod * 2) {
    xx %= mod;
  }
  if (xx >= mod)
    xx -= mod;
  // if (xx < 0)xx += mod;
  return xx;
}
// ax + by = gcd(a,b)を満たすx,yにする
long long extGCD(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  long long d = extGCD(b, a % b, y, x);
  y -= a / b * x;
  return d;
}

template <class T> void vecout(vector<T> &vec) {
  for (T t : vec)
    cout << t << " ";
  cout << endl;
}
template <class T> void vecout(vector<vector<T>> &vec) {
  for (vector<T> tvec : vec) {
    for (T t : tvec)
      cout << t << " ";
    cout << endl;
  }
}
template <class T> void vecout(vector<pair<T, T>> &vec) {
  for (pair<T, T> p : vec) {
    cout << p.first << " " << p.second << endl;
  }
}
template <class T> void vecin(vector<T> &vec) {
  for (int i = 0; i < (int)vec.size(); i++)
    cin >> vec[i];
}
bool chmax(int &xx, int yy) {
  if (xx < yy) {
    xx = yy;
    return true;
  }
  return false;
}
bool chmin(int &xx, int yy) {
  if (xx > yy) {
    xx = yy;
    return true;
  }
  return false;
}
// x未満の要素数を返す二分探索関数
int b_s(vector<int> &vec, int xx) {
  return lower_bound(ALL(vec), xx) - vec.begin();
}
int gcd(int xx, int yy) {
  if (yy > xx)
    swap(xx, yy);
  while (xx % yy != 0) {
    xx %= yy;
    swap(xx, yy);
  }
  return yy;
}
int lcm(int xx, int yy) { return (xx / gcd(xx, yy)) * yy; }
bool prime(int xx) {
  if (xx <= 1)
    return 0;
  if (xx == 2)
    return 1;
  for (int i = 3; i * i <= xx; i += 2) {
    if (xx % i == 0) {
      return 0;
    }
  }
  return 1;
}

signed main() {
  int n, k;
  cin >> n >> k;
  VI vec(n);
  vecin(vec);
  segment_tree<int> seg(300100);
  rep(i, n) {
    seg.update(vec[i],
               seg.get_sum(max(vec[i] - k, 0ll), min(vec[i] + k, 300010ll)) +
                   1);
  }
  cout << seg.all() << endl;
}


/// // // // // // // // // ///
// Author : Kh@ntil S@nghani //
/// // // // // // // // // ///

#include <bits/stdc++.h>

using namespace std;
#define pb push_back
#define ll long long int
#define ld long double
#define ss second
#define ff first
#define inf LLONG_MAX
#define con continue
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define M 1000000007
#define endl '\\n'
// if vector isn't soted then it will remove consecutive same elements
#define make_unique(vec) vec.erase(unique(all(vec)), vec.end())
template <class T> ostream &operator<<(ostream &cout, vector<T> V) {
  cout << "[ ";
  for (auto v : V)
    cout << v << ' ';
  return cout << ']';
}
template <typename T> ostream &operator<<(ostream &out, const set<T> &N_A) {
  out << "{ ";
  for (const auto &i : N_A)
    out << i << ", ";
  return out << "}" << endl;
}
template <typename T, typename G>
ostream &operator<<(ostream &out, const map<T, G> &N_A) {
  out << "< ";
  for (const auto &i : N_A)
    out << i << ", ";
  return out << ">" << endl;
}
template <typename T> inline istream &operator>>(istream &in, vector<T> &N_A) {
  for (auto &x : N_A)
    in >> x;
  return in;
}
#define MAXN 10000001

ll dp[300005], a[300005];
ll n, k;
ll rec(ll x) {
  if (x >= n)
    return 0;
  if (dp[x] != -1)
    return dp[x];
  ll ans = 1;

  for (ll i = x + 1; i < n; i++) {
    if (i < n) {
      if (abs(a[x] - a[i]) <= k) {
        ans = max(ans, 1 + rec(i));
      }
    }
  }

  // ans=max(ans,rec(i+1));

  return dp[x] = ans;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ll _;
  _ = 1;
  // cin>>_;

  while (_--) {
    // cout<<fixed<<setprecision(9)<<y<<" "<<x<<endl;
    // cout<<_<<endl;
    cin >> n >> k;
    for (ll i = 0; i < n; i++) {
      dp[i] = -1;
      cin >> a[i];
    }
    for (ll i = n; i < n + 5; i++) {
      dp[i] = -1;
      a[i] = -1;
    }
    ll ans = 0;
    // for(ll i=0;i<n;i++)
    // {
    // 	ans=max(ans,rec(i));
    // }
    for (ll i = n - 1; i >= 0; i--) {
      ans = max(ans, rec(i));
    }
    cout << ans << endl;
    // for(ll i=0;i<n;i++) cout<<dp[i]<<" ";
  }
  return 0;
}

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

#define fast                                                                   \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

#define pb push_back
#define mp make_pair
#define F first
#define S second
#define pll pair<int, int>
#define int long long int
#define endl "\\n"

#define ALL(v) v.begin(), v.end()
#define ALLR(v) v.rbegin(), v.rend()
#define pii 3.14159265358979323
#define inf LLONG_MAX
#define ones(x) __builtin_popcount(x)
#define fill(a, b) memset(a, b, sizeof(a))
#define mod 998244353

ll mod_pow(ll a, ll b, ll m) {
  ll res = 1;
  while (b) {
    if (b & 1) {
      res = (res * a) % m;
    }
    a = (a * a) % m;
    b >>= 1;
  }
  return res;
}

ll mod_inverse(int a, int m) { return mod_pow(a, m - 2, m); }

const int maxn = 3e5 + 5;

int a[maxn];

int tree[6 * maxn];

int query(int v, int l, int r, int lq, int rq) {
  if (lq <= l && r <= rq) {
    return tree[v];
  }

  if (l > rq or lq > r) {
    return 0;
  }

  int mid = (l + r) / 2;

  int t1 = query(2 * v + 1, l, mid, lq, rq);
  int t2 = query(2 * v + 2, mid + 1, r, lq, rq);

  return max(t1, t2);
}

void update(int v, int pos, int l, int r, int val) {
  if (l == r) {
    tree[v] = val;
    return;
  }

  int mid = (l + r) / 2;

  if (pos <= mid) {
    update(2 * v + 1, pos, l, mid, val);
  } else {
    update(2 * v + 2, pos, mid + 1, r, val);
  }

  tree[v] = max(tree[2 * v + 1], tree[2 * v + 2]);
}

signed main() {
  fast;

  int n, k;

  cin >> n >> k;

  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
  }

  int mx = 1;

  for (int i = 1; i <= n; ++i) {
    int t1 = query(1, 1, 3e5, max(1LL, a[i] - k), min((ll)3e5, a[i] + k));
    int t2 = query(1, 1, 3e5, a[i], a[i]);

    if (t2 < t1 + 1) {
      update(1, a[i], 1, 3e5, t1 + 1);
      mx = max(mx, t1 + 1);
    }
  }

  cout << mx;

  return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define lld long double
#define pb push_back
#define pii pair<ll, ll>
#define mi map<ll, ll>
#define vec vector<ll>
#define all(a) (a).begin(), (a).end()
#define F first
#define S second
#define mod 1000000007
#define rep(i, a, b) for (ll i = a; i < b; i++)
#define repi(i, a, b) for (ll i = a; i <= b; i++)
#define per(i, a, b) for (ll i = a; i >= b; i--)
#define mp make_pair
#define mit map<ll, ll>::iterator
#define sit set<ll>::iterator
#define pit pair<ll, ll>::iterator
#define xxx exit(0);
#define tr(container, it)                                                      \\
  for (__typeof(container.begin()) it = container.begin();                     \\
       it != container.end(); it++)
using namespace std;
ll xo(ll x, ll y) { return (x | y) & (~x | ~y); }
ll bin_Expo(ll x, ll n) {
  if (x == 0)
    return 0;
  if (n == 0)
    return 1;
  else if (n % 2 == 0) // n is even
    return bin_Expo(x * x, n / 2);
  else // n is odd
    return x * bin_Expo(x * x, (n - 1) / 2);
}
ll mod_Expo(ll x, ll n, ll M) {
  if (x == 0)
    return 0;
  if (n == 0)
    return 1;
  else if (n % 2 == 0) // n is even
    return mod_Expo((x * x) % M, n / 2, M);
  else // n is odd
    return (x * mod_Expo((x * x) % M, (n - 1) / 2, M)) % M;
}
bool prime_check(ll x) {
  bool prime = (x >= 2);
  for (ll i = 2; i * i <= x; i++) {
    if (x % i == 0) {
      prime = false;
      break;
    }
  }
  return prime;
}
ll logg(ll base, ll x) { return (ll)(log(x) / log(base)); }
ll a[300005], dp[300005], n, k;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int TESTS = 1;
  //	cin>>TESTS;
  while (TESTS--) {
    ll m, i, j, l, h, w, q, ans, x, y;
    cin >> n >> k;
    rep(i, 0, n) cin >> a[i], dp[i] = 1;
    x = 1;
    rep(i, 1, n) {
      rep(j, 0, i) {
        if (abs(a[i] - a[j]) <= k)
          dp[i] = max(dp[i], dp[j] + 1);
      }
      x = max(x, dp[i]);
    }
    cout << x;
  }
  return 0;
}

#include <bits/stdc++.h>
#define ll long long int
#define lld long double
#define pb push_back
#define pii pair<ll, ll>
#define mi map<ll, ll>
#define vec vector<ll>
#define all(a) (a).begin(), (a).end()
#define F first
#define S second
#define mod 1000000007
#define rep(i, a, b) for (ll i = a; i < b; i++)
#define repi(i, a, b) for (ll i = a; i <= b; i++)
#define per(i, a, b) for (ll i = a; i >= b; i--)
#define mp make_pair
#define mit map<ll, ll>::iterator
#define sit set<ll>::iterator
#define pit pair<ll, ll>::iterator
#define xxx exit(0);
#define tr(container, it)                                                      \\
  for (__typeof(container.begin()) it = container.begin();                     \\
       it != container.end(); it++)
using namespace std;
ll xo(ll x, ll y) { return (x | y) & (~x | ~y); }
ll bin_Expo(ll x, ll n) {
  if (x == 0)
    return 0;
  if (n == 0)
    return 1;
  else if (n % 2 == 0) // n is even
    return bin_Expo(x * x, n / 2);
  else // n is odd
    return x * bin_Expo(x * x, (n - 1) / 2);
}
ll mod_Expo(ll x, ll n, ll M) {
  if (x == 0)
    return 0;
  if (n == 0)
    return 1;
  else if (n % 2 == 0) // n is even
    return mod_Expo((x * x) % M, n / 2, M);
  else // n is odd
    return (x * mod_Expo((x * x) % M, (n - 1) / 2, M)) % M;
}
bool prime_check(ll x) {
  bool prime = (x >= 2);
  for (ll i = 2; i * i <= x; i++) {
    if (x % i == 0) {
      prime = false;
      break;
    }
  }
  return prime;
}
ll logg(ll base, ll x) { return (ll)(log(x) / log(base)); }
ll a[300005], dp[300005], n, k;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int TESTS = 1;
  //	cin>>TESTS;
  while (TESTS--) {
    ll m, i, j, l, h, w, q, ans, x, y;
    cin >> n >> k;
    rep(i, 0, n) cin >> a[i], dp[i] = 1;
    x = 1;
    rep(i, 1, n) {
      for (j = i - 1; j >= 0 && i - j <= 100; j--) {
        if (abs(a[i] - a[j]) <= k)
          dp[i] = max(dp[i], dp[j] + 1);
      }
      x = max(x, dp[i]);
    }
    cout << x;
  }
  return 0;
}