#include <bits/stdc++.h>

#define all(x) x.begin(), x.end()

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const long long MOD = 1e9 + 7;
const long long LINF = 1e18;
const int INF = 0x3f3f3f3f;
const int MAXN = 300050;

int a[MAXN], dp[MAXN];
int lg[MAXN] = {-1};
int maxn[MAXN][50];
int minn[MAXN][50];
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - 48;
    ch = getchar();
  }
  return x * f;
}
void create_ST(int n) {
  for (int i = 1; i <= n; i++) {
    lg[i] = lg[i / 2] + 1;
    maxn[i][0] = a[i];
    minn[i][0] = a[i];
  }
  for (int i = 1; i <= lg[n]; i++) {
    for (int j = 1; j + (1 << i) - 1 <= n; j++) {
      maxn[j][i] = max(maxn[j][i - 1], maxn[j + (1 << (i - 1))][i - 1]);
      minn[j][i] = min(minn[j][i - 1], minn[j + (1 << (i - 1))][i - 1]);
    }
  }
}
ll query_max(int l, int r) {
  int len = lg[r - l + 1];
  return max(maxn[l][len], maxn[r - (1 << (len)) + 1][len]);
}
ll query_min(int l, int r) {
  int len = lg[r - l + 1];
  return min(minn[l][len], minn[r - (1 << (len)) + 1][len]);
}

void solve(int T) {
  int n, l, r, k;
  n = read();
  k = read();
  for (int i = 1; i <= n; i++) {
    a[i] = read();
  }
  create_ST(n);
  dp[1] = 1;
  for (int i = 2; i <= n; i++) {
    if (query_max(1, i - 1) + k < a[i] || query_min(1, i - 1) - k > a[i]) {
      dp[i] = 1;
      continue;
    }
    for (int j = 1; j < i; j++) {
      if (a[j] + k < a[i] || a[j] - k > a[i])
        continue;
      dp[i] = max(dp[i], dp[j] + 1);
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++)
    ans = max(ans, dp[i]);
  printf("%d", ans);
}
signed main() {
  int t = 1;
  // ios::sync_with_stdio(false);
  // cin.tie(0);
  // scanf("%d",&t);
  for (int i = 1; i <= t; i++) {
    solve(i);
  }
}

#include <bits/stdc++.h>

#define all(x) x.begin(), x.end()

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const long long MOD = 1e9 + 7;
const long long LINF = 1e18;
const int INF = 0x3f3f3f3f;
const int MAXN = 300050;

ll a[MAXN];
struct Node {
  ll mx, lz_sum;
} tr[4 * MAXN + 10];
ll in[MAXN + 10];
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - 48;
    ch = getchar();
  }
  return x * f;
}
/*ll max(ll a,ll b)
{
        if(a>=b)return a;
        else return b;
}
ll min(ll a,ll b)
{
        if(a>=b)return b;
        else return a;
}*/
void build(int p, int l, int r) {
  if (r == l) {
    tr[p].mx = in[l];
    tr[p].lz_sum = 0;
    return;
  }
  build(p * 2, l, (l + r) / 2);
  build(p * 2 + 1, (l + r) / 2 + 1, r);
  tr[p].mx = max(tr[p * 2].mx, tr[p * 2 + 1].mx);
}
void change(ll val, int l, int r, int p, int lb, int rb) {
  if (lb == l && rb == r) {
    tr[p].mx = val;
    return;
  }
  int mid = (l + r) / 2;
  if (lb <= mid)
    change(val, l, mid, p * 2, lb, rb);
  if (rb >= mid + 1)
    change(val, mid + 1, r, p * 2 + 1, lb, rb);
  tr[p].mx = max(tr[p * 2].mx, tr[p * 2 + 1].mx);
}
ll query_max(int p, int l, int r, int lb, int rb) {
  if (lb <= l && rb >= r)
    return tr[p].mx;
  int mid = (l + r) / 2;
  ll temp = 0;
  if (lb <= mid && rb > mid)
    temp = max(query_max(p * 2, l, mid, lb, rb),
               query_max(p * 2 + 1, mid + 1, r, lb, rb));
  else if (lb > mid)
    temp = query_max(p * 2 + 1, mid + 1, r, lb, rb);
  else if (rb <= mid)
    temp = query_max(p * 2, l, mid, lb, rb);
  return temp;
}
void solve(int T) {
  ll N, l, r, k;
  N = read();
  k = read();
  ll maxx = 0;
  for (int i = 1; i <= N; i++) {
    a[i] = read();
    maxx = max(a[i], maxx);
  }
  build(1, 0, N);
  ll tmp = 0;
  for (int i = 1; i <= N; i++) {
    tmp = query_max(1, 0, maxx, max(0ll, a[i] - k), a[i] + k);
    change(tmp + 1, 0, maxx, 1, a[i], a[i]);
  }
  printf("%lld", query_max(1, 1, N, 1, N));
}
signed main() {
  int t = 1;
  // ios::sync_with_stdio(false);
  // cin.tie(0);
  // scanf("%d",&t);
  for (int i = 1; i <= t; i++) {
    solve(i);
  }
}


#pragma GCC optimize(2)
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

const ll mod = 1e9 + 7;
const int N = 3e5 + 10, M = 1e6 + 10;
const ll INF = 1e18;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;

#define pi acos(-1)

int n, k;
int a[N];

bool cmp(int a, int b) { return abs(a - b) <= k; }

int main() {
  cin >> n >> k;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  sort(a + 1, a + n + 1, cmp);
  int num = 1;
  for (int i = 2; i <= n; i++) {
    if (abs(a[i] - a[i - 1]) > k)
      break;
    num++;
  }
  cout << num << endl;
  return 0;
}

/*

*/

#pragma GCC optimize(2)
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

const ll mod = 1e9 + 7;
const int N = 6e5 + 10, M = 1e6 + 10;
const ll INF = 1e18;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;

#define pi acos(-1)

int n, k;
int a[N];
struct wc {
  int l, r;
  int dat;
} tr[N << 4];

void pushup(int p) { tr[p].dat = max(tr[p << 1].dat, tr[p << 1 | 1].dat); }

void build(int p, int l, int r) {
  tr[p] = {l, r};
  if (l == r)
    return;
  int mid = l + r >> 1;
  build(p << 1, l, mid);
  build(p << 1 | 1, mid + 1, r);
}

void modify(int p, int x, int v) {
  if (tr[p].l == x && tr[p].r == x) {
    tr[p].dat = max(tr[p].dat, v);
    return;
  }
  int mid = tr[p].l + tr[p].r >> 1;
  if (x <= mid)
    modify(p << 1, x, v);
  else
    modify(p << 1 | 1, x, v);
  pushup(p);
}

int ask(int p, int l, int r) {
  if (tr[p].l >= l && tr[p].r <= r) {
    return tr[p].dat;
  }
  int maxn = 0;
  int mid = tr[p].l + tr[p].r >> 1;
  if (r <= mid)
    maxn = max(maxn, ask(p << 1, l, r));
  else if (l > mid)
    maxn = max(maxn, ask(p << 1 | 1, l, r));
  else {
    maxn = max({maxn, ask(p << 1, l, mid), ask(p << 1 | 1, mid + 1, r)});
  }
  return maxn;
}
int main() {
  cin >> n >> k;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  build(1, 1, N - 1);
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int num = ask(1, max(1, a[i] - k), a[i] + k) + 1;
    ans = max(ans, num);
    modify(1, a[i], num);
    // cout << num << ' ';
  }
  cout << ans << endl;
}
/*

*/


/*
       ▄▄▄▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄▄
      ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░▌
      ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀█░▌
      ▐░▌          ▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░▌ ▄▄▄▄▄▄▄▄ ▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░▌▐░░░░░░░░▌▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░▌ ▀▀▀▀▀▀█░▌▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░▌       ▐░▌▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░█▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄█░▌
      ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░▌
       ▀▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀

 #can_change_the_world_with_the_help_of_0_1
                                    -darshan786    */

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mod 1000000007
#define boost                                                                  \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);
#define F first
#define MAXN 1010
#define int long long
#define S second
#define all(v) v.begin(), v.end()
#define PI pair<int, int>
#define PIS pair<int, string>

int values[41];

void value() {
  values[0] = 1;
  for (int i = 1; i <= 40; i++) {
    values[i] = 2 * values[i - 1];
  }
}

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

  int n, k;
  cin >> n >> k;
  int s[n + 1];
  for (int i = 0; i < n; i++)
    cin >> s[i];

  vector<int> dp(n, 0);

  auto solve = [&]() {
    map<int, int> ma;

    for (int i = 0; i < n; i++) {

      int curr = s[i];

      int low = max(curr - k, 0ll);

      int high = min(curr + k, n);

      for (int j = low; j < high + 1; j++)
        dp[i] = max(dp[i], ma[j] + 1);

      ma[curr] = max(dp[i], ma[curr]);
    }

    int ans = 0;

    for (int i : dp)
      ans = max(i, ans);

    return ans;
  };

  cout << solve() << endl;
}

/*
       ▄▄▄▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄▄
      ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░▌
      ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀█░▌
      ▐░▌          ▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░▌ ▄▄▄▄▄▄▄▄ ▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░▌▐░░░░░░░░▌▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░▌ ▀▀▀▀▀▀█░▌▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░▌       ▐░▌▐░▌       ▐░▌▐░▌       ▐░▌
      ▐░█▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄█░▌
      ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░▌
       ▀▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀

 #can_change_the_world_with_the_help_of_0_1
                                    -darshan786    */

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mod 1000000007
#define boost                                                                  \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);
#define F first
#define MAXN 1010
#define int long long
#define S second
#define all(v) v.begin(), v.end()
#define PI pair<int, int>
#define PIS pair<int, string>

int values[41];

void value() {
  values[0] = 1;
  for (int i = 1; i <= 40; i++) {
    values[i] = 2 * values[i - 1];
  }
}
const int maxn = 3e5 + 5;

int a[maxn];

int tree[6 * maxn];

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

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

  int mid = (l + r) / 2;

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

  return max(t1, t2);
}

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

  int mid = (l + r) / 2;

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

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

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

  int n, k;

  cin >> n >> k;

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

  auto solve = [&]() {
    int mx = 1;

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

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

    return mx;
  };

  cout << solve();
}


#include <cstdio>
class segment_tree {
private:
  int mx[12000005];
  inline int max(int a, int b) { return a > b ? a : b; }
  inline void update(int k) { mx[k] = max(mx[k << 1], mx[k << 1 | 1]); }

public:
  void change(int k, int l, int r, int pos, int x) {
    if (l == r && r == pos) {
      mx[k] = x;
      return;
    }
    int mid = l + r >> 1;
    if (mid >= pos)
      change(k << 1, l, mid, pos, x);
    else
      change(k << 1 | 1, mid + 1, r, pos, x);
    update(k);
  }
  int query(int k, int l, int r, int x, int y) {
    if (x <= 0)
      x = 1;
    if (y > 300000)
      y = 300000;
    if (l >= x && r <= y)
      return mx[k];
    int mid = l + r >> 1, res = 0;
    if (mid >= x)
      res = max(res, query(k << 1, l, mid, x, y));
    if (mid < y)
      res = max(res, query(k << 1 | 1, mid + 1, r, x, y));
    return res;
  }
} t;
int n, k, a[300005];
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
  for (int i = 1; i <= n; ++i)
    t.change(1, 1, 300000, a[i], t.query(1, 1, 300000, a[i] - k, a[i] + k) + 1);
  printf("%d", t.query(1, 1, 300000, 1, 300000));
}

#include <cstdio>
class segment_tree {
private:
  int mx[1200005];
  inline int max(int a, int b) { return a > b ? a : b; }
  inline void update(int k) { mx[k] = max(mx[k << 1], mx[k << 1 | 1]); }

public:
  void change(int k, int l, int r, int pos, int x) {
    if (l == r && r == pos) {
      mx[k] = x;
      return;
    }
    int mid = l + r >> 1;
    if (mid >= pos)
      change(k << 1, l, mid, pos, x);
    else
      change(k << 1 | 1, mid + 1, r, pos, x);
    update(k);
  }
  int query(int k, int l, int r, int x, int y) {
    if (x < 0)
      x = 0;
    if (y > 300000)
      y = 300000;
    if (l >= x && r <= y)
      return mx[k];
    int mid = l + r >> 1, res = 0;
    if (mid >= x)
      res = max(res, query(k << 1, l, mid, x, y));
    if (mid < y)
      res = max(res, query(k << 1 | 1, mid + 1, r, x, y));
    return res;
  }
} t;
int n, k, a[300005];
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
  for (int i = 1; i <= n; ++i)
    t.change(1, 0, 300000, a[i], t.query(1, 0, 300000, a[i] - k, a[i] + k) + 1);
  printf("%d", t.query(1, 0, 300000, 0, 300000));
}


/*
 * じょえチャンネル
 * 高評価・チャンネル登録よろしくおねがいします！
 * https://www.youtube.com/channel/UCRXsI3FL_kvaVL9zoolBfbQ
 */

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")

// here!!!
//  define int long long !!!!!

#define int long long

// define int long long !!!!!

// #define mod 1000000007ll
constexpr int mod = 998244353ll;

constexpr double PI = 3.141592653589793238462643383279;
// constexpr double eps = DBL_EPSILON;

typedef long long ll;

#ifdef int
#define inf (int)(3e18)
#else
#define inf (int)(5e8)
#endif

#define intt long long
#define itn long long
#define innt long long
#define P pair<long long, long long>

#define rep(i, n) for (int i = 0; i < n; i++)
#define REP(i, n) for (int i = 1; i <= n; i++)
#define rev_rep(i, n) for (int i = n - 1; i >= 0; i--)
#define REV_REP(i, n) for (int i = n; i >= 1; i--)

#define ALL(v) v.begin(), v.end()

#define smallpriority_queue(T) priority_queue<T, vector<T>, greater<T>>

using namespace std;

// Library
// モッドパウ
inline int modpow(int x, int y, int m = mod) {
  int res = 1;
  while (y) {
    if (y & 1) {
      res *= x;
      res %= m;
    }
    x = x * x % m;
    y /= 2;
  }
  return res;
}

int mypow(int x, int y) {
  int res = 1;
  while (y) {
    if (y % 2) {
      res *= x;
    }
    x = x * x;
    y /= 2;
  }
  return res;
}
// is the number (x) a prime number?
// bool prime(int x) {
//     if (!x || x == 1) {
//         return false;
//     }
//     for (int i = 2; i * i <= x; i++) {
//         if (!(x % i)) {
//             return false;
//         }
//     }
//     return true;
// }
bool prime(int x) {
  if (!x || x == 1) {
    return false;
  }
  if (x == 2) {
    return true;
  }
  if (!(x & 1)) {
    return false;
  }
  for (int i = 3; i * i <= x; i += 2) {
    if (!(x % i)) {
      return false;
    }
  }
  return true;
}

// saidai-kouyakusuu
inline int gcd(int x, int y) {
  if (!y) {
    return x;
  }
  return gcd(y, x % y);
}

// number of keta
int keta(int x) {
  int ans = 0;
  while (x) {
    x /= 10;
    ans++;
  }
  return ans;
}

// number of 2shinsuu keta
int bitketa(int x) {
  int ans = 0;
  while (x) {
    x >>= 1;
    ans++;
  }
  return ans;
}

// sum of keta
int ketasum(int x) {
  int ans = 0;
  while (x) {
    ans += x % 10;
    x /= 10;
  }
  return ans;
}

inline int lcm(int x, int y) {
  int ans = x / gcd(x, y) * y;
  return ans;
}
int twobeki(int x) {
  int ans = 0;
  while (1) {
    if (!(x & 1)) {
      ans++;
      x >>= 1;
    } else {
      break;
    }
  }
  return ans;
}

template <class T, class U> inline bool chmax(T &lhs, const U &rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <class T, class U> inline bool chmin(T &lhs, const U &rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }

#define fin(i) scanf("%lld", &i)
#define fout(i) printf("%lld", i)
#define fendl printf("\\n")

int kai(int x, int y) {
  int res = 1;
  for (int i = x - y + 1; i <= x; i++) {
    res *= i;
    res %= mod;
  }
  return res;
}

int comb(int x, int y) {
  if (y > x)
    return 0;
  //    cout<<kai(x, y)<<' '<<modpow(kai(y, y), mod - 2)<<endl;
  return kai(x, y) * modpow(kai(y, y), mod - 2) % mod;
}
// Library-End

// 入出力高速化時にはoff！！！！
// #define vecin(v) for(int i=0;i<v.size();i++)scanf("%lld",&v[i]);
// #define vecout(v) {if(v.size())printf("%lld",v[0]);for(int
// i=1;i<(int)v.size();i++)printf(" %lld",v[i]);printf("\\n");}

template <class T> class SegTree {
  int n;
  vector<T> node;
  T def;
  function<T(T, T)> operation;
  function<T(T, T)> update;

public:
  SegTree(unsigned int _n, T _def, function<T(T, T)> _operation,
          function<T(T, T)> _update)
      : def(_def), operation(_operation), update(_update) {
    n = 1;
    while (n < _n) {
      n *= 2;
    }
    node = vector<T>(n * 2, def);
  }
  SegTree(vector<int> &initvec, function<T(T, T)> _operation,
          function<T(T, T)> _update)
      : operation(_operation), update(_update) {
    n = 1;
    while (n < initvec.size()) {
      n *= 2;
    }
    node = vector<T>(n * 2, def);
    for (int i = n; i < n + initvec.size(); i++) {
      node[i] = initvec[i - n];
    }
    for (int i = n - 1; i >= 1; i--) {
      node[i] = operation(node[i * 2], node[i * 2 + 1]);
    }
  }
  void change(int i, T x) {
    i += n;
    node[i] = update(node[i], x);
    while (i >= 1) {
      i >>= 1;
      node[i] = operation(node[i * 2], node[i * 2 + 1]);
    }
  }
  T query(int l, int r) {
    l += n;
    r += n;
    T rx = def, lx = def;
    while (l < r) {
      if (l & 1) {
        lx = operation(lx, node[l]);
        l++;
      }
      if (r & 1) {
        r--;
        rx = operation(node[r], rx);
      }
      l >>= 1;
      r >>= 1;
    }
    return operation(lx, rx);
  }
  T operator[](const int &x) { return node[x + n]; }
  void fill(T x) { std::fill(ALL(node), x); }
  void print() {
    rep(i, n) std::cout << operator[](i) << " ";
    std::cout << std::endl;
  }
  T queryForALL() { return node[1]; }
};

#define R_MIN ([](long long a, long long b) { return min(a, b); })
#define R_MAX ([](long long a, long long b) { return max(a, b); })
#define R_SUM ([](long long a, long long b) { return a + b; })

#define NORMAL_UPDATE ([](long long a, long long b) { return b; })
#define ADD_UPDATE ([](long long a, long long b) { return a + b; })
#define MINUS_UPDATE ([](long long a, long long b) { return a - b; }

class Union_Find {
  vector<int> par;
  vector<int> ookisa;

public:
  Union_Find(int size) {
    par = vector<int>(size);
    ookisa = vector<int>(size);
    for (int i = 0; i < size; i++) {
      par[i] = i;
      ookisa[i] = 1;
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    }
    return par[x] = find(par[x]);
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) {
      return;
    }
    if (ookisa[x] < ookisa[y]) {
      par[x] = y;
      ookisa[y] += ookisa[x];
      ookisa[x] = 0;
    } else {
      par[y] = x;
      ookisa[x] += ookisa[y];
      ookisa[y] = 0;
    }
  }
  int size(int i) {
    i = find(i);
    return ookisa[i];
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

class BIT {
  vector<int> data;
  int size = 0;

public:
  BIT(int _size) {
    data = vector<int>(_size + 1);
    size = _size;
  }
  void add(int i, int x) {
    while (i <= size) {
      data[i] += x;
      i += i & -i;
    }
  }
  int sum(int i) {
    assert(i <= size);
    int s = 0;
    while (i > 0) {
      s += data[i];
      i -= i & -i;
    }
    return s;
  }
  int lower_bound(int x) {
    if (x <= 0) {
      return 0;
    } else {
      int i = 0;
      int r = 1;
      while (r < size)
        r = r << 1;
      for (int len = r; len > 0; len = len >> 1) {
        if (i + len < size && data[i + len] < x) {
          x -= data[i + len];
          i += len;
        }
      }
      return i + 1;
    }
  }
};

// Union-Find-End

int perm[2000005];
void init_perm() {
  perm[0] = 1;
  REP(i, 2000004) { perm[i] = perm[i - 1] * i % mod; }
}

int nCk(int x, int y) {
  if (y > x) {
    return 0;
  }
  if (x < 0) {
    return 0;
  }
  return perm[x] * modpow(perm[x - y], mod - 2) % mod *
         modpow(perm[y], mod - 2) % mod;
}

struct Dot {
  double x;
  double y;
  Dot(double _x = 0.0, double _y = 0.0) {
    x = _x;
    y = _y;
  }
};

struct Dot_i {
  int x;
  int y;
  Dot_i(int _x = 0, int _y = 0) {
    x = _x;
    y = _y;
  }
};

double kyori(pair<int, int> f, pair<int, int> s) {
  double ans = 0;
  double t = fabs(f.first - s.first);
  double y = fabs(f.second - s.second);
  ans = sqrt(t * t + y * y);
  return ans;
}

double kyori(Dot f, Dot s) {
  double ans = 0;
  double t = fabs(f.x - s.x);
  double y = fabs(f.y - s.y);
  ans = sqrt(t * t + y * y);
  return ans;
}

inline bool stringmax(string &x, string &y) {
  if (x.size() != y.size()) {
    return x.size() < y.size();
  }
  return x < y;
}

// vector<int>  RollingHash(string &s, string& t){
//     vector<int> ans;
//     if(s.size()<t.size())return ans;
//     __int128 h=0,hamod=0,ki=0,kim=0,hikaku=0,one=0;
//     one=1;
//     ki=1000000007ll;
//     hamod=(one<<61)-1;
//     kim=1;
//     rep(i,t.size()){
//         hikaku*=ki;
//         h*=ki;
//         kim*=ki;
//         hikaku+=t[i];
//         h+=s[i];
//         hikaku%=hamod;
//         h%=hamod;
//         kim%=hamod;
//     }
//     rep(i,(int)s.size()-(int)t.size()){
//         if (h==hikaku) {
//             ans.emplace_back(i);
//         }
//         h*=ki;
//         h%=hamod;
//         h+=s[i+(int)t.size()];
//         h%=hamod;
//         h+=hamod;
//         h-=s[i]*kim%hamod;
//         h%=hamod;
//     }
//     if(h==hikaku)ans.emplace_back((int)s.size()-(int)t.size());
//     return ans;
// }
struct edge {
  int to;
  int length;
  edge(int _to, int _length) {
    to = _to;
    length = _length;
  }
};
vector<int> djkstra(vector<vector<edge>> &road, int start) {
  vector<int> kyo(road.size(), inf);
  smallpriority_queue(P) q;
  q.push({0, start});
  kyo[start] = 0;
  while (q.size()) {
    int x = q.top().second;
    itn now = q.top().first;
    q.pop();
    if (kyo[x] < now) {
      continue;
    }
    for (auto &i : road[x]) {
      if (kyo[i.to] > now + i.length) {
        kyo[i.to] = now + i.length;
        q.push({kyo[i.to], i.to});
      }
    }
  }
  return kyo;
}

template <class T> void change_to_unique(vector<T> &v) {
  std::sort(ALL(v));
  auto k = unique(ALL(v));
  if (k != v.end())
    v.erase(k, v.end());
}

double kodo_dosuu(double r) { return 180.0 * r / (double)PI; }

double dosuu_kodo(double r) { return r * (double)PI / 180.0; }

double kakudo(Dot a, Dot b1, Dot b2) {
  double size1 = kyori(a, b1), size2 = kyori(a, b2);
  double nai = (b1.x - a.x) * (b2.x - a.x) + (b1.y - a.y) * (b2.y - a.y);
  nai /= size1 * size2;
  return kodo_dosuu(acos(nai));
}

struct fraction {
  int shi;
  int bo;
  fraction(int bunshi, int bunbo) : bo(bunbo), shi(bunshi) {
    if (bunbo && bunshi) {
      int g = gcd(bo, shi);
      bo /= g;
      shi /= g;
    }
  };
  explicit inline operator double() const { return (double)shi / (double)bo; }
  explicit inline operator long double() const {
    return (long double)shi / (long double)bo;
  }
};
bool operator<(const fraction &b1, const fraction &b2) {
  return b1.shi * b2.bo < b2.shi * b1.bo;
}
bool operator>(const fraction &b1, const fraction &b2) {
  return b1.shi * b2.bo > b2.shi * b1.bo;
}

template <class T> void vecout(vector<T> &v) {
  if (v.size()) {
    cout << v[0];
  }
  REP(i, (int)v.size() - 1) { cout << ' ' << v[i]; }
  cout << endl;
}

inline int zeronCk(int x, int y) { return nCk(y + x - 1, x - 1); }

inline int modinv(int x, int MOD = mod) { return modpow(x, MOD - 2); }

#define endl "\\n" // interactive の時に注意！！！
#define Endl "\\n" // interactive の時に注意！！！
#define cinn cin
#define printd cout << fixed << setprecision(10)
#define rrep(i, f, s) for (int i = f; i < s; i++)
#define RREP(i, f, s) for (int i = f; i <= s; i++)
#define REV_RREP(i, f, s) for (int i = s; i >= f; i--)
#define hen_rep(i, l, step) for (int i = 0; i < l; i += step)
#define HEN_REP(i, l, step) for (int i = 1; i <= l; i += step)

int n, k, a[300004], ans, memo[300004];
signed main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  cin >> n >> k;
  SegTree<int> seg(10, 0, R_MAX, NORMAL_UPDATE);
  rep(i, n) { cin >> a[i]; }
  rep(i, n) {
    chmax(ans, seg.query(max(0ll, a[i] - k), min(300004ll, a[i] + k + 1)) + 1);
    seg.change(a[i], max(1ll, seg.query(max(0ll, a[i] - k),
                                        min(300004ll, a[i] + k + 1)) +
                                  1));
  }
  cout << ans << endl;
}

/*
 * じょえチャンネル
 * 高評価・チャンネル登録よろしくおねがいします！
 * https://www.youtube.com/channel/UCRXsI3FL_kvaVL9zoolBfbQ
 */

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")

// here!!!
//  define int long long !!!!!

#define int long long

// define int long long !!!!!

// #define mod 1000000007ll
constexpr int mod = 998244353ll;

constexpr double PI = 3.141592653589793238462643383279;
// constexpr double eps = DBL_EPSILON;

typedef long long ll;

#ifdef int
#define inf (int)(3e18)
#else
#define inf (int)(5e8)
#endif

#define intt long long
#define itn long long
#define innt long long
#define P pair<long long, long long>

#define rep(i, n) for (int i = 0; i < n; i++)
#define REP(i, n) for (int i = 1; i <= n; i++)
#define rev_rep(i, n) for (int i = n - 1; i >= 0; i--)
#define REV_REP(i, n) for (int i = n; i >= 1; i--)

#define ALL(v) v.begin(), v.end()

#define smallpriority_queue(T) priority_queue<T, vector<T>, greater<T>>

using namespace std;

// Library
// モッドパウ
inline int modpow(int x, int y, int m = mod) {
  int res = 1;
  while (y) {
    if (y & 1) {
      res *= x;
      res %= m;
    }
    x = x * x % m;
    y /= 2;
  }
  return res;
}

int mypow(int x, int y) {
  int res = 1;
  while (y) {
    if (y % 2) {
      res *= x;
    }
    x = x * x;
    y /= 2;
  }
  return res;
}
// is the number (x) a prime number?
// bool prime(int x) {
//     if (!x || x == 1) {
//         return false;
//     }
//     for (int i = 2; i * i <= x; i++) {
//         if (!(x % i)) {
//             return false;
//         }
//     }
//     return true;
// }
bool prime(int x) {
  if (!x || x == 1) {
    return false;
  }
  if (x == 2) {
    return true;
  }
  if (!(x & 1)) {
    return false;
  }
  for (int i = 3; i * i <= x; i += 2) {
    if (!(x % i)) {
      return false;
    }
  }
  return true;
}

// saidai-kouyakusuu
inline int gcd(int x, int y) {
  if (!y) {
    return x;
  }
  return gcd(y, x % y);
}

// number of keta
int keta(int x) {
  int ans = 0;
  while (x) {
    x /= 10;
    ans++;
  }
  return ans;
}

// number of 2shinsuu keta
int bitketa(int x) {
  int ans = 0;
  while (x) {
    x >>= 1;
    ans++;
  }
  return ans;
}

// sum of keta
int ketasum(int x) {
  int ans = 0;
  while (x) {
    ans += x % 10;
    x /= 10;
  }
  return ans;
}

inline int lcm(int x, int y) {
  int ans = x / gcd(x, y) * y;
  return ans;
}
int twobeki(int x) {
  int ans = 0;
  while (1) {
    if (!(x & 1)) {
      ans++;
      x >>= 1;
    } else {
      break;
    }
  }
  return ans;
}

template <class T, class U> inline bool chmax(T &lhs, const U &rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <class T, class U> inline bool chmin(T &lhs, const U &rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }

#define fin(i) scanf("%lld", &i)
#define fout(i) printf("%lld", i)
#define fendl printf("\\n")

int kai(int x, int y) {
  int res = 1;
  for (int i = x - y + 1; i <= x; i++) {
    res *= i;
    res %= mod;
  }
  return res;
}

int comb(int x, int y) {
  if (y > x)
    return 0;
  //    cout<<kai(x, y)<<' '<<modpow(kai(y, y), mod - 2)<<endl;
  return kai(x, y) * modpow(kai(y, y), mod - 2) % mod;
}
// Library-End

// 入出力高速化時にはoff！！！！
// #define vecin(v) for(int i=0;i<v.size();i++)scanf("%lld",&v[i]);
// #define vecout(v) {if(v.size())printf("%lld",v[0]);for(int
// i=1;i<(int)v.size();i++)printf(" %lld",v[i]);printf("\\n");}

template <class T> class SegTree {
  int n;
  vector<T> node;
  T def;
  function<T(T, T)> operation;
  function<T(T, T)> update;

public:
  SegTree(unsigned int _n, T _def, function<T(T, T)> _operation,
          function<T(T, T)> _update)
      : def(_def), operation(_operation), update(_update) {
    n = 1;
    while (n < _n) {
      n *= 2;
    }
    node = vector<T>(n * 2, def);
  }
  SegTree(vector<int> &initvec, function<T(T, T)> _operation,
          function<T(T, T)> _update)
      : operation(_operation), update(_update) {
    n = 1;
    while (n < initvec.size()) {
      n *= 2;
    }
    node = vector<T>(n * 2, def);
    for (int i = n; i < n + initvec.size(); i++) {
      node[i] = initvec[i - n];
    }
    for (int i = n - 1; i >= 1; i--) {
      node[i] = operation(node[i * 2], node[i * 2 + 1]);
    }
  }
  void change(int i, T x) {
    i += n;
    node[i] = update(node[i], x);
    while (i >= 1) {
      i >>= 1;
      node[i] = operation(node[i * 2], node[i * 2 + 1]);
    }
  }
  T query(int l, int r) {
    l += n;
    r += n;
    T rx = def, lx = def;
    while (l < r) {
      if (l & 1) {
        lx = operation(lx, node[l]);
        l++;
      }
      if (r & 1) {
        r--;
        rx = operation(node[r], rx);
      }
      l >>= 1;
      r >>= 1;
    }
    return operation(lx, rx);
  }
  T operator[](const int &x) { return node[x + n]; }
  void fill(T x) { std::fill(ALL(node), x); }
  void print() {
    rep(i, n) std::cout << operator[](i) << " ";
    std::cout << std::endl;
  }
  T queryForALL() { return node[1]; }
};

#define R_MIN ([](long long a, long long b) { return min(a, b); })
#define R_MAX ([](long long a, long long b) { return max(a, b); })
#define R_SUM ([](long long a, long long b) { return a + b; })

#define NORMAL_UPDATE ([](long long a, long long b) { return b; })
#define ADD_UPDATE ([](long long a, long long b) { return a + b; })
#define MINUS_UPDATE ([](long long a, long long b) { return a - b; }

class Union_Find {
  vector<int> par;
  vector<int> ookisa;

public:
  Union_Find(int size) {
    par = vector<int>(size);
    ookisa = vector<int>(size);
    for (int i = 0; i < size; i++) {
      par[i] = i;
      ookisa[i] = 1;
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    }
    return par[x] = find(par[x]);
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) {
      return;
    }
    if (ookisa[x] < ookisa[y]) {
      par[x] = y;
      ookisa[y] += ookisa[x];
      ookisa[x] = 0;
    } else {
      par[y] = x;
      ookisa[x] += ookisa[y];
      ookisa[y] = 0;
    }
  }
  int size(int i) {
    i = find(i);
    return ookisa[i];
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

class BIT {
  vector<int> data;
  int size = 0;

public:
  BIT(int _size) {
    data = vector<int>(_size + 1);
    size = _size;
  }
  void add(int i, int x) {
    while (i <= size) {
      data[i] += x;
      i += i & -i;
    }
  }
  int sum(int i) {
    assert(i <= size);
    int s = 0;
    while (i > 0) {
      s += data[i];
      i -= i & -i;
    }
    return s;
  }
  int lower_bound(int x) {
    if (x <= 0) {
      return 0;
    } else {
      int i = 0;
      int r = 1;
      while (r < size)
        r = r << 1;
      for (int len = r; len > 0; len = len >> 1) {
        if (i + len < size && data[i + len] < x) {
          x -= data[i + len];
          i += len;
        }
      }
      return i + 1;
    }
  }
};

// Union-Find-End

int perm[2000005];
void init_perm() {
  perm[0] = 1;
  REP(i, 2000004) { perm[i] = perm[i - 1] * i % mod; }
}

int nCk(int x, int y) {
  if (y > x) {
    return 0;
  }
  if (x < 0) {
    return 0;
  }
  return perm[x] * modpow(perm[x - y], mod - 2) % mod *
         modpow(perm[y], mod - 2) % mod;
}

struct Dot {
  double x;
  double y;
  Dot(double _x = 0.0, double _y = 0.0) {
    x = _x;
    y = _y;
  }
};

struct Dot_i {
  int x;
  int y;
  Dot_i(int _x = 0, int _y = 0) {
    x = _x;
    y = _y;
  }
};

double kyori(pair<int, int> f, pair<int, int> s) {
  double ans = 0;
  double t = fabs(f.first - s.first);
  double y = fabs(f.second - s.second);
  ans = sqrt(t * t + y * y);
  return ans;
}

double kyori(Dot f, Dot s) {
  double ans = 0;
  double t = fabs(f.x - s.x);
  double y = fabs(f.y - s.y);
  ans = sqrt(t * t + y * y);
  return ans;
}

inline bool stringmax(string &x, string &y) {
  if (x.size() != y.size()) {
    return x.size() < y.size();
  }
  return x < y;
}

// vector<int>  RollingHash(string &s, string& t){
//     vector<int> ans;
//     if(s.size()<t.size())return ans;
//     __int128 h=0,hamod=0,ki=0,kim=0,hikaku=0,one=0;
//     one=1;
//     ki=1000000007ll;
//     hamod=(one<<61)-1;
//     kim=1;
//     rep(i,t.size()){
//         hikaku*=ki;
//         h*=ki;
//         kim*=ki;
//         hikaku+=t[i];
//         h+=s[i];
//         hikaku%=hamod;
//         h%=hamod;
//         kim%=hamod;
//     }
//     rep(i,(int)s.size()-(int)t.size()){
//         if (h==hikaku) {
//             ans.emplace_back(i);
//         }
//         h*=ki;
//         h%=hamod;
//         h+=s[i+(int)t.size()];
//         h%=hamod;
//         h+=hamod;
//         h-=s[i]*kim%hamod;
//         h%=hamod;
//     }
//     if(h==hikaku)ans.emplace_back((int)s.size()-(int)t.size());
//     return ans;
// }
struct edge {
  int to;
  int length;
  edge(int _to, int _length) {
    to = _to;
    length = _length;
  }
};
vector<int> djkstra(vector<vector<edge>> &road, int start) {
  vector<int> kyo(road.size(), inf);
  smallpriority_queue(P) q;
  q.push({0, start});
  kyo[start] = 0;
  while (q.size()) {
    int x = q.top().second;
    itn now = q.top().first;
    q.pop();
    if (kyo[x] < now) {
      continue;
    }
    for (auto &i : road[x]) {
      if (kyo[i.to] > now + i.length) {
        kyo[i.to] = now + i.length;
        q.push({kyo[i.to], i.to});
      }
    }
  }
  return kyo;
}

template <class T> void change_to_unique(vector<T> &v) {
  std::sort(ALL(v));
  auto k = unique(ALL(v));
  if (k != v.end())
    v.erase(k, v.end());
}

double kodo_dosuu(double r) { return 180.0 * r / (double)PI; }

double dosuu_kodo(double r) { return r * (double)PI / 180.0; }

double kakudo(Dot a, Dot b1, Dot b2) {
  double size1 = kyori(a, b1), size2 = kyori(a, b2);
  double nai = (b1.x - a.x) * (b2.x - a.x) + (b1.y - a.y) * (b2.y - a.y);
  nai /= size1 * size2;
  return kodo_dosuu(acos(nai));
}

struct fraction {
  int shi;
  int bo;
  fraction(int bunshi, int bunbo) : bo(bunbo), shi(bunshi) {
    if (bunbo && bunshi) {
      int g = gcd(bo, shi);
      bo /= g;
      shi /= g;
    }
  };
  explicit inline operator double() const { return (double)shi / (double)bo; }
  explicit inline operator long double() const {
    return (long double)shi / (long double)bo;
  }
};
bool operator<(const fraction &b1, const fraction &b2) {
  return b1.shi * b2.bo < b2.shi * b1.bo;
}
bool operator>(const fraction &b1, const fraction &b2) {
  return b1.shi * b2.bo > b2.shi * b1.bo;
}

template <class T> void vecout(vector<T> &v) {
  if (v.size()) {
    cout << v[0];
  }
  REP(i, (int)v.size() - 1) { cout << ' ' << v[i]; }
  cout << endl;
}

inline int zeronCk(int x, int y) { return nCk(y + x - 1, x - 1); }

inline int modinv(int x, int MOD = mod) { return modpow(x, MOD - 2); }

#define endl "\\n" // interactive の時に注意！！！
#define Endl "\\n" // interactive の時に注意！！！
#define cinn cin
#define printd cout << fixed << setprecision(10)
#define rrep(i, f, s) for (int i = f; i < s; i++)
#define RREP(i, f, s) for (int i = f; i <= s; i++)
#define REV_RREP(i, f, s) for (int i = s; i >= f; i--)
#define hen_rep(i, l, step) for (int i = 0; i < l; i += step)
#define HEN_REP(i, l, step) for (int i = 1; i <= l; i += step)

int n, k, a[300004], ans, memo[300004];
signed main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  cin >> n >> k;
  SegTree<int> seg(300004, 0, R_MAX, NORMAL_UPDATE);
  rep(i, n) { cin >> a[i]; }
  rep(i, n) {
    chmax(ans,
          seg.query(max(0ll, a[i] - k), min(300004ll, a[i] + k + 1ll)) + 1);
    seg.change(a[i], max(1ll, seg.query(max(0ll, a[i] - k),
                                        min(300004ll, a[i] + k + 1ll)) +
                                  1));
  }
  cout << ans << endl;
}


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

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];
  vector<int> dp(n, 1);
  for (int i = 1; i < n; i++) {
    for (int j = 0; j < i; j++) {
      if (abs(a[j] - a[i]) <= k && dp[j] + 1 > dp[i])
        dp[i] = 1 + dp[j];
    }
  }
  cout << *max_element(dp.begin(), dp.end()) << endl;
  return 0;
}

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

void build(int node, int start, int end, vector<int> &dp, vector<int> &a) {
  if (start == end) {
    dp[node] = 1;
  } else {
    int mid = start + (end - start) / 2;
    build(2 * node + 1, start, mid, dp, a);
    build(2 * node + 2, mid + 1, end, dp, a);
    if (dp[2 * node + 1] > dp[2 * node + 2])
      dp[node] = dp[2 * node + 1];
    else
      dp[node] = dp[2 * node + 2];
  }
}

void update(int node, int in, int val, int start, int end, vector<int> &dp) {
  if (start == end) {
    dp[node] = val;
    return;
  }

  int l = 2 * node + 1;
  int r = 2 * node + 2;
  int mid = start + (end - start) / 2;
  if (start <= in && in <= mid)
    update(l, in, val, start, mid, dp);
  else
    update(r, in, val, mid + 1, end, dp);
  if (dp[l] > dp[r])
    dp[node] = dp[l];
  else
    dp[node] = dp[r];
}

int query(int node, int start, int end, int l, int r, vector<int> &dp) {
  if (l <= start && end <= r)
    return dp[node];
  if (r < start || l > end)
    return 0;
  int mid = start + (end - start) / 2;
  int left = query(2 * node + 1, start, mid, l, r, dp);
  int right = query(2 * node + 2, mid + 1, end, l, r, dp);
  if (left > right)
    return left;
  else
    return right;
}

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

  // build(0,0,300000,dp,a);

  for (int i = 0; i < n; i++) {
    int curr = query(0, 0, 300000, a[i] - k, a[i] + k, dp);
    update(0, a[i], curr + 1, 0, 300000, dp);
  }
  cout << query(0, 0, 300000, 0, 300000, dp) << endl;
  return 0;
}


/**
 *		author:  zvm
 *		created: 28.09.2020 17:53:16
 **/

#include <bits/stdc++.h>

using namespace std;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);

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

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

  // dp[i] stores max length of flat subseq that ends at pos i
  vector<int> dp(n, 1);

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

  cout << dp.back() << endl;
}

/**
 *		author:  zvm
 *		created: 28.09.2020 17:53:16
 **/

#include <bits/stdc++.h>

using namespace std;

template <typename T> class Segment_tree {
public:
  Segment_tree(int _n) {
    n = _n;
    tree.resize(2 * n, 0);
  }

  T combine(T lchild, T rchild) { return max(lchild, rchild); }

  void update(int idx, T val) {
    for (tree[idx += n] = val, idx /= 2; idx >= 1; idx /= 2) {
      tree[idx] = combine(tree[idx << 1], tree[idx << 1 | 1]);
    }
  }

  T query(int l, int r) {
    T ans = 0;
    for (l += n, r += n; l <= r; l /= 2, r /= 2) {
      if (l & 1) {
        ans = combine(ans, tree[l++]);
      }
      if (!(r & 1)) {
        ans = combine(ans, tree[r--]);
      }
    }
    return ans;
  }

private:
  int n;
  vector<T> tree;
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);

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

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

  int sz = 1 << 19;
  Segment_tree<int> dp(1 << 19);

  // dp[i] stores max length of flat subseq ending with val i
  dp.update(a[0], 1);

  for (int i = 1; i < n; ++i) {
    dp.update(a[i], 1 + dp.query(max(a[i] - k, 0), min(a[i] + k, 300000)));
  }

  cout << dp.query(0, sz - 1) << endl;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
template <typename T, typename E> struct SegmentTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  int n, N;
  F f;
  G g;
  T d1;
  E d0;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(int n_, F f, G g, T d1, vector<T> v = vector<T>())
      : f(f), g(g), d1(d1) {
    N = n_;
    init(n_);
    if (n_ == (int)v.size())
      build(n_, v);
  }
  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.clear();
    dat.resize(2 * n - 1, d1);
  }
  void build(int n_, vector<T> v) {
    for (int i = 0; i < n_; i++)
      dat[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  void update(int k, E a) {
    k += n - 1;
    dat[k] = g(dat[k], a);
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  inline T query(int a, int b) {
    T vl = d1, vr = d1;
    for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = f(vl, dat[(l++) - 1]);
      if (r & 1)
        vr = f(dat[(--r) - 1], vr);
    }
    return f(vl, vr);
  }

  template <bool (*h)(T)> int max_right(int l) {
    return max_right(l, [](T x) { return h(x); });
  }
  template <class H> int max_right(int l, H h) {
    assert(0 <= l && l <= N);
    assert(h(d1));
    if (l == N)
      return N;
    l += n - 1;
    T tm = d1;
    do {
      while (l & 1)
        l = (l - 1) / 2;
      if (!h(f(tm, dat[l]))) {
        while (l < n - 1) {
          l = (2 * l + 1);
          if (h(f(tm, dat[l]))) {
            tm = f(tm, dat[l]);
            l++;
          }
        }
        return l - n + 1;
      }
      tm = f(tm, dat[l]);
      l++;
    } while (((l + 1) & -(l + 1)) != (l + 1));
    return N;
  }

  template <bool (*h)(T)> int min_left(int r) {
    return min_left(r, [](T x) { return h(x); });
  }
  template <class H> int min_left(int r, H h) {
    assert(0 <= r && r <= N);
    assert(h(d1));
    if (r == 0)
      return 0;
    r += n - 1;
    T tm = d1;
    do {
      r--;
      while (r && (r % 2 == 0))
        r = (r - 2) / 2;
      if (!h(f(dat[r], tm))) {
        while (r < n - 1) {
          r = 2 * r + 2;
          if (h(f(dat[r], tm))) {
            tm = f(dat[r], tm);
            r--;
          }
        }
        return r + 1 - n + 1;
      }
      tm = f(dat[r], tm);
    } while (((r + 1) & -(r + 1)) != (r + 1));
    return 0;
  }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n, k;
  cin >> n >> k;
  SegmentTree<int, int> seg(
      n, [](int a, int b) { return max(a, b); },
      [](int a, int b) { return max(a, b); }, 0);
  int a[n];
  rep(i, n) cin >> a[i];
  vector<int> ans(n);
  rep(i, n) {
    int p = seg.query(max(0, a[i] - k - 1), min(n, a[i] + k));
    seg.update(a[i] - 1, p + 1);
  }
  cout << seg.query(0, n) << endl;

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
template <typename T, typename E> struct SegmentTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  int n, N;
  F f;
  G g;
  T d1;
  E d0;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(int n_, F f, G g, T d1, vector<T> v = vector<T>())
      : f(f), g(g), d1(d1) {
    N = n_;
    init(n_);
    if (n_ == (int)v.size())
      build(n_, v);
  }
  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.clear();
    dat.resize(2 * n - 1, d1);
  }
  void build(int n_, vector<T> v) {
    for (int i = 0; i < n_; i++)
      dat[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  void update(int k, E a) {
    k += n - 1;
    dat[k] = g(dat[k], a);
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  inline T query(int a, int b) {
    T vl = d1, vr = d1;
    for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = f(vl, dat[(l++) - 1]);
      if (r & 1)
        vr = f(dat[(--r) - 1], vr);
    }
    return f(vl, vr);
  }

  template <bool (*h)(T)> int max_right(int l) {
    return max_right(l, [](T x) { return h(x); });
  }
  template <class H> int max_right(int l, H h) {
    assert(0 <= l && l <= N);
    assert(h(d1));
    if (l == N)
      return N;
    l += n - 1;
    T tm = d1;
    do {
      while (l & 1)
        l = (l - 1) / 2;
      if (!h(f(tm, dat[l]))) {
        while (l < n - 1) {
          l = (2 * l + 1);
          if (h(f(tm, dat[l]))) {
            tm = f(tm, dat[l]);
            l++;
          }
        }
        return l - n + 1;
      }
      tm = f(tm, dat[l]);
      l++;
    } while (((l + 1) & -(l + 1)) != (l + 1));
    return N;
  }

  template <bool (*h)(T)> int min_left(int r) {
    return min_left(r, [](T x) { return h(x); });
  }
  template <class H> int min_left(int r, H h) {
    assert(0 <= r && r <= N);
    assert(h(d1));
    if (r == 0)
      return 0;
    r += n - 1;
    T tm = d1;
    do {
      r--;
      while (r && (r % 2 == 0))
        r = (r - 2) / 2;
      if (!h(f(dat[r], tm))) {
        while (r < n - 1) {
          r = 2 * r + 2;
          if (h(f(dat[r], tm))) {
            tm = f(dat[r], tm);
            r--;
          }
        }
        return r + 1 - n + 1;
      }
      tm = f(dat[r], tm);
    } while (((r + 1) & -(r + 1)) != (r + 1));
    return 0;
  }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n, k;
  cin >> n >> k;
  int N = 300001;
  SegmentTree<int, int> seg(
      N, [](int a, int b) { return max(a, b); },
      [](int a, int b) { return max(a, b); }, 0);
  int a[n];
  rep(i, n) cin >> a[i];
  vector<int> ans(n);
  rep(i, n) {
    int p = seg.query(max(0, a[i] - k), min(N, a[i] + k + 1));
    seg.update(a[i], p + 1);
  }
  cout << seg.query(0, N) << endl;

  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <vector>

using namespace std;

vector<int> T[20];

int query(int h, int k, int i, int j) {
  int m = (k << h) + (1 << h - 1);
  if (i == (k << h) && j == (k + 1 << h) - 1)
    return T[h][k];
  if (j < m)
    return query(h - 1, k << 1, i, j);
  if (i >= m)
    return query(h - 1, k << 1 | 1, i, j);
  return max(query(h - 1, k << 1, i, m - 1), query(h - 1, k << 1 | 1, m, j));
}

int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  int d = ceil(log2(n + 5));
  for (int i = 0; i <= d; i++) {
    T[i].clear();
    T[i].resize(1 << (d - i), 0);
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int a;
    scanf("%d", &a);
    int q = query(d, 0, max(a - k, 0), min(a + k, 300000));
    ans = max(ans, q + 1);

    int p = a;
    T[0][p] = max(T[0][p], q + 1);
    p >>= 1;
    for (int j = 1; j <= d; j++) {
      T[j][p] = max(T[j - 1][p << 1], T[j - 1][p << 1 | 1]);
      p >>= 1;
    }
  }
  printf("%d\\n", ans);
  return 0;
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <vector>

using namespace std;

vector<int> T[20];

int query(int h, int k, int i, int j) {
  int m = (k << h) + (1 << h - 1);
  if (i == (k << h) && j == (k + 1 << h) - 1)
    return T[h][k];
  if (j < m)
    return query(h - 1, k << 1, i, j);
  if (i >= m)
    return query(h - 1, k << 1 | 1, i, j);
  return max(query(h - 1, k << 1, i, m - 1), query(h - 1, k << 1 | 1, m, j));
}

int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  int d = 19;
  for (int i = 0; i <= d; i++) {
    T[i].clear();
    T[i].resize(1 << (d - i), 0);
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int a;
    scanf("%d", &a);
    int q = query(d, 0, max(a - k, 0), min(a + k, 300000));
    ans = max(ans, q + 1);

    int p = a;
    T[0][p] = max(T[0][p], q + 1);
    p >>= 1;
    for (int j = 1; j <= d; j++) {
      T[j][p] = max(T[j - 1][p << 1], T[j - 1][p << 1 | 1]);
      p >>= 1;
    }
  }
  printf("%d\\n", ans);
  return 0;
}


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

#define rep(i, n) for (int i = 0; i < n; i++)
#define repd(i, n) for (int i = n - 1; i >= 0; i--)
#define fo(i, a, b) for (int i = a; i < b; i++)
#define fod(i, a, b) for (int i = a; i >= b; i--)
#define umap unordered_map
#define mii map<int, int>
#define pii pair<int, int>
#define vc vector
#define vi vc<int>
#define vvi vc<vi>
#define pqmin priority_queue<int, vector<int>, greater<int>>
#define pqmax priority_queue<int>
#define all(v) v.begin(), v.end()
#define gcd(a, b) __gcd((a), (b))
#define lcm(a, b) ((a) * (b)) / gcd((a), (b))
#define remax(a, b) a = max(a, b)
#define remin(a, b) a = min(a, b)
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define w(t)                                                                   \\
  int t;                                                                       \\
  cin >> t;                                                                    \\
  while (t--)
#define ps(x, y) fixed << setprecision(y) << x
#define out(x) cout << x << endl;
#define print(a, n)                                                            \\
  rep(i, n) cout << a[i] << " ";                                               \\
  cout << endl;
#define clr(a, x) memset(a, x, sizeof a)

const int mod = 1e9 + 7;
const int mod2 = 998244353;
const int N = 3e5;
const int inf = 1e18;

//=====================================================

template <typename... T> void read(T &...args) { ((cin >> args), ...); }
template <typename... T> void write(T &&...args) {
  ((cout << args << " "), ...);
}
template <typename... T> void writeline(T &&...args) {
  ((cout << args << " "), ...);
  cout << endl;
}

int add(int a, int b) {
  int res = (a + b) % mod;
  return (res < 0) ? res + mod : res;
}
int mul(int a, int b) {
  int res = (a * 1LL * b) % mod;
  return (res < 0) ? res + mod : res;
}
string binary(int x) {
  string res = "";
  rep(i, 32) res += (1 << i & x) ? '1' : '0';
  return res;
}
int in(int x, int y, int z) {
  if (y > z)
    swap(y, z);
  return (x >= y && x <= z);
}
struct customCompare {
  bool operator()(pii x, pii y) { return x.first > y.second; }
};

//=====================================================

int tree[N + 5];
int a[10 * N + 5];

// update value of element at index i
void pointUpdate(int i, int j, int k, int l, int val) {
  if (i > l || j < l)
    return;
  if (i == j) {
    tree[k] = a[l] = val;
    return;
  }
  if (i >= l && l <= j) {
    tree[k] = max(tree[k], val);
  }

  int mid = (i + j) / 2;
  pointUpdate(i, mid, 2 * k, l, val);
  pointUpdate(mid + 1, j, 2 * k + 1, l, val);
  tree[k] = max(tree[2 * k], tree[2 * k + 1]);
}

int query(int i, int j, int l, int r, int k) {
  if (i > r || j < l)
    return 0;
  if (i >= l && j <= r)
    return tree[k];
  int mid = (i + j) / 2;
  return max(query(i, mid, l, r, 2 * k), query(mid + 1, j, l, r, 2 * k + 1));
}

void solve() {
  int n, k;
  cin >> n >> k;
  int b[n];
  rep(i, n) cin >> b[i];

  int mx = *max_element(b, b + n);
  int ans = 0;

  // int si = 1;
  // while (si < mx) si *= 2;
  // tree.resize(si, 0);

  rep(i, n) {
    int l = max(1LL, b[i] - k);
    int r = min(mx, b[i] + k);

    int q = query(1, mx, l, r, 1);
    pointUpdate(1, mx, 1, b[i], q + 1);

    remax(ans, a[b[i]]);
  }

  cout << ans;
}

int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  solve();

  return 0;
}

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

#define rep(i, n) for (int i = 0; i < n; i++)
#define repd(i, n) for (int i = n - 1; i >= 0; i--)
#define fo(i, a, b) for (int i = a; i < b; i++)
#define fod(i, a, b) for (int i = a; i >= b; i--)
#define umap unordered_map
#define mii map<int, int>
#define pii pair<int, int>
#define vc vector
#define vi vc<int>
#define vvi vc<vi>
#define pqmin priority_queue<int, vector<int>, greater<int>>
#define pqmax priority_queue<int>
#define all(v) v.begin(), v.end()
#define gcd(a, b) __gcd((a), (b))
#define lcm(a, b) ((a) * (b)) / gcd((a), (b))
#define remax(a, b) a = max(a, b)
#define remin(a, b) a = min(a, b)
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define w(t)                                                                   \\
  int t;                                                                       \\
  cin >> t;                                                                    \\
  while (t--)
#define ps(x, y) fixed << setprecision(y) << x
#define out(x) cout << x << endl;
#define print(a, n)                                                            \\
  rep(i, n) cout << a[i] << " ";                                               \\
  cout << endl;
#define clr(a, x) memset(a, x, sizeof a)

const int mod = 1e9 + 7;
const int mod2 = 998244353;
const int N = 3e5;
const int inf = 1e18;

//=====================================================

template <typename... T> void read(T &...args) { ((cin >> args), ...); }
template <typename... T> void write(T &&...args) {
  ((cout << args << " "), ...);
}
template <typename... T> void writeline(T &&...args) {
  ((cout << args << " "), ...);
  cout << endl;
}

int add(int a, int b) {
  int res = (a + b) % mod;
  return (res < 0) ? res + mod : res;
}
int mul(int a, int b) {
  int res = (a * 1LL * b) % mod;
  return (res < 0) ? res + mod : res;
}
string binary(int x) {
  string res = "";
  rep(i, 32) res += (1 << i & x) ? '1' : '0';
  return res;
}
int in(int x, int y, int z) {
  if (y > z)
    swap(y, z);
  return (x >= y && x <= z);
}
struct customCompare {
  bool operator()(pii x, pii y) { return x.first > y.second; }
};

//=====================================================

int tree[10000000];
int a[300005];

void pointUpdate(int i, int j, int k, int l, int val) {
  if (i > l || j < l)
    return;
  if (i == j) {
    tree[k] = a[l] = val;
    return;
  }

  int mid = (i + j) / 2;
  pointUpdate(i, mid, 2 * k, l, val);
  pointUpdate(mid + 1, j, 2 * k + 1, l, val);
  tree[k] = max(tree[2 * k], tree[2 * k + 1]);
}

int query(int i, int j, int l, int r, int k) {
  if (i > r || j < l)
    return 0;
  if (i >= l && j <= r)
    return tree[k];
  int mid = (i + j) / 2;
  return max(query(i, mid, l, r, 2 * k), query(mid + 1, j, l, r, 2 * k + 1));
}

void solve() {
  int n, k;
  cin >> n >> k;
  int b[n];
  rep(i, n) cin >> b[i];
  int mx = *max_element(b, b + n);

  rep(i, n) {
    int l = max(0LL, b[i] - k);
    int r = min(mx, b[i] + k);

    int q = query(0, mx, l, r, 1);
    pointUpdate(0, mx, 1, b[i], q + 1);
  }

  cout << query(0, mx, 1, mx, 1);
}

int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  solve();

  return 0;
}


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

vector<int> sgt;
int sz{1};

void g() {
  while (sz < 3e4)
    sz *= 2;
  sgt.resize(2 * sz);
}

int f(int l, int r) {
  int ans{};
  l += sz, r += sz;
  while (l <= r) {
    if (l & 1)
      ans = max(ans, sgt[l++]);
    if (!(r & 1))
      ans = max(ans, sgt[r--]);
    l /= 2, r /= 2;
  }
  return ans;
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);

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

  for (int i = 0; i < n; i++) {
    int z = f(max(0, a[i] - k), min(300000, a[i] + k));
    //	cout << z << endl;
    a[i] += sz;
    sgt[a[i]] = z + 1;
    a[i] /= 2;
    while (a[i]) {
      sgt[a[i]] = max(sgt[2 * a[i]], sgt[2 * a[i] + 1]);
      a[i] /= 2;
    }
  }
  cout << sgt[1];
}

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

vector<int> sgt;
int sz{1};

void g() {
  while (sz < 3e5)
    sz *= 2;
  sgt.resize(2 * sz);
}

int f(int l, int r) {
  int ans{};
  l += sz, r += sz;
  while (l <= r) {
    if (l & 1)
      ans = max(ans, sgt[l++]);
    if (!(r & 1))
      ans = max(ans, sgt[r--]);
    l /= 2, r /= 2;
  }
  return ans;
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);

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

  for (int i = 0; i < n; i++) {
    int z = f(max(0, a[i] - k), min(300000, a[i] + k));
    //	cout << z << endl;
    a[i] += sz;
    sgt[a[i]] = z + 1;
    a[i] /= 2;
    while (a[i]) {
      sgt[a[i]] = max(sgt[2 * a[i]], sgt[2 * a[i] + 1]);
      a[i] /= 2;
    }
  }
  cout << sgt[1];
}


// Problem : D - Flat Subsequence
// Contest : AtCoder - ACL Beginner Contest
// URL : https://atcoder.jp/contests/abl/tasks/abl_d
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

// $%U%$
// Mere bas ka nahi hai
// still i'm trying
// apna time aayega
//
//        .--------------.
//        | Try First One|
//        '--------------'
//                |     .--------------.
//                |     |              |
//                V     V              |
//              .--------------.       |
//              |      AC.     |<---.  |
//              '--------------'    |  |
//              (True)|  |(False)   |  |
//           .--------'  |          |  |
//           |           V          |  |
//           |  .--------------.    |  |
//           |  |   Try Again  |----'  |
//           |  '--------------'       |
//           |                         |
//           |  .--------------.       |
//           '->| Try Next One |-------'
//              '--------------'
//
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll power(ll x, ll y, ll m) {
  if (y == 0)
    return 1;
  ll p = power(x, y / 2, m) % m;
  p = (p * p) % m;
  return (y % 2 == 0) ? p : (x * p) % m;
}
ll nCr(ll n, ll r, ll m) {
  if (r > n)
    return 0;
  ll a = 1, b = 1, i;
  for (i = 0; i < r; i++) {
    a = (a * n) % m;
    --n;
  }
  while (r) {
    b = (b * r) % m;
    --r;
  }
  return (a * power(b, m - 2, m)) % m;
}
#define Test                                                                   \\
  int t;                                                                       \\
  cin >> t;                                                                    \\
  while (t--)
#define endl '\\n'
vector<int> tree, v, t;
void update(int l, int r, int index, int cindex) {
  if (l == r) {
    tree[index] = t[l];
    return;
  }
  int mid = (l + r) / 2;
  if (cindex <= mid)
    update(l, mid, 2 * index + 1, cindex);
  else
    update(mid + 1, r, 2 * index + 2, cindex);
  tree[index] = max(tree[index * 2 + 1], tree[index * 2 + 2]);
}

int find(int l, int r, int tl, int tr, int index) {
  if (tl > tr) {
    return 0;
  }
  if (tl == l && tr == r) {
    return tree[index];
  }
  int mid = (l + r) / 2;
  int t1 = find(l, mid, tl, min(tr, mid), 2 * index + 1);
  int t2 = find(mid + 1, r, max(tl, mid + 1), tr, 2 * index + 2);
  return max(t1, t2);
}

void solve() {
  int n, k;
  cin >> n >> k;
  v = t = vector<int>(n);
  tree = vector<int>(4 * (300001));
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
    int temp = find(0, 300000, max(v[i] - k, 0), min(v[i] + k, 300000), 0);
    // cout << temp << endl;
    t[v[i]] = temp + 1;
    update(0, 300000, 0, v[i]);
  }
  cout << tree[0] << endl;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  // Test
  solve();
  return 0;
}

// Problem : D - Flat Subsequence
// Contest : AtCoder - ACL Beginner Contest
// URL : https://atcoder.jp/contests/abl/tasks/abl_d
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

// $%U%$
// Mere bas ka nahi hai
// still i'm trying
// apna time aayega
//
//        .--------------.
//        | Try First One|
//        '--------------'
//                |     .--------------.
//                |     |              |
//                V     V              |
//              .--------------.       |
//              |      AC.     |<---.  |
//              '--------------'    |  |
//              (True)|  |(False)   |  |
//           .--------'  |          |  |
//           |           V          |  |
//           |  .--------------.    |  |
//           |  |   Try Again  |----'  |
//           |  '--------------'       |
//           |                         |
//           |  .--------------.       |
//           '->| Try Next One |-------'
//              '--------------'
//
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll power(ll x, ll y, ll m) {
  if (y == 0)
    return 1;
  ll p = power(x, y / 2, m) % m;
  p = (p * p) % m;
  return (y % 2 == 0) ? p : (x * p) % m;
}
ll nCr(ll n, ll r, ll m) {
  if (r > n)
    return 0;
  ll a = 1, b = 1, i;
  for (i = 0; i < r; i++) {
    a = (a * n) % m;
    --n;
  }
  while (r) {
    b = (b * r) % m;
    --r;
  }
  return (a * power(b, m - 2, m)) % m;
}
#define Test                                                                   \\
  int t;                                                                       \\
  cin >> t;                                                                    \\
  while (t--)
#define endl '\\n'
vector<int> tree, v, t;
void update(int l, int r, int index, int cindex) {
  if (l == r) {
    tree[index] = t[l];
    return;
  }
  int mid = (l + r) / 2;
  if (cindex <= mid)
    update(l, mid, 2 * index + 1, cindex);
  else
    update(mid + 1, r, 2 * index + 2, cindex);
  tree[index] = max(tree[index * 2 + 1], tree[index * 2 + 2]);
}

int find(int l, int r, int tl, int tr, int index) {
  if (tl > tr) {
    return 0;
  }
  if (tl == l && tr == r) {
    return tree[index];
  }
  int mid = (l + r) / 2;
  int t1 = find(l, mid, tl, min(tr, mid), 2 * index + 1);
  int t2 = find(mid + 1, r, max(tl, mid + 1), tr, 2 * index + 2);
  return max(t1, t2);
}

void solve() {
  int n, k;
  cin >> n >> k;
  v = vector<int>(n);
  t = vector<int>(300001);
  tree = vector<int>(4 * (300001));
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
    int temp = find(0, 300000, max(v[i] - k, 0), min(v[i] + k, 300000), 0);
    // cout << temp << endl;
    t[v[i]] = temp + 1;
    update(0, 300000, 0, v[i]);
  }
  cout << tree[0] << endl;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  // Test
  solve();
  return 0;
}


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

template <typename T> constexpr int intof(const T x) {
  return static_cast<int>(x);
}

int solve(const vector<int> &xs, const int k) {
  const int n = xs.size();
  vector<multiset<int>> trees(n);
  trees[0].insert(xs[0]);

  for (int i = 1; i < n; ++i) {
    trees[i] = trees[i - 1];
    trees[i].insert(xs[i]);
  }

  int ans = 1;

  for (int i = 1; i < n; ++i) {
    const auto tree = trees[i - 1];
    const auto lo = tree.lower_bound(max(0, xs[i] - k));
    const auto hi = tree.upper_bound(xs[i] + k);
    ans = max(ans, intof(distance(lo, hi)));
  }

  return ans;
}

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

  int N, K;
  cin >> N >> K;

  vector<int> xs(N, 0);
  for (auto &x : xs)
    cin >> x;

  cout << solve(xs, K) << '\\n';

  return 0;
}

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

template <typename T> constexpr int intof(const T x) {
  return static_cast<int>(x);
}

constexpr int mmax(const int x, const int y) { return max(x, y); }
constexpr int e() { return 0; }

int solve(const vector<int> &xs, const int k) {
  const int hi = *max_element(cbegin(xs), cend(xs));
  atcoder::segtree<int, mmax, e> max_lengths_by_val(hi + 1);

  for (const int x : xs) {
    const int h =
        max_lengths_by_val.prod(max(0, x - k), min(hi + 1, x + k + 1));
    max_lengths_by_val.set(x, h + 1);
  }

  return max_lengths_by_val.all_prod();
}

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

  int N, K;
  cin >> N >> K;

  vector<int> xs(N, 0);
  for (auto &x : xs)
    cin >> x;

  cout << solve(xs, K) << '\\n';

  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define vb vector<bool>
#define vl vector<long>
#define vi vector<int>
#define fastio                                                                 \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
char dir[] = {'R', 'L', 'D', 'U'};
const int MOD = 1e9 + 7;

void solve() {
  int n, k;
  cin >> n >> k;
  vi a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];

  int dp[n];
  for (int i = 0; i < n; i++)
    dp[i] = 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);
    }
  }

  int result = 1;
  for (int i = 0; i < n; i++)
    if (result < dp[i])
      result = dp[i];
  cout << result << endl;
}

int main() {
  fastio

      // ifstream fin(".in");
      // ofstream fout(".out");

      int t = 1;
  // cin >> t;

  while (t-- > 0)
    solve();
}

#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define vb vector<bool>
#define vl vector<long>
#define vi vector<int>
#define fastio                                                                 \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define f first
#define s second

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
char dir[] = {'R', 'L', 'D', 'U'};
const int MOD = 1e9 + 7;

void solve() {
  int n, k;
  cin >> n >> k;
  vi a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];

  vector<int> dp(n);

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

int main() {
  fastio

      // ifstream fin(".in");
      // ofstream fout(".out");

      int t = 1;
  // cin >> t;

  while (t-- > 0)
    solve();
}


#include "bits/stdc++.h"
#define ll int
#define MX 300000
using namespace std;
ll tr[4 * MX + 2], a[MX + 2];
void update(ll pos, ll st, ll ed, ll x, ll val) {
  if (st == ed && st == x) {
    tr[pos] = max(tr[pos], val);
    return;
  }
  ll mid = st + ((ed - st) >> 1);
  if (x <= mid)
    update(2 * pos, st, mid, x, val);
  else
    update(2 * pos + 1, mid + 1, ed, x, val);
  tr[pos] = max(tr[2 * pos], tr[2 * pos + 1]);
}
ll query(ll pos, ll st, ll ed, ll l, ll r) {
  if (st > r || ed < l)
    return 0;
  if (st >= l && ed <= r) {
    return tr[pos];
  }
  ll mid = st + ((ed - st) >> 1);
  return max(query(2 * pos, st, mid, l, r),
             query(2 * pos + 1, mid + 1, ed, l, r));
}
int main() {
  ll n, k;
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= n; i++) {
    ll l = max(0, a[i] - k);
    ll r = min(300000, a[i] + k);
    ll p = query(1, 1, 300000, l, r);
    update(1, 1, 300000, a[i], p + 1);
  }
  cout << query(1, 1, 300000, 1, 300000) << "\\n";
  return 0;
}

#include "bits/stdc++.h"
#define ll int
#define MX 300000
using namespace std;
ll tr[4 * MX + 5], a[MX + 5];
void update(ll pos, ll st, ll ed, ll x, ll val) {
  if (st == ed && st == x) {
    tr[pos] = max(tr[pos], val);
    return;
  }
  ll mid = st + ((ed - st) >> 1);
  if (x <= mid)
    update(2 * pos, st, mid, x, val);
  else
    update(2 * pos + 1, mid + 1, ed, x, val);
  tr[pos] = max(tr[2 * pos], tr[2 * pos + 1]);
}
ll query(ll pos, ll st, ll ed, ll l, ll r) {
  if (st > r || ed < l)
    return 0;
  if (st >= l && ed <= r) {
    return tr[pos];
  }
  ll mid = st + ((ed - st) >> 1);
  return max(query(2 * pos, st, mid, l, r),
             query(2 * pos + 1, mid + 1, ed, l, r));
}
int main() {
  ll n, k;
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    a[i]++;
  }
  for (int i = 1; i <= n; i++) {
    ll l = max(1, a[i] - k);
    ll r = min(300001, a[i] + k);
    ll p = query(1, 1, 300001, l, r);
    update(1, 1, 300001, a[i], p + 1);
  }
  cout << query(1, 1, 300001, 1, 300001) << "\\n";
  return 0;
}


#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
using namespace std;
typedef long long ll;
const int INF = 1e9;
const ll MOD = 1e9 + 7;
const ll LINF = 1e18;
template <class T> void get_unique(vector<T> &x) {
  x.erase(unique(x.begin(), x.end()), x.end());
}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> vector<T> make_vec(size_t a) { return vector<T>(a); }
template <class T, class... Ts> auto make_vec(size_t a, Ts... ts) {
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
template <typename T> ostream &operator<<(ostream &os, vector<T> v) {
  for (int i = 0; i < sz(v); i++) {
    os << v[i];
    if (i < sz(v) - 1)
      os << " ";
  }
  return os;
}
template <class S, S (*op)(S, S), S (*e)()> struct SegmentTree {
public:
  SegmentTree() : SegmentTree(0) {}
  SegmentTree(int n) : SegmentTree(std::vector<S>(n, e())) {}
  SegmentTree(const std::vector<S> &v) : _n(int(v.size())) {
    log = ceil_pow2(_n);
    size = 1 << log;
    d = std::vector<S>(2 * size, e());
    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;
    d[p] = x;
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  S get(int p) {
    assert(0 <= p && p < _n);
    return d[p + size];
  }

  S prod(int l, int r) {
    assert(0 <= l && l <= r && r <= _n);
    S sml = e(), smr = e();
    l += size;
    r += size;

    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]; }

  template <bool (*f)(S)> int max_right(int l) {
    return max_right(l, [](S x) { return f(x); });
  }
  template <class F> int max_right(int l, F f) {
    assert(0 <= l && l <= _n);
    assert(f(e()));
    if (l == _n)
      return _n;
    l += size;
    S sm = e();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!f(op(sm, d[l]))) {
        while (l < size) {
          l = (2 * l);
          if (f(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 (*f)(S)> int min_left(int r) {
    return min_left(r, [](S x) { return f(x); });
  }
  template <class F> int min_left(int r, F f) {
    assert(0 <= r && r <= _n);
    assert(f(e()));
    if (r == 0)
      return 0;
    r += size;
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!f(op(d[r], sm))) {
        while (r < size) {
          r = (2 * r + 1);
          if (f(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;
  int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n))
      x++;
    return x;
  }
  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
using S = int;
S op(S a, S b) { return max(a, b); }
S e() { return 0; }
int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  rep(i, n) cin >> a[i];
  SegmentTree<S, op, e> segt(300300);
  rep(i, n) {
    int MAX = segt.prod(max(0, a[i] - k), min(n - 1, a[i] + k) + 1);
    segt.set(a[i], max(segt.get(a[i]), MAX + 1));
  }
  // rep(i, 10) cout << i << ':' << segt.prod(i, i + 1) << '\\n';
  cout << segt.all_prod() << '\\n';
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
using namespace std;
typedef long long ll;
const int INF = 1e9;
const ll MOD = 1e9 + 7;
const ll LINF = 1e18;
template <class T> void get_unique(vector<T> &x) {
  x.erase(unique(x.begin(), x.end()), x.end());
}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> vector<T> make_vec(size_t a) { return vector<T>(a); }
template <class T, class... Ts> auto make_vec(size_t a, Ts... ts) {
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
template <typename T> ostream &operator<<(ostream &os, vector<T> v) {
  for (int i = 0; i < sz(v); i++) {
    os << v[i];
    if (i < sz(v) - 1)
      os << " ";
  }
  return os;
}
template <class S, S (*op)(S, S), S (*e)()> struct SegmentTree {
public:
  SegmentTree() : SegmentTree(0) {}
  SegmentTree(int n) : SegmentTree(std::vector<S>(n, e())) {}
  SegmentTree(const std::vector<S> &v) : _n(int(v.size())) {
    log = ceil_pow2(_n);
    size = 1 << log;
    d = std::vector<S>(2 * size, e());
    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;
    d[p] = x;
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  S get(int p) {
    assert(0 <= p && p < _n);
    return d[p + size];
  }

  S prod(int l, int r) {
    assert(0 <= l && l <= r && r <= _n);
    S sml = e(), smr = e();
    l += size;
    r += size;

    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]; }

  template <bool (*f)(S)> int max_right(int l) {
    return max_right(l, [](S x) { return f(x); });
  }
  template <class F> int max_right(int l, F f) {
    assert(0 <= l && l <= _n);
    assert(f(e()));
    if (l == _n)
      return _n;
    l += size;
    S sm = e();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!f(op(sm, d[l]))) {
        while (l < size) {
          l = (2 * l);
          if (f(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 (*f)(S)> int min_left(int r) {
    return min_left(r, [](S x) { return f(x); });
  }
  template <class F> int min_left(int r, F f) {
    assert(0 <= r && r <= _n);
    assert(f(e()));
    if (r == 0)
      return 0;
    r += size;
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!f(op(d[r], sm))) {
        while (r < size) {
          r = (2 * r + 1);
          if (f(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;
  int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n))
      x++;
    return x;
  }
  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
using S = int;
S op(S a, S b) { return max(a, b); }
S e() { return 0; }
int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  rep(i, n) cin >> a[i];
  SegmentTree<S, op, e> segt(300300);
  rep(i, n) {
    int MAX = segt.prod(max(0, a[i] - k), min(300300, a[i] + k + 1));
    segt.set(a[i], max(segt.get(a[i]), MAX + 1));
  }
  // rep(i, 10) cout << i << ':' << segt.prod(i, i + 1) << '\\n';
  cout << segt.all_prod() << '\\n';
}


#include <algorithm>
#include <cmath>
#include <fstream>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>

using namespace std;

#define I_MAX 2147483647
#define LL_MAX 9223372036854775807
#define ll long long
#define ld long double

struct XX {
  int x;
  int y;
  int i;
  int ans;
};

class xxGreater {
public:
  bool operator()(const XX &riLeft, const XX &riRight) const {
    // 第2条件
    if ((riLeft.x) == (riRight.x)) {
      return riLeft.y <
             riRight.y; //<:昇順(小さいものから順番)、>:降順(大きいものから順番)
      // プライオリティキューの場合は > で、top()すると値の小さいものがとれる
    }
    // 第1条件
    return (riLeft.x) < (riRight.x);
  }
};

// map<long long,long long> prime_f(long long n){
//     map<long long,long long>res;
//     for(int i=2;i*i<=n;i++){
//         while(n%i==0){
//             ++res[i];
//             n/=i;
//         }
//     }
//     if(n!=1)res[n]=1;
//     return res;
// }

// int n;
////int dat[2*10000000];
////int dat2[2*10000000];
// int dat[10];
// int dat2[10];
//
// void init(int n_){
//     n=1;
//     while(n<n_)n*=2;
//     for(int i=0;i<2*n-1;i++){
//         dat[i]=0;
//         dat2[i]=0;
//     }
// }
//
// void initset(int k,int a){
//     k+=n-1;
//     dat[k]=a;
//     while(k>0){
//         k=(k-1)/2;
//         dat[k]=dat[k*2+1]+dat[k*2+2];
//     }
// }
//
////[a,b)の間を[l,r]区間で比較しアップデート
////引数のindexに注意
////nは固定。initで計算すみ
////update2(L[i],R[i]+1,0,0,n,D[i]);
// void update2(int a,int b,int k,int l,int r,int v){//v更新値、区間は0-index
//     if(r<=a || b<=l)return;
//     if(a<=l && r<=b){
//         dat[k]+=dat2[k];
//         if(r-l>1){
//             dat2[k*2+1]+=dat2[k]/2;
//             dat2[k*2+1]+=dat2[k]/2;
//         }
//         dat2[k]=v*(r-l);
//         return;
//     }else{
//         update2(a,b,k*2+1,l,(l+r)/2,v);
//         update2(a,b,k*2+2,(l+r)/2,r,v);
//         return;
//     }
// }
//
// int query(int a,int b,int k,int l,int r){
//     if(r<=a || b<=l)return 0;
//     if(a<=l && r<=b){
//         dat[k]+=dat2[k];
//         if(r-l>1){
//             dat2[k*2+1]+=dat2[k]/2;
//             dat2[k*2+1]+=dat2[k]/2;
//         }
//         dat2[k]=0;
//         return dat[k];
//     }
//     else{
//         int vl=query(a,b,k*2+1,l,(l+r)/2);
//         int vr=query(a,b,k*2+2,(l+r)/2,r);
//         return vl+vr;
//     }
// }

// void printb(unsigned int v) {
//     unsigned int mask = (int)1 << (sizeof(v) * CHAR_BIT - 1);
//     do putchar(mask & v ? '1' : '0');
//     while (mask >>= 1);
// }

#ifdef DEBUG
int treesize, dat[200];
#else
const int MAX_N = 300001;
int treesize, dat[3 * MAX_N]; // 頂点数の2倍の配列
#endif

void init(int n_) {
  treesize = 1;
  while (treesize < n_)
    treesize *= 2;
  for (int i = 0; i < 2 * treesize - 1; i++)
    dat[i] = 0;
}

void update(int k, int a) {
  k += treesize - 1;
  dat[k] = a;
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = max(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
}

int query(int a, int b, int k, int l, int r) {
  if (r <= a || b <= l)
    return 0;
  if (a <= l && r <= b)
    return dat[k];
  else {
    int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
}

int main(int argc, const char *argv[]) {
  // scanf("%s",S);
  // scanf("%d",&N);
  // scanf("%lld %lld",&target1,&target2);
  // sscanf(tmp.c_str(),"%dd%d%d",&time[i], &dice[i], &z[i]);
  // getline(cin, target);
  // ifstream ifs("01");//テスト用
  // ifs >> a;
  // ここから

  // 入力高速化
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n, k;
  cin >> n >> k;
  int a[300000];
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  init(n);
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int tmp =
        query(max(0, a[i] - k), min(a[i] + k + 1, 300001), 0, 0, treesize);
    update(a[i], tmp + 1);
    ans = max(ans, tmp + 1);
  }

  cout << ans << endl;

  // ここまで
  // cout << "ans" << endl;
  // cout << " " << "ans" << endl;
  // printf("%.0f\\n",ans);//小数点以下表示なし
  // printf("%.7f\\n",p);

  return 0;
}

#include <algorithm>
#include <cmath>
#include <fstream>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>

using namespace std;

#define I_MAX 2147483647
#define LL_MAX 9223372036854775807
#define ll long long
#define ld long double

struct XX {
  int x;
  int y;
  int i;
  int ans;
};

class xxGreater {
public:
  bool operator()(const XX &riLeft, const XX &riRight) const {
    // 第2条件
    if ((riLeft.x) == (riRight.x)) {
      return riLeft.y <
             riRight.y; //<:昇順(小さいものから順番)、>:降順(大きいものから順番)
      // プライオリティキューの場合は > で、top()すると値の小さいものがとれる
    }
    // 第1条件
    return (riLeft.x) < (riRight.x);
  }
};

// map<long long,long long> prime_f(long long n){
//     map<long long,long long>res;
//     for(int i=2;i*i<=n;i++){
//         while(n%i==0){
//             ++res[i];
//             n/=i;
//         }
//     }
//     if(n!=1)res[n]=1;
//     return res;
// }

// int n;
////int dat[2*10000000];
////int dat2[2*10000000];
// int dat[10];
// int dat2[10];
//
// void init(int n_){
//     n=1;
//     while(n<n_)n*=2;
//     for(int i=0;i<2*n-1;i++){
//         dat[i]=0;
//         dat2[i]=0;
//     }
// }
//
// void initset(int k,int a){
//     k+=n-1;
//     dat[k]=a;
//     while(k>0){
//         k=(k-1)/2;
//         dat[k]=dat[k*2+1]+dat[k*2+2];
//     }
// }
//
////[a,b)の間を[l,r]区間で比較しアップデート
////引数のindexに注意
////nは固定。initで計算すみ
////update2(L[i],R[i]+1,0,0,n,D[i]);
// void update2(int a,int b,int k,int l,int r,int v){//v更新値、区間は0-index
//     if(r<=a || b<=l)return;
//     if(a<=l && r<=b){
//         dat[k]+=dat2[k];
//         if(r-l>1){
//             dat2[k*2+1]+=dat2[k]/2;
//             dat2[k*2+1]+=dat2[k]/2;
//         }
//         dat2[k]=v*(r-l);
//         return;
//     }else{
//         update2(a,b,k*2+1,l,(l+r)/2,v);
//         update2(a,b,k*2+2,(l+r)/2,r,v);
//         return;
//     }
// }
//
// int query(int a,int b,int k,int l,int r){
//     if(r<=a || b<=l)return 0;
//     if(a<=l && r<=b){
//         dat[k]+=dat2[k];
//         if(r-l>1){
//             dat2[k*2+1]+=dat2[k]/2;
//             dat2[k*2+1]+=dat2[k]/2;
//         }
//         dat2[k]=0;
//         return dat[k];
//     }
//     else{
//         int vl=query(a,b,k*2+1,l,(l+r)/2);
//         int vr=query(a,b,k*2+2,(l+r)/2,r);
//         return vl+vr;
//     }
// }

// void printb(unsigned int v) {
//     unsigned int mask = (int)1 << (sizeof(v) * CHAR_BIT - 1);
//     do putchar(mask & v ? '1' : '0');
//     while (mask >>= 1);
// }

#ifdef DEBUG
int treesize, dat[200];
#else
const int MAX_N = 300001;
int treesize, dat[4 * MAX_N]; // 頂点数の2倍の配列
#endif

void init(int n_) {
  treesize = 1;
  while (treesize < n_)
    treesize *= 2;
  for (int i = 0; i < 2 * treesize - 1; i++)
    dat[i] = 0;
}

void update(int k, int a) {
  k += treesize - 1;
  dat[k] = a;
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = max(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
}

int query(int a, int b, int k, int l, int r) {
  if (r <= a || b <= l)
    return 0;
  if (a <= l && r <= b)
    return dat[k];
  else {
    int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
}

int main(int argc, const char *argv[]) {
  // scanf("%s",S);
  // scanf("%d",&N);
  // scanf("%lld %lld",&target1,&target2);
  // sscanf(tmp.c_str(),"%dd%d%d",&time[i], &dice[i], &z[i]);
  // getline(cin, target);
  // ifstream ifs("01");//テスト用
  // ifs >> a;
  // ここから

  // 入力高速化
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n, k;
  cin >> n >> k;
  int a[300000];
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  init(300001);
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int tmp =
        query(max(0, a[i] - k), min(a[i] + k + 1, 300001), 0, 0, treesize);
    update(a[i], tmp + 1);
  }
  ans = query(0, 300001, 0, 0, treesize);
  cout << ans << endl;

  // ここまで
  // cout << "ans" << endl;
  // cout << " " << "ans" << endl;
  // printf("%.0f\\n",ans);//小数点以下表示なし
  // printf("%.7f\\n",p);

  return 0;
}


#include <bits/stdc++.h>

using namespace std;

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
//
// using namespace __gnu_pbds;
// template<typename T> using ordered_set = tree<T, null_type, less<T>,
// rb_tree_tag, tree_order_statistics_node_update>;

// class Timer {
//     clock_t start;
//     string name;
// public:
//     Timer() {name = "";start = clock();}
//     Timer(string s){name = s;start = clock();}
//     ~Timer() {fprintf(stderr, "%s: %.3gs\\n", name.c_str(), 1.0*(clock() -
//     start) / CLOCKS_PER_SEC);}
// };

// #define isValid(a, b) ((a) >= 0 && (a) < (b))
// int dr[]  =  {0, -1, -1, -1,  0,  1, 1, 1};
// int dc[]  =  {1,  1,  0, -1, -1, -1, 0, 1};

#define all(x) (x).begin(), (x).end()
#define pb push_back
#define eb emplace_back
#define um unordered_map
#define us unordered_set
#define endl '\\n'
#define what_is(x)                                                             \\
  cerr << fixed << setprecision(2) << boolalpha << #x << " = " << x << endl

const double EPS = 1e-9;
const double PI = acos(-1.0);

template <typename T> inline T sq(T a) { return a * a; }
template <typename T1, typename T2> inline pair<T1, T2> mp(T1 a, T2 b) {
  return make_pair(a, b);
}
template <typename T1, typename T2> inline T1 safeMod(T1 a, T2 m) {
  return (a % m + m) % m;
} /*handling negative sign of remainder*/
template <typename T1, typename T2> inline bool isEq(T1 a, T2 b) {
  return abs(a - b) < EPS;
}
template <typename T1, typename T2, typename T3>
inline bool isEq(T1 a, T2 b, T3 eps) {
  return abs(a - b) < eps;
}
template <typename T> inline bool isKthBitOn(T n, int k) {
  assert(n <= numeric_limits<T>::max());
  assert(k <= numeric_limits<T>::digits);
  T ONE = 1;
  return bool((n & (ONE << k)));
}
template <typename T> inline void setKthBit(T &n, int k) {
  assert(n <= numeric_limits<T>::max());
  assert(k <= numeric_limits<T>::digits);
  T ONE = 1;
  n = (n | (ONE << k));
}
// mt19937 rng((int)chrono::steady_clock::now().time_since_epoch().count());
// template<typename T> inline T nextRand(T lo, T hi){return
// uniform_int_distribution<T>(lo, hi)(rng);}

#define toRad(deg) ((deg)*PI / 180.0)
#define toDeg(rad) ((rad)*180.0 / PI)

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int oo = 0x3f3f3f3f;
const int MAX = 200010;
const int MOD = 1000000007;
const int precision = 10;

int tree[4 * 300000];
#define max(a, b) ((a) > (b)) ? (a) : (b)
#define min(a, b) ((a) < (b)) ? (a) : (b)
void update(int n, int l, int r, int p, int v) {
  if (l == r) {
    if (l == p)
      tree[n] = max(tree[n], v);
    return;
  }
  int m = (l + r) / 2;
  update(2 * n, l, m, p, v);
  update(2 * n + 1, m + 1, r, p, v);
  tree[n] = max(tree[n << 1], tree[(n << 1) | 1]);
}

int query(int n, int l, int r, int ql, int qr) {
  if (r < ql || qr < l)
    return 0;
  if (ql <= l && r <= qr)
    return tree[n];
  int m = (l + r) / 2;
  return max(query(n << 1, l, m, ql, qr),
             query((n << 1) | 1, m + 1, r, ql, qr));
}

int v[300005];
void solve(int kas) {
  int n, k;
  scanf("%d %d", &n, &k);
  int mv = 0;
  for (int i = 0; i < n; i++) {
    scanf("%d", &v[i]);
    mv = max(mv, v[i]);
  }
  int mx = 0;
  for (int i = n - 1; i >= 0; i--) {
    int l = max(0, v[i] - k);
    int r = min(mv, v[i] + k);
    int mm = query(1, 0, mv, l, r);
    mx = max(mx, 1 + mm);
    update(1, 0, mv, v[i], 1 + mm);
    // cout << i << " " << v[i] << " " << mx << endl;
  }
  printf("%d\\n", mx);
}

int main() {
  // assert(freopen("in.txt", "r", stdin));
  // assert(freopen("out.txt", "w", stdout));
  // cout << fixed << setprecision(precision);
  int tc = 1;
  // cin >> tc;
  for (int _ = 1; _ <= tc; _++) {
    solve(_);
  }
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
//
// using namespace __gnu_pbds;
// template<typename T> using ordered_set = tree<T, null_type, less<T>,
// rb_tree_tag, tree_order_statistics_node_update>;

// class Timer {
//     clock_t start;
//     string name;
// public:
//     Timer() {name = "";start = clock();}
//     Timer(string s){name = s;start = clock();}
//     ~Timer() {fprintf(stderr, "%s: %.3gs\\n", name.c_str(), 1.0*(clock() -
//     start) / CLOCKS_PER_SEC);}
// };

// #define isValid(a, b) ((a) >= 0 && (a) < (b))
// int dr[]  =  {0, -1, -1, -1,  0,  1, 1, 1};
// int dc[]  =  {1,  1,  0, -1, -1, -1, 0, 1};

#define all(x) (x).begin(), (x).end()
#define pb push_back
#define eb emplace_back
#define um unordered_map
#define us unordered_set
#define endl '\\n'
#define what_is(x)                                                             \\
  cerr << fixed << setprecision(2) << boolalpha << #x << " = " << x << endl

const double EPS = 1e-9;
const double PI = acos(-1.0);

template <typename T> inline T sq(T a) { return a * a; }
template <typename T1, typename T2> inline pair<T1, T2> mp(T1 a, T2 b) {
  return make_pair(a, b);
}
template <typename T1, typename T2> inline T1 safeMod(T1 a, T2 m) {
  return (a % m + m) % m;
} /*handling negative sign of remainder*/
template <typename T1, typename T2> inline bool isEq(T1 a, T2 b) {
  return abs(a - b) < EPS;
}
template <typename T1, typename T2, typename T3>
inline bool isEq(T1 a, T2 b, T3 eps) {
  return abs(a - b) < eps;
}
template <typename T> inline bool isKthBitOn(T n, int k) {
  assert(n <= numeric_limits<T>::max());
  assert(k <= numeric_limits<T>::digits);
  T ONE = 1;
  return bool((n & (ONE << k)));
}
template <typename T> inline void setKthBit(T &n, int k) {
  assert(n <= numeric_limits<T>::max());
  assert(k <= numeric_limits<T>::digits);
  T ONE = 1;
  n = (n | (ONE << k));
}
// mt19937 rng((int)chrono::steady_clock::now().time_since_epoch().count());
// template<typename T> inline T nextRand(T lo, T hi){return
// uniform_int_distribution<T>(lo, hi)(rng);}

#define toRad(deg) ((deg)*PI / 180.0)
#define toDeg(rad) ((rad)*180.0 / PI)

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int oo = 0x3f3f3f3f;
const int MAX = 200010;
const int MOD = 1000000007;
const int precision = 10;
//
// #define max(a, b) ((a) > (b))?(a):(b)
// #define min(a, b) ((a) < (b))?(a):(b)

int tree[4 * 300002];
int mv;
void update(int p, int v) {
  p += mv;
  tree[p] = max(tree[p], v);
  while (p > 1) {
    tree[p / 2] = max(tree[p], tree[p ^ 1]);
    p /= 2;
  }
}
int query(int l, int r) //[l, r)
{
  int mx = 0;
  l += mv;
  r += mv;
  while (l < r) {
    if (l & 1)
      mx = max(mx, tree[l++]);
    if (r & 1)
      mx = max(mx, tree[--r]);
    l /= 2;
    r /= 2;
  }
  return mx;
}

int v[300005];
void solve(int kas) {
  int n, k;
  scanf("%d %d", &n, &k);
  mv = 0;
  for (int i = 0; i < n; i++) {
    scanf("%d", &v[i]);
    mv = max(mv, v[i] + k);
  }
  for (int i = mv - 1; i > 0; i--) {
    tree[i] = max(tree[i << 1], tree[(i << 1) | 1]);
  }
  int mx = 0;
  for (int i = n - 1; i >= 0; i--) {
    int l = max(0, v[i] - k);
    int r = min(mv, v[i] + k);
    int mm = query(l, r + 1);
    mx = max(mx, 1 + mm);
    update(v[i], 1 + mm);
    // cout << i << " " << v[i] << " " << mm+1 << endl;
  }
  printf("%d\\n", mx);
}

int main() {
  // assert(freopen("in.txt", "r", stdin));
  // assert(freopen("out.txt", "w", stdout));
  // cout << fixed << setprecision(precision);
  int tc = 1;
  // cin >> tc;
  for (int _ = 1; _ <= tc; _++) {
    solve(_);
  }
  return 0;
}


#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <bitset>    // bitset
#include <cassert>
#include <cctype> // isupper, islower, isdigit, toupper, tolower
#include <cmath>
#include <cstdint> // int64_t, int*_t
#include <cstdio>  // printf
#include <deque>   // deque
#include <functional>
#include <iostream> // cout, endl, cin
#include <limits>
#include <list>
#include <map>           // map
#include <queue>         // queue, priority_queue
#include <set>           // set
#include <stack>         // stack
#include <string>        // string, to_string, stoi
#include <tuple>         // tuple, make_tuple
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <utility>       // pair, make_pair
#include <vector>        // vector
#define ALL(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define int_INF 2147483647
#define pint_INF 2000000000
#define ll_INF 9223372036854775807
#define MOD 1000000007
#define vi vector<int>
#define vvi vector<vector<int>>
#define vvll vector<vector<long long>>
#define vvc vector<vector<char>>
#define vll vector<long long>
#define pii pair<int, int>
#define vpii vector<pair<int, int>>
#define sysp system("PAUSE")
#define pno cout << "no" << endl
#define pyes cout << "yes" << endl
#define pYes cout << "Yes" << endl
#define pNo cout << "No" << endl
#define pNO cout << "NO" << endl
#define pYES cout << "YES" << endl
#define endl "\\n"
#define pi 3.14159265358979
using namespace std;
using ll = long long;
#define int ll

class Segtree { // inputは0-indexed
private:
  int N = -1;
  vector<int> data; // ゼロに近いほうが親
  function<int(int, int)> func;
  int e_id;

public:
  Segtree(int n_, function<int(int, int)> f, int e) {
    func = f;
    e_id = e;

    int N_ = 1;
    while (N_ < n_)
      N_ *= 2;
    N = N_;
    data.resize(2 * N - 1, e_id);
  }

  void update(int k, int a) {
    k += N - 1;
    data[k] =
        a; // １点更新 // add queryのときは data[k] += a;としなければならない
    while (k > 0) {
      k = (k - 1) / 2;
      data[k] = func(data[k * 2 + 1], data[k * 2 + 2]);
    }
  }

  int query_sub(int a, int b, int k, int l, int r) {
    // k:現在見ているノードの位置  [l,r):dat[k]が表している区間
    if (r <= a || b <= l) { // 範囲外なら考えない
      return 0;
    } else if (a <= l && r <= b) { // 範囲内なので自身の値を返す
      return data[k];
    } else { // 一部区間が被る時
      int vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
      int vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
      return func(vl, vr);
    }
  }
  int query(int a, int b) {
    if (b < a)
      swap(a, b);
    return query_sub(a, b + 1, 0, 0, N);
  }
};

signed main() {
  int N, K;
  cin >> N >> K;
  auto fx = [](int x1, int x2) -> int { return max(x1, x2); };
  int e = 0;
  Segtree RMQ(N + 1, fx, e);
  vector<int> vec(N);
  rep(i, N) {
    cin >> vec[i];
    vec[i];
  }
  for (int i = 0; i < N; i++) {
    int left = max(ll(0), vec[i] - K);
    int right = min(N, vec[i] + K);
    int M = RMQ.query(left, right);
    RMQ.update(vec[i], M + 1);
  }
  cout << RMQ.query(0, N - 1) << endl;
  sysp;
}

#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <bitset>    // bitset
#include <cassert>
#include <cctype> // isupper, islower, isdigit, toupper, tolower
#include <cmath>
#include <cstdint> // int64_t, int*_t
#include <cstdio>  // printf
#include <deque>   // deque
#include <functional>
#include <iostream> // cout, endl, cin
#include <limits>
#include <list>
#include <map>           // map
#include <queue>         // queue, priority_queue
#include <set>           // set
#include <stack>         // stack
#include <string>        // string, to_string, stoi
#include <tuple>         // tuple, make_tuple
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <utility>       // pair, make_pair
#include <vector>        // vector
#define ALL(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define int_INF 2147483647
#define pint_INF 2000000000
#define ll_INF 9223372036854775807
#define MOD 1000000007
#define vi vector<int>
#define vvi vector<vector<int>>
#define vvll vector<vector<long long>>
#define vvc vector<vector<char>>
#define vll vector<long long>
#define pii pair<int, int>
#define vpii vector<pair<int, int>>
#define sysp system("PAUSE")
#define pno cout << "no" << endl
#define pyes cout << "yes" << endl
#define pYes cout << "Yes" << endl
#define pNo cout << "No" << endl
#define pNO cout << "NO" << endl
#define pYES cout << "YES" << endl
#define endl "\\n"
#define pi 3.14159265358979
using namespace std;
using ll = long long;
#define int ll

class Segtree { // inputは0-indexed
private:
  int N = -1;
  vector<int> data; // ゼロに近いほうが親
  function<int(int, int)> func;
  int e_id;

public:
  Segtree(int n_, function<int(int, int)> f, int e) {
    func = f;
    e_id = e;

    int N_ = 1;
    while (N_ < n_)
      N_ *= 2;
    N = N_;
    data.resize(2 * N - 1, e_id);
  }

  void update(int k, int a) {
    k += N - 1;
    data[k] =
        a; // １点更新 // add queryのときは data[k] += a;としなければならない
    while (k > 0) {
      k = (k - 1) / 2;
      data[k] = func(data[k * 2 + 1], data[k * 2 + 2]);
    }
  }

  int query_sub(int a, int b, int k, int l, int r) {
    // k:現在見ているノードの位置  [l,r):dat[k]が表している区間
    if (r <= a || b <= l) { // 範囲外なら考えない
      return 0;
    } else if (a <= l && r <= b) { // 範囲内なので自身の値を返す
      return data[k];
    } else { // 一部区間が被る時
      int vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
      int vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
      return func(vl, vr);
    }
  }
  int query(int a, int b) {
    if (b < a)
      swap(a, b);
    return query_sub(a, b + 1, 0, 0, N);
  }
};

signed main() {
  const int Mx = 3000010;
  int N, K;
  cin >> N >> K;
  auto fx = [](int x1, int x2) -> int { return max(x1, x2); };
  int e = 0;
  Segtree RMQ(Mx + 1, fx, e);
  vector<int> vec(N);
  rep(i, N) { cin >> vec[i]; }
  for (int i = 0; i < N; i++) {
    int left = max(ll(0), vec[i] - K);
    int right = min(Mx + 1, vec[i] + K);
    int M = RMQ.query(left, right);
    RMQ.update(vec[i], M + 1);
  }
  cout << RMQ.query(0, Mx + 1) << endl;
  sysp;
}