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

typedef long long ll;
typedef unsigned long long int ull;
#define endl "\\n"
#define pb push_back
#define sq(a) (a) * (a)
#define all(x) (x).begin(), (x).end()
#define debug(x) cerr << #x << '=' << (x) << endl;
#define debugv(v)                                                              \\
  cerr << #v << " : ";                                                         \\
  for (auto x : v)                                                             \\
    cerr << x << ' ';                                                          \\
  cerr << endl;
#define MOD 1000000007
#define PI 3.141592653589793238
#define IOS                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

ll exp(ll x, ll n, ll mod) {
  ll result = 1;
  while (n) {
    if (n & 1)
      result = (result * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return result;
}

int32_t main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  IOS

      int n,
      k;
  cin >> n >> k;

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

  int ans = 1;
  for (int i = 1; i < n; i++) {
    for (int j = 0; j < i; j++) {
      if (abs(a[i] - a[j]) <= k)
        dp[i] = max(dp[i], dp[j] + 1);
    }
    ans = max(ans, dp[i]);
  }

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

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

typedef long long ll;
typedef unsigned long long int ull;
#define endl "\\n"
#define pb push_back
#define sq(a) (a) * (a)
#define all(x) (x).begin(), (x).end()
#define debug(x) cerr << #x << '=' << (x) << endl;
#define debugv(v)                                                              \\
  cerr << #v << " : ";                                                         \\
  for (auto x : v)                                                             \\
    cerr << x << ' ';                                                          \\
  cerr << endl;
#define MOD 1000000007
#define PI 3.141592653589793238
#define IOS                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

ll exp(ll x, ll n, ll mod) {
  ll result = 1;
  while (n) {
    if (n & 1)
      result = (result * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return result;
}

const int N = 3e5;

// Use Segment Tree for fuck sake

struct item {
  ll v;
};

struct segtree {
  int size;
  vector<item> values;

  void init(int n) {
    size = 1;
    while (size < n)
      size <<= 1;

    values.assign(2 * size, NEUTRAL_ELEMENT);
  }

  item NEUTRAL_ELEMENT = {0};

  item single(int v) { return {v}; }

  item merge(item a, item b) { return {max(a.v, b.v)}; }

  void build(vector<int> &a, int x, int lx, int rx) {
    if (rx - lx == 1) {
      if (lx < a.size())
        values[x] = single(a[lx]);
      return;
    }

    int m = (lx + rx) / 2;

    build(a, 2 * x + 1, lx, m);
    build(a, 2 * x + 2, m, rx);

    values[x] = merge(values[2 * x + 1], values[2 * x + 2]);
  }

  void build(vector<int> &a) { build(a, 0, 0, size); }

  void set(int i, int v, int x, int lx, int rx) {
    if (rx - lx == 1) {
      values[x] = single(v);
      return;
    }

    int m = (lx + rx) / 2;

    if (i < m)
      set(i, v, 2 * x + 1, lx, m);
    else
      set(i, v, 2 * x + 2, m, rx);

    values[x] = merge(values[2 * x + 1], values[2 * x + 2]);
  }

  void set(int i, int v) { set(i, v, 0, 0, size); }

  item calc(int l, int r, int x, int lx, int rx) {
    if (lx >= r || rx <= l)
      return NEUTRAL_ELEMENT;

    if (lx >= l && rx <= r)
      return values[x];

    int m = (lx + rx) / 2;

    item s1 = calc(l, r, 2 * x + 1, lx, m);
    item s2 = calc(l, r, 2 * x + 2, m, rx);

    return merge(s1, s2);
  }

  item calc(int l, int r) { return calc(l, r, 0, 0, size); }
};

int32_t main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  IOS

      int n,
      k;
  cin >> n >> k;

  segtree st;
  st.init(N + 1);
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int x;
    cin >> x;

    int l = max(x - k, 0), r = min(x + k, N);
    int temp = st.calc(l, r + 1).v + 1;
    ans = max(ans, temp);
    st.set(x, temp);
  }

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


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using pl = pair<ll, ll>;
using pi = pair<int, int>;
#define all(x) x.begin(), x.end()
#define rep(i, j, n) for (long long i = j; i < (long long)(n); i++)
#define _GLIBCXX_DEBUG
const ll MOD = 1000000007;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
//(a+b-1)/b
// priority_queue<ll, vector<ll>, greater<ll>> q;

class SegmentTree { // Range Maximum Queery
private:
  ll len;
  vl seg;

public:
  SegmentTree(ll n) {
    len = n;
    seg.resize(2 * n, 0);
  }

  void add(ll ind, ll x) {
    ind += len;
    seg[ind] += x;
    while (true) {
      ind /= 2;
      if (ind == 0)
        break;
      seg[ind] = max(seg[2 * ind], seg[2 * ind + 1]);
    }
  }

  void update(ll ind, ll x) {
    ind += len;
    seg[ind] = x;
    while (true) {
      ind /= 2;
      if (ind == 0)
        break;
      seg[ind] = max(seg[2 * ind], seg[2 * ind + 1]);
    }
  }

  ll get_max(ll l, ll r) {
    ll ans = 0;
    l += len;
    r += len;
    while (l < r) {
      if (l % 2 == 1) {
        chmax(ans, seg[l]);
        l++;
      }
      l /= 2;
      if (r % 2 == 1) {
        chmax(ans, seg[r - 1]);
        --r;
      }
      r /= 2;
    }
    return ans;
  }
};

signed main() {
  // cout << fixed << setprecision(10);
  ll n, k;
  cin >> n >> k;
  vl a(n);
  SegmentTree seg(n + 1);
  rep(i, 0, n) {
    ll x;
    cin >> x;
    a[i] = x;
  }
  rep(i, 0, n) {
    ll l = max((ll)1, a[i] - k);
    ll r = min(n, a[i] + k);
    seg.update(a[i], seg.get_max(l, r + 1) + 1);
  }
  cout << seg.get_max(1, n + 1) << endl;

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using pl = pair<ll, ll>;
using pi = pair<int, int>;
#define all(x) x.begin(), x.end()
#define rep(i, j, n) for (long long i = j; i < (long long)(n); i++)
#define _GLIBCXX_DEBUG
const ll MOD = 1000000007;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
//(a+b-1)/b
// priority_queue<ll, vector<ll>, greater<ll>> q;

class SegmentTree { // Range Maximum Queery
private:
  ll len;
  vl seg;

public:
  SegmentTree(ll n) {
    len = n;
    seg.resize(2 * n, 0);
  }

  void add(ll ind, ll x) {
    ind += len;
    seg[ind] += x;
    while (true) {
      ind /= 2;
      if (ind == 0)
        break;
      seg[ind] = max(seg[2 * ind], seg[2 * ind + 1]);
    }
  }

  void update(ll ind, ll x) {
    ind += len;
    seg[ind] = x;
    while (true) {
      ind /= 2;
      if (ind == 0)
        break;
      seg[ind] = max(seg[2 * ind], seg[2 * ind + 1]);
    }
  }

  ll get_max(ll l, ll r) {
    ll ans = 0;
    l += len;
    r += len;
    while (l < r) {
      if (l % 2 == 1) {
        chmax(ans, seg[l]);
        l++;
      }
      l /= 2;
      if (r % 2 == 1) {
        chmax(ans, seg[r - 1]);
        --r;
      }
      r /= 2;
    }
    return ans;
  }
};

signed main() {
  // cout << fixed << setprecision(10);
  ll n, k;
  cin >> n >> k;
  vl a(n);
  SegmentTree seg(300001);
  rep(i, 0, n) {
    ll x;
    cin >> x;
    a[i] = x;
  }
  rep(i, 0, n) {
    ll l = max((ll)0, a[i] - k);
    ll r = min((ll)300001, a[i] + k);
    seg.update(a[i], seg.get_max(l, r + 1) + 1);
  }
  cout << seg.get_max(0, 300001) << endl;

  return 0;
}


#include <bits/stdc++.h>
#define watch(x) std::cout << (#x) << " is " << (x) << std::endl
#define print(x) std::cout << (x) << std::endl
#define println std::cout << std::endl;
using LL = long long;
#define lrt rt << 1
#define rrt rt << 1 | 1
#define lson l, m, lrt
#define rson m + 1, r, rrt
const int N = 3e5 + 2;
int mx[N * 3];

void update(int p, int val, int l, int r, int rt) {
  mx[rt] = std::max(mx[rt], val);
  if (l == r)
    return;
  int m = (l + r) >> 1;
  if (p > m)
    update(p, val, rson);
  else
    update(p, val, lson);
}
int query(int L, int R, int l, int r, int rt) {
  if (L <= l && R >= r)
    return mx[rt];
  int m = (l + r) >> 1;
  int ans = 0;
  if (L <= m)
    ans = std::max(ans, query(L, R, lson));
  if (R > m)
    ans = std::max(ans, query(L, R, rson));
  return ans;
}
int main() {
  // freopen("in","r",stdin);
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int n, k;
  std::cin >> n >> k;
  for (int i = 0, x; i < n; ++i) {
    std::cin >> x;
    ++x;
    int now = query(x - k, x + k, 1, N, 1);
    update(x, now + 1, 1, N, 1);
  }
  print(mx[1]);
  return 0;
}

#include <bits/stdc++.h>
#define watch(x) std::cout << (#x) << " is " << (x) << std::endl
#define print(x) std::cout << (x) << std::endl
#define println std::cout << std::endl;
using LL = long long;
#define lrt rt << 1
#define rrt rt << 1 | 1
#define lson l, m, lrt
#define rson m + 1, r, rrt
const int N = 3e5 + 2;
int mx[N * 5];

void update(int p, int val, int l, int r, int rt) {
  mx[rt] = std::max(mx[rt], val);
  if (l == r)
    return;
  int m = (l + r) >> 1;
  if (p > m)
    update(p, val, rson);
  else
    update(p, val, lson);
}
int query(int L, int R, int l, int r, int rt) {
  if (L <= l && R >= r)
    return mx[rt];
  int m = (l + r) >> 1;
  int ans = 0;
  if (L <= m)
    ans = std::max(ans, query(L, R, lson));
  if (R > m)
    ans = std::max(ans, query(L, R, rson));
  return ans;
}
int main() {
  // freopen("in","r",stdin);
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int n, k;
  std::cin >> n >> k;
  for (int i = 0, x; i < n; ++i) {
    std::cin >> x;
    ++x;
    int now = query(x - k, x + k, 1, N, 1);
    update(x, now + 1, 1, N, 1);
  }
  print(mx[1]);
  return 0;
}


// #include "bits/stdc++.h"
#include <bits/stdc++.h>
using namespace std;
// using namespace atcoder;
using ll = long long;

template <typename T>
void print_vec(const vector<T> &v, bool is_reverse = false, ll num = 0) {
  if (num == 0)
    num = (ll)v.size();
  cout << endl;
  cout << "i=  ";
  for (ll i = 0; i < num; i++)
    cout << i << "   ";
  cout << endl;
  cout << "    ";
  if (is_reverse)
    for (ll i = num - 1; i >= 0; i--) {
      cout << v[i];
      if (i != 0)
        cout << "   ";
    }
  else
    for (ll i = 0; i < num; i++) {
      cout << v[i];
      if (i != num - 1)
        cout << "   ";
    }
  cout << endl;
}

// template <typename T>
// void print_pairvec(const vector<T> &v, ll num=0){
//   if(num == 0) num = (ll)v.size();
//   cout << endl; for(ll i=0; i<num; i++){ cout << v[i].first << " " <<
//   v[i].second << endl;}
// }
template <typename T> void print_pairvec(const T &_pair, ll num = 0) {
  cout << endl;
  for (pair<ll, int> x : _pair) {
    cout << x.first << " " << x.second << endl;
  }
}

template <typename T> void print_vec2(const vector<vector<T>> &v) {
  cout << endl;
  cout << "       ";
  for (ll i = 0; i < v[0].size(); i++)
    cout << i << "   ";
  cout << endl;
  for (ll i = 0; i < v.size(); i++) {
    cout << "i=" << i << ":   ";
    for (ll j = 0; j < v[i].size(); j++) {
      if (v[i][j] == 0)
        cout << "\\x1B[0m" << v[i][j] << "   ";
      else
        cout << "\\x1B[31m" << v[i][j]
             << "   "; // https://stackoverrun.com/ja/q/12618775
    }
    cout << "\\x1B[0m" << endl;
  }
}

int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];

  const ll MAX = 3e5 + 10;
  vector<ll> vec(MAX, 0);
  for (int i = 0; i < n; i++) {
    ll tmp = vec[a[i]];
    for (int j = a[i] - k; j <= a[i] + k; j++) {
      if (j >= MAX)
        continue;
      if (j < 0)
        continue;
      tmp = max(tmp, vec[j] + 1);
    }
    vec[a[i]] = tmp;
  }

  ll ans = 0;
  for (int i = 0; i < (int)vec.size(); i++)
    ans = max(ans, vec[i]);
  cout << ans << endl;

  return 0;
  // // const ll MAX =3e5+k + 10;
  // // vector<ll> dp(MAX + 5, 0);

  // // for(int i=0; i<N; i++){
  // //   for(int j)
  // // }

  // vector<stack<ll>> st;
  // // using P = pair<ll, int>;
  // // vector<P> backs;
  // vector<ll> backs;
  // for(int i=0; i<n; i++){
  //   bool is_add = false;
  //   ll l_index, r_index;
  //   ll l_index = lower_bound(backs.begin(), backs.end(), a[i]-k) -
  //   backs.begin(); ll r_index = upper_bound(backs.begin(), backs.end(), a[i]
  //   + k) - backs.begin(); vector<stack<ll>> tmp_st; vector<ll> tmp_backs;
  //   // ll size = (ll)st.size();
  //   for(int j=l_index; j<= r_index; j++){
  //     // int index = backs[j].second;
  //     // ll x = st[index].top();
  //     ll x =
  //     if(abs(x - a[i]) <= k ){
  //       stack<ll> b;
  //       b = st[j];
  //       b.push(a[i]);
  //       is_add = true;
  //       tmp_st.push_back(b);
  //       tmp_st.push_back(st[j]);
  //     }
  //     else tmp_st.push_back(st[j]);
  //   }

  //   // for(int j=0; j<size; j++){
  //   //   ll x = st[j].top();
  //   //   if(abs(x - a[i]) <= k){
  //   //     stack<ll> b;
  //   //     b = st[j];
  //   //     b.push(a[i]);
  //   //     // st.push_back(b);
  //   //     is_add = true;
  //   //     tmp_st.push_back(b);
  //   //     tmp_st.push_back(st[j]);
  //   //     tmp_backs.push_back()
  //   //   }
  //   //   else tmp_st.push_back(st[j]);

  //   st.clear();
  //   st = tmp_st;
  //   if(is_add == false){
  //     stack<ll> b;
  //     b.push(a[i]);
  //     st.push_back(b);
  //   }
  // }

  // ll ans = 0;
  // for(stack<ll> x: st) ans = max(ans, (ll)x.size());

  // cout << ans << endl;

  return 0;
  // cout << fixed;//小数点を確実に10桁で表示するためのもの
  // cout << setprecision(10);
}

#include "bits/stdc++.h"
// #include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
using ll = long long;

template <typename T>
void print_vec(const vector<T> &v, bool is_reverse = false, ll num = 0) {
  if (num == 0)
    num = (ll)v.size();
  cout << endl;
  cout << "i=  ";
  for (ll i = 0; i < num; i++)
    cout << i << "   ";
  cout << endl;
  cout << "    ";
  if (is_reverse)
    for (ll i = num - 1; i >= 0; i--) {
      cout << v[i];
      if (i != 0)
        cout << "   ";
    }
  else
    for (ll i = 0; i < num; i++) {
      cout << v[i];
      if (i != num - 1)
        cout << "   ";
    }
  cout << endl;
}

// template <typename T>
// void print_pairvec(const vector<T> &v, ll num=0){
//   if(num == 0) num = (ll)v.size();
//   cout << endl; for(ll i=0; i<num; i++){ cout << v[i].first << " " <<
//   v[i].second << endl;}
// }
template <typename T> void print_pairvec(const T &_pair, ll num = 0) {
  cout << endl;
  for (pair<ll, int> x : _pair) {
    cout << x.first << " " << x.second << endl;
  }
}

template <typename T> void print_vec2(const vector<vector<T>> &v) {
  cout << endl;
  cout << "       ";
  for (ll i = 0; i < v[0].size(); i++)
    cout << i << "   ";
  cout << endl;
  for (ll i = 0; i < v.size(); i++) {
    cout << "i=" << i << ":   ";
    for (ll j = 0; j < v[i].size(); j++) {
      if (v[i][j] == 0)
        cout << "\\x1B[0m" << v[i][j] << "   ";
      else
        cout << "\\x1B[31m" << v[i][j]
             << "   "; // https://stackoverrun.com/ja/q/12618775
    }
    cout << "\\x1B[0m" << endl;
  }
}

const int INF = 1e+5;
int op(int a, int b) { return max(a, b); }
// int e(){return -INF;}
int e() { return 0; }
int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];

  const int A_MAX = 3e5 + 5;
  segtree<int, op, e> seg(A_MAX + 5);
  // dp[j]: 最後がjであるときのaの部分列の最大長
  for (int i = 0; i < n; i++) {
    int j = a[i];
    int l = max(0, j - k);
    int r = min(j + k + 1, A_MAX);
    seg.set(j, seg.prod(l, r) + 1);
  }

  // int ans = seg.all_prod();
  int ans = seg.prod(0, A_MAX);
  cout << ans << endl;
  return 0;
  // cout << fixed;//小数点を確実に10桁で表示するためのもの
  // cout << setprecision(10);
}


#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;

#define BOOST
#ifdef BOOST
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
using ml = boost::multiprecision::cpp_int;
using md = boost::multiprecision::cpp_dec_float_100;
#endif

/***** type *****/
using ll = long long;
using ld = long double;
using pll = pair<long long, long long>;
template <class T> using vt = vector<T>;
template <class T> using vvt = vector<vector<T>>;
template <class T> using vvvt = vector<vector<vector<T>>>;
using mg = vector<vector<long long>>;
using lg = vector<vector<long long>>;
using wlg = vector<vector<pair<long long, long long>>>;
/***** define *****/
#define all(c) (c).begin(), (c).end()            // begin to end
#define coutld cout << fixed << setprecision(10) // cout double
#define output(x)                                                              \\
  do {                                                                         \\
    cout << x << endl;                                                         \\
    exit(0);                                                                   \\
  } while (0)
#define rep(i, b, e) for (ll i = b; i < e; i++)  // repeat
#define repr(i, b, e) for (ll i = b; e < i; i--) // repeat reverse
#define fori(i, ...)                                                           \\
  if (ll i = -1)                                                               \\
    for (__VA_ARGS__)                                                          \\
      if (i++, 1)
#define each(i, e, c) fori(i, auto &&e : c) // for each
/***** const value *****/
#define llong_max 9223372036854775807 // 9 * 10^18
#define ldbl_max 1.79769e+308         // 1.7 * 10^308
#define pi 3.1415926535897932         // 3.14 ...
/***** lambda *****/
auto Ceil = [] // if (a % b != 0) return a / b + 1;
    (auto x) { return (ll)ceil(x); };
auto Count = [] // long long count value
    (auto b, auto e, auto x) { return (ll)count(b, e, x); };
auto CtoL = [] // char to number
    (auto c) { return (ll)c - (ll)'0'; };
auto LtoC = [] // number to char
    (auto n) { return (char)('0' + n); };
auto Pow = [] // long long pow
    (auto a, auto b) { return (ll)pow(a, b); };
auto Pow2 = [] // long long pow2
    (auto n) { return (1LL << n); };
auto Pow10 = [] // long long pow10
    (auto n) { return (ll)pow(10, n); };
auto Size = [] // long long collection size
    (auto &c) { return (ll)(c).size(); };
auto Sum = [] // long long accumulate
    (auto b, auto e) { return accumulate(b, e, 0LL); };

/***** operator *****/
template <class T, class S>
pair<T, S> operator+(pair<T, S> l, pair<T, S> r) { // pair<T, S> + pair<T, S>
  return {l.first + r.first, l.second + r.second};
}
template <class T, class S>
pair<T, S> operator-(pair<T, S> l, pair<T, S> r) { // pair<T, S> - pair<T, S>
  return {l.first - r.first, l.second - r.second};
}
/***** template *****/
template <class A, class B, class C> struct triple { // tuple<A, B, C>
  A a = A();
  B b = B();
  C c = C();
};
template <class T>
void MakeVVT(ll ys, ll xs, vvt<T> &v,
             T fill = T()) { // vector<vector<T>> resize + fill
  v.resize(ys);
  rep(y, 0, ys) v[y].resize(xs, fill);
}
template <class T>
void MakeVVVT(ll zs, ll ys, ll xs, vvvt<T> &v,
              T fill = T()) { // vector<vector<vector<T>>> resize + fill
  v.resize(zs);
  rep(z, 0, zs) MakeVVT(ys, xs, v[z], fill);
}
template <class T>
void InputVVT(ll ys, ll xs, vvt<T> &v,
              T fix = T()) { // input vector<vector<T>> (T != struct) + fix
  MakeVVT(ys, xs, v, fix);
  rep(y, 0, ys) rep(x, 0, xs) {
    cin >> v[y][x];
    v[y][x] += fix;
  }
}
template <class T>
void InputVVVT(
    ll zs, ll ys, ll xs, vvvt<T> &v,
    T fix = T()) { // input vector<vector<vector<T>>> (T != struct) + fix
  v.resize(zs);
  rep(z, 0, zs) InputVVT(ys, xs, v[z], fix);
}

/**************************************/
/********** BEGIN OF NYA LIB **********/
/**************************************/

namespace NyaGadget {}

namespace NyaGadget {
template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S),
          F (*composition)(F, F), F (*id)()>
struct DS_NyaaLST {
public:
  DS_NyaaLST() : DS_NyaaLST(0) {}
  DS_NyaaLST(int n) : DS_NyaaLST(std::vector<S>(n, e())) {}
  DS_NyaaLST(const std::vector<S> &v) : _n(int(v.size())) {
    log = ceil_pow2(_n);
    size = 1 << log;
    d = std::vector<S>(2 * size, e());
    lz = std::vector<F>(size, id());
    for (int i = 0; i < _n; i++)
      d[size + i] = v[i];
    for (int i = size - 1; i >= 1; i--) {
      update(i);
    }
  }

  void set(int p, S x) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--)
      push(p >> i);
    d[p] = x;
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  S get(int p) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--)
      push(p >> i);
    return d[p];
  }

  S prod(long long L, long long R) { // long long -> int 型変換
    int l = (int)L;
    int r = (int)R;
    assert(0 <= l && l <= r && r <= _n);
    if (l == r)
      return e();

    l += size;
    r += size;

    for (int i = log; i >= 1; i--) {
      if (((l >> i) << i) != l)
        push(l >> i);
      if (((r >> i) << i) != r)
        push(r >> i);
    }

    S sml = e(), smr = e();
    while (l < r) {
      if (l & 1)
        sml = op(sml, d[l++]);
      if (r & 1)
        smr = op(d[--r], smr);
      l >>= 1;
      r >>= 1;
    }

    return op(sml, smr);
  }

  S all_prod() { return d[1]; }

  void apply(int p, F f) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--)
      push(p >> i);
    d[p] = mapping(f, d[p]);
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  void apply(long long L, long long R, F f) { // long long -> int 型変換
    int l = (int)L;
    int r = (int)R;
    assert(0 <= l && l <= r && r <= _n);
    if (l == r)
      return;

    l += size;
    r += size;

    for (int i = log; i >= 1; i--) {
      if (((l >> i) << i) != l)
        push(l >> i);
      if (((r >> i) << i) != r)
        push((r - 1) >> i);
    }

    {
      int l2 = l, r2 = r;
      while (l < r) {
        if (l & 1)
          all_apply(l++, f);
        if (r & 1)
          all_apply(--r, f);
        l >>= 1;
        r >>= 1;
      }
      l = l2;
      r = r2;
    }

    for (int i = 1; i <= log; i++) {
      if (((l >> i) << i) != l)
        update(l >> i);
      if (((r >> i) << i) != r)
        update((r - 1) >> i);
    }
  }

  template <bool (*g)(S)> int max_right(int l) {
    return max_right(l, [](S x) { return g(x); });
  }

  template <class G> int max_right(int l, G g) {
    assert(0 <= l && l <= _n);
    assert(g(e()));
    if (l == _n)
      return _n;
    l += size;
    for (int i = log; i >= 1; i--)
      push(l >> i);
    S sm = e();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!g(op(sm, d[l]))) {
        while (l < size) {
          push(l);
          l = (2 * l);
          if (g(op(sm, d[l]))) {
            sm = op(sm, d[l]);
            l++;
          }
        }
        return l - size;
      }
      sm = op(sm, d[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }

  template <bool (*g)(S)> int min_left(int r) {
    return min_left(r, [](S x) { return g(x); });
  }

  template <class G> int min_left(int r, G g) {
    assert(0 <= r && r <= _n);
    assert(g(e()));
    if (r == 0)
      return 0;
    r += size;
    for (int i = log; i >= 1; i--)
      push((r - 1) >> i);
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!g(op(d[r], sm))) {
        while (r < size) {
          push(r);
          r = (2 * r + 1);
          if (g(op(d[r], sm))) {
            sm = op(d[r], sm);
            r--;
          }
        }
        return r + 1 - size;
      }
      sm = op(d[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

private:
  int _n, size, log;
  std::vector<S> d;
  std::vector<F> lz;
  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
  void all_apply(int k, F f) {
    d[k] = mapping(f, d[k]);
    if (k < size)
      lz[k] = composition(f, lz[k]);
  }
  void push(int k) {
    all_apply(2 * k, lz[k]);
    all_apply(2 * k + 1, lz[k]);
    lz[k] = id();
  }
  // @param n `0 <= n`
  // @return minimum non-negative `x` s.t. `n <= 2**x`
  int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n))
      x++;
    return x;
  }
};
} // namespace NyaGadget

/**************************************/
/*********** END OF NYA LIB ***********/
/**************************************/

using namespace NyaGadget;
// using mll = NT_ModLL< 1000000007 >;
// using mll = NT_ModLL< 998244353 >;

using TypeLST = long long;
const TypeLST LST_INF = 8e18;
TypeLST op(TypeLST a, TypeLST b) { return std::max(a, b); }
TypeLST e() { return -LST_INF; }
TypeLST mapping(TypeLST f, TypeLST x) { return f + x; }
TypeLST composition(TypeLST f, TypeLST g) { return f + g; }
TypeLST id() { return 0; }

int main() {
  int N, K;
  cin >> N >> K;
  vt<int> A(N);
  each(i, e, A) cin >> e;
  DS_NyaaLST<TypeLST, op, e, TypeLST, mapping, composition, id> lst(N);

  lst.apply(A[0], A[0] + 1, 1);
  rep(i, 1, Size(A))
      lst.apply(A[i], A[i] + 1,
                lst.prod(max(0, A[i] - K), min(300000 + 1, A[i] + K + 1)) + 1);

  ll ans = 0;
  rep(i, 0, Size(A)) ans = max(ans, lst.prod(A[i], A[i] + 1));
  cout << ans;
  return 0;
}

#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;

#define BOOST
#ifdef BOOST
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
using ml = boost::multiprecision::cpp_int;
using md = boost::multiprecision::cpp_dec_float_100;
#endif

/***** type *****/
using ll = long long;
using ld = long double;
using pll = pair<long long, long long>;
template <class T> using vt = vector<T>;
template <class T> using vvt = vector<vector<T>>;
template <class T> using vvvt = vector<vector<vector<T>>>;
using mg = vector<vector<long long>>;
using lg = vector<vector<long long>>;
using wlg = vector<vector<pair<long long, long long>>>;
/***** define *****/
#define all(c) (c).begin(), (c).end()            // begin to end
#define coutld cout << fixed << setprecision(10) // cout double
#define output(x)                                                              \\
  do {                                                                         \\
    cout << x << endl;                                                         \\
    exit(0);                                                                   \\
  } while (0)
#define rep(i, b, e) for (ll i = b; i < e; i++)  // repeat
#define repr(i, b, e) for (ll i = b; e < i; i--) // repeat reverse
#define fori(i, ...)                                                           \\
  if (ll i = -1)                                                               \\
    for (__VA_ARGS__)                                                          \\
      if (i++, 1)
#define each(i, e, c) fori(i, auto &&e : c) // for each
/***** const value *****/
#define llong_max 9223372036854775807 // 9 * 10^18
#define ldbl_max 1.79769e+308         // 1.7 * 10^308
#define pi 3.1415926535897932         // 3.14 ...
/***** lambda *****/
auto Ceil = [] // if (a % b != 0) return a / b + 1;
    (auto x) { return (ll)ceil(x); };
auto Count = [] // long long count value
    (auto b, auto e, auto x) { return (ll)count(b, e, x); };
auto CtoL = [] // char to number
    (auto c) { return (ll)c - (ll)'0'; };
auto LtoC = [] // number to char
    (auto n) { return (char)('0' + n); };
auto Pow = [] // long long pow
    (auto a, auto b) { return (ll)pow(a, b); };
auto Pow2 = [] // long long pow2
    (auto n) { return (1LL << n); };
auto Pow10 = [] // long long pow10
    (auto n) { return (ll)pow(10, n); };
auto Size = [] // long long collection size
    (auto &c) { return (ll)(c).size(); };
auto Sum = [] // long long accumulate
    (auto b, auto e) { return accumulate(b, e, 0LL); };

/***** operator *****/
template <class T, class S>
pair<T, S> operator+(pair<T, S> l, pair<T, S> r) { // pair<T, S> + pair<T, S>
  return {l.first + r.first, l.second + r.second};
}
template <class T, class S>
pair<T, S> operator-(pair<T, S> l, pair<T, S> r) { // pair<T, S> - pair<T, S>
  return {l.first - r.first, l.second - r.second};
}
/***** template *****/
template <class A, class B, class C> struct triple { // tuple<A, B, C>
  A a = A();
  B b = B();
  C c = C();
};
template <class T>
void MakeVVT(ll ys, ll xs, vvt<T> &v,
             T fill = T()) { // vector<vector<T>> resize + fill
  v.resize(ys);
  rep(y, 0, ys) v[y].resize(xs, fill);
}
template <class T>
void MakeVVVT(ll zs, ll ys, ll xs, vvvt<T> &v,
              T fill = T()) { // vector<vector<vector<T>>> resize + fill
  v.resize(zs);
  rep(z, 0, zs) MakeVVT(ys, xs, v[z], fill);
}
template <class T>
void InputVVT(ll ys, ll xs, vvt<T> &v,
              T fix = T()) { // input vector<vector<T>> (T != struct) + fix
  MakeVVT(ys, xs, v, fix);
  rep(y, 0, ys) rep(x, 0, xs) {
    cin >> v[y][x];
    v[y][x] += fix;
  }
}
template <class T>
void InputVVVT(
    ll zs, ll ys, ll xs, vvvt<T> &v,
    T fix = T()) { // input vector<vector<vector<T>>> (T != struct) + fix
  v.resize(zs);
  rep(z, 0, zs) InputVVT(ys, xs, v[z], fix);
}

/**************************************/
/********** BEGIN OF NYA LIB **********/
/**************************************/

namespace NyaGadget {}

namespace NyaGadget {
template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S),
          F (*composition)(F, F), F (*id)()>
struct DS_NyaaLST {
public:
  DS_NyaaLST() : DS_NyaaLST(0) {}
  DS_NyaaLST(int n) : DS_NyaaLST(std::vector<S>(n, e())) {}
  DS_NyaaLST(const std::vector<S> &v) : _n(int(v.size())) {
    log = ceil_pow2(_n);
    size = 1 << log;
    d = std::vector<S>(2 * size, e());
    lz = std::vector<F>(size, id());
    for (int i = 0; i < _n; i++)
      d[size + i] = v[i];
    for (int i = size - 1; i >= 1; i--) {
      update(i);
    }
  }

  void set(int p, S x) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--)
      push(p >> i);
    d[p] = x;
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  S get(int p) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--)
      push(p >> i);
    return d[p];
  }

  S prod(long long L, long long R) { // long long -> int 型変換
    int l = (int)L;
    int r = (int)R;
    assert(0 <= l && l <= r && r <= _n);
    if (l == r)
      return e();

    l += size;
    r += size;

    for (int i = log; i >= 1; i--) {
      if (((l >> i) << i) != l)
        push(l >> i);
      if (((r >> i) << i) != r)
        push(r >> i);
    }

    S sml = e(), smr = e();
    while (l < r) {
      if (l & 1)
        sml = op(sml, d[l++]);
      if (r & 1)
        smr = op(d[--r], smr);
      l >>= 1;
      r >>= 1;
    }

    return op(sml, smr);
  }

  S all_prod() { return d[1]; }

  void apply(int p, F f) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--)
      push(p >> i);
    d[p] = mapping(f, d[p]);
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  void apply(long long L, long long R, F f) { // long long -> int 型変換
    int l = (int)L;
    int r = (int)R;
    assert(0 <= l && l <= r && r <= _n);
    if (l == r)
      return;

    l += size;
    r += size;

    for (int i = log; i >= 1; i--) {
      if (((l >> i) << i) != l)
        push(l >> i);
      if (((r >> i) << i) != r)
        push((r - 1) >> i);
    }

    {
      int l2 = l, r2 = r;
      while (l < r) {
        if (l & 1)
          all_apply(l++, f);
        if (r & 1)
          all_apply(--r, f);
        l >>= 1;
        r >>= 1;
      }
      l = l2;
      r = r2;
    }

    for (int i = 1; i <= log; i++) {
      if (((l >> i) << i) != l)
        update(l >> i);
      if (((r >> i) << i) != r)
        update((r - 1) >> i);
    }
  }

  template <bool (*g)(S)> int max_right(int l) {
    return max_right(l, [](S x) { return g(x); });
  }

  template <class G> int max_right(int l, G g) {
    assert(0 <= l && l <= _n);
    assert(g(e()));
    if (l == _n)
      return _n;
    l += size;
    for (int i = log; i >= 1; i--)
      push(l >> i);
    S sm = e();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!g(op(sm, d[l]))) {
        while (l < size) {
          push(l);
          l = (2 * l);
          if (g(op(sm, d[l]))) {
            sm = op(sm, d[l]);
            l++;
          }
        }
        return l - size;
      }
      sm = op(sm, d[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }

  template <bool (*g)(S)> int min_left(int r) {
    return min_left(r, [](S x) { return g(x); });
  }

  template <class G> int min_left(int r, G g) {
    assert(0 <= r && r <= _n);
    assert(g(e()));
    if (r == 0)
      return 0;
    r += size;
    for (int i = log; i >= 1; i--)
      push((r - 1) >> i);
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!g(op(d[r], sm))) {
        while (r < size) {
          push(r);
          r = (2 * r + 1);
          if (g(op(d[r], sm))) {
            sm = op(d[r], sm);
            r--;
          }
        }
        return r + 1 - size;
      }
      sm = op(d[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

private:
  int _n, size, log;
  std::vector<S> d;
  std::vector<F> lz;
  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
  void all_apply(int k, F f) {
    d[k] = mapping(f, d[k]);
    if (k < size)
      lz[k] = composition(f, lz[k]);
  }
  void push(int k) {
    all_apply(2 * k, lz[k]);
    all_apply(2 * k + 1, lz[k]);
    lz[k] = id();
  }
  // @param n `0 <= n`
  // @return minimum non-negative `x` s.t. `n <= 2**x`
  int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n))
      x++;
    return x;
  }
};
} // namespace NyaGadget

/**************************************/
/*********** END OF NYA LIB ***********/
/**************************************/

using namespace NyaGadget;
// using mll = NT_ModLL< 1000000007 >;
// using mll = NT_ModLL< 998244353 >;

// LST定義（範囲更新、範囲最大値取得）
using TypeLST = long long;
const TypeLST INF = 8e18;
const TypeLST ID = 8e18;
TypeLST op(TypeLST a, TypeLST b) { return std::max(a, b); }
TypeLST e() { return -INF; }
TypeLST mapping(TypeLST f, TypeLST x) { return (f == ID ? x : f); }
TypeLST composition(TypeLST f, TypeLST g) { return (f == ID ? g : f); }
TypeLST id() { return ID; }

int main() {
  ll N, K;
  cin >> N >> K;
  vt<ll> A(N);
  each(i, e, A) cin >> e;
  DS_NyaaLST<TypeLST, op, e, TypeLST, mapping, composition, id> lst(
      vt<TypeLST>(300000 + 2));

  lst.apply(A[0], A[0] + 1, 1);
  rep(i, 1, Size(A)) lst.apply(
      A[i], A[i] + 1,
      lst.prod(max(0LL, A[i] - K), min(300000LL + 1, A[i] + K + 1)) + 1);

  ll ans = 0;
  rep(i, 0, Size(A)) ans = max(ans, lst.prod(A[i], A[i] + 1));
  cout << ans;
  return 0;
}

6e267a69-9522-4221-a6b2-bfc71e0b37a1.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p02537/C++/s182087722.cpp:139: S NyaGadget::DS_NyaaLST<S, op, e, F, mapping, composition, id>::prod(long long int, long long int) [with S = long long int; S (* op)(S, S) = op; S (* e)() = e; F = long long int; S (* mapping)(F, S) = mapping; F (* composition)(F, F) = composition; F (* id)() = id]: Assertion `0 <= l && l <= r && r <= _n' failed.


#include <bits/stdc++.h>
using namespace std;
#define int long long
struct segt {
  int l, r, maxv;
} tree[2400010];
int a[300010], dp[300010];
void build(int le, int ri, int i) {
  tree[i].l = le;
  tree[i].r = ri;
  tree[i].maxv = 0;
  if (le == ri)
    return;
  int mid = (le + ri) >> 1;
  build(le, mid, i << 1);
  build(mid + 1, ri, i << 1 | 1);
}
void change(int p, int x, int i) {
  if (tree[i].l == tree[i].r) {
    tree[i].maxv = max(tree[i].maxv, x);
    return;
  }
  if (tree[i << 1].r >= p)
    change(p, x, i << 1);
  else
    change(p, x, i << 1 | 1);
  tree[i].maxv = max(tree[i << 1].maxv, tree[i << 1 | 1].maxv);
}
int ask(int le, int ri, int i) {
  if (le <= tree[i].l && tree[i].r <= ri)
    return tree[i].maxv;
  int cnt = 0;
  if (tree[i << 1].r >= le)
    cnt = ask(le, ri, i << 1);
  if (tree[i << 1 | 1].l <= ri)
    cnt = max(cnt, ask(le, ri, i << 1 | 1));
  return cnt;
}
signed main() {
  int n, k, i, ans = 1;
  cin >> n >> k;
  for (i = 1; i <= n; i++)
    cin >> a[i];
  build(1, 300002, 1);
  for (i = 1; i <= n; i++) {
    dp[i] = max(
        1ll, ask(max(0ll, a[i] - k) + 1, min(300000ll, a[i] + k) + 1, 1) + 1);
    change(a[i] + 1, dp[i], 1);
    ans = max(ans, dp[i]);
  }
  cout << ans;
  return 0;
}


#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(v) v.begin(), v.end()
typedef long long ll;

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

const int INF = 2147483647;

/* RMQ：[0,n-1] について、区間ごとの最小値を管理する構造体
    set(int i, T x), build():
   i番目の要素をxにセット。まとめてセグ木を構築する。O(n) update(i,x): i
   番目の要素を x に更新。O(log(n)) query(a,b): [a,b)
   での最小の要素を取得。O(log(n)) find_rightest(a,b,x): [a,b) で
   x以下の要素を持つ最右位置を求める。O(log(n)) find_leftest(a,b,x): [a,b) で
   x以下の要素を持つ最左位置を求める。O(log(n))
*/
template <typename X> struct SegTree {
  using FX = function<X(X, X)>; // X•X -> X となる関数の型
  int n;
  FX fx;
  const X ex;
  vector<X> dat;
  SegTree(int n_, FX fx_, X ex_) : n(), fx(fx_), ex(ex_), dat(n_ * 4, ex_) {
    int x = 1;
    while (n_ > x) {
      x *= 2;
    }
    n = x;
  }
  void set(int i, X x) { dat[i + n - 1] = x; }
  void build() {
    for (int k = n - 2; k >= 0; k--)
      dat[k] = fx(dat[2 * k + 1], dat[2 * k + 2]);
  }
  void update(int i, X x) {
    i += n - 1;
    dat[i] = x;
    while (i > 0) {
      i = (i - 1) / 2; // parent
      dat[i] = fx(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }
  X get(int i) { return dat[i + n - 1]; }
  X all() { return dat[1]; }
  X query(int a, int b) { return query_sub(a, b, 0, 0, n); }
  X query_sub(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return ex;
    } else if (a <= l && r <= b) {
      return dat[k];
    } else {
      X vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
      X vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
      return fx(vl, vr);
    }
  }
  int find_rightest(int a, int b, X x) {
    return find_rightest_sub(a, b, x, 0, 0, n);
  }
  int find_leftest(int a, int b, X x) {
    return find_leftest_sub(a, b, x, 0, 0, n);
  }
  int find_rightest_sub(int a, int b, X x, int k, int l, int r) {
    if (dat[k] > x || r <= a ||
        b <= l) { // 自分の値がxより大きい or [a,b)が[l,r)の範囲外ならreturn a-1
      return a - 1;
    } else if (k >= n - 1) { // 自分が葉ならその位置をreturn
      return (k - (n - 1));
    } else {
      int vr = find_rightest_sub(a, b, x, 2 * k + 2, (l + r) / 2, r);
      if (vr != a - 1) { // 右の部分木を見て a-1 以外ならreturn
        return vr;
      } else { // 左の部分木を見て値をreturn
        return find_rightest_sub(a, b, x, 2 * k + 1, l, (l + r) / 2);
      }
    }
  }
  int find_leftest_sub(int a, int b, X x, int k, int l, int r) {
    if (dat[k] > x || r <= a ||
        b <= l) { // 自分の値がxより大きい or [a,b)が[l,r)の範囲外ならreturn b
      return b;
    } else if (k >= n - 1) { // 自分が葉ならその位置をreturn
      return (k - (n - 1));
    } else {
      int vl = find_leftest_sub(a, b, x, 2 * k + 1, l, (l + r) / 2);
      if (vl != b) { // 左の部分木を見て b 以外ならreturn
        return vl;
      } else { // 右の部分木を見て値をreturn
        return find_leftest_sub(a, b, x, 2 * k + 2, (l + r) / 2, r);
      }
    }
  }
};

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

  vector<int> A(n);
  rep(i, n) cin >> A[i];

  // fx:二項演算,ex:単位元,0-index
  using X = int;
  auto fx = [](X x1, X x2) -> X { return max(x1, x2); };
  X ex = 0;
  SegTree<X> seg(n, fx, ex);

  rep(i, n) {
    int l = max(0, A[i] - k);
    int r = min(n - 1, A[i] + k);
    int tmp = seg.query(l, r + 1) + 1;
    seg.update(A[i], tmp);
  }
  cout << seg.all() << endl;

  return 0;
}

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(v) v.begin(), v.end()
typedef long long ll;

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

const int INF = 2147483647;

/* RMQ：[0,n-1] について、区間ごとの最小値を管理する構造体
    set(int i, T x), build():
   i番目の要素をxにセット。まとめてセグ木を構築する。O(n) update(i,x): i
   番目の要素を x に更新。O(log(n)) query(a,b): [a,b)
   での最小の要素を取得。O(log(n)) find_rightest(a,b,x): [a,b) で
   x以下の要素を持つ最右位置を求める。O(log(n)) find_leftest(a,b,x): [a,b) で
   x以下の要素を持つ最左位置を求める。O(log(n))
*/
template <typename X> struct SegTree {
  using FX = function<X(X, X)>; // X•X -> X となる関数の型
  int n;
  FX fx;
  const X ex;
  vector<X> dat;
  SegTree(int n_, FX fx_, X ex_) : n(), fx(fx_), ex(ex_), dat(n_ * 4, ex_) {
    int x = 1;
    while (n_ > x) {
      x *= 2;
    }
    n = x;
  }
  void set(int i, X x) { dat[i + n - 1] = x; }
  void build() {
    for (int k = n - 2; k >= 0; k--)
      dat[k] = fx(dat[2 * k + 1], dat[2 * k + 2]);
  }
  void update(int i, X x) {
    i += n - 1;
    dat[i] = x;
    while (i > 0) {
      i = (i - 1) / 2; // parent
      dat[i] = fx(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }
  X get(int i) { return dat[i + n - 1]; }
  X all() { return dat[0]; }
  X query(int a, int b) { return query_sub(a, b, 0, 0, n); }
  X query_sub(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return ex;
    } else if (a <= l && r <= b) {
      return dat[k];
    } else {
      X vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
      X vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
      return fx(vl, vr);
    }
  }
  int find_rightest(int a, int b, X x) {
    return find_rightest_sub(a, b, x, 0, 0, n);
  }
  int find_leftest(int a, int b, X x) {
    return find_leftest_sub(a, b, x, 0, 0, n);
  }
  int find_rightest_sub(int a, int b, X x, int k, int l, int r) {
    if (dat[k] > x || r <= a ||
        b <= l) { // 自分の値がxより大きい or [a,b)が[l,r)の範囲外ならreturn a-1
      return a - 1;
    } else if (k >= n - 1) { // 自分が葉ならその位置をreturn
      return (k - (n - 1));
    } else {
      int vr = find_rightest_sub(a, b, x, 2 * k + 2, (l + r) / 2, r);
      if (vr != a - 1) { // 右の部分木を見て a-1 以外ならreturn
        return vr;
      } else { // 左の部分木を見て値をreturn
        return find_rightest_sub(a, b, x, 2 * k + 1, l, (l + r) / 2);
      }
    }
  }
  int find_leftest_sub(int a, int b, X x, int k, int l, int r) {
    if (dat[k] > x || r <= a ||
        b <= l) { // 自分の値がxより大きい or [a,b)が[l,r)の範囲外ならreturn b
      return b;
    } else if (k >= n - 1) { // 自分が葉ならその位置をreturn
      return (k - (n - 1));
    } else {
      int vl = find_leftest_sub(a, b, x, 2 * k + 1, l, (l + r) / 2);
      if (vl != b) { // 左の部分木を見て b 以外ならreturn
        return vl;
      } else { // 右の部分木を見て値をreturn
        return find_leftest_sub(a, b, x, 2 * k + 2, (l + r) / 2, r);
      }
    }
  }
};

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

  vector<int> A(n);
  rep(i, n) cin >> A[i];

  // fx:二項演算,ex:単位元,0-index
  using X = int;
  auto fx = [](X x1, X x2) -> X { return max(x1, x2); };
  X ex = 0;
  SegTree<X> seg(300010, fx, ex);

  rep(i, n) {
    int l = max(0, A[i] - k);
    int r = min(300000, A[i] + k);
    int tmp = seg.query(l, r + 1) + 1;
    seg.update(A[i], tmp);
  }
  cout << seg.all() << endl;

  return 0;
}


#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>

using namespace std;

#define INF (int)1E6

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }

  // a, maxlength
  vector<pair<int, int>> al;
  for (int i = 0; i < n; i++) {
    if (al.size() == 0) {
      al.emplace_back(make_pair(a[i], 1));
    } else {
      sort(al.begin(), al.end());
      auto minIter =
          lower_bound(al.begin(), al.end(), make_pair(a[i] - k, -INF));
      auto maxIter =
          upper_bound(al.begin(), al.end(), make_pair(a[i] + k, INF));
      // 該当なし
      if (maxIter - minIter <= 0) {
        al.emplace_back(make_pair(a[i], 1));
      } else {
        int minindex = minIter - al.begin();
        sort(minIter, maxIter,
             [](const auto &l, const auto &r) { return l.second > r.second; });
        al.emplace_back(make_pair(a[i], 1 + al[minindex].second));
      }
    }
  }

  sort(al.begin(), al.end(),
       [](auto const &l, auto const &r) { return l.second > r.second; });
  cout << al[0].second << endl;
}

#include <algorithm>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>

using namespace std;

#define INF (int)1E6

struct seg {
  int log, size;
  vector<int> v;
  seg(int n) {
    log = 0;
    while ((1 << log) < n) {
      log++;
    }
    size = (1 << log);
    v = vector<int>(2 * size, 0);
  }

  void set(int p, int x) {
    p += size;
    v[p] = x;
    for (int i = 1; i <= log; i++) {
      int parent = p >> i;
      v[parent] = max(v[2 * parent], v[2 * parent + 1]);
    }
  }

  int query(int l, int r) {
    int sml = 0, smr = 0;
    l += size;
    r += size;
    while (l < r) {
      if (l & 1)
        sml = max(sml, v[l++]);
      if (r & 1)
        smr = max(v[--r], smr);
      l >>= 1;
      r >>= 1;
    }
    return max(sml, smr);
  }

  int get(int p) { return v[p + size]; }
};

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }

  seg s(300010);
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int l = max(0, a[i] - k);
    int r = min(300000, a[i] + k);
    int tmp = s.query(l, r + 1) + 1;
    s.set(a[i], tmp);
    ans = max(ans, tmp);
  }

  cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
int n, k;

struct ST {
  int st[4 * N];

  void update(int v, int tl, int tr, int idx, int val) {
    if (tl == idx && tl == tr) {
      st[v] = max(st[v], val);
      return;
    }
    int tm = (tl + tr) / 2;
    if (idx <= tm) {
      update(v * 2, tl, tm, idx, val);
    } else {
      update(v * 2 + 1, tm + 1, tr, idx, val);
    }
    st[v] = max(st[v * 2], st[v * 2 + 1]);
  }

  int query(int v, int tl, int tr, int l, int r) {
    if (l > r) {
      return 0;
    }
    if (tl == l && tr == r) {
      return st[v];
    }
    int tm = (tl + tr) / 2;
    int ql = query(v * 2, tl, tm, l, min(tm, r));
    int qr = query(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r);
    return max(ql, qr);
  }

  int mx() { return st[1]; }
};

ST st;

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);

  cin >> n >> k;

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

    int li = max(a - k, 1);
    int ri = min(a + k, N - 1);
    int best = st.query(1, 1, N - 1, li, ri) + 1;
    st.update(1, 1, N - 1, a, best);
  }

  cout << st.mx() << '\\n';

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
int n, k;

struct ST {
  int st[4 * N];

  ST() { memset(st, 0, sizeof st); }

  void update(int v, int tl, int tr, int idx, int val) {
    if (tl == idx && tl == tr) {
      st[v] = max(st[v], val);
      return;
    }
    int tm = (tl + tr) / 2;
    if (idx <= tm) {
      update(v * 2, tl, tm, idx, val);
    } else {
      update(v * 2 + 1, tm + 1, tr, idx, val);
    }
    st[v] = max(st[v * 2], st[v * 2 + 1]);
  }

  int query(int v, int tl, int tr, int l, int r) {
    if (l > r) {
      return 0;
    }
    if (tl == l && tr == r) {
      return st[v];
    }
    int tm = (tl + tr) / 2;
    int ql = query(v * 2, tl, tm, l, min(tm, r));
    int qr = query(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r);
    return max(ql, qr);
  }

  int mx() { return st[1]; }
};

ST st;

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);

  cin >> n >> k;

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

    int li = max(a - k, 0);
    int ri = min(a + k, N - 1);
    int best = st.query(1, 0, N - 1, li, ri) + 1;
    st.update(1, 0, N - 1, a, best);
  }

  cout << st.mx() << '\\n';

  return 0;
}


#include <bits/stdc++.h>
#define fo(i, a, b) for (int i = a; i < b; ++i)
#define rep(i, n) fo(i, 0, n)
#define pln(n) printf("%lld", n)
#define sll(n) scanf("%lld", &n)
#define ss(n) scanf("%s", n)
#define vi vector<int>
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define dbg(x)                                                                 \\
  { cout << #x << ": " << (x) << endl; }
#define dbg2(x, y)                                                             \\
  { cout << #x << ": " << (x) << " , " << #y << ": " << (y) << endl; }
#define dbg3(x, y, z)                                                          \\
  {                                                                            \\
    cout << #x << ": " << (x) << " , " << #y << ": " << (y) << " , " << #z     \\
         << ": " << (z) << endl;                                               \\
  }
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
#define vll vector<long long>
#define vvll vector<vector<long long>>
#define vvvll vector<vector<vector<ll>>>
#define si set<int>
#define tr(c, it) for (decltype(c.begin()) it = c.begin(); it != c.end(); it++)
#define pis pair<int, string>
#define present(c, x) (c.find(x) != c.end())
#define cpresent(c, x) (find(all(c), x) != c.end())
#define ones(x) __builtin_popcount(x)
using namespace std;

int main() {
  // freopen("input.txt", "r", stdin);
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  int L[n];
  L[0] = 1;
  for (int i = 1; i < n; i++) {
    L[i] = 1;
    for (int j = i - 1; j >= 0; j--) {
      if (abs(a[j] - a[i]) <= k) {
        L[i] = max(L[i], L[j] + 1);
      }
    }
  }
  cout << *max_element(L, L + n) << endl;
}

#include <bits/stdc++.h>
#define fo(i, a, b) for (int i = a; i < b; ++i)
#define rep(i, n) fo(i, 0, n)
#define pln(n) printf("%lld", n)
#define sll(n) scanf("%lld", &n)
#define ss(n) scanf("%s", n)
#define vi vector<int>
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define dbg(x)                                                                 \\
  { cout << #x << ": " << (x) << endl; }
#define dbg2(x, y)                                                             \\
  { cout << #x << ": " << (x) << " , " << #y << ": " << (y) << endl; }
#define dbg3(x, y, z)                                                          \\
  {                                                                            \\
    cout << #x << ": " << (x) << " , " << #y << ": " << (y) << " , " << #z     \\
         << ": " << (z) << endl;                                               \\
  }
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
#define vll vector<long long>
#define vvll vector<vector<long long>>
#define vvvll vector<vector<vector<ll>>>
#define si set<int>
#define tr(c, it) for (decltype(c.begin()) it = c.begin(); it != c.end(); it++)
#define pis pair<int, string>
#define present(c, x) (c.find(x) != c.end())
#define cpresent(c, x) (find(all(c), x) != c.end())
#define ones(x) __builtin_popcount(x)
using namespace std;

int main() {
  // freopen("input.txt", "r", stdin);
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  int L[n];
  L[0] = 1;
  set<pair<int, int>, greater<pair<int, int>>> s;
  s.insert({L[0], 0});
  for (int i = 1; i < n; i++) {
    L[i] = 1;
    for (auto it = s.begin(); it != s.end(); it++) {
      if (abs(a[it->second] - a[i]) <= k) {
        L[i] = max(L[i], it->first + 1);
        break;
      }
    }
    s.insert({L[i], i});
  }
  cout << *max_element(L, L + n) << endl;
}


#pragma GCC optimize(2)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define lowbit(n) n & (-n)
#define ls x << 1
#define rs x << 1 | 1
#define clc(a, b) memset(a, b, sizeof(a))
#define Buff ios::sync_with_stdio(false)
#define rush()                                                                 \\
  int Case = 0;                                                                \\
  int T;                                                                       \\
  scanf("%d", &T);                                                             \\
  while (T--)
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define reps(i, a, b) for (int i = a; b; i++)
#define read(a) scanf("%d", &a)
#define readd(a) scanf("%lf", &a)
#define readl(a) scanf("%lld", &a)
#define readc(a) scanf("%c", &a)
#define reads(a) scanf("%s", a)
#define sqr(x) x *x
#define pb push_back
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int N = 3e5 + 7;
int a[N], f[N];
struct BIT {
  int n, bit[N];
  void init() { clc(bit, 0), clc(f, 0); }
  int query(int l, int r) {
    int res = f[r];
    for (; r > l;) {
      for (r--; r - lowbit(r) >= l; r -= lowbit(r))
        res = max(res, bit[r]);
      res = max(res, f[r]);
    }
    return res;
  }
  void modify(int p, int v) {
    f[p] = v;
    for (int i = p; i <= n; i += lowbit(i)) {
      bit[i] = v;
      for (int j = 1; j < lowbit(i); j <<= 1)
        bit[i] = max(bit[i], bit[i - j]);
    }
  }
} tree;
int main() {
  Buff;
  int n, k, maxv = 0, res = 0;
  cin >> n >> k;
  tree.init();
  rep(i, 1, n) {
    cin >> a[i];
    a[i]++;
    maxv = max(maxv, a[i]);
  }
  tree.n = maxv;
  for (int i = 1; i <= n; i++) {
    int l = max(1, a[i] - k);
    int r = min(maxv, a[i] + k);
    int t = tree.query(l, r);
    //        cout <<"t:"<< t <<endl;
    res = max(res, t + 1);
    tree.modify(a[i], t + 1);
  }
  cout << res << endl;
  return 0;
}

#pragma GCC optimize(2)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define lowbit(n) n & (-n)
#define ls x << 1
#define rs x << 1 | 1
#define clc(a, b) memset(a, b, sizeof(a))
#define Buff ios::sync_with_stdio(false)
#define rush()                                                                 \\
  int Case = 0;                                                                \\
  int T;                                                                       \\
  scanf("%d", &T);                                                             \\
  while (T--)
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define reps(i, a, b) for (int i = a; b; i++)
#define read(a) scanf("%d", &a)
#define readd(a) scanf("%lf", &a)
#define readl(a) scanf("%lld", &a)
#define readc(a) scanf("%c", &a)
#define reads(a) scanf("%s", a)
#define sqr(x) x *x
#define pb push_back
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int N = 3e5 + 7;
int b[N];
struct BIT // binary index tree
{
  int t[N], n;
  int a[N];
#define lowbit(x) (x & (-x))
  void init(int n_) {
    n = n_;
    for (int i = 1; i <= n; i++)
      t[i] = a[i] = 0;
  }
  int query(int l, int r) {
    int res = a[r];
    while (r > l) // t[i]维护 [i-lowbit(i)+1,i]的最值
    {
      for (--r; r - lowbit(r) >= l;
           r -= lowbit(r)) // r-lowbit(r)+1>=l return max t[r],query(l,r-low(r))
        res = max(res, t[r]); // r-lowbit(r)+1<l return max a[r],query(l,r-1)
      res = max(res, a[r]);
    }
    return res;
  }
  void modify(int x, int v) {
    a[x] = v;
    while (x <= n) {
      t[x] = a[x];
      for (int i = 1, j = lowbit(x); i < j; i <<= 1) // y+( lowbit(y)=2^i) =x
        t[x] = max(
            t[x],
            t[x -
              i]); // 对pos=x的修改需要考虑其维护的(x-lowbit(x),x]区间里的数对该区间最值贡献
      x += lowbit(x); // 转移至包含该区间的下一个位置
    }
  }
};
BIT tree;
int main() {
  Buff;
  int n, k, maxv = 1, res = 0;
  cin >> n >> k;
  rep(i, 1, n) {
    cin >> b[i];
    b[i]++;
    maxv = max(maxv, b[i]);
  }
  tree.init(maxv);
  rep(i, 1, n) {
    int l = max(1, b[i] - k);
    int r = min(maxv, b[i] + k);
    int t = tree.query(l, r);
    //        cout <<"t:"<< t <<endl;
    res = max(res, t + 1);
    tree.modify(b[i], t + 1);
  }
  cout << res << endl;
  return 0;
}


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

int n, k, result, a;
int t[1300005];

void update(int idx, int l, int r, int aim, int val) {
  if (l == aim and aim == r) {
    t[idx] = val; // 这里是否可以直接赋值???
    return;
  }
  int mid = (l + r) >> 1;
  if (aim <= mid) {
    update(idx << 1, l, mid, aim, val);
  } else {
    update(idx << 1 | 1, mid + 1, r, aim, val);
  }
  t[idx] = max(t[idx << 1], t[idx << 1 | 1]);
  return;
}

int query(int idx, int l, int r, int aiml, int aimr) {
  if (aiml <= l and r <= aimr) {
    return t[idx];
  }
  int mid = (l + r) >> 1, ansl = 0, ansr = 0;
  if (aiml <= mid) {
    ansl = query(idx << 1, l, mid, aiml, aimr);
  }
  if (mid < aimr) {
    ansr = query(idx << 1 | 1, mid + 1, r, aiml, aimr);
  }
  return max(ansl, ansr);
}

int main() {
  cin >> n >> k;
  for (int i = 0; i < n; i++) {
    scanf("%d", &a);
    result = query(1, 1, 300000, max(1, a - k), min(300000, a + k)) + 1;
    update(1, 1, 300000, a, result);
  }
  cout << result << endl;
  return 0;
}

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

int n, k, result, a;
int t[1300005];

void update(int idx, int l, int r, int aim, int val) {
  if (l == aim and aim == r) {
    t[idx] = val; // 这里是否可以直接赋值???
    return;
  }
  int mid = (l + r) >> 1;
  if (aim <= mid) {
    update(idx << 1, l, mid, aim, val);
  } else {
    update(idx << 1 | 1, mid + 1, r, aim, val);
  }
  t[idx] = max(t[idx << 1], t[idx << 1 | 1]);
  return;
}

int query(int idx, int l, int r, int aiml, int aimr) {
  if (aiml <= l and r <= aimr) {
    return t[idx];
  }
  int mid = (l + r) >> 1, ansl = 0, ansr = 0;
  if (aiml <= mid) {
    ansl = query(idx << 1, l, mid, aiml, aimr);
  }
  if (mid < aimr) {
    ansr = query(idx << 1 | 1, mid + 1, r, aiml, aimr);
  }
  return max(ansl, ansr);
}

int main() {
  cin >> n >> k;
  for (int i = 0; i < n; i++) {
    scanf("%d", &a);
    result = query(1, 0, 300000, max(0, a - k), min(300000, a + k)) + 1;
    update(1, 0, 300000, a, result);
  }
  cout << query(1, 0, 300000, 0, 300000) << endl;
  return 0;
}


/**
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀⠀⠀⢀⡀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡖⠁⠀⠀⠀⠀⠀⠀⠈⢲⣄
⠀⠀⠀⠀⠀⠀⠀⠀⣼⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣧
⠀⠀⠀⠀⠀⠀⠀⣸⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣇
⠀⠀⠀⠀⠀⠀⠀⣿⣿⡇⠀⢀⣀⣤⣤⣤⣤⣀⡀⠀⢸⣿⣿
⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣔⢿⡿⠟⠛⠛⠻⢿⡿⣢⣿⣿⡟
⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣷⣤⣀⡀⢀⣀⣤⣾⣿⣿⣿⣷⣶⣤⡀
⠀⠀⢠⣾⣿⡿⠿⠿⠿⣿⣿⣿⣿⡿⠏⠻⢿⣿⣿⣿⣿⠿⠿⠿⢿⣿⣷⡀
⠀⢠⡿⠋⠁⠀⠀⢸⣿⡇⠉⠻⣿⠇⠀⠀⠸⣿⡿⠋⢰⣿⡇⠀⠀⠈⠙⢿⡄
⠀⡿⠁⠀⠀⠀⠀⠘⣿⣷⡀⠀⠰⣿⣶⣶⣿⡎⠀⢀⣾⣿⠇⠀⠀⠀⠀⠈⢿
⠀⡇⠀⠀⠀⠀⠀⠀⠹⣿⣷⣄⠀⣿⣿⣿⣿⠀⣠⣾⣿⠏⠀⠀⠀⠀⠀⠀⢸
⠀⠁⠀⠀⠀⠀⠀⠀⠀⠈⠻⢿⢇⣿⣿⣿⣿⡸⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠈
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣧⡀
⠀⠀⠀⠐⢤⣀⣀⢀⣀⣠⣴⣿⣿⠿⠋⠙⠿⣿⣿⣦⣄⣀⠀⠀⣀⡠⠂
⠀⠀⠀⠀⠀⠈⠉⠛⠛⠛⠛⠉⠀⠀⠀⠀⠀⠈⠉⠛⠛⠛⠛⠋⠁
 *    author:  Daredevil666
 *    institution: IIT Patna
**/
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define nl cout << "\\n";
#define ll long long int
#define REP(i, a, n) for (i = a; i <= n; i++)
#define F(i, a, b) for (i = a; i < b; i++)
#define RF(i, b, a) for (i = b; i >= a; i--)
#define IOS                                                                    \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0);
using namespace std;
const ll mod = 1e9 + 7;
const ll MAXN = 300001;
const ll M = 1000000;
ll i, j, mask, test;
vector<ll> tree(M), A(MAXN);
void update(ll node, ll start, ll ends, ll idx, ll val) {
  if (start == ends) {
    // Leaf node
    A[idx] = val;
    tree[node] = val;
  } else {
    int mid = (start + ends) / 2;
    if (start <= idx and idx <= mid) {
      // If idx is in the left child, recurse on the left child
      update(2 * node, start, mid, idx, val);
    } else {
      // if idx is in the right child, recurse on the right child
      update(2 * node + 1, mid + 1, ends, idx, val);
    }
    // Internal node will have the sum of both of its children
    tree[node] = max(tree[2 * node], tree[2 * node + 1]);
  }
}
ll query(ll node, ll start, ll ends, ll l, ll r) {
  if (r < start || ends < l) {
    // range represented by a node is completely outside the given range
    return 0;
  }
  if (l <= start && ends <= r) {
    // range represented by a node is completely inside the given range
    return tree[node];
  }
  // range represented by a node is partially inside and partially outside the
  // given range
  int mid = (start + ends) / 2;
  int p1 = query(2 * node, start, mid, l, r);
  int p2 = query(2 * node + 1, mid + 1, ends, l, r);
  return max(p1, p2);
}
int main() {
  IOS
      /*#ifndef ONLINE_JUDGE
         freopen("input.txt","r",stdin);
         freopen("output.txt","w",stdout);
      #endif // ONLINE_JUDGE*/
      ll n,
      k;
  cin >> n >> k;
  while (n--) {
    ll x;
    cin >> x;
    ll p = query(1, 0, MAXN - 1, max((ll)0, x - k), x + k);
    update(1, 0, MAXN - 1, x, p + 1);
  }
  ll maxx = 0;
  F(i, 0, MAXN) { maxx = max(maxx, A[i]); }
  cout << maxx;
  return 0;
}

/**
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀⠀⠀⢀⡀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡖⠁⠀⠀⠀⠀⠀⠀⠈⢲⣄
⠀⠀⠀⠀⠀⠀⠀⠀⣼⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣧
⠀⠀⠀⠀⠀⠀⠀⣸⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣇
⠀⠀⠀⠀⠀⠀⠀⣿⣿⡇⠀⢀⣀⣤⣤⣤⣤⣀⡀⠀⢸⣿⣿
⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣔⢿⡿⠟⠛⠛⠻⢿⡿⣢⣿⣿⡟
⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣷⣤⣀⡀⢀⣀⣤⣾⣿⣿⣿⣷⣶⣤⡀
⠀⠀⢠⣾⣿⡿⠿⠿⠿⣿⣿⣿⣿⡿⠏⠻⢿⣿⣿⣿⣿⠿⠿⠿⢿⣿⣷⡀
⠀⢠⡿⠋⠁⠀⠀⢸⣿⡇⠉⠻⣿⠇⠀⠀⠸⣿⡿⠋⢰⣿⡇⠀⠀⠈⠙⢿⡄
⠀⡿⠁⠀⠀⠀⠀⠘⣿⣷⡀⠀⠰⣿⣶⣶⣿⡎⠀⢀⣾⣿⠇⠀⠀⠀⠀⠈⢿
⠀⡇⠀⠀⠀⠀⠀⠀⠹⣿⣷⣄⠀⣿⣿⣿⣿⠀⣠⣾⣿⠏⠀⠀⠀⠀⠀⠀⢸
⠀⠁⠀⠀⠀⠀⠀⠀⠀⠈⠻⢿⢇⣿⣿⣿⣿⡸⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠈
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣧⡀
⠀⠀⠀⠐⢤⣀⣀⢀⣀⣠⣴⣿⣿⠿⠋⠙⠿⣿⣿⣦⣄⣀⠀⠀⣀⡠⠂
⠀⠀⠀⠀⠀⠈⠉⠛⠛⠛⠛⠉⠀⠀⠀⠀⠀⠈⠉⠛⠛⠛⠛⠋⠁
 *    author:  Daredevil666
 *    institution: IIT Patna
**/
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define nl cout << "\\n";
#define ll long long int
#define REP(i, a, n) for (i = a; i <= n; i++)
#define F(i, a, b) for (i = a; i < b; i++)
#define RF(i, b, a) for (i = b; i >= a; i--)
#define IOS                                                                    \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0);
using namespace std;
const ll mod = 1e9 + 7;
const ll MAXN = 300001;
const ll M = 3000000;
ll i, j, mask, test;
vector<ll> tree(M), A(MAXN);
void update(ll node, ll start, ll ends, ll idx, ll val) {
  if (start == ends) {
    // Leaf node
    A[idx] = val;
    tree[node] = val;
  } else {
    int mid = (start + ends) / 2;
    if (start <= idx && idx <= mid) {
      // If idx is in the left child, recurse on the left child
      update(2 * node, start, mid, idx, val);
    } else {
      // if idx is in the right child, recurse on the right child
      update(2 * node + 1, mid + 1, ends, idx, val);
    }
    // Internal node will have the sum of both of its children
    tree[node] = max(tree[2 * node], tree[2 * node + 1]);
  }
}
ll query(ll node, ll start, ll ends, ll l, ll r) {
  if (r < start || ends < l) {
    // range represented by a node is completely outside the given range
    return 0;
  }
  if (l <= start && ends <= r) {
    // range represented by a node is completely inside the given range
    return tree[node];
  }
  // range represented by a node is partially inside and partially outside the
  // given range
  int mid = (start + ends) / 2;
  int p1 = query(2 * node, start, mid, l, r);
  int p2 = query(2 * node + 1, mid + 1, ends, l, r);
  return max(p1, p2);
}
int main() {
  IOS
      /*#ifndef ONLINE_JUDGE
         freopen("input.txt","r",stdin);
         freopen("output.txt","w",stdout);
      #endif // ONLINE_JUDGE*/
      ll n,
      k;
  cin >> n >> k;
  while (n--) {
    ll x;
    cin >> x;
    ll p = query(1, 0, MAXN - 1, max((ll)0, x - k), min(MAXN - 1, x + k));
    update(1, 0, MAXN - 1, x, p + 1);
  }
  ll maxx = 0;
  F(i, 0, MAXN) { maxx = max(maxx, A[i]); }
  cout << maxx;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vll vector<ll>
#define vc vector<char>
#define vs vector<string>
#define vpll vector<pll>
#define vpii vector<pii>
#define umap unordered_map
#define uset unordered_set
#define PQ priority_queue
#define printa(a, L, R)                                                        \\
  for (int i = L; i < R; i++)                                                  \\
  cout << a[i] << (i == R - 1 ? '\\n' : ' ')
#define printv(a) printa(a, 0, a.size())
#define print2d(a, r, c)                                                       \\
  for (int i = 0; i < r; i++)                                                  \\
    for (int j = 0; j < c; j++)                                                \\
  cout << a[i][j] << (j == c - 1 ? '\\n' : ' ')
#define pb push_back
#define eb emplace_back
#define UB upper_bound
#define LB lower_bound
#define F first
#define S second
#define mem(a, x) memset(a, x, sizeof(a))
#define inf 1e18
#define E 2.71828182845904523536
#define gamma 0.5772156649
#define nl "\\n"
#define lg(r, n) (int)(log2(n) / log2(r))
#define rev(v) reverse(v.begin(), v.end())
#define srt(v) sort(v.begin(), v.end())
#define grtsrt(v) sort(v.begin(), v.end(), greater<ll>())
#define all(v) v.begin(), v.end()
#define mnv(v) *min_element(v.begin(), v.end())
#define mxv(v) *max_element(v.begin(), v.end())
#define toint(a) atoi(a.c_str())
#define BeatMeScanf ios_base::sync_with_stdio(false)
#define one(x) __builtin_popcount(x)
#define Unique(v) v.erase(unique(all(v)), v.end())
#define fout(x) fixed << setprecision(x)

const int mod = 1e9 + 7;
const int N = 3e5 + 9;
const ld eps = 1e-9;
const ld PI = acos(-1.0);
ll gc(ll a, ll b) {
  while (b) {
    ll x = a % b;
    a = b;
    b = x;
  }
  return a;
}
ll lc(ll a, ll b) { return a / gc(a, b) * b; }
ll qpow(ll n, ll k) {
  ll ans = 1;
  assert(k >= 0);
  n %= mod;
  while (k > 0) {
    if (k & 1)
      ans = (ans * n) % mod;
    n = (n * n) % mod;
    k >>= 1;
  }
  return ans % mod;
}

#define MX 300000

ll t[1400000];

ll mx(int v, int tl, int tr, int l, int r) {
  if (l > r)
    return 0;
  if (l == tl && r == tr) {
    return t[v];
  }
  int tm = (tl + tr) / 2;
  return max(mx(v * 2, tl, tm, l, min(r, tm)),
             mx(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}

void update(int v, int tl, int tr, int pos, int new_val) {
  if (tl == tr) {
    t[v] = new_val;
  } else {
    int tm = (tl + tr) / 2;
    if (pos <= tm)
      update(v * 2, tl, tm, pos, new_val);
    else
      update(v * 2 + 1, tm + 1, tr, pos, new_val);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
}

void solve() {
  ll n, k;
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    ll x;
    cin >> x;
    ll y = mx(1, 1, MX, max(1LL, x - k), x + k);
    update(1, 1, MX, x, y + 1);
  }
  cout << t[1] << nl;
}

int main() {
  solve();
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vll vector<ll>
#define vc vector<char>
#define vs vector<string>
#define vpll vector<pll>
#define vpii vector<pii>
#define umap unordered_map
#define uset unordered_set
#define PQ priority_queue
#define printa(a, L, R)                                                        \\
  for (int i = L; i < R; i++)                                                  \\
  cout << a[i] << (i == R - 1 ? '\\n' : ' ')
#define printv(a) printa(a, 0, a.size())
#define print2d(a, r, c)                                                       \\
  for (int i = 0; i < r; i++)                                                  \\
    for (int j = 0; j < c; j++)                                                \\
  cout << a[i][j] << (j == c - 1 ? '\\n' : ' ')
#define pb push_back
#define eb emplace_back
#define UB upper_bound
#define LB lower_bound
#define F first
#define S second
#define mem(a, x) memset(a, x, sizeof(a))
#define inf 1e18
#define E 2.71828182845904523536
#define gamma 0.5772156649
#define nl "\\n"
#define lg(r, n) (int)(log2(n) / log2(r))
#define rev(v) reverse(v.begin(), v.end())
#define srt(v) sort(v.begin(), v.end())
#define grtsrt(v) sort(v.begin(), v.end(), greater<ll>())
#define all(v) v.begin(), v.end()
#define mnv(v) *min_element(v.begin(), v.end())
#define mxv(v) *max_element(v.begin(), v.end())
#define toint(a) atoi(a.c_str())
#define BeatMeScanf ios_base::sync_with_stdio(false)
#define one(x) __builtin_popcount(x)
#define Unique(v) v.erase(unique(all(v)), v.end())
#define fout(x) fixed << setprecision(x)

const int mod = 1e9 + 7;
const int N = 3e5 + 9;
const ld eps = 1e-9;
const ld PI = acos(-1.0);
ll gc(ll a, ll b) {
  while (b) {
    ll x = a % b;
    a = b;
    b = x;
  }
  return a;
}
ll lc(ll a, ll b) { return a / gc(a, b) * b; }
ll qpow(ll n, ll k) {
  ll ans = 1;
  assert(k >= 0);
  n %= mod;
  while (k > 0) {
    if (k & 1)
      ans = (ans * n) % mod;
    n = (n * n) % mod;
    k >>= 1;
  }
  return ans % mod;
}

#define MX 300000LL

ll t[1400000];

ll mx(ll v, ll tl, ll tr, ll l, ll r) {
  if (l > r)
    return 0;
  if (l == tl && r == tr) {
    return t[v];
  }
  ll tm = (tl + tr) / 2;
  return max(mx(v * 2, tl, tm, l, min(r, tm)),
             mx(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}

void update(ll v, ll tl, ll tr, ll pos, ll new_val) {
  if (tl == tr) {
    t[v] = new_val;
  } else {
    ll tm = (tl + tr) / 2;
    if (pos <= tm)
      update(v * 2, tl, tm, pos, new_val);
    else
      update(v * 2 + 1, tm + 1, tr, pos, new_val);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
}

void solve() {
  ll n, k;
  cin >> n >> k;
  for (ll i = 1; i <= n; i++) {
    ll x;
    cin >> x;
    ll y = mx(1, 0, MX, max(0LL, x - k), min(MX, x + k));
    update(1, 0, MX, x, y + 1);
  }
  cout << t[1] << nl;
}

int main() {
  solve();
  return 0;
}


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

template <typename T> struct SegmentTree { // 1-indexed
  T m_id;
  T op(const T &a, const T &b) const { return max(a, b); }
  vector<T> m_SegT;

  SegmentTree(int N) : m_id(0), m_SegT(2 * N, m_id) {}
  SegmentTree(const vector<T> &data) : m_id(0), m_SegT(2 * data.size()) {
    int N = m_SegT.size() >> 1;
    for (int i = 0; i < N; i++) {
      m_SegT.at(i + N) = data.at(i);
    }
    for (int i = N - 1; i > 0; i--) {
      m_SegT.at(i) = op(m_SegT.at(i << 1), m_SegT.at((i << 1) | 1));
    }
  }

  void set_val(int idx, T val) {
    idx += m_SegT.size() >> 1;
    m_SegT.at(idx) = val;
    while ((idx >> 1) > 0) {
      idx >>= 1;
      m_SegT.at(idx) = op(m_SegT.at(idx << 1), m_SegT.at((idx << 1) | 1));
    }
  }

  T range(int left, int right) const { // [left, right)
    left += m_SegT.size() >> 1;
    right += m_SegT.size() >> 1;
    T calc_l = m_id;
    T calc_r = m_id;

    while (left < right) {
      if (left & 1) {
        calc_l = op(calc_l, m_SegT.at(left));
        left++;
      }
      if (right & 1) {
        calc_r = op(m_SegT.at(right - 1), calc_r);
      }

      left >>= 1;
      right >>= 1;
    }

    return op(calc_l, calc_r);
  }
};

int main() {
  int N, K;
  cin >> N >> K;

  vector<int> data(N);
  for (int i = 0; i < N; i++) {
    cin >> data.at(i);
    data.at(i)++; // [0,N] -> [1,N+1]
  }

  const int Vmax = N + 1;
  SegmentTree<int> st(Vmax + 1);
  for (int i = 0; i < N; i++) {
    int left = max(1, data.at(i) - K);
    int right = min(Vmax, data.at(i) + K);
    int len_prev = st.range(left, right + 1);
    st.set_val(data.at(i), len_prev + 1);
  }

  int ans = st.range(0, Vmax + 1);
  cout << ans << endl;
}

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

template <typename T> struct SegmentTree { // 1-indexed
  T m_id;
  T op(const T &a, const T &b) const { return max(a, b); }
  vector<T> m_SegT;

  SegmentTree(int N) : m_id(0), m_SegT(2 * N, m_id) {}
  SegmentTree(const vector<T> &data) : m_id(0), m_SegT(2 * data.size()) {
    int N = m_SegT.size() >> 1;
    for (int i = 0; i < N; i++) {
      m_SegT.at(i + N) = data.at(i);
    }
    for (int i = N - 1; i > 0; i--) {
      m_SegT.at(i) = op(m_SegT.at(i << 1), m_SegT.at((i << 1) | 1));
    }
  }

  void set_val(int idx, T val) {
    idx += m_SegT.size() >> 1;
    m_SegT.at(idx) = val;
    while ((idx >> 1) > 0) {
      idx >>= 1;
      m_SegT.at(idx) = op(m_SegT.at(idx << 1), m_SegT.at((idx << 1) | 1));
    }
  }

  T range(int left, int right) const { // [left, right)
    left += m_SegT.size() >> 1;
    right += m_SegT.size() >> 1;
    T calc_l = m_id;
    T calc_r = m_id;

    while (left < right) {
      if (left & 1) {
        calc_l = op(calc_l, m_SegT.at(left));
        left++;
      }
      if (right & 1) {
        calc_r = op(m_SegT.at(right - 1), calc_r);
      }

      left >>= 1;
      right >>= 1;
    }

    return op(calc_l, calc_r);
  }
};

int main() {
  int N, K;
  cin >> N >> K;

  vector<int> data(N);
  for (int i = 0; i < N; i++) {
    cin >> data.at(i);
    data.at(i)++; // [0,N] -> [1,N+1]
  }

  constexpr int Vmax = 300'001; // '
  SegmentTree<int> st(Vmax + 1);
  for (int i = 0; i < N; i++) {
    int left = max(1, data.at(i) - K);
    int right = min(Vmax, data.at(i) + K);
    int len_prev = st.range(left, right + 1);
    st.set_val(data.at(i), len_prev + 1);
  }

  int ans = st.range(0, Vmax + 1);
  cout << ans << endl;
}


#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = x, i##end = y; i <= i##end; ++i)
#define _rep(i, x, y) for (int i = x, i##end = y; i >= i##end; --i)
#define ll long long
typedef std::pair<int, int> pii;
inline bool up(int &x, const int y) { return x < y ? x = y, 1 : 0; }
inline bool down(int &x, const int y) { return x > y ? x = y, 1 : 0; }
#define N 300005
int n, k, a[N];
int dp[N];
struct segment {
#define ls rt << 1
#define rs rt << 1 | 1
#define lson ls, l, mid
#define rson rs, mid + 1, r
  int mx[N];
  inline void pushup(int rt) { mx[rt] = std::max(mx[ls], mx[rs]); }
  inline void build(int rt, int l, int r) {
    mx[rt] = 0;
    if (l == r)
      return;
    int mid = l + r >> 1;
    build(lson), build(rson), pushup(rt);
  }
  inline void ins(int rt, int l, int r, int x, int v) {
    if (l == r)
      return mx[rt] = v, void();
    int mid = l + r >> 1;
    if (x <= mid)
      ins(lson, x, v);
    else
      ins(rson, x, v);
    pushup(rt);
  }
  inline int qry(int rt, int l, int r, int x, int y) {
    if (x <= l && r <= y)
      return mx[rt];
    int mid = l + r >> 1, ret = 0;
    if (x <= mid)
      up(ret, qry(lson, x, y));
    if (mid < y)
      up(ret, qry(rson, x, y));
    //		std::cerr<<x<<' '<<y<<' '<<ret<<'\\n';
    return ret;
  }
} T;
int m;
int main() {
  std::ios::sync_with_stdio(0);
  std::cin >> n >> k;
  rep(i, 1, n) std::cin >> a[i], ++a[i], up(m, a[i]);
  memset(dp, 0, sizeof(dp));
  T.build(1, 1, m);
  int ret = 0;
  rep(i, 1, n) {
    int l = std::max(1, a[i] - k), r = std::min(m, a[i] + k);
    dp[i] = T.qry(1, 1, m, l, r) + 1;
    T.ins(1, 1, m, a[i], dp[i]);
    up(ret, dp[i]);
  }
  //	rep(i,1,n) std::cerr<<dp[i]<<" \\n"[i==n];
  std::cout << ret << '\\n';
  return 0;
}

#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = x, i##end = y; i <= i##end; ++i)
#define _rep(i, x, y) for (int i = x, i##end = y; i >= i##end; --i)
#define ll long long
typedef std::pair<int, int> pii;
inline bool up(int &x, const int y) { return x < y ? x = y, 1 : 0; }
inline bool down(int &x, const int y) { return x > y ? x = y, 1 : 0; }
#define N 300005
int n, k, a[N];
int dp[N];
struct segment {
#define ls rt << 1
#define rs rt << 1 | 1
#define lson ls, l, mid
#define rson rs, mid + 1, r
  int mx[N << 2];
  inline void pushup(int rt) { mx[rt] = std::max(mx[ls], mx[rs]); }
  inline void build(int rt, int l, int r) {
    mx[rt] = 0;
    if (l == r)
      return;
    int mid = l + r >> 1;
    build(lson), build(rson), pushup(rt);
  }
  inline void ins(int rt, int l, int r, int x, int v) {
    if (l == r)
      return mx[rt] = v, void();
    int mid = l + r >> 1;
    if (x <= mid)
      ins(lson, x, v);
    else
      ins(rson, x, v);
    pushup(rt);
  }
  inline int qry(int rt, int l, int r, int x, int y) {
    if (x <= l && r <= y)
      return mx[rt];
    int mid = l + r >> 1, ret = 0;
    if (x <= mid)
      up(ret, qry(lson, x, y));
    if (mid < y)
      up(ret, qry(rson, x, y));
    //		std::cerr<<x<<' '<<y<<' '<<ret<<'\\n';
    return ret;
  }
} T;
int m;
int main() {
  std::ios::sync_with_stdio(0);
  std::cin >> n >> k;
  rep(i, 1, n) std::cin >> a[i], ++a[i], up(m, a[i]);
  memset(dp, 0, sizeof(dp));
  T.build(1, 1, m);
  int ret = 0;
  rep(i, 1, n) {
    int l = std::max(1, a[i] - k), r = std::min(m, a[i] + k);
    dp[i] = T.qry(1, 1, m, l, r) + 1;
    T.ins(1, 1, m, a[i], dp[i]);
    up(ret, dp[i]);
  }
  //	rep(i,1,n) std::cerr<<dp[i]<<" \\n"[i==n];
  std::cout << ret << '\\n';
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
typedef pair<int, int> pp;
bool com(pp x, pp y) { return x.ff < y.ff; }
int N = 3e5 + 9, k;
void input_() {
#ifndef ONLINE_JUDGE
  // for getting input from input.txt
  freopen("input.txt", "r", stdin);
  // for writing output to output.txt
  freopen("output.txt", "w", stdout);
#endif
}
std::vector<int> dp(N, -1);
int f(int i, int n, int k, int *a) {
  if (i == n - 1)
    return 1;
  if (dp[i] != -1)
    return dp[i];
  for (int j = i + 1; j < n; j++) {
    if (abs(a[i] - a[j]) <= k) {
      dp[i] = max(dp[i], 1 + f(j, n, k, a));
    }
  }
  return dp[i];
}
void solve() {
  int n, k;
  cin >> n >> k;
  int a[n];
  int ans = 0;
  for (int i = 0; i < n; i++)
    cin >> a[i];
  for (int i = 0; i < n; i++) {
    if (dp[i] == -1)
      ans = max(f(i, n, k, a), ans);
  }
  cout << ans;
}
int main() {
  input_();
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  // cin>>t;
  while (t--)
    solve();
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
typedef pair<int, int> pp;
bool com(pp x, pp y) { return x.ff < y.ff; }
int N = 3e5 + 9, k;
void input_() {
#ifndef ONLINE_JUDGE
  // for getting input from input.txt
  freopen("input.txt", "r", stdin);
  // for writing output to output.txt
  freopen("output.txt", "w", stdout);
#endif
}
std::vector<int> dp(N, -1);
int f(int i, int n, int k, int *a) {
  if (i == n - 1)
    return 1;
  if (dp[i] != -1)
    return dp[i];
  int x = -1, y = -1;
  for (int j = i + 1; j < n; j++) {
    if (a[j] - a[i] <= k && a[j] >= a[i]) {
      x = j;
      // cout<<a[j]-a[i]<<" "<<i<<"\\n";
      break;
    }
  }
  for (int j = i + 1; j < n; j++) {
    if (a[i] - a[j] <= k && a[j] < a[i]) {
      y = j;
      break;
    }
  }
  if (x == -1 && y == -1)
    dp[i] = 1;
  else if (x == -1)
    dp[i] = 1 + f(y, n, k, a);
  else if (y == -1)
    dp[i] = 1 + f(x, n, k, a);
  else
    dp[i] = max(1 + f(x, n, k, a), 1 + f(y, n, k, a));
  // cout<<dp[i]<<" "<<i<<"\\n";
  return dp[i];
}
void solve() {
  int n, k;
  cin >> n >> k;
  int a[n];
  int ans = 0;
  for (int i = 0; i < n; i++)
    cin >> a[i];
  for (int i = 0; i < n; i++) {
    if (dp[i] == -1)
      ans = max(f(i, n, k, a), ans);
  }
  cout << ans;
}
int main() {
  input_();
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  // cin>>t;
  while (t--)
    solve();
  return 0;
}


#include "assert.h"
#include "math.h"
#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

int inf = std::numeric_limits<int>().max();

#define BUFF ios::sync_with_stdio(false)
#define epsilon 1e-07
#define pi 2 * acos(0.0);
#define mod 1000000007 // 1e9+7
#define ll long long
#define cerr                                                                   \\
  if (false)                                                                   \\
  cerr
#define watch(x) cerr << #x << " = " << x << endl;

/*

        Segment Tree
                - utilizada para consultar e atualizar valores em intervalos de
   v[0..n).
                - operações:
                        - build - O(n lg n).
                        - search - O(lg n) - consulta o valor mínimo contido no
   intervalo [0..n-1].
                        - add - O(lg n) - atualiza o valor de v(i).

                        - soma (nulo = 0), mínimo (nulo = inf), etc.

*/

void build_segment_tree(vector<int> &v, vector<int> &st, int nulo) {
  int n = v.size();
  int k = 1;

  while (pow(2, k) < n)
    k++;
  int ns = pow(2, k);
  st.resize(2 * ns);

  for (int i = ns; i < 2 * ns; i++) {
    if (i - ns < n)
      st[i] = v[i - ns];
    else
      st[i] = nulo;
  }

  int start = ns;
  int delta = 2 * ns;
  for (int pot = k; pot >= 0; pot--) {
    int sz = pow(2, pot);
    for (int i = start; i < delta; i += 2) {
      st[i / 2] = max(st[i], st[i + 1]);
    }
    delta = start;
    start /= 2;
  }
}

int search(int i, int j, vector<int> &st) {
  int n = st.size() / 2;
  i += n;
  j += n;
  bool i_last = false;
  bool j_last = false;
  int t = 0;
  while (i <= j) {
    if (!i_last and (i % 2 == 1 or j_last)) {
      t = max(t, st[i]);
      i++;
    }
    if (!j_last and (j % 2 == 0 or i_last)) {
      t = max(t, st[j]);
      j--;
    }
    if (!i_last and i % 2 == 1) {
      i_last = true;
    }
    if (!j_last and j % 2 == 0) {
      j_last = true;
    }
    i = i / 2;
    j = j / 2;
  }
  return t;
}

void add(int x, int i, vector<int> &st) {
  int n = st.size() / 2;
  i += n;
  st[i] = x;
  int t = st[i];
  while (i >= 1) {
    st[i] = max(st[i], t);
    i /= 2;
  }
}

void show(vector<int> &st) {
  cout << st.size() << ": ";
  for (int i = 0; i < st.size(); i++) {
    cout << st[i] << " ";
  }
  cout << endl;
}

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

  vector<int> v(n, 0);
  for (int i = 0; i < n; i++) {
    cin >> v[i];
    v[i]--;
  }

  vector<int> w(n, 0);
  vector<int> st;
  build_segment_tree(w, st, 0);

  for (int i = 0; i < n; i++) {
    int a, b;
    a = max(0, v[i] - k);
    b = min(n - 1, v[i] + k);
    int t = search(a, b, st);
    add(t + 1, v[i], st);
    // cout << v[i] << " ab: " << a << " " << b << ": " << search(a, b, st) <<
    // endl;
  }

  //	add(10, 4, st);
  //	add(-9, 1, st);
  //	show(st);

  cout << search(0, n - 1, st) << endl;
}

#include "assert.h"
#include "math.h"
#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

int inf = std::numeric_limits<int>().max();

#define BUFF ios::sync_with_stdio(false)
#define epsilon 1e-07
#define pi 2 * acos(0.0);
#define mod 1000000007 // 1e9+7
#define ll long long
#define cerr                                                                   \\
  if (false)                                                                   \\
  cerr
#define watch(x) cerr << #x << " = " << x << endl;

/*

        Segment Tree
                - utilizada para consultar e atualizar valores em intervalos de
   v[0..n).
                - operações:
                        - build - O(n lg n).
                        - search - O(lg n) - consulta o valor mínimo contido no
   intervalo [0..n-1].
                        - add - O(lg n) - atualiza o valor de v(i).

                        - soma (nulo = 0), mínimo (nulo = inf), etc.

*/

void build_segment_tree(vector<int> &v, vector<int> &st, int nulo) {
  int n = v.size();
  int k = 1;

  while (pow(2, k) < n)
    k++;
  int ns = pow(2, k);
  st.resize(2 * ns);

  for (int i = ns; i < 2 * ns; i++) {
    if (i - ns < n)
      st[i] = v[i - ns];
    else
      st[i] = nulo;
  }

  int start = ns;
  int delta = 2 * ns;
  for (int pot = k; pot >= 0; pot--) {
    for (int i = start; i < delta; i += 2) {
      st[i / 2] = max(st[i], st[i + 1]);
    }
    delta = start;
    start /= 2;
  }
}

int search(int i, int j, vector<int> &st) {
  int n = st.size() / 2;
  i += n;
  j += n;
  bool i_last = false;
  bool j_last = false;
  int t = 0;
  while (i <= j) {
    if (!i_last and (i % 2 == 1 or j_last)) {
      t = max(t, st[i]);
      i++;
    }
    if (!j_last and (j % 2 == 0 or i_last)) {
      t = max(t, st[j]);
      j--;
    }
    if (!i_last and i % 2 == 1) {
      i_last = true;
    }
    if (!j_last and j % 2 == 0) {
      j_last = true;
    }
    i = i / 2;
    j = j / 2;
  }
  return t;
}

void add(int x, int i, vector<int> &st) {
  int n = st.size() / 2;
  i += n;
  st[i] = x;
  int t = st[i];
  while (i >= 1) {
    st[i] = max(st[i], t);
    i /= 2;
  }
}

void show(vector<int> &st) {
  cout << st.size() << ": ";
  for (int i = 0; i < st.size(); i++) {
    cout << st[i] << " ";
  }
  cout << endl;
}

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

  vector<int> v(n, 0);
  for (int i = 0; i < n; i++) {
    cin >> v[i];
  }

  vector<int> w(300001, 0);
  vector<int> st;
  build_segment_tree(w, st, 0);

  for (int i = 0; i < n; i++) {
    int a, b;
    a = max(0, v[i] - k);
    b = min(300001 - 1, v[i] + k);
    int t = search(a, b, st);
    add(t + 1, v[i], st);
    //		cout << v[i] << " ab: " << a << " " << b << ": " << search(a, b, st)
    //<< endl;
  }

  //	add(10, 4, st);
  //	add(-9, 1, st);
  //	show(st);

  cout << search(0, 300001 - 1, st) << endl;
}


#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn = 1e7;
struct point {
  int l, r, sum;
} t[maxn];
int n, k, sum, ans;
void make(int left, int right, int num) {
  t[num].l = left;
  t[num].r = right;
  if (left == right)
    return;
  else {
    make(left, (left + right) / 2, num * 2);
    make((right + left) / 2 + 1, right, num * 2 + 1);
    t[num].sum = t[num * 2].sum + t[num * 2 + 1].sum;
  }
}
void find(int left, int right, int num) {
  if (t[num].l == t[num].r)
    return;
  if (!(left <= t[num].l && right >= t[num].r)) {
    if (right <= (t[num].l + t[num].r) / 2)
      find(left, right, num * 2);
    else if (left >= (t[num].l + t[num].r) / 2 + 1)
      find(left, right, num * 2 + 1);
    else {
      find(left, right, num * 2);
      find(left, right, num * 2 + 1);
    }
  } else {
    sum = max(sum, t[num].sum);
  }
}
void add(int x, int y, int num) {
  if (t[num].l == t[num].r) {
    t[num].sum++;
    return;
  }
  if (y <= (t[num].l + t[num].r) / 2)
    add(x, y, num * 2);
  else if (x >= (t[num].l + t[num].r) / 2)
    add(x, y, num * 2 + 1);
  else {
    add(x, y, num * 2);
    add(x, y, num * 2 + 1);
  }
  t[num].sum = max(t[num * 2].sum, t[num * 2 + 1].sum);
}
int main() {
  cin >> n >> k;
  make(0, 3 * n, 1);
  for (int i = 1, x; i <= n; i++) {
    cin >> x;
    add(x, x + 2 * k, 1);
    sum = 0;
    find(x, x + 2 * k, 1);
    ans = max(sum, ans);
  }
  cout << ans;
}

#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 5e5 + 5;
int t[maxn << 2];
void update(int x, int nv, int l, int r, int num) {
  if (l == r) {
    t[num] = nv;
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    update(x, nv, l, mid, num << 1);
  else
    update(x, nv, mid + 1, r, num << 1 | 1);
  t[num] = max(t[num << 1], t[num << 1 | 1]);
}
int query(int x, int y, int l, int r, int num) {
  if (l > y || r < x)
    return 0;
  if (l >= x && r <= y)
    return t[num];
  int mid = (l + r) >> 1;
  return max(query(x, y, l, mid, num << 1),
             query(x, y, mid + 1, r, num << 1 | 1));
}
int n, k, ans;
int main() {
  cin >> n >> k;
  for (int i = 1, x; i <= n; i++) {
    cin >> x;
    int p = query(max(0, x - k), x + k, 0, maxn - 1, 1);
    ans = max(ans, 1 + p);
    update(x, 1 + p, 0, maxn - 1, 1);
  }
  cout << ans;
}


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

struct RMst { // Range max segtree
  vector<int> d;
  int zero;
  RMst(int sz, int num) {
    int x = 1;
    while (x < sz)
      x *= 2;
    zero = x;
    d.resize(sz * 2, num);
  }
  void setnum(int di, int num) {
    di += zero;
    d[di] = num;
    di /= 2;
    while (di >= 1 && d[di] < num) {
      d[di] = max(d[di * 2], d[di * 2 + 1]);
      di /= 2;
    }
    return;
  }
  int ranmax(int l, int r) { // 0-index,[l,r)
    if (l >= r)
      return -1;
    int x = -1001001001;
    l += zero;
    r += zero;
    while (1) {
      if (l % 2 == 1) {
        x = max(x, d[l]);
        ++l;
      }
      if (r % 2 == 1) {
        x = max(x, d[r - 1]);
        --r;
      }
      if (l == r)
        break;
      l /= 2;
      r /= 2;
    }
    return x;
  }
};

int main() {
  int n, k;
  cin >> n >> k;
  RMst dp(300005, 0);
  for (int i = 0; i < n; ++i) {
    int a;
    cin >> a;
    int l = max(0, a - k);
    int r = min(300003, a + k + 1);
    dp.setnum(a, dp.ranmax(l, r) + 1);
  }
  cout << dp.ranmax(0, 300005) << endl;
}

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

struct RMst { // Range max segtree
  vector<int> d;
  int zero;
  RMst(int sz, int num) {
    int x = 1;
    while (x < sz)
      x *= 2;
    zero = x;
    d.resize(x * 2, num);
  }
  void setnum(int di, int num) {
    di += zero;
    d[di] = num;
    di /= 2;
    while (di >= 1 && d[di] < num) {
      d[di] = num;
      di /= 2;
    }
    return;
  }
  int ranmax(int l, int r) { // 0-index,[l,r)
    if (l >= r)
      return -1;
    int x = -1001001001;
    l += zero;
    r += zero;
    while (1) {
      if (l % 2 == 1) {
        x = max(x, d[l]);
        ++l;
      }
      if (r % 2 == 1) {
        x = max(x, d[r - 1]);
        --r;
      }
      if (l == r)
        break;
      l /= 2;
      r /= 2;
    }
    return x;
  }
};

int main() {
  int n, k;
  cin >> n >> k;
  RMst dp(300005, 0);
  for (int i = 0; i < n; ++i) {
    int a;
    cin >> a;
    int l = max(0, a - k);
    int r = min(300003, a + k + 1);
    dp.setnum(a, dp.ranmax(l, r) + 1);
  }
  cout << dp.ranmax(0, 300005) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll INF = 1e9 + 7;
ll MOD = 998244353;
typedef pair<long long, ll> ii;
#define iii pair<ii, ll>
#define f(i, a, b) for (ll i = a; i < b; i++)
#define rf(i, a, b) for (long long i = a; i >= b; i--)
#define fastio                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define w(t) while (t--)
#define c(n)                                                                   \\
  ;                                                                            \\
  cin >> n;
#define p(n) cout << n;
#define pl(n) cout << n << "\\n";
#define ps(n)                                                                  \\
  ;                                                                            \\
  cout << n << " ";
#define F first
#define S second
#define pb(a) push_back(a)
#define all(x) (x).begin(), (x).end()
#define ull unsigned long long
#define vll vector<ll>
#define vii vector<ii>
#define mkp make_pair
#define ld long double
#define arrin(a, n)                                                            \\
  f(i, 0, n) { cin >> a[i]; }
#define arrout(a, n)                                                           \\
  f(i, 0, n) { cout << a[i] << " "; }
#define printclock                                                             \\
  cerr << "Time : " << *(ld)clock() / (ld)CLOCKS_PER_SEC << "ms\\n";
#define PI (2 * acos(0))
#define EPS 1e-18
ll seg[1000005] = {0};
void update(ll s, ll e, ll qs, ll qe, ll idx, ll k) {
  if (s == e && s == qs) {
    seg[idx] = k;
    return;
  }
  if (qs > e || qe < s) {
    return;
  }
  ll mid = (s + e) / 2;
  update(s, mid, qs, qe, idx * 2, k);
  update(mid + 1, e, qs, qe, idx * 2 + 1, k);
  seg[idx] = max(seg[idx * 2], seg[idx * 2 + 1]);
}
ll query(ll s, ll e, ll qs, ll qe, ll idx) {
  if (qs <= s && e <= qe) {
    return seg[idx];
  }
  if (qs > e || qe < s) {
    return 0;
  }
  ll mid = (s + e) / 2;
  ll a = query(s, mid, qs, qe, idx * 2);
  ll b = query(mid + 1, e, qs, qe, idx * 2 + 1);
  return max(a, b);
}
int main(void) {
  fastio;
  ll n, k;
  cin >> n >> k;
  ll arr[n];
  arrin(arr, n);
  ll dp[n];
  ll ans = 0;
  ll n2 = 300000;
  rf(i, n - 1, 0) {
    dp[i] = 1 + query(1, n2, max(1LL, arr[i] - k), min(n2, arr[i] + k), 1);
    update(1, n2, arr[i], arr[i], 1, dp[i]);
    ans = max(ans, dp[i]);
  }
  pl(ans);
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll INF = 1e9 + 7;
ll MOD = 998244353;
typedef pair<long long, ll> ii;
#define iii pair<ii, ll>
#define f(i, a, b) for (ll i = a; i < b; i++)
#define rf(i, a, b) for (long long i = a; i >= b; i--)
#define fastio                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define w(t) while (t--)
#define c(n)                                                                   \\
  ;                                                                            \\
  cin >> n;
#define p(n) cout << n;
#define pl(n) cout << n << "\\n";
#define ps(n)                                                                  \\
  ;                                                                            \\
  cout << n << " ";
#define F first
#define S second
#define pb(a) push_back(a)
#define all(x) (x).begin(), (x).end()
#define ull unsigned long long
#define vll vector<ll>
#define vii vector<ii>
#define mkp make_pair
#define ld long double
#define arrin(a, n)                                                            \\
  f(i, 0, n) { cin >> a[i]; }
#define arrout(a, n)                                                           \\
  f(i, 0, n) { cout << a[i] << " "; }
#define printclock                                                             \\
  cerr << "Time : " << *(ld)clock() / (ld)CLOCKS_PER_SEC << "ms\\n";
#define PI (2 * acos(0))
#define EPS 1e-18
ll seg[1200005] = {0};
void update(ll s, ll e, ll qs, ll qe, ll idx, ll k) {
  if (s == e && s == qs) {
    seg[idx] = k;
    return;
  }
  if (qs > e || qe < s) {
    return;
  }
  ll mid = (s + e) / 2;
  update(s, mid, qs, qe, idx * 2, k);
  update(mid + 1, e, qs, qe, idx * 2 + 1, k);
  seg[idx] = max(seg[idx * 2], seg[idx * 2 + 1]);
}
ll query(ll s, ll e, ll qs, ll qe, ll idx) {
  if (qs <= s && e <= qe) {
    return seg[idx];
  }
  if (qs > e || qe < s) {
    return 0;
  }
  ll mid = (s + e) / 2;
  ll a = query(s, mid, qs, qe, idx * 2);
  ll b = query(mid + 1, e, qs, qe, idx * 2 + 1);
  return max(a, b);
}
int main(void) {
  fastio;
  ll n, k;
  cin >> n >> k;
  ll arr[n];
  arrin(arr, n);
  f(i, 0, n) { arr[i]++; }
  ll dp[n];
  ll ans = 0;
  ll n2 = 300001;
  rf(i, n - 1, 0) {
    dp[i] = 1 + query(1, n2, max(1LL, arr[i] - k), min(n2, arr[i] + k), 1);
    update(1, n2, arr[i], arr[i], 1, dp[i]);
    ans = max(ans, dp[i]);
  }
  pl(ans);
}