#include <bits/stdc++.h>
using namespace std;
#define maxn 3000005
int tree[4 * maxn], f[maxn], a[maxn], lazy[4 * maxn];
void pushup(int i) { tree[i] = max(tree[i << 1], tree[i << 1 | 1]); }
void xia(int i, int l, int r) {
  tree[i << 1] = max(tree[i << 1], lazy[i]);
  tree[i << 1 | 1] = max(tree[i << 1 | 1], lazy[i]);
  lazy[i << 1] = max(lazy[i << 1], lazy[i]);
  lazy[i << 1 | 1] = max(lazy[i << 1 | 1], lazy[i]);
  lazy[i] = 0;
}
void update(int i, int l, int r, int x, int y, int val) {
  if (x <= l && r <= y) {
    tree[i] = max(tree[i], val);
    lazy[i] = max(lazy[i], val);
    return;
  }
  if (lazy[i])
    xia(i, l, r);
  int mid = (l + r) / 2;
  if (x <= mid)
    update(i << 1, l, mid, x, y, val);
  if (y > mid)
    update(i << 1 | 1, mid + 1, r, x, y, val);
  pushup(i);
}
int query(int i, int l, int r, int x, int y) {
  if (x <= l && r <= y)
    return tree[i];
  int maxm = 0;
  if (lazy[i])
    xia(i, l, r);
  int mid = (l + r) / 2;
  if (x <= mid)
    maxm = max(maxm, query(i << 1, l, mid, x, y));
  if (y > mid)
    maxm = max(maxm, query(i << 1 | 1, mid + 1, r, x, y));
  return maxm;
}
int tree1[4 * maxn], lazy1[4 * maxn];
void pushup1(int i) { tree1[i] = max(tree1[i << 1], tree1[i << 1 | 1]); }
void xia1(int i, int l, int r) {
  tree1[i << 1] = max(tree1[i << 1], lazy1[i]);
  tree1[i << 1 | 1] = max(tree1[i << 1 | 1], lazy1[i]);
  lazy1[i << 1] = max(lazy1[i << 1], lazy1[i]);
  lazy1[i << 1 | 1] = max(lazy1[i << 1 | 1], lazy1[i]);
  lazy1[i] = 0;
}
void update1(int i, int l, int r, int x, int y, int val) {
  if (x <= l && r <= y) {
    tree1[i] = max(tree1[i], val);
    lazy1[i] = max(lazy1[i], val);
    return;
  }
  if (lazy1[i])
    xia1(i, l, r);
  int mid = (l + r) / 2;
  if (x <= mid)
    update1(i << 1, l, mid, x, y, val);
  if (y > mid)
    update1(i << 1 | 1, mid + 1, r, x, y, val);
  pushup1(i);
}
int query1(int i, int l, int r, int x, int y) {
  if (x <= l && r <= y)
    return tree1[i];
  int maxm = 0;
  if (lazy1[i])
    xia1(i, l, r);
  int mid = (l + r) / 2;
  if (x <= mid)
    maxm = max(maxm, query1(i << 1, l, mid, x, y));
  if (y > mid)
    maxm = max(maxm, query1(i << 1 | 1, mid + 1, r, x, y));
  return maxm;
}
int ans = 0, n, k;
int da = 0;
int main() {
  cin >> n >> k;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), da = max(da, a[i]);
  for (int i = 1; i <= n; i++) {
    int tmp = 0;
    tmp = max(tmp, query1(1, 1, da, max(0, a[i] - k), a[i]));
    tmp = max(tmp, query(1, 1, da, a[i], min(da, a[i] + k)));
    f[i] = tmp + 1;
    ans = max(f[i], ans);
    update1(1, 1, da, max(a[i] - k, 0), a[i], f[i]);
    update(1, 1, da, a[i], min(da, a[i] + k), f[i]);
  }
  cout << ans;
}

#include <bits/stdc++.h>
using namespace std;
#define maxn 300005
int tree[4 * maxn], f[maxn], a[maxn], lazy[4 * maxn];
void pushup(int i) { tree[i] = max(tree[i << 1], tree[i << 1 | 1]); }
void xia(int i, int l, int r) {
  tree[i << 1] = max(tree[i << 1], lazy[i]);
  tree[i << 1 | 1] = max(tree[i << 1 | 1], lazy[i]);
  lazy[i << 1] = max(lazy[i << 1], lazy[i]);
  lazy[i << 1 | 1] = max(lazy[i << 1 | 1], lazy[i]);
  lazy[i] = 0;
}
void update(int i, int l, int r, int x, int y, int val) {
  if (x <= l && r <= y) {
    tree[i] = max(tree[i], val);
    lazy[i] = max(lazy[i], val);
    return;
  }
  if (lazy[i])
    xia(i, l, r);
  int mid = (l + r) / 2;
  if (x <= mid)
    update(i << 1, l, mid, x, y, val);
  if (y > mid)
    update(i << 1 | 1, mid + 1, r, x, y, val);
  pushup(i);
}
int query(int i, int l, int r, int x, int y) {
  if (x <= l && r <= y)
    return tree[i];
  int maxm = 0;
  if (lazy[i])
    xia(i, l, r);
  int mid = (l + r) / 2;
  if (x <= mid)
    maxm = max(maxm, query(i << 1, l, mid, x, y));
  if (y > mid)
    maxm = max(maxm, query(i << 1 | 1, mid + 1, r, x, y));
  return maxm;
}
int tree1[4 * maxn], lazy1[4 * maxn];
void pushup1(int i) { tree1[i] = max(tree1[i << 1], tree1[i << 1 | 1]); }
void xia1(int i, int l, int r) {
  tree1[i << 1] = max(tree1[i << 1], lazy1[i]);
  tree1[i << 1 | 1] = max(tree1[i << 1 | 1], lazy1[i]);
  lazy1[i << 1] = max(lazy1[i << 1], lazy1[i]);
  lazy1[i << 1 | 1] = max(lazy1[i << 1 | 1], lazy1[i]);
  lazy1[i] = 0;
}
void update1(int i, int l, int r, int x, int y, int val) {
  if (x <= l && r <= y) {
    tree1[i] = max(tree1[i], val);
    lazy1[i] = max(lazy1[i], val);
    return;
  }
  if (lazy1[i])
    xia1(i, l, r);
  int mid = (l + r) / 2;
  if (x <= mid)
    update1(i << 1, l, mid, x, y, val);
  if (y > mid)
    update1(i << 1 | 1, mid + 1, r, x, y, val);
  pushup1(i);
}
int query1(int i, int l, int r, int x, int y) {
  if (x <= l && r <= y)
    return tree1[i];
  int maxm = 0;
  if (lazy1[i])
    xia1(i, l, r);
  int mid = (l + r) / 2;
  if (x <= mid)
    maxm = max(maxm, query1(i << 1, l, mid, x, y));
  if (y > mid)
    maxm = max(maxm, query1(i << 1 | 1, mid + 1, r, x, y));
  return maxm;
}
int ans = 0, n, k;
int da = 0;
int main() {
  cin >> n >> k;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), da = max(da, a[i]);
  for (int i = 1; i <= n; i++) {
    int tmp = 0;
    tmp = max(tmp, query1(1, 0, da, max(0, a[i] - k), a[i]));
    tmp = max(tmp, query(1, 0, da, a[i], min(da, a[i] + k)));
    f[i] = tmp + 1;
    ans = max(f[i], ans);
    update1(1, 0, da, max(a[i] - k, 0), a[i], f[i]);
    update(1, 0, da, a[i], min(da, a[i] + k), f[i]);
  }
  cout << ans;
}


#pragma GCC optimize("O3")
#pragma GCC target("sse4")

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

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef pair<db, db> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<db> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define mp make_pair
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define F0R(i, a) FOR(i, 0, a)
#define ROF(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i, a) ROF(i, 0, a)
#define trav(a, x) for (auto &a : x)

const int MX = 2e5 + 5;
const int MOD = 1e9 + 7; // 998244353;
const ll INF = 1e18;
const ld PI = acos((ld)-1);

const int xd[4] = {1, 0, -1, 0}, yd[4] = {0, 1, 0, -1};
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

template <class T> bool ckmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template <class T> bool ckmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

constexpr int pct(int x) { return __builtin_popcount(x); }  // number of ones
constexpr int bits(int x) { return 31 - __builtin_clz(x); } // floor(log2(x))
template <class T> T cdiv(T a, T b) {
  return a / b + !(a < 0 || a % b == 0);
} // division of a by b rounded up, assumes b > 0

int fstTrue(function<bool(int)> f, int lo, int hi) {
  hi++;
  assert(lo <= hi); // assuming f is increasing
  while (lo < hi) { // find first index such that f is true
    int mid = (lo + hi) / 2;
    f(mid) ? hi = mid : lo = mid + 1;
  }
  return lo;
}

template <class T> void remDup(vector<T> &v) {
  sort(all(v));
  v.erase(unique(all(v)), end(v));
}

// DEBUG
void DBG() { cerr << "]" << endl; }
template <class H, class... T> void DBG(H h, T... t) {
  cerr << h;
  if (sizeof...(t))
    cerr << ", ";
  DBG(t...);
}
#define dbg(...)                                                               \\
  cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [",           \\
      DBG(__VA_ARGS__)

// FILE I/O
void setIn(str S) { freopen(S.c_str(), "r", stdin); }
void setOut(str S) { freopen(S.c_str(), "w", stdout); }
void setIO(str S = "") {
  ios_base::sync_with_stdio(0);
  cin.tie(0); // fast I/O
  // cin.exceptions(cin.failbit);
  // throws exception when do smth illegal
  // ex. try to read letter into int
  if (sz(S)) {
    setIn(S + ".in"), setOut(S + ".out");
  } // for USACO
}

template <class T> struct Seg { // comb(ID,b) = b
  const T ID = 0;
  T comb(T a, T b) { return max(a, b); }
  int N;
  vector<T> seg;
  void init(int _N) {
    N = _N;
    seg.assign(2 * N, ID);
  }
  void pull(int p) { seg[p] = comb(seg[2 * p], seg[2 * p + 1]); }
  void upd(int p, T val) { // set val at position p
    p += N, seg[p] = max(seg[p], val);
    for (p /= 2; p; p /= 2)
      pull(p);
  }
  T query(int l, int r) {
    T ra = ID, rb = ID;
    for (l += N, r += N + 1; l < r; l /= 2, r /= 2) {
      if (l & 1)
        ra = comb(ra, seg[l++]);
      if (r & 1)
        rb = comb(seg[--r], rb);
    }
    return comb(ra, rb);
  }
};

int arr[MX];
Seg<ll> ST;

int32_t main() {

  setIO();

  int N, K;
  cin >> N >> K;
  ST.init(N);

  F0R(i, N) { cin >> arr[i]; }

  int res = 0;
  F0R(i, N) {
    int left = max(0, arr[i] - K), right = min(N - 1, arr[i] + K);
    int value = ST.query(left, right);
    res = max(res, value + 1);
    ST.upd(arr[i], value + 1);
  }

  cout << res << "\\n";
}

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

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

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef pair<db, db> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<db> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define mp make_pair
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define F0R(i, a) FOR(i, 0, a)
#define ROF(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i, a) ROF(i, 0, a)
#define trav(a, x) for (auto &a : x)

const int MX = 3e5 + 5;
const int MOD = 1e9 + 7; // 998244353;
const ll INF = 1e18;
const ld PI = acos((ld)-1);

const int xd[4] = {1, 0, -1, 0}, yd[4] = {0, 1, 0, -1};
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

template <class T> bool ckmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template <class T> bool ckmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

constexpr int pct(int x) { return __builtin_popcount(x); }  // number of ones
constexpr int bits(int x) { return 31 - __builtin_clz(x); } // floor(log2(x))
template <class T> T cdiv(T a, T b) {
  return a / b + !(a < 0 || a % b == 0);
} // division of a by b rounded up, assumes b > 0

int fstTrue(function<bool(int)> f, int lo, int hi) {
  hi++;
  assert(lo <= hi); // assuming f is increasing
  while (lo < hi) { // find first index such that f is true
    int mid = (lo + hi) / 2;
    f(mid) ? hi = mid : lo = mid + 1;
  }
  return lo;
}

template <class T> void remDup(vector<T> &v) {
  sort(all(v));
  v.erase(unique(all(v)), end(v));
}

// DEBUG
void DBG() { cerr << "]" << endl; }
template <class H, class... T> void DBG(H h, T... t) {
  cerr << h;
  if (sizeof...(t))
    cerr << ", ";
  DBG(t...);
}
#define dbg(...)                                                               \\
  cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [",           \\
      DBG(__VA_ARGS__)

// FILE I/O
void setIn(str S) { freopen(S.c_str(), "r", stdin); }
void setOut(str S) { freopen(S.c_str(), "w", stdout); }
void setIO(str S = "") {
  ios_base::sync_with_stdio(0);
  cin.tie(0); // fast I/O
  // cin.exceptions(cin.failbit);
  // throws exception when do smth illegal
  // ex. try to read letter into int
  if (sz(S)) {
    setIn(S + ".in"), setOut(S + ".out");
  } // for USACO
}

template <class T> struct Seg { // comb(ID,b) = b
  const T ID = 0;
  T comb(T a, T b) { return max(a, b); }
  int N;
  vector<T> seg;
  void init(int _N) {
    N = _N;
    seg.assign(2 * N, ID);
  }
  void pull(int p) { seg[p] = comb(seg[2 * p], seg[2 * p + 1]); }
  void upd(int p, T val) { // set val at position p
    p += N, seg[p] = max(seg[p], val);
    for (p /= 2; p; p /= 2)
      pull(p);
  }
  T query(int l, int r) {
    T ra = ID, rb = ID;
    for (l += N, r += N + 1; l < r; l /= 2, r /= 2) {
      if (l & 1)
        ra = comb(ra, seg[l++]);
      if (r & 1)
        rb = comb(seg[--r], rb);
    }
    return comb(ra, rb);
  }
};

int arr[MX];
Seg<ll> ST;

int32_t main() {

  setIO();

  int N, K;
  cin >> N >> K;
  ST.init(MX + 1);

  F0R(i, N) { cin >> arr[i]; }

  int res = 0;
  F0R(i, N) {
    int left = max(0, arr[i] - K), right = min(MX - 1, arr[i] + K);
    int value = ST.query(left, right);
    res = max(res, value + 1);
    ST.upd(arr[i], value + 1);
  }

  cout << res << "\\n";
}


#include <bits/stdc++.h>
#define int long long
#define zmrl(x) (int)((x).size())
#define ahen(x) (x).begin(), (x).end()
#define pb push_back
#define fi first
#define se second
using namespace std;
using pii = pair<int, int>;
const int N = 300001;

int tree[300300 << 1];

void update(int idx, int val) {
  tree[idx += N] = val;
  for (idx >>= 1; idx; idx >>= 1) {
    tree[idx] = max(tree[idx << 1], tree[idx << 1 | 1]);
  }
}

int solve(int le, int ri) {
  int ret = 0;
  for (le += N, ri += N; le <= ri; le >>= 1, ri >>= 1) {
    if (le & 1)
      ret = max(ret, tree[le++]);
    if (~ri & 1)
      ret = max(ret, tree[ri--]);
  }
  return ret;
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, k;
  cin >> n >> k;
  int A[300300], dp[300300];
  for (int i = 1; i <= n; i++) {
    cin >> A[i];
  }
  dp[0] = 0;
  int res = dp[1] = 1;
  update(A[1], 1);
  for (int i = 2; i <= n; i++) {
    int maxidx = solve(A[i] - k, A[i] + k);
    res = max(dp[i] = dp[maxidx] + 1, res);
    dp[i] = max(dp[i], dp[i - 1]);
    update(A[i], i);
  }
  cout << res << '\\n';
  return 0;
}

#include <bits/stdc++.h>
#define int long long
#define zmrl(x) (int)((x).size())
#define ahen(x) (x).begin(), (x).end()
#define pb push_back
#define fi first
#define se second
using namespace std;
using pii = pair<int, int>;
const int N = 300001;

int tree[300300 << 1];

void update(int idx, int val) {
  tree[idx += N] = val;
  for (idx >>= 1; idx; idx >>= 1) {
    tree[idx] = max(tree[idx << 1], tree[idx << 1 | 1]);
  }
}

int solve(int le, int ri) {
  int ret = 0;
  for (le += N, ri += N; le <= ri; le >>= 1, ri >>= 1) {
    if (le & 1)
      ret = max(ret, tree[le++]);
    if (~ri & 1)
      ret = max(ret, tree[ri--]);
  }
  return ret;
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, k;
  cin >> n >> k;
  int A[300300];
  for (int i = 1; i <= n; i++) {
    cin >> A[i];
  }
  int res = 1;
  update(A[1], 1);
  for (int i = 2; i <= n; i++) {
    int maxlen = solve(max(A[i] - k, 0LL), min(A[i] + k, N - 1));
    res = max(res, maxlen + 1);
    if (tree[A[i] + N] < maxlen + 1) {
      update(A[i], maxlen + 1);
    }
  }
  cout << res << '\\n';
  return 0;
}


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

const int N = 1200010;
int n, m, a[N];

struct SegTree {
  int l[N], r[N], maxn[N];

  void build(int x, int ql, int qr) {
    l[x] = ql;
    r[x] = qr;
    if (ql == qr)
      return;
    int mid = (ql + qr) >> 1;
    build(x * 2, ql, mid);
    build(x * 2 + 1, mid + 1, qr);
  }

  int query(int x, int ql, int qr) {
    if (l[x] == ql && r[x] == qr)
      return maxn[x];
    int mid = (l[x] + r[x]) >> 1;
    if (qr <= mid)
      return query(x * 2, ql, qr);
    if (ql > mid)
      return query(x * 2 + 1, ql, qr);
    return max(query(x * 2, ql, mid), query(x * 2 + 1, mid + 1, qr));
  }

  void update(int x, int p, int v) {
    if (l[x] == p && r[x] == p) {
      maxn[x] = max(maxn[x], v);
      return;
    }
    int mid = (l[x] + r[x]) >> 1;
    if (p <= mid)
      update(x * 2, p, v);
    else
      update(x * 2 + 1, p, v);
    maxn[x] = max(maxn[x * 2], maxn[x * 2 + 1]);
  }
} seg;

int main() {
  scanf("%d%d", &n, &m);
  seg.build(1, 1, n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    seg.update(1, a[i], seg.query(1, max(1, a[i] - m), min(n, a[i] + m)) + 1);
  }
  printf("%d\\n", seg.maxn[1]);
  return 0;
}

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

const int N = 1500010;
int n, m, a[N];

struct SegTree {
  int l[N], r[N], maxn[N];

  void build(int x, int ql, int qr) {
    l[x] = ql;
    r[x] = qr;
    if (ql == qr)
      return;
    int mid = (ql + qr) >> 1;
    build(x * 2, ql, mid);
    build(x * 2 + 1, mid + 1, qr);
  }

  int query(int x, int ql, int qr) {
    if (l[x] == ql && r[x] == qr)
      return maxn[x];
    int mid = (l[x] + r[x]) >> 1;
    if (qr <= mid)
      return query(x * 2, ql, qr);
    if (ql > mid)
      return query(x * 2 + 1, ql, qr);
    return max(query(x * 2, ql, mid), query(x * 2 + 1, mid + 1, qr));
  }

  void update(int x, int p, int v) {
    if (l[x] == p && r[x] == p) {
      maxn[x] = max(maxn[x], v);
      return;
    }
    int mid = (l[x] + r[x]) >> 1;
    if (p <= mid)
      update(x * 2, p, v);
    else
      update(x * 2 + 1, p, v);
    maxn[x] = max(maxn[x * 2], maxn[x * 2 + 1]);
  }
} seg;

int main() {
  scanf("%d%d", &n, &m);
  seg.build(1, 1, 300010);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    a[i]++;
    seg.update(1, a[i],
               seg.query(1, max(1, a[i] - m), min(300010, a[i] + m)) + 1);
  }
  printf("%d\\n", seg.maxn[1]);
  return 0;
}


/*
    Created by Rahul Goel.
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
/*******************************************************************************/
using namespace std;
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
/*******************************************************************************/
using ll = long long;
using ld = long double;
const ll MOD = 1000000007;
// const ll MOD = 998244353;
const int INF = 1e9;
const ll LINF = 1e18;
/*******************************************************************************/
ll mod_sum() { return 0LL; }
template <typename T, typename... Args> T mod_sum(T a, Args... args) {
  return ((a + mod_sum(args...)) % MOD + MOD) % MOD;
}
/*******************************************************************************/
ll mod_prod() { return 1LL; }
template <typename T, typename... Args> T mod_prod(T a, Args... args) {
  return (a * mod_prod(args...)) % MOD;
}
/*******************************************************************************/
#ifdef ONLINE_JUDGE
#define endl '\\n'
#endif
#define fastio                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
#define all(c) (c).begin(), (c).end()
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define uniq(c) (c).resize(distance((c).begin(), unique(all(c))))
#define min_pq(t) priority_queue<t, vector<t>, greater<t>>
#define max_pq(t) priority_queue<t>
#define pb push_back
#define ff first
#define ss second
/*******************************************************************************/
using pii = pair<int, int>;
using vi = vector<int>;
using vb = vector<bool>;
using vvi = vector<vector<int>>;
using vvb = vector<vector<bool>>;
using vpii = vector<pii>;
using vvpii = vector<vector<pii>>;
/*******************************************************************************/
//.-.. . -. -.- .- .. ... .-.. --- ...- .
/*
    Code begins after this.
*/

struct SegmentTree {
  vi t;

  SegmentTree(int n) { t.resize(n << 2); }

  void pull(int v) { t[v] = max(t[v << 1], t[v << 1 | 1]); }

  void upd(int v, int tl, int tr, int pos, int val) {
    if (tl == tr) {
      t[v] = val;
      return;
    }
    int tm = (tl + tr) >> 1;
    if (pos <= tm) {
      upd(v << 1, tl, tm, pos, val);
    } else {
      upd(v << 1 | 1, tm + 1, tr, pos, val);
    }
    pull(v);
  }

  int query(int v, int tl, int tr, int ql, int qr) {
    if (ql <= tl && tr <= qr) {
      return t[v];
    }
    int tm = (tl + tr) >> 1;
    int ret = -INF;
    if (ql <= tm) {
      ret = max(ret, query(v << 1, tl, tm, ql, qr));
    }
    if (tm + 1 <= qr) {
      ret = max(ret, query(v << 1 | 1, tm + 1, tr, ql, qr));
    }
    pull(v);
    return ret;
  }
};

int solve() {
  int n, k;
  cin >> n >> k;
  SegmentTree st(300005);

  for (int i = 0; i < n; i++) {
    int x;
    cin >> x;
    int y = st.query(1, 0, n - 1, max(0, x - k), min(300000, x + k));
    st.upd(1, 0, n - 1, x, y + 1);
  }

  int ans = st.query(1, 0, 300005 - 1, 0, 300000);
  cout << ans << endl;

  return 0;
}

signed main() {
  fastio;

  int t = 1;
  while (t--) {
    solve();
  }
  return 0;
}

/*
    Created by Rahul Goel.
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
/*******************************************************************************/
using namespace std;
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
/*******************************************************************************/
using ll = long long;
using ld = long double;
const ll MOD = 1000000007;
// const ll MOD = 998244353;
const int INF = 1e9;
const ll LINF = 1e18;
/*******************************************************************************/
ll mod_sum() { return 0LL; }
template <typename T, typename... Args> T mod_sum(T a, Args... args) {
  return ((a + mod_sum(args...)) % MOD + MOD) % MOD;
}
/*******************************************************************************/
ll mod_prod() { return 1LL; }
template <typename T, typename... Args> T mod_prod(T a, Args... args) {
  return (a * mod_prod(args...)) % MOD;
}
/*******************************************************************************/
#ifdef ONLINE_JUDGE
#define endl '\\n'
#endif
#define fastio                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
#define all(c) (c).begin(), (c).end()
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define uniq(c) (c).resize(distance((c).begin(), unique(all(c))))
#define min_pq(t) priority_queue<t, vector<t>, greater<t>>
#define max_pq(t) priority_queue<t>
#define pb push_back
#define ff first
#define ss second
/*******************************************************************************/
using pii = pair<int, int>;
using vi = vector<int>;
using vb = vector<bool>;
using vvi = vector<vector<int>>;
using vvb = vector<vector<bool>>;
using vpii = vector<pii>;
using vvpii = vector<vector<pii>>;
/*******************************************************************************/
//.-.. . -. -.- .- .. ... .-.. --- ...- .
/*
    Code begins after this.
*/

struct SegmentTree {
  vi t;

  SegmentTree(int n) { t.resize(n << 2); }

  void pull(int v) { t[v] = max(t[v << 1], t[v << 1 | 1]); }

  void upd(int v, int tl, int tr, int pos, int val) {
    if (tl == tr) {
      t[v] = val;
      return;
    }
    int tm = (tl + tr) >> 1;
    if (pos <= tm) {
      upd(v << 1, tl, tm, pos, val);
    } else {
      upd(v << 1 | 1, tm + 1, tr, pos, val);
    }
    pull(v);
  }

  int query(int v, int tl, int tr, int ql, int qr) {
    if (ql <= tl && tr <= qr) {
      return t[v];
    }
    int tm = (tl + tr) >> 1;
    int ret = -INF;
    if (ql <= tm) {
      ret = max(ret, query(v << 1, tl, tm, ql, qr));
    }
    if (tm + 1 <= qr) {
      ret = max(ret, query(v << 1 | 1, tm + 1, tr, ql, qr));
    }
    pull(v);
    return ret;
  }
};

int solve() {
  int n, k;
  cin >> n >> k;
  SegmentTree st(300005);

  for (int i = 0; i < n; i++) {
    int x;
    cin >> x;
    int y = st.query(1, 0, 300005 - 1, max(0, x - k), min(300000, x + k));
    st.upd(1, 0, 300005 - 1, x, y + 1);
  }

  int ans = st.query(1, 0, 300005 - 1, 0, 300000);
  cout << ans << endl;

  return 0;
}

signed main() {
  fastio;

  int t = 1;
  while (t--) {
    solve();
  }
  return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string.h>
#include <utility>
#include <vector>
#define s(n) scanf("%d", &n)
#define sc(n) scanf("%c", &n)
#define sl(n) scanf("%I64d", &n)
#define sf(n) scanf("%lf", &n)
#define ss(n) scanf("%s", n)
#define INF (int)1e9
#define EPS 1e-9
#define bitcount __builtin_popcount
#define gcd __gcd
#define forall(i, a, b) for (int i = a; i < b; i++)
#define foreach(v, c)                                                          \\
  for (typeof((c).begin()) v = (c).begin(); v != (c).end(); ++v)
#define all(a) a.begin(), a.end()
#define in(a, b) ((b).find(a) != (b).end())
#define pb push_back
#define fill(a, v) memset(a, v, sizeof a)
#define sz(a) ((int)(a.size()))
#define mp make_pair
#define MOD 1000000007
typedef long long ll;
/*For you see , each day i love you
 more.Today more than yesterday
  less than tomorrow.*/
using namespace std;

int seg_tree[1100000];

int dp[300001];

int find_max(int left, int right, int low, int high, int cur) {
  //	cout<<left<<" "<<right<<" "<<low<<" "<<high<<endl;
  if (left == right) {

    //	cout<<'('<<left<<" "<<right<<" "<<low<<" "<<high<<endl;
    return seg_tree[cur];
  }

  int mid = (left + right) / 2;

  if (low >= left && high <= mid) {
    return find_max(left, mid, low, high, cur * 2 + 1);
  } else if (low > mid && high <= right) {
    return find_max(mid + 1, right, low, high, cur * 2 + 2);
  } else {
    int low1 = max(left, low);
    int maxi1 = find_max(left, mid, low1, mid, cur * 2 + 1);
    int high1 = min(right, high);

    int maxi2 = find_max(mid + 1, right, mid + 1, high1, cur * 2 + 2);

    return max(maxi1, maxi2);
  }
}

void fix_it(int left, int right, int key, int ne, int cur) {
  // cout<<left<<" "<<right<<endl;
  if (left == right) {
    seg_tree[cur] = max(ne, seg_tree[cur]);
    return;
  }

  int mid = (left + right) / 2;

  if (key <= mid) {
    fix_it(left, mid, key, ne, cur * 2 + 1);
  } else {
    fix_it(mid + 1, right, key, ne, cur * 2 + 2);
  }
}

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

  vector<int> vec;

  for (int i = 0; i < n; i++) {
    int x;
    s(x);
    vec.push_back(x);
  }

  for (int i = n - 1; i >= 0; i--) {
    int low = max(0, vec[i] - k);
    int high = min(300000, vec[i] + k);

    int maxi = find_max(0, 300000, low, high, 0);

    dp[i] = 1 + maxi;

    fix_it(0, 300000, vec[i], dp[i], 0);
  }

  cout << dp[0] << endl;

  return 0;
}

#include <algorithm>
#include <atcoder/segtree>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string.h>
#include <utility>
#include <vector>
#define s(n) scanf("%d", &n)
#define sc(n) scanf("%c", &n)
#define sl(n) scanf("%I64d", &n)
#define sf(n) scanf("%lf", &n)
#define ss(n) scanf("%s", n)
#define INF (int)1e9
#define EPS 1e-9
#define bitcount __builtin_popcount
#define gcd __gcd
#define forall(i, a, b) for (int i = a; i < b; i++)
#define foreach(v, c)                                                          \\
  for (typeof((c).begin()) v = (c).begin(); v != (c).end(); ++v)
#define all(a) a.begin(), a.end()
#define in(a, b) ((b).find(a) != (b).end())
#define pb push_back
#define fill(a, v) memset(a, v, sizeof a)
#define sz(a) ((int)(a.size()))
#define mp make_pair
#define MOD 1000000007
typedef long long ll;
/*For you see , each day i love you
 more.Today more than yesterday
  less than tomorrow.*/
using namespace std;
using namespace atcoder;

int dp[300001];

int op(int a, int b) { return max(a, b); }
int e() { return 0; }

int main() {
  int n, k;
  cin >> n >> k;
  segtree<int, op, e> seg(300001);

  vector<int> vec;

  for (int i = 0; i < n; i++) {
    int x;
    s(x);
    vec.push_back(x);
  }

  int maxii = 0;

  for (int i = n - 1; i >= 0; i--) {
    int low = max(0, vec[i] - k);
    int high = min(300000, vec[i] + k);

    int maxi = seg.prod(low, high + 1);

    dp[i] = 1 + maxi;
    maxii = max(maxii, dp[i]);

    seg.set(vec[i], dp[i]);
  }

  cout << maxii << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
int Read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 3) + (x << 1) + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, k, f[300055], maxn[1200055], a[300055];
void modify(int o, int l, int r, int pos, int x) {
  if (l == r) {
    maxn[o] = max(maxn[o], x);
    return;
  }
  int mid = (l + r) >> 1;
  if (pos <= mid)
    modify(o << 1, l, mid, pos, x);
  else
    modify(o << 1 | 1, mid + 1, r, pos, x);
  maxn[o] = max(maxn[o << 1], maxn[o << 1 | 1]);
}
int query(int o, int l, int r, int nl, int nr) {
  if (nl <= l && r <= nr)
    return maxn[o];
  int mid = (l + r) >> 1, ans = 0;
  if (nl <= mid)
    ans = max(ans, query(o << 1, l, mid, nl, nr));
  if (mid < nr)
    ans = max(ans, query(o << 1 | 1, mid + 1, r, nl, nr));
  return ans;
}
signed main() {
  n = Read(), k = Read();
  for (int i = 1; i <= n; i++)
    a[i] = Read() + 1;
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    f[i] = query(1, 1, n, max(a[i] - k, 1), min(a[i] + k, 300001)) + 1;
    modify(1, 1, n, a[i], f[i]);
    ans = max(ans, f[i]);
  }
  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
int Read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 3) + (x << 1) + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, k, f[600055], maxn[2400055], a[600055];
void modify(int o, int l, int r, int pos, int x) {
  if (l == r) {
    maxn[o] = max(maxn[o], x);
    return;
  }
  int mid = (l + r) >> 1;
  if (pos <= mid)
    modify(o << 1, l, mid, pos, x);
  else
    modify(o << 1 | 1, mid + 1, r, pos, x);
  maxn[o] = max(maxn[o << 1], maxn[o << 1 | 1]);
}
int query(int o, int l, int r, int nl, int nr) {
  if (nl <= l && r <= nr)
    return maxn[o];
  int mid = (l + r) >> 1, ans = 0;
  if (nl <= mid)
    ans = max(ans, query(o << 1, l, mid, nl, nr));
  if (mid < nr)
    ans = max(ans, query(o << 1 | 1, mid + 1, r, nl, nr));
  return ans;
}
signed main() {
  n = Read(), k = Read();
  for (int i = 1; i <= n; i++)
    a[i] = Read() + 1;
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    f[i] = query(1, 1, 300001, max(a[i] - k, 1), min(a[i] + k, 300001)) + 1;
    modify(1, 1, 300001, a[i], f[i]);
    ans = max(ans, f[i]);
  }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
int dp[4 * 30000 + 5];
int n, x, k;
int qry(int ni, int ns, int ne, int nl, int nr) {
  if (nl <= ns && ne <= nr)
    return dp[ni];
  if (nr < ns || ne < nl)
    return 0;
  int mid = ns + (ne - ns) / 2;
  int l = ni * 2 + 1, r = ni * 2 + 2;
  int x = qry(l, ns, mid, nl, nr);
  int y = qry(r, mid + 1, ne, nl, nr);
  return max(x, y);
}
int upd(int ni, int ns, int ne, int idx, int val) {
  if (ne < idx || idx < ns)
    return dp[ni];
  if (ns == ne)
    return dp[ni] = val;
  int mid = ns + (ne - ns) / 2;
  int l = ni * 2 + 1, r = ni * 2 + 2;
  int x = upd(l, ns, mid, idx, val);
  int y = upd(r, mid + 1, ne, idx, val);
  return dp[ni] = max(x, y);
}
signed main() {
  cin >> n >> k;
  int ans = 0;
  for (int i = 0; i < n; i++) {
    cin >> x;
    int q = 1 + qry(0, 1, (int)3e5, max(1, x - k), min((int)3e5, x + k));
    cout << 11 << endl;
    ans = max(ans, q);
    upd(0, 1, (int)3e5, x, q);
  }
  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
int dp[4 * 300000 + 5];
int n, x, k;
int qry(int ni, int ns, int ne, int nl, int nr) {
  if (nl <= ns && ne <= nr)
    return dp[ni];
  if (nr < ns || ne < nl)
    return 0;
  int mid = ns + (ne - ns) / 2;
  int l = ni * 2 + 1, r = ni * 2 + 2;
  int x = qry(l, ns, mid, nl, nr);
  int y = qry(r, mid + 1, ne, nl, nr);
  return max(x, y);
}
int upd(int ni, int ns, int ne, int idx, int val) {
  if (ne < idx || idx < ns)
    return dp[ni];
  if (ns == ne)
    return dp[ni] = val;
  int mid = ns + (ne - ns) / 2;
  int l = ni * 2 + 1, r = ni * 2 + 2;
  int x = upd(l, ns, mid, idx, val);
  int y = upd(r, mid + 1, ne, idx, val);
  return dp[ni] = max(x, y);
}
signed main() {
  cin >> n >> k;
  int ans = 0;
  for (int i = 0; i < n; i++) {
    cin >> x;
    int q = 1 + qry(0, 0, (int)3e5, max(0, x - k), min((int)3e5, x + k));
    ans = max(ans, q);
    upd(0, 0, (int)3e5, x, q);
  }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 1000000007LL;
#define speed                                                                  \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL)
//_______________________________________________________________________________
const int N = 300005;
int seg[2 * N];
int a[N];
int dp[N];
void build(int ind, int rl, int rr) {
  if (rl == rr) {
    seg[ind] = a[rr];
    return;
  }
  int mid = (rl + rr) / 2;
  build(2 * ind, rl, mid);
  build((2 * ind) + 1, mid + 1, rr);
  seg[ind] = max(seg[2 * ind], seg[(2 * ind) + 1]);
}
void update(int ind, int idx, int val, int rl, int rr) {
  if (rl == rr) {
    seg[ind] = val;
    // a[idx] = val;
    return;
  }
  int mid = (rl + rr) / 2;
  if (idx >= rl && idx <= mid) {
    update(2 * ind, idx, val, rl, mid);
  } else {
    update((2 * ind) + 1, idx, val, mid + 1, rr);
  }
  seg[ind] = max(seg[2 * ind], seg[(2 * ind) + 1]);
}
int query(int ind, int ql, int qr, int rl, int rr) {
  if (ql > rr || rl > qr) {
    return -1;
  }
  if (rr <= qr && rl >= ql) {
    return seg[ind];
  }
  int mid = (rl + rr) / 2;
  return max(query(2 * ind, ql, qr, rl, mid),
             query((2 * ind) + 1, ql, qr, mid + 1, rr));
}
int main() {
  int n, k;
  cin >> n >> k;
  memset(dp, 0, sizeof dp);
  memset(seg, 0, sizeof seg);
  for (int i = 0; i < n; i++)
    cin >> a[i];
  for (int i = n - 1; i >= 0; i--) {
    int mn = max(a[i] - k, 0);
    int mx = min(a[i] + k, 300002);
    dp[a[i]] = max(dp[a[i]], query(1, mn, mx, 0, 300002) + 1);
    //       cout<<a[i]<<" "<<query(1,mn,mx,0,300002)<<endl;
    update(1, a[i], dp[a[i]], 0, 300002);
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    ans = max(ans, dp[a[i]]);
  }
  cout << ans << endl;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 1000000007LL;
#define speed                                                                  \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL)
//_______________________________________________________________________________
const int N = 300005;
int seg[4 * N];
int a[N];
int dp[N];
void build(int ind, int rl, int rr) {
  if (rl == rr) {
    seg[ind] = a[rr];
    return;
  }
  int mid = (rl + rr) / 2;
  build(2 * ind, rl, mid);
  build((2 * ind) + 1, mid + 1, rr);
  seg[ind] = max(seg[2 * ind], seg[(2 * ind) + 1]);
}
void update(int ind, int idx, int val, int rl, int rr) {
  if (rl == rr) {
    seg[ind] = val;
    // a[idx] = val;
    return;
  }
  int mid = (rl + rr) / 2;
  if (idx >= rl && idx <= mid) {
    update(2 * ind, idx, val, rl, mid);
  } else {
    update((2 * ind) + 1, idx, val, mid + 1, rr);
  }
  seg[ind] = max(seg[2 * ind], seg[(2 * ind) + 1]);
}
int query(int ind, int ql, int qr, int rl, int rr) {
  if (ql > rr || rl > qr) {
    return -1;
  }
  if (rr <= qr && rl >= ql) {
    return seg[ind];
  }
  int mid = (rl + rr) / 2;
  return max(query(2 * ind, ql, qr, rl, mid),
             query((2 * ind) + 1, ql, qr, mid + 1, rr));
}
int main() {
  int n, k;
  cin >> n >> k;
  memset(dp, 0, sizeof dp);
  memset(seg, 0, sizeof seg);
  for (int i = 0; i < n; i++)
    cin >> a[i];
  for (int i = n - 1; i >= 0; i--) {
    int mn = max(a[i] - k, 0);
    int mx = min(a[i] + k, 300002);
    dp[a[i]] = max(dp[a[i]], query(1, mn, mx, 0, 300002) + 1);
    //       cout<<a[i]<<" "<<query(1,mn,mx,0,300002)<<endl;
    update(1, a[i], dp[a[i]], 0, 300002);
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    ans = max(ans, dp[a[i]]);
  }
  cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define forn(i, a, b) for (int i = a; i < b; ++i)
#define SZ(x) int(x.size())
#define pb push_back
#define F first
#define S second
void dbg_out() { cerr << endl; }
template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) {
  cerr << ' ' << H;
  dbg_out(T...);
}

const int N = 3 * 1e5 + 1;
int n, k;

int main() {
#ifdef LOCAL
  freopen("d.txt", "r", stdin);
// freopen("main.txt", "w", stdout);
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
  ios::sync_with_stdio(0);
  cin.tie(0);
#define endl '\\n'
#define dbg(...) 18
#endif
  cin >> n >> k;
  map<int, int> mp;
  int a, mx;
  for (int i = 0; i < n; i++) {
    cin >> a;
    auto x = mp.lower_bound(a - k);
    if (x == mp.end()) {
      mp[a] = 1;
    } else {
      mx = 0;
      while (x->F <= a + k && x != mp.end()) {
        mx = max(mx, x->S);
        // mp.erase(x->F);
        x++;
      }
      mp[a] = mx + 1;
    }
  }
  int ans = 0;
  for (auto x : mp)
    ans = max(ans, x.S);
  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define forn(i, a, b) for (int i = a; i < b; ++i)
#define SZ(x) int(x.size())
#define pb push_back
#define F first
#define S second
void dbg_out() { cerr << endl; }
template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) {
  cerr << ' ' << H;
  dbg_out(T...);
}

const int N = 3 * 1e5 + 1;
int n, k;

typedef int T;
struct segtree {
  vector<T> st;
  int n;
  T neutro = 0;

  segtree(int p) {
    n = p;
    st.assign(n * 4, 0);
    build(1, 0, n - 1);
  }

  void build(int p, int L, int R) {
    if (L == R)
      st[p] = 0;
    else {
      int m = (L + R) / 2, l = p * 2, r = l + 1;
      build(l, L, m);
      build(r, m + 1, R);
      st[p] = max(st[l], st[r]);
    }
  }

  T query(int i, int j) { return query(1, 0, n - 1, i, j); }
  void upd(int i, int j, T val) { upd(1, 0, n - 1, i, j, val); }

  T query(int p, int L, int R, int i, int j) {
    if (i > R || j < L)
      return neutro;
    if (i <= L && j >= R)
      return st[p];
    int m = (L + R) / 2, l = p * 2, r = l + 1;
    T lf = query(l, L, m, i, j);
    T rg = query(r, m + 1, R, i, j);
    return max(lf, rg);
  }

  void upd(int p, int L, int R, int i, int j, T val) {
    if (i > R || j < L)
      return;
    if (i <= L && j >= R)
      st[p] = val;
    else {
      int m = (L + R) / 2, l = p * 2, r = l + 1;
      upd(l, L, m, i, j, val);
      upd(r, m + 1, R, i, j, val);
      st[p] = max(st[l], st[r]);
    }
  }
};

int main() {
#ifdef LOCAL
  freopen("d.txt", "r", stdin);
// freopen("main.txt", "w", stdout);
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
  ios::sync_with_stdio(0);
  cin.tie(0);
#define endl '\\n'
#define dbg(...) 18
#endif
  cin >> n >> k;
  int mx = 0;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    mx = max(mx, a[i]);
  }
  segtree st(mx + 1);
  for (int i = 0; i < n; i++) {
    st.upd(a[i], a[i], st.query(a[i] - k, a[i] + k) + 1);
  }
  cout << (st.query(0, mx)) << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define loop(__x, __start, __end) for (int __x = __start; __x < __end; __x++)

typedef pair<ll, ll> P;
int main() {
  int n, k;
  cin >> n >> k;
  vector<ll> A(n);
  loop(i, 0, n) cin >> A[i];
  queue<P> Q;
  Q.emplace(-1, 0);
  loop(i, 0, n) {
    int m = Q.size();
    ll a = A[i];
    loop(j, 0, m) {
      auto p = Q.front();
      Q.pop();
      if (p.first == -1 or abs(p.first - a) <= k) {
        // とれるからとる
        Q.emplace(a, p.second + 1);

        // あえてとらない
        Q.push(p);
      } else {
        // とらない
        Q.push(p);
      }
    }
  }

  ll ma = 0;
  while (Q.size()) {
    auto p = Q.front();
    Q.pop();
    ma = max(ma, p.second);
  }
  cout << ma << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define loop(__x, __start, __end) for (int __x = __start; __x < __end; __x++)
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < v.size(); ++i) {
    os << v[i];
    if (i != v.size() - 1)
      os << ' ';
  }
  return os;
}

class SegTree {
public:
  SegTree(vector<ll> vec) {
    int size = vec.size();
    n = 1;
    while (n < size)
      n *= 2;

    node.resize(2 * n - 1, IDENT);
    lazy.resize(2 * n - 1, INF);

    loop(i, 0, size) node[i + n - 1] = vec[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = f(node[c1(i)], node[c2(i)]);
  }

  void update(int l, int r, ll v) { updateRec(l, r, v, 0, 0, n); }

  ll get(int l, int r) { return getRec(l, r, 0, 0, n); }

  void debug() {
    cout << "node: " << node << endl;
    cout << "lazy: " << lazy << endl;
  }

private:
  int n;
  vector<ll> node, lazy;
  const ll INF = 1000000000000000000;
  const ll IDENT = 0;

  ll f(ll a, ll b) { return max(a, b); }

  void f_lazy(ll &a, ll b) { a = b; }

  inline int p(int i) { return (i - 1) / 2; }
  inline int c1(int i) { return i * 2 + 1; }
  inline int c2(int i) { return i * 2 + 2; }

  void eval(int k, int l, int r) {
    if (lazy[k] == INF)
      return;
    f_lazy(node[k], lazy[k]);

    if (r - l > 1) {
      f_lazy(lazy[c1(k)], lazy[k] / 2);
      f_lazy(lazy[c2(k)], lazy[k] / 2);
    }

    lazy[k] = INF;
  }

  void updateRec(int l, int r, ll v, int k, int selfL, int selfR) {
    eval(k, l, r);
    if (r <= selfL or selfR <= l)
      return;
    if (l <= selfL and selfR <= r) {
      lazy[k] = (r - l) * v;
      eval(k, l, r);
      return;
    }

    updateRec(l, r, v, c1(k), selfL, (selfL + selfR) / 2);
    updateRec(l, r, v, c2(k), (selfL + selfR) / 2, selfR);
    node[k] = f(node[c1(k)], node[c2(k)]);
  }

  ll getRec(int l, int r, int k, int selfL, int selfR) {
    if (r <= selfL or selfR <= l)
      return IDENT;
    eval(k, l, r);
    if (l <= selfL and selfR <= r) {
      eval(k, l, r);
      return node[k];
    }

    return f(getRec(l, r, c1(k), selfL, (selfL + selfR) / 2),
             getRec(l, r, c2(k), (selfL + selfR) / 2, selfR));
  }
};

int main() {
  int n, k;
  cin >> n >> k;
  vector<ll> A(n, 0);
  loop(i, 0, n) cin >> A[i];
  SegTree seg(vector<ll>(600100, 0));

  loop(i, 0, n) {
    ll a = A[i];
    ll ma = seg.get(max(a - k, 0LL), a + k + 1);
    seg.update(a, a + 1, ma + 1);
    // seg.debug();
  }

  ll ans = 0;
  loop(i, 0, 300000) { ans = max(ans, seg.get(i, i + 1)); }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
using namespace std;
ll c[600005] = {0}, tree[1200005] = {0};
ll query(ll ql, ll qr, ll s, ll e, ll in) {
  if (ql > e || qr < s || s > e)
    return -1;
  if (ql <= s && qr >= e) {
    return tree[in];
  }

  int mid = (s + e) / 2;
  // cout<<"Okay";
  return max(query(ql, qr, s, mid, 2 * in + 1),
             query(ql, qr, mid + 1, e, 2 * in + 2));
}
void update(ll s, ll e, ll in, ll key, ll up) {
  if (s > e)
    return;
  if (s == e && s == key) {
    tree[in] = up;
    return;
  } else if (s == e)
    return;
  ll mid = (s + e) / 2;

  update(s, mid, 2 * in + 1, key, up);

  update(mid + 1, e, 2 * in + 2, key, up);
  tree[in] = max(tree[2 * in + 1], tree[2 * in + 2]);
}
int main() {
  ll n, k;
  cin >> n >> k;
  ll a[n];
  for (int i = 0; i < n; i++)
    cin >> a[i];
  ll ans = 1;
  for (int i = 0; i < n; i++) {
    ll curr = query(max(0ll, a[i] - k), min(300000ll, a[i] + k), 0, 300000, 0);
    // cout<<curr<<endl;
    ans = max(ans, curr + 1);
    update(0, 300000, 0, a[i], curr + 1);
  }
  cout << ans;
}

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
using namespace std;
ll c[600005] = {0}, tree[1200005] = {0};
ll query(ll ql, ll qr, ll s, ll e, ll in) {
  if (ql > e || qr < s || s > e)
    return -1;
  if (ql <= s && qr >= e) {
    return tree[in];
  }

  int mid = (s + e) / 2;
  // cout<<"Okay";
  return max(query(ql, qr, s, mid, 2 * in + 1),
             query(ql, qr, mid + 1, e, 2 * in + 2));
}
void update(ll s, ll e, ll in, ll key, ll up) {
  if (s > e)
    return;
  if (s == e && s == key) {
    tree[in] = up;
    return;
  } else if (s == e)
    return;
  ll mid = (s + e) / 2;

  if (mid >= key)
    update(s, mid, 2 * in + 1, key, up);
  else
    update(mid + 1, e, 2 * in + 2, key, up);
  tree[in] = max(tree[2 * in + 1], tree[2 * in + 2]);
}
int main() {
  ll n, k;
  cin >> n >> k;
  ll a[n];
  for (int i = 0; i < n; i++)
    cin >> a[i];
  ll ans = 1;
  for (int i = 0; i < n; i++) {
    ll curr = query(max(0ll, a[i] - k), min(300000ll, a[i] + k), 0, 300000, 0);
    // cout<<curr<<endl;
    ans = max(ans, curr + 1);
    update(0, 300000, 0, a[i], curr + 1);
  }
  cout << ans;
}


#include <bits/stdc++.h>

#include <algorithm>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
  int x = 0;
  while ((1U << x) < (unsigned int)(n))
    x++;
  return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
  unsigned long index;
  _BitScanForward(&index, n);
  return index;
#else
  return __builtin_ctz(n);
#endif
}

} // namespace internal

} // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
public:
  segtree() : segtree(0) {}
  segtree(int n) : segtree(std::vector<S>(n, e())) {}
  segtree(const std::vector<S> &v) : _n(int(v.size())) {
    log = internal::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;

  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

} // namespace atcoder

#define fi first
#define se second
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rrep(i, n) for (int i = 1; i <= (n); ++i)
#define drep(i, n) for (int i = (n)-1; i >= 0; --i)
#define srep(i, s, t) for (int i = s; i < t; ++i)
#define rng(a) a.begin(), a.end()
#define rrng(a) a.rbegin(), a.rend()
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
#define limit(x, l, r) max(l, min(x, r))
#define lims(x, l, r) (x = max(l, min(x, r)))
#define isin(x, l, r) ((l) <= (x) && (x) < (r))
#define pb push_back
#define eb emplace_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcountll
#define uni(x) x.erase(unique(rng(x)), x.end())
#define show(x) cout << #x << " = " << x << endl;
#define print(x) cout << x << endl;
#define PQ(T) priority_queue<T, v(T), greater<T>>
#define bn(x) ((1 << x) - 1)
#define dup(x, y) (((x) + (y)-1) / (y))
#define newline puts("")
#define v(T) vector<T>
#define vv(T) v(v(T))
using namespace std;
using namespace atcoder;
typedef long long int ll;
typedef unsigned uint;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<P> vp;
typedef vector<T> vt;

ll op(ll a, ll b) { return max(a, b); }

ll e() { return (ll)(0); }

int main() {
  ll n, k;
  cin >> n >> k;
  segtree<ll, op, e> t(603030);
  vl a(n);
  rep(i, n) cin >> a[i];
  ll ans = 0;
  rep(i, n) {
    ll l = max(0LL, a[i] - k), r = min(n, a[i] + k);
    ll x = t.prod(l, r + 1);
    t.set(a[i], x + 1);
    maxs(ans, x + 1);
  }
  print(ans);
  return 0;
}

#include <bits/stdc++.h>

#include <algorithm>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
  int x = 0;
  while ((1U << x) < (unsigned int)(n))
    x++;
  return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
  unsigned long index;
  _BitScanForward(&index, n);
  return index;
#else
  return __builtin_ctz(n);
#endif
}

} // namespace internal

} // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
public:
  segtree() : segtree(0) {}
  segtree(int n) : segtree(std::vector<S>(n, e())) {}
  segtree(const std::vector<S> &v) : _n(int(v.size())) {
    log = internal::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;

  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

} // namespace atcoder

#define fi first
#define se second
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rrep(i, n) for (int i = 1; i <= (n); ++i)
#define drep(i, n) for (int i = (n)-1; i >= 0; --i)
#define srep(i, s, t) for (int i = s; i < t; ++i)
#define rng(a) a.begin(), a.end()
#define rrng(a) a.rbegin(), a.rend()
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
#define limit(x, l, r) max(l, min(x, r))
#define lims(x, l, r) (x = max(l, min(x, r)))
#define isin(x, l, r) ((l) <= (x) && (x) < (r))
#define pb push_back
#define eb emplace_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcountll
#define uni(x) x.erase(unique(rng(x)), x.end())
#define show(x) cout << #x << " = " << x << endl;
#define print(x) cout << x << endl;
#define PQ(T) priority_queue<T, v(T), greater<T>>
#define bn(x) ((1 << x) - 1)
#define dup(x, y) (((x) + (y)-1) / (y))
#define newline puts("")
#define v(T) vector<T>
#define vv(T) v(v(T))
using namespace std;
using namespace atcoder;
typedef long long int ll;
typedef unsigned uint;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<P> vp;
typedef vector<T> vt;

ll op(ll a, ll b) { return max(a, b); }

ll e() { return (ll)(0); }

int main() {
  int n;
  ll k;
  cin >> n >> k;
  segtree<ll, op, e> t(603030);
  vl a(n);
  rep(i, n) cin >> a[i];
  ll ans = 0;
  rep(i, n) {
    ll l = max(0LL, a[i] - k), r = a[i] + k;
    ll x = t.prod(l, r + 1);
    t.set(a[i], x + 1);
    maxs(ans, x + 1);
  }
  cout << ans << endl;
  return 0;
}


/*/ Author: KaySeeKay /*/

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

/*/---------------------------Defines-----------------------------------------/*/

#pragma GCC optimize("Ofast")
#define int long long
#define IOS                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);
#define pb push_back
#define eb emplace_back
#define fn for (int i = 0; i < n; i++)
#define fn1 for (int i = 1; i <= n; i++)
#define fm for (int j = 0; j < m; j++)
#define fm1 for (int j = 1; j <= m; j++)
#define fi first
#define se second
#define endl '\\n'
#define PI 3.14159265358979323846
#define MOD 1000000007
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
const int N = 3e5 + 5;
const int INF = 1e18L;
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
/*/-----------------------------Debug
 * begins----------------------------------/*/
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c))
    v.emplace_back(x);
  return move(v);
}
template <typename T, typename... Args> inline string arrStr(T arr, int n) {
  stringstream s;
  s << "[";
  for (int i = 0; i < n - 1; i++)
    s << arr[i] << ",";
  if (n > 0)
    s << arr[n - 1];
  s << "]";
  return s.str();
}
#define trace(args...)                                                         \\
  {                                                                            \\
    __trace_begin(__LINE__);                                                   \\
    __trace(split(#args, ',').begin(), args);                                  \\
  }
inline void __trace_begin(int line) { cerr << "#" << line << ": "; }
template <typename T> inline void __trace_out_var(vector<T> val) {
  cerr << arrStr(val, val.size());
}
template <typename T> inline void __trace_out_var(T *val) {
  cerr << arrStr(val, 10);
}
template <typename T> inline void __trace_out_var(T val) { cerr << val; }
inline void __trace(vector<string>::iterator it) { cerr << endl; }

template <typename T, typename... Args>
inline void __trace(vector<string>::iterator it, T a, Args... args) {
  cerr << it->substr((*it)[0] == ' ', it->length()) << "=";
  __trace_out_var(a);
  cerr << "; ";
  __trace(++it, args...);
}
/*/-----------------------------Code begins----------------------------------/*/
int ar[N];
int dp[N];
int tree[2 * N];
void update(int pos, int v, int l, int r, int tn) {
  if (l == r && l == pos) {
    tree[tn] = v;
    return;
  }
  int mid = (l + r) / 2;
  if (pos >= l && pos <= mid)
    update(pos, v, l, mid, tn * 2 + 1);
  else if (pos > mid && pos <= r)
    update(pos, v, mid + 1, r, 2 * tn + 2);
  tree[tn] = max(tree[tn * 2 + 1], tree[tn * 2 + 2]);
}
int qry(int l, int r, int ql, int qr, int tn) {
  if (l > qr || r < ql)
    return -1;
  if (l >= ql && r <= qr)
    return tree[tn];
  int mid = (l + r) / 2;
  return max(qry(l, mid, ql, qr, tn * 2 + 1),
             qry(mid + 1, r, ql, qr, 2 * tn + 2));
}
signed main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  IOS;
  int T = 1;
  // cin >> T;
  while (T--) {
    int n;
    cin >> n;
    int k;
    cin >> k;
    int ans = 0;
    fn {
      cin >> ar[i];
      int l = max(0ll, ar[i] - k);
      int r = ar[i] + k;
      int x = qry(l, r, 1, N, 0);
      ans = max(ans, x);
      update(ar[i], x + 1, 1, N, 0);
    }
    cout << ans << '\\n';
  }
  return 0;
}

/*/ Author: KaySeeKay /*/

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

/*/---------------------------Defines-----------------------------------------/*/

#pragma GCC optimize("Ofast")
#define int long long
#define IOS                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);
#define pb push_back
#define eb emplace_back
#define fn for (int i = 0; i < n; i++)
#define fn1 for (int i = 1; i <= n; i++)
#define fm for (int j = 0; j < m; j++)
#define fm1 for (int j = 1; j <= m; j++)
#define fi first
#define se second
#define endl '\\n'
#define PI 3.14159265358979323846
#define MOD 1000000007
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
const int N = 3e5 + 5;
const int INF = 1e18L;
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
/*/-----------------------------Debug
 * begins----------------------------------/*/
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c))
    v.emplace_back(x);
  return move(v);
}
template <typename T, typename... Args> inline string arrStr(T arr, int n) {
  stringstream s;
  s << "[";
  for (int i = 0; i < n - 1; i++)
    s << arr[i] << ",";
  if (n > 0)
    s << arr[n - 1];
  s << "]";
  return s.str();
}
#define trace(args...)                                                         \\
  {                                                                            \\
    __trace_begin(__LINE__);                                                   \\
    __trace(split(#args, ',').begin(), args);                                  \\
  }
inline void __trace_begin(int line) { cerr << "#" << line << ": "; }
template <typename T> inline void __trace_out_var(vector<T> val) {
  cerr << arrStr(val, val.size());
}
template <typename T> inline void __trace_out_var(T *val) {
  cerr << arrStr(val, 10);
}
template <typename T> inline void __trace_out_var(T val) { cerr << val; }
inline void __trace(vector<string>::iterator it) { cerr << endl; }

template <typename T, typename... Args>
inline void __trace(vector<string>::iterator it, T a, Args... args) {
  cerr << it->substr((*it)[0] == ' ', it->length()) << "=";
  __trace_out_var(a);
  cerr << "; ";
  __trace(++it, args...);
}
/*/-----------------------------Code begins----------------------------------/*/
int ar[N];
int dp[N];
int tree[4 * N];
void update(int pos, int v, int l, int r, int tn) {
  if (l == r && l == pos) {
    tree[tn] = v;
    return;
  }
  int mid = (l + r) / 2;
  if (pos >= l && pos <= mid)
    update(pos, v, l, mid, tn * 2 + 1);
  else if (pos > mid && pos <= r)
    update(pos, v, mid + 1, r, 2 * tn + 2);
  tree[tn] = max(tree[tn * 2 + 1], tree[tn * 2 + 2]);
}
int qry(int l, int r, int ql, int qr, int tn) {
  if (l > qr || r < ql)
    return INT_MIN;
  if (l >= ql && r <= qr)
    return tree[tn];
  int mid = (l + r) / 2;
  return max(qry(l, mid, ql, qr, tn * 2 + 1),
             qry(mid + 1, r, ql, qr, 2 * tn + 2));
}
signed main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  IOS;
  int T = 1;
  // cin >> T;
  while (T--) {
    int n;
    cin >> n;
    int k;
    cin >> k;
    int ans = 1;
    fn {
      int y;
      cin >> y;
      int l = max(0ll, y - k);
      int r = min(N, y + k);
      int x = qry(0, N, l, r, 0);
      ans = max(ans, 1 + x);
      update(y, x + 1, 0, N, 0);
    }
    cout << ans << '\\n';
  }
  return 0;
}


#include <bits/stdc++.h>
#define NMAX 300005
using namespace std;
typedef long long ll;
ll segmTree[NMAX * 4], l[NMAX * 4], r[NMAX * 4], leaves[NMAX];
void init(size_t nd) {
  if (nd == 0)
    l[0] = 0, r[0] = NMAX - 1;
  else {
    if (nd & 1)
      l[nd] = l[nd / 2], r[nd] = (l[nd / 2] + r[nd / 2]) / 2;
    else
      l[nd] = r[nd - 1] + 1, r[nd] = r[nd / 2 - 1];
  }
  if (l[nd] == r[nd])
    leaves[l[nd]] = nd;
  else {
    init(nd * 2 + 1);
    init(nd * 2 + 2);
  }
}
void upd(ll p, ll x) {
  ll nd = leaves[p];
  if (segmTree[nd] >= x)
    return;
  segmTree[nd] = x;
  do {
    nd = (nd - 1) / 2;
    segmTree[nd] = max(segmTree[nd * 2 + 1], segmTree[nd * 2 + 2]);
  } while (nd > 0);
}
ll query(ll L, ll R) {
  ll ans = 0;
  while (L <= R) {
    ll nd = leaves[L];
    while (nd > 0 && l[(nd - 1) / 2] >= L && r[(nd - 1) / 2] <= R)
      nd = (nd - 1) / 2;
    ans = max(ans, segmTree[nd]);
    L = r[nd] + 1;
  }
  return ans;
}
ll dp[NMAX], v[NMAX];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  init(0);
  ll n, k, ans = 0;
  cin >> n >> k;
  for (ll i = 0; i < n; i++)
    cin >> v[i];
  for (ll i = n - 1; i >= 0; i--) {
    dp[i] = query(max(0ll, v[i] - k), v[i] + k) + 1;
    upd(v[i], dp[i]);
    ans = max(ans, dp[i]);
  }
  cout << ans;
  return 0;
}

#include <bits/stdc++.h>
#define NMAX 300005
using namespace std;
typedef long long ll;
ll segmTree[NMAX * 4], l[NMAX * 4], r[NMAX * 4], leaves[NMAX];
void init(size_t nd) {
  if (nd == 0)
    l[0] = 0, r[0] = NMAX - 1;
  else {
    if (nd & 1)
      l[nd] = l[nd / 2], r[nd] = (l[nd / 2] + r[nd / 2]) / 2;
    else
      l[nd] = r[nd - 1] + 1, r[nd] = r[nd / 2 - 1];
  }
  if (l[nd] == r[nd])
    leaves[l[nd]] = nd;
  else {
    init(nd * 2 + 1);
    init(nd * 2 + 2);
  }
}
void upd(ll p, ll x) {
  ll nd = leaves[p];
  if (segmTree[nd] >= x)
    return;
  segmTree[nd] = x;
  do {
    nd = (nd - 1) / 2;
    segmTree[nd] = max(segmTree[nd * 2 + 1], segmTree[nd * 2 + 2]);
  } while (nd > 0);
}
ll query(ll L, ll R) {
  ll ans = 0;
  while (L <= R) {
    ll nd = leaves[L];
    while (nd > 0 && l[(nd - 1) / 2] >= L && r[(nd - 1) / 2] <= R)
      nd = (nd - 1) / 2;
    ans = max(ans, segmTree[nd]);
    L = r[nd] + 1;
  }
  return ans;
}
ll dp[NMAX], v[NMAX];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  init(0);
  ll n, k, ans = 0;
  cin >> n >> k;
  for (ll i = 0; i < n; i++)
    cin >> v[i];
  for (ll i = n - 1; i >= 0; i--) {
    dp[i] = query(max(0ll, v[i] - k), min((ll)NMAX - 1, v[i] + k)) + 1;
    upd(v[i], dp[i]);
    ans = max(ans, dp[i]);
  }
  cout << ans;
  return 0;
}


/*
このコード、と～おれ!
Be accepted!
∧＿∧
（｡･ω･｡)つ━☆・*。
⊂　　 ノ 　　　・゜+.
　しーＪ　　　°。+ *´¨)
 　　　　　　　　　.· ´¸.·*´¨) ¸.·*¨)
                  　　　　　　　　　　(¸.·´ (¸.·'* ☆
*/

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

////多倍長整数, cpp_intで宣言
// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;
//
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("Ofast")
// #pragma GCC optimization ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define repeat(i, n, m) for (int i = n; i < (m); ++i)
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define printynl(a) printf(a ? "yes\\n" : "no\\n")
#define printyn(a) printf(a ? "Yes\\n" : "No\\n")
#define printYN(a) printf(a ? "YES\\n" : "NO\\n")
#define printim(a) printf(a ? "possible\\n" : "imposible\\n")
#define printdb(a) printf("%.50lf\\n", a)    // 少数出力
#define printLdb(a) printf("%.50Lf\\n", a)   // 少数出力
#define printdbd(a) printf("%.16lf\\n", a)   // 少数出力(桁少なめ)
#define prints(s) printf("%s\\n", s.c_str()) // string出力
#define all(x) (x).begin(), (x).end()
#define deg_to_rad(deg) (((deg) / 360.0L) * 2.0L * PI)
#define rad_to_deg(rad) (((rad) / 2.0L / PI) * 360.0L)
#define Please return
#define AC 0
#define manhattan_dist(a, b, c, d)                                             \\
  (abs(a - c) + abs(b - d)) /*(a, b) から (c, d) のマンハッタン距離 */
#define inf numeric_limits<double>::infinity();
#define linf numeric_limits<long double>::infinity()

using ll = long long;
using ull = unsigned long long;

constexpr int INF = 1073741823;
constexpr int MINF = -1073741823;
constexpr ll LINF = ll(4661686018427387903);
constexpr ll MOD = 1e9 + 7;
constexpr ll mod = 998244353;
constexpr long double eps = 1e-6;
const long double PI = acosl(-1.0L);

using namespace std;

void scans(string &str) {
  char c;
  str = "";
  scanf("%c", &c);
  if (c == '\\n')
    scanf("%c", &c);
  while (c != '\\n' && c != -1 && c != ' ') {
    str += c;
    scanf("%c", &c);
  }
}

void scanc(char &str) {
  char c;
  scanf("%c", &c);
  if (c == -1)
    return;
  while (c == '\\n') {
    scanf("%c", &c);
  }
  str = c;
}

double acot(double x) { return PI / 2 - atan(x); }

ll LSB(ll n) { return (n & (-n)); }

template <typename T> inline T chmin(T &a, const T &b) {
  if (a > b)
    a = b;
  return a;
}

template <typename T> inline T chmax(T &a, const T &b) {
  if (a < b)
    a = b;
  return a;
}

////atcoder library
// #include <atcoder/all>
// using namespace atcoder;

/*-----------------------------------------ここからコード-----------------------------------------*/

int main() {

  int n, k;
  scanf("%d%d", &n, &k);
  vector<int> a(n);
  rep(i, n) { scanf("%d", &a[i]); }
  vector<int> dp(n);
  fill(all(dp), -1);
  dp[0] = 0;
  int ans = 0;
  rep(i, n) {
    for (int j = i + 1; j < n; ++j) {
      if (dp[j] > dp[i] + 1)
        break;
      if (abs(a[j] - a[i]) <= k)
        chmax(dp[j], dp[i] + 1);
    }
  }
  printf("%d\\n", dp[n - 1] + 1);

  Please AC;
}

/*
このコード、と～おれ!
Be accepted!
∧＿∧
（｡･ω･｡)つ━☆・*。
⊂　　 ノ 　　　・゜+.
　しーＪ　　　°。+ *´¨)
 　　　　　　　　　.· ´¸.·*´¨) ¸.·*¨)
                  　　　　　　　　　　(¸.·´ (¸.·'* ☆
*/

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

////多倍長整数, cpp_intで宣言
// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;
//
#pragma GCC target("avx2")
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define repeat(i, n, m) for (int i = n; i < (m); ++i)
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define printynl(a) printf(a ? "yes\\n" : "no\\n")
#define printyn(a) printf(a ? "Yes\\n" : "No\\n")
#define printYN(a) printf(a ? "YES\\n" : "NO\\n")
#define printim(a) printf(a ? "possible\\n" : "imposible\\n")
#define printdb(a) printf("%.50lf\\n", a)    // 少数出力
#define printLdb(a) printf("%.50Lf\\n", a)   // 少数出力
#define printdbd(a) printf("%.16lf\\n", a)   // 少数出力(桁少なめ)
#define prints(s) printf("%s\\n", s.c_str()) // string出力
#define all(x) (x).begin(), (x).end()
#define deg_to_rad(deg) (((deg) / 360.0L) * 2.0L * PI)
#define rad_to_deg(rad) (((rad) / 2.0L / PI) * 360.0L)
#define Please return
#define AC 0
#define manhattan_dist(a, b, c, d)                                             \\
  (abs(a - c) + abs(b - d)) /*(a, b) から (c, d) のマンハッタン距離 */
#define inf numeric_limits<double>::infinity();
#define linf numeric_limits<long double>::infinity()

using ll = long long;
using ull = unsigned long long;

constexpr int INF = 1073741823;
constexpr int MINF = -1073741823;
constexpr ll LINF = ll(4661686018427387903);
constexpr ll MOD = 1e9 + 7;
constexpr ll mod = 998244353;
constexpr long double eps = 1e-6;
const long double PI = acosl(-1.0L);

using namespace std;

void scans(string &str) {
  char c;
  str = "";
  scanf("%c", &c);
  if (c == '\\n')
    scanf("%c", &c);
  while (c != '\\n' && c != -1 && c != ' ') {
    str += c;
    scanf("%c", &c);
  }
}

void scanc(char &str) {
  char c;
  scanf("%c", &c);
  if (c == -1)
    return;
  while (c == '\\n') {
    scanf("%c", &c);
  }
  str = c;
}

double acot(double x) { return PI / 2 - atan(x); }

ll LSB(ll n) { return (n & (-n)); }

template <typename T> inline T chmin(T &a, const T &b) {
  if (a > b)
    a = b;
  return a;
}

template <typename T> inline T chmax(T &a, const T &b) {
  if (a < b)
    a = b;
  return a;
}

////atcoder library
// #include <atcoder/all>
// using namespace atcoder;

/*-----------------------------------------ここからコード-----------------------------------------*/

/*
 * @title segment-tree
 * @docs kyopro/docs/segtree.md
 */

// セグ木/0-indexed/非再帰/(大きさ, 単位元)で初期化
template <typename T, typename F> struct segtree {
  // 木を配列であらわしたもの
  vector<T> seg;
  // 木の1/2の大きさ
  int siz;
  // 単位元
  const T e;
  ////比較関数の型
  // using F = function<T(T, T)>;
  // マージする関数
  const F f;

  // n の大きさ, a (単位元) で segtree を初期化する
  segtree(int n, const T a, const F f) : e(a), f(f) {
    siz = 1;
    while (siz < n)
      siz <<= 1;
    seg.assign(2 * siz - 1, e);
    --siz;
  }

  // k (0-indexed) 番目に t を代入
  void set(int k, const T &t) { seg[k + siz] = t; }

  // f によって木を構築
  void build() {
    for (int i = siz - 1; i >= 0; --i)
      seg[i] = f(seg[i * 2 + 1], seg[i * 2 + 2]);
  }

  // i 番目の要素を返す
  T operator[](const int i) { return seg[i + siz]; }

  // k 番目の値を a に更新
  void update(int k, T a) {
    k += siz;
    // 必要であればここを変える
    seg[k] = a;
    while (k > 0) {
      k = ((k - 1) >> 1);
      seg[k] = f(seg[k * 2 + 1], seg[k * 2 + 2]);
    }
  }

  //[a, b) について f した結果を返す
  T query(int a, int b) {
    T l = e, r = e;
    for (a += siz, b += siz; a < b; a >>= 1, b >>= 1) {
      if (!(a & 1))
        l = f(l, seg[a++]);
      if (!(b & 1))
        r = f(seg[--b], r);
    }
    return f(l, r);
  }

  //[start, end) について、[l, r) を調べながら k 番目が check を満たすか二分探索
  //最後が true なら left, false なら right fの逆演算
  template <typename C, typename FT>
  int find(const int start, const int end, int l, int r, int k, const C check,
           T &checknum, const bool b, const FT revf) {
    // cerr << checknum << '\\n';
    // 範囲外またはそこがすでに満たさないとき
    // cerr << k << ',' << checknum << '\\n';
    if (start <= l && r <= end && !check(seg[k], checknum)) {
      checknum = revf(checknum, seg[k]);
      return -1;
    }
    if ((r <= start || l >= end)) {
      return -1;
    }
    // 既に葉
    if (k >= siz) {
      return k - siz;
    }
    int res;
    if (b) {
      // 左側を調べる
      res = find<C, FT>(start, end, l, ((l + r) >> 1), (k << 1) + 1, check,
                        checknum, b, revf);
      // 左側が適してたらそれが答え
      if (res != -1)
        return (res);
      return find<C, FT>(start, end, ((l + r) >> 1), r, (k << 1) + 2, check,
                         checknum, b, revf);
    } else {
      // 右側を調べる
      res = find<C, FT>(start, end, ((l + r) >> 1), r, (k << 1) + 2, check,
                        checknum, b, revf);
      // 右側が適してたらそれが答え
      if (res != -1)
        return (res);
      return find<C, FT>(start, end, l, ((l + r) >> 1), (k << 1) + 1, check,
                         checknum, b, revf);
    }
  }

  template <typename C, typename FT>
  int find_left(int start, int end, const C check, T checknum, FT revf) {
    return find<C, FT>(start, end, 0, siz + 1, 0, check, checknum, true, revf);
  }

  template <typename C, typename FT>
  int find_right(int start, int end, const C check, T checknum, FT revf) {
    return find<C, FT>(start, end, 0, siz + 1, 0, check, checknum, false, revf);
  }
};

int main() {

  int n, k;
  scanf("%d%d", &n, &k);
  auto f = [](int a, int b) { return max(a, b); };
  segtree<int, decltype(f)> seg(300001, 0, f);
  seg.build();
  int ans = 1, a;
  rep(i, n) {
    scanf("%d", &a);
    int tmp = seg.query(max(0, a - k), min(a + k + 1, 300001)) + 1;
    chmax(ans, tmp);
    seg.update(a, tmp);
  }
  printf("%d\\n", ans);

  Please AC;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define _IO                                                                    \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
const ll N = 3e5 + 5, mod = 1e9 + 7, inf = 1e18;
struct node {
  ll l, r;
  ll val;
} tr[N * 4];
ll n, k;

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

void build(ll u, ll l, ll r) {

  if (l == r) {
    tr[u] = {l, r, 0};
  } else {

    tr[u] = {l, r};
    ll mid = l + r << 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);
  }
}

void modify(ll u, ll x, ll v) {

  if (tr[u].l > x || tr[u].r < x)
    return;
  if (tr[u].l == tr[u].r) {
    tr[u].val = max(tr[u].val, v);
  } else {

    ll mid = tr[u].l + tr[u].r >> 1;
    // ll mid = (tr[u].l+tr[u].r)/2;
    modify(u << 1, x, v);
    modify(u << 1 | 1, x, v);
    pushup(u);
  }
}

ll query(ll u, ll l, ll r) {

  if (tr[u].l > r || tr[u].r < l)
    return -inf;
  if (tr[u].l >= l && tr[u].r <= r)
    return tr[u].val;
  else {
    ll mid = (tr[u].l + tr[u].r) / 2;
    ll ans = -inf;
    if (l <= mid)
      ans = max(ans, query(u << 1, l, r));
    if (r > mid)
      ans = max(ans, query(u << 1 | 1, l, r));
    return ans;
  }
}

int main() {
  _IO;
  ll n, k;
  cin >> n >> k;
  build(1, 0, n);

  ll mx = 0;
  while (n--) {
    ll x;
    cin >> x;
    ll p = query(1, max(0LL, x - k), min(N, x + k));
    modify(1, x, p + 1);
    mx = max(mx, p + 1);
  }
  cout << mx << "\\n";

  return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define _IO                                                                    \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
const ll N = 3e5 + 5, mod = 1e9 + 7, inf = 1e18;
struct node {

  ll l, r;
  ll val;
} tr[N * 4];
ll n, k;

void pushup(ll u) { tr[u].val = max(tr[u * 2].val, tr[u * 2 + 1].val); }

void build(ll u, ll l, ll r) {

  if (l == r) {
    tr[u] = {l, r, 0};
  } else {

    tr[u] = {l, r};
    ll mid = (l + r) / 2;
    build(u * 2, l, mid);
    build(u * 2 + 1, mid + 1, r);
    pushup(u);
  }
}

void modify(ll u, ll x, ll v) {

  if (tr[u].l > x || tr[u].r < x)
    return;
  if (tr[u].l == tr[u].r) {
    tr[u].val = max(tr[u].val, v);
    return;
  } else {

    // ll mid = tr[u].l+tr[u].r>>1;
    ll mid = (tr[u].l + tr[u].r) / 2;
    modify(u * 2, x, v);
    modify(u * 2 + 1, x, v);
    pushup(u);
  }
}

ll query(ll u, ll l, ll r) {

  if (tr[u].l > r || tr[u].r < l)
    return -inf;
  if (tr[u].l >= l && tr[u].r <= r)
    return tr[u].val;
  else {
    ll mid = (tr[u].l + tr[u].r) / 2;
    return max(query(u * 2, l, r), query(u * 2 + 1, l, r));
  }
}

int main() {
  _IO;
  ll n, k;
  cin >> n >> k;
  build(1, 0, N);

  ll mx = 0;
  while (n--) {
    ll x;
    cin >> x;
    ll p = query(1, max(0LL, x - k), min(N, x + k));
    modify(1, x, p + 1);
    mx = max(mx, p + 1);
  }
  cout << mx;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ft                                                                     \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
const int N = 3e5 + 1;
int tr[3 * N];
int Q(int node, int s, int e, int i, int j) {
  if (i > e || j < s) {
    return 0;
  } else if (i <= s && e <= j) {
    return tr[node];
  }
  int l = node * 2;
  int r = l + 1;
  int m = (s + e) / 2;
  int p = Q(l, s, m, i, j);
  int q = Q(r, m + 1, e, i, j);
  return max(p, q);
}
void up(int node, int s, int e, int i, int v) {
  if (i > e || i < s) {
    return;
  } else if (s == e && i == s) {
    tr[node] = v;
    return;
  }
  int l = node * 2;
  int r = l + 1;
  int m = (s + e) / 2;
  up(l, s, m, i, v);
  up(r, m + 1, e, i, v);
  tr[node] = max(tr[l], tr[r]);
}
int main() {
  ft int t, i, j, n, m, l, r, ans = -1;
  cin >> n >> m;
  for (i = 0; i < n; i++) {
    cin >> l;
    r = Q(1, 1, N - 1, max(0, l - m), min(N - 1, l + m));
    up(1, 1, N - 1, l, r + 1);
    ans = max(ans, r + 1);
  }
  cout << ans << "\\n";
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ft                                                                     \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
const int N = 3e5;
int tr[4 * N];
int Q(int node, int s, int e, int i, int j) {
  if (i > e || j < s) {
    return 0;
  } else if (i <= s && e <= j) {
    return tr[node];
  }
  int l = node * 2;
  int r = l + 1;
  int m = (s + e) / 2;
  int p = Q(l, s, m, i, j);
  int q = Q(r, m + 1, e, i, j);
  return max(p, q);
}
void up(int node, int s, int e, int i, int v) {
  if (i > e || i < s) {
    return;
  } else if (s == e && i == s) {
    tr[node] = v;
    return;
  }
  int l = node * 2;
  int r = l + 1;
  int m = (s + e) / 2;
  up(l, s, m, i, v);
  up(r, m + 1, e, i, v);
  tr[node] = max(tr[l], tr[r]);
}
int main() {
  ft int t, i, j, n, m, l, r, ans = -1;
  cin >> n >> m;
  for (i = 0; i < n; i++) {
    cin >> l;
    r = Q(1, 0, N, max(0, l - m), min(N, l + m));
    up(1, 0, N, l, r + 1);
    ans = max(ans, r + 1);
  }
  cout << ans << "\\n";
  return 0;
}


#include <bits/stdc++.h>
#define ll long long
const int md = 998244353;
#define fast                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
/* VECTORS */
#define pb push_back
#define g(v, i, j) get<i>(v[j])
#define co(v, x) count(v.begin(), v.end(), x)
#define mxe(v) *max_element(v.begin(), v.end())
#define mne(v) *min_element(v.begin(), v.end())
#define vi vector<int>
#define vll vector<ll>
#define srt(v) sort(v.begin(), v.end())
#define rsrt(v) sort(v.begin(), v.end(), greater<int>())
/* INPUT/OUTPUT*/
#define pr printf
#define sc scanf
#define pi(a) printf("%d\\n", a)
#define pll(a) printf("%lld\\n", a)
#define si(a) scanf("%d", &a)
#define sll(a) scanf("%lld", &a)
/* LOOPS*/
#define fi(i, a, b) for (int i = a; i < b; i++)
#define fll(i, a, b) for (ll i = a; i < b; i++)
using namespace std;
using namespace std::chrono;
ll pw(ll a, ll b) {
  ll c = 1, m = a;
  while (b) {
    if (b & 1)
      c = (c * m);
    m = (m * m);
    b /= 2;
  }
  return c;
}
ll pwmd(ll a, ll b) {
  ll c = 1, m = a;
  while (b) {
    if (b & 1)
      c = (c * m) % md;
    m = (m * m) % md;
    b /= 2;
  }
  return c;
}
ll modinv(ll n) { return pwmd(n, md - 2); }
ll inverse(ll i) {
  if (i == 1)
    return 1;
  return (md - ((md / i) * inverse(md % i)) % md + md) % md;
}
ll ceel(ll a, ll b) {
  if (a % b == 0)
    return a / b;
  else
    return a / b + 1;
}
ll my_log(ll n, ll b) {
  ll i = 1;
  ll ans = 0;
  while (1) {
    if (i > n) {
      ans--;
      break;
    }
    if (i == n)
      break;
    i *= b;
    ans++;
  }
  return ans;
}
bool sortbysec(const pair<ll, ll> &a, const pair<ll, ll> &b) {
  return (a.second < b.second);
}
/* auto start = high_resolution_clock::now();
 auto stop = high_resolution_clock::now();
 auto duration = duration_cast<microseconds>(stop - start);
 cerr << "Time taken: "
      << duration.count()<< "ms" <<"\\n";*/
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
vector<char> capl = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                     'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
                     'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
vector<char> sml = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
                    'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
                    's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
string conv(ll a) {
  string b;
  ll e = 2;
  ll c = my_log(a, e);
  c++;
  b = '1';
  for (int i = 0; i < c - 1; i++) {
    ll k = a >> (c - 2 - i);
    if (k & 1)
      b += '1';
    else
      b += '0';
  }
  if (a == 0)
    return "0";
  return b;
}
ll mysqt(ll a) {
  ll ans = 1;
  while (ans * ans <= a)
    ans++;
  ans--;
  return ans;
}
bool isprime(int p) {
  int i = 2;
  while (i <= sqrt(p)) {
    if (p % i == 0) {
      return false;
    }
    i++;
  }
  return true;
}
int main() {
  fast;
  int n, a, k;
  cin >> n >> k;
  vi v;
  v.pb(0);
  fi(i, 0, n) cin >> a, v.pb(a);
  int dp[n + 1];
  fi(i, 0, n + 1) dp[i] = 1;
  dp[1] = 1;
  fi(i, 2, n + 1) {
    for (int j = i - 1; j >= 1; j--) {
      if (abs(v[i] - v[j]) <= k) {
        dp[i] = max(dp[i], dp[j] + 1);
      }
    }
  }
  int mx = 1;
  fi(i, 1, n + 1) mx = max(mx, dp[i]);
  cout << mx;
}

#include <bits/stdc++.h>
#define ll long long
const int md = 998244353;
#define fast                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
/* VECTORS */
#define pb push_back
#define g(v, i, j) get<i>(v[j])
#define co(v, x) count(v.begin(), v.end(), x)
#define mxe(v) *max_element(v.begin(), v.end())
#define mne(v) *min_element(v.begin(), v.end())
#define vi vector<int>
#define vll vector<ll>
#define srt(v) sort(v.begin(), v.end())
#define rsrt(v) sort(v.begin(), v.end(), greater<int>())
/* INPUT/OUTPUT*/
#define pr printf
#define sc scanf
#define pi(a) printf("%d\\n", a)
#define pll(a) printf("%lld\\n", a)
#define si(a) scanf("%d", &a)
#define sll(a) scanf("%lld", &a)
/* LOOPS*/
#define fi(i, a, b) for (int i = a; i < b; i++)
#define fll(i, a, b) for (ll i = a; i < b; i++)
using namespace std;
using namespace std::chrono;
ll pw(ll a, ll b) {
  ll c = 1, m = a;
  while (b) {
    if (b & 1)
      c = (c * m);
    m = (m * m);
    b /= 2;
  }
  return c;
}
ll pwmd(ll a, ll b) {
  ll c = 1, m = a;
  while (b) {
    if (b & 1)
      c = (c * m) % md;
    m = (m * m) % md;
    b /= 2;
  }
  return c;
}
ll modinv(ll n) { return pwmd(n, md - 2); }
ll inverse(ll i) {
  if (i == 1)
    return 1;
  return (md - ((md / i) * inverse(md % i)) % md + md) % md;
}
ll ceel(ll a, ll b) {
  if (a % b == 0)
    return a / b;
  else
    return a / b + 1;
}
ll my_log(ll n, ll b) {
  ll i = 1;
  ll ans = 0;
  while (1) {
    if (i > n) {
      ans--;
      break;
    }
    if (i == n)
      break;
    i *= b;
    ans++;
  }
  return ans;
}
bool sortbysec(const pair<ll, ll> &a, const pair<ll, ll> &b) {
  return (a.second < b.second);
}
/* auto start = high_resolution_clock::now();
 auto stop = high_resolution_clock::now();
 auto duration = duration_cast<microseconds>(stop - start);
 cerr << "Time taken: "
      << duration.count()<< "ms" <<"\\n";*/
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
vector<char> capl = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                     'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
                     'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
vector<char> sml = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
                    'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
                    's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
string conv(ll a) {
  string b;
  ll e = 2;
  ll c = my_log(a, e);
  c++;
  b = '1';
  for (int i = 0; i < c - 1; i++) {
    ll k = a >> (c - 2 - i);
    if (k & 1)
      b += '1';
    else
      b += '0';
  }
  if (a == 0)
    return "0";
  return b;
}
ll mysqt(ll a) {
  ll ans = 1;
  while (ans * ans <= a)
    ans++;
  ans--;
  return ans;
}
bool isprime(int p) {
  int i = 2;
  while (i <= sqrt(p)) {
    if (p % i == 0) {
      return false;
    }
    i++;
  }
  return true;
}
int getMid(int s, int e) { return s + (e - s) / 2; }

/*  A recursive function to get the sum of
    values in given range of the array.
    The following are parameters for this
    function.

    st       -> Pointer to segment tree
    node     -> Index of current node in
                the segment tree .
    ss & se  -> Starting and ending indexes
                of the segment represented
                by current node, i.e., st[node]
    l & r    -> Starting and ending indexes
                of range query */
int MaxUtil(int *st, int ss, int se, int l, int r, int node) {
  // If segment of this node is completely
  // part of given range, then return
  // the max of segment
  if (l <= ss && r >= se)
    return st[node];

  // If segment of this node does not
  // belong to given range
  if (se < l || ss > r)
    return -1;

  // If segment of this node is partially
  // the part of given range
  int mid = getMid(ss, se);

  return max(MaxUtil(st, ss, mid, l, r, 2 * node + 1),
             MaxUtil(st, mid + 1, se, l, r, 2 * node + 2));
}

/* A recursive function to update the nodes which
   have the given index in their range. The following
   are parameters st, ss and se are same as defined
   above index -> index of the element to be updated.*/
void updateValue(int arr[], int *st, int ss, int se, int index, int value,
                 int node) {
  if (index < ss || index > se) {
    cout << "Invalid Input" << endl;
    return;
  }

  if (ss == se) {
    // update value in array and in segment tree
    arr[index] = value;
    st[node] = value;
  } else {
    int mid = getMid(ss, se);

    if (index >= ss && index <= mid)
      updateValue(arr, st, ss, mid, index, value, 2 * node + 1);
    else
      updateValue(arr, st, mid + 1, se, index, value, 2 * node + 2);

    st[node] = max(st[2 * node + 1], st[2 * node + 2]);
  }
  return;
}

// Return max of elements in range from
// index l (query start) to r (query end).
int getMax(int *st, int n, int l, int r) {
  // Check for erroneous input values
  if (l < 0 || r > n - 1 || l > r) {
    printf("Invalid Input");
    return -1;
  }

  return MaxUtil(st, 0, n - 1, l, r, 0);
}

// A recursive function that constructs Segment
// Tree for array[ss..se]. si is index of
// current node in segment tree st
int constructSTUtil(int arr[], int ss, int se, int *st, int si) {
  // If there is one element in array, store
  // it in current node of segment tree and return
  if (ss == se) {
    st[si] = arr[ss];
    return arr[ss];
  }

  // If there are more than one elements, then
  // recur for left and right subtrees and
  // store the max of values in this node
  int mid = getMid(ss, se);

  st[si] = max(constructSTUtil(arr, ss, mid, st, si * 2 + 1),
               constructSTUtil(arr, mid + 1, se, st, si * 2 + 2));

  return st[si];
}

/* Function to construct segment tree from given array.
   This function allocates memory for segment tree.*/
int *constructST(int arr[], int n) {
  // Height of segment tree
  int x = (int)(ceil(log2(n)));

  // Maximum size of segment tree
  int max_size = 2 * (int)pow(2, x) - 1;

  // Allocate memory
  int *st = new int[max_size];

  // Fill the allocated memory st
  constructSTUtil(arr, 0, n - 1, st, 0);

  // Return the constructed segment tree
  return st;
}

int main() {
  int p, k;
  cin >> p >> k;
  int v[p];
  int mm = 0;
  fi(i, 0, p) cin >> v[i], mm = max(mm, v[i]);
  int arr[mm + 1 + k];
  fi(i, 0, mm + 1 + k) arr[i] = 0;
  int n = sizeof(arr) / sizeof(arr[0]);
  int *st = constructST(arr, n);
  int dp[p];
  fi(i, 0, p) dp[i] = 1;
  dp[0] = 1;
  updateValue(arr, st, 0, n - 1, v[0], 1, 0);
  vi vis(mm + 1);
  vis[v[0]] = 1;
  fi(i, 1, p) {
    int q;
    if (vis[v[i]])
      q = getMax(st, n, max(0, v[i] - k), v[i] + k);
    else {
      q = getMax(st, n, max(0, v[i] - k), max(0, v[i] - 1));
      q = max(q, getMax(st, n, v[i] + 1, v[i] + k));
    }
    vis[v[i]] = 1;
    dp[i] = max(dp[i], q + 1);
    //  cout<<v[i]<<" "<<q<<" "<<dp[i]<<"\\n";
    updateValue(arr, st, 0, n - 1, v[i], dp[i], 0);
  }
  int mx = 0;
  fi(i, 0, p) mx = max(mx, dp[i]);
  cout << mx;
}


#include <bits/stdc++.h>

using ll = long long;
using namespace std;
const int INFint = 1e9 + 1;
const ll INFll = (ll)1e18 + 1;
ll MOD = 1e9 + 7;

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(0); i < N; i++) {
    for (int j(i + 1); j < i + 1000; j++) {
      if (abs(A[i] - A[j]) <= K) {
        dp[j] = max(dp[j], dp[i] + 1);
      }
    }
  }
  int ans(0);
  for (int i(0); i < N; i++) {
    ans = max(dp[i], ans);
  }
  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>

using ll = long long;
using namespace std;
const int INFint = 1e9 + 1;
const ll INFll = (ll)1e18 + 1;
ll MOD = 1e9 + 7;

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(0); i < N; i++) {
    for (int j(i + 1); j < min(i + 1000, N); j++) {
      if (abs(A[i] - A[j]) <= K) {
        dp[j] = max(dp[j], dp[i] + 1);
      }
    }
  }
  int ans(0);
  for (int i(0); i < N; i++) {
    ans = max(dp[i], ans);
  }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
int n, k;
int a[300005], dp[300005];
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
  }
  dp[1] = 1;
  for (int i = 1; i <= n; ++i) {
    int pos = 0;
    for (int j = i - 1; j >= 1; --j) {
      if (abs(a[i] - a[j]) <= k) {
        dp[i] = max(dp[i], dp[j] + 1);
      }
    }
  }
  int mx = 0;
  for (int i = 1; i <= n; ++i) {
    mx = max(mx, dp[i]);
  }
  printf("%d\\n", mx);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int T[N << 2], a[N], dp[N], n, k;

void change(int rt, int tl, int tr, int pos, int val) {
  if (tl == tr) {
    T[rt] = max(T[rt], val);
    return;
  }
  int mid = tl + tr >> 1;
  if (mid >= pos)
    change(2 * rt, tl, mid, pos, val);
  else
    change(2 * rt + 1, mid + 1, tr, pos, val);
  T[rt] = max(T[2 * rt], T[2 * rt + 1]);
}

int query(int rt, int ql, int qr, int tl, int tr) {
  if (tl >= ql && tr <= qr) {
    return T[rt];
  }
  int mid = tl + tr >> 1;
  int res = 0;
  if (mid >= ql)
    res = max(res, query(2 * rt, ql, qr, tl, mid));
  if (mid + 1 <= qr)
    res = max(res, query(2 * rt + 1, ql, qr, mid + 1, tr));
  return res;
}
int main() {
  cin >> n >> k;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
  }
  dp[1] = 1;
  int ans = 0;
  change(1, 0, N, a[1], dp[1]);
  for (int i = 2; i <= n; ++i) {
    dp[i] = query(1, max(0, a[i] - k), min(a[i] + k, N - 5), 0, N) + 1;
    change(1, 0, N, a[i], dp[i]);
    ans = max(ans, dp[i]);
  }
  cout << ans << '\\n';
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define dd double
#define endl "\\n"
#define pb push_back
#define all(v) v.begin(), v.end()
#define mp make_pair
#define fi first
#define se second
#define vll vector<ll>
#define pll pair<ll, ll>
#define fo(i, n) for (int i = 0; i < n; i++)
#define fo1(i, n) for (int i = 1; i <= n; i++)
ll mod = 1000000007;
ll n, k, t, m, q, flag = 0;
ll power(ll a, ll b) {
  ll res = 1;
  a %= mod;
  assert(b >= 0);
  for (; b; b >>= 1) {
    if (b & 1)
      res = res * a % mod;
    a = a * a % mod;
  }
  return res;
}
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less<int>,
// rb_tree_tag,tree_order_statistics_node_update> ordered_set s ;
// s.order_of_key(a) -- no. of elements strictly less than a s.find_by_order(i)
// -- itertor to ith element (0 indexed)
ll min(ll a, ll b) {
  if (a > b)
    return b;
  else
    return a;
}
ll max(ll a, ll b) {
  if (a > b)
    return a;
  else
    return b;
}
ll gcd(ll a, ll b) {
  if (b > a)
    return gcd(b, a);
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

ll tree[900001];
ll a[300000];
void update(ll mini, ll maxi, ll treeindex, ll index, ll val) {
  if (mini == maxi) {
    tree[treeindex] = val;
    return;
  }
  ll mid = (mini + maxi) / 2;
  if (mid >= index) {
    update(mini, mid, 2 * treeindex, index, val);
  } else
    update(mid + 1, maxi, 2 * treeindex + 1, index, val);
  tree[treeindex] = max(tree[treeindex * 2], tree[2 * treeindex + 1]);
}

ll maxval(ll mini, ll maxi, ll l, ll r, ll index) {
  if (l > r)
    return 0;
  if (l == mini && r == maxi) {
    return tree[index];
  }
  ll mid = (mini + maxi) / 2;
  return max(maxval(mini, mid, l, min(r, mid), 2 * index),
             maxval(mid + 1, maxi, max(l, mid + 1), r, 2 * index + 1));
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
#ifdef NOOBxCODER
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#else
#define NOOBxCODER 0
#endif
  // cin>>t;
  t = 1;
  while (t--) {
    cin >> n;
    cin >> k;
    fo(i, n) cin >> a[i];
    // fo(i,300001)node[i]=0;
    fo(i, 900001) tree[i] = 0;
    ll ans;
    fo(i, n) {
      ll val =
          maxval(0, 300000, max(0, a[i] - k), min(300000, a[i] + k), 1) + 1;
      update(0, 300000, 1, a[i], val);
    }
    cout << tree[1];
  }
  cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC
       << "ms\\n";
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define dd double
#define endl "\\n"
#define pb push_back
#define all(v) v.begin(), v.end()
#define mp make_pair
#define fi first
#define se second
#define vll vector<ll>
#define pll pair<ll, ll>
#define fo(i, n) for (int i = 0; i < n; i++)
#define fo1(i, n) for (int i = 1; i <= n; i++)
ll mod = 1000000007;
ll n, k, t, m, q, flag = 0;
ll power(ll a, ll b) {
  ll res = 1;
  a %= mod;
  assert(b >= 0);
  for (; b; b >>= 1) {
    if (b & 1)
      res = res * a % mod;
    a = a * a % mod;
  }
  return res;
}
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less<int>,
// rb_tree_tag,tree_order_statistics_node_update> ordered_set s ;
// s.order_of_key(a) -- no. of elements strictly less than a s.find_by_order(i)
// -- itertor to ith element (0 indexed)
ll min(ll a, ll b) {
  if (a > b)
    return b;
  else
    return a;
}
ll max(ll a, ll b) {
  if (a > b)
    return a;
  else
    return b;
}
ll gcd(ll a, ll b) {
  if (b > a)
    return gcd(b, a);
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

ll tree[1200001];
ll a[300001];
void update(ll mini, ll maxi, ll treeindex, ll index, ll val) {
  if (mini == maxi) {
    tree[treeindex] = val;
    return;
  }
  ll mid = (mini + maxi) / 2;
  if (mid >= index) {
    update(mini, mid, 2 * treeindex, index, val);
  } else
    update(mid + 1, maxi, 2 * treeindex + 1, index, val);
  tree[treeindex] = max(tree[treeindex * 2], tree[2 * treeindex + 1]);
}

ll maxval(ll mini, ll maxi, ll l, ll r, ll index) {
  if (l > r)
    return 0;
  if (l == mini && r == maxi) {
    return tree[index];
  }
  ll mid = (mini + maxi) / 2;
  return max(maxval(mini, mid, l, min(r, mid), 2 * index),
             maxval(mid + 1, maxi, max(l, mid + 1), r, 2 * index + 1));
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
#ifdef NOOBxCODER
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#else
#define NOOBxCODER 0
#endif
  // cin>>t;
  t = 1;
  while (t--) {
    cin >> n;
    cin >> k;
    fo(i, n) cin >> a[i];
    // fo(i,300001)node[i]=0;
    fo(i, 1200001) tree[i] = 0;
    ll ans;
    fo(i, n) {
      ll val =
          maxval(0, 300000, max(0, a[i] - k), min(300000, a[i] + k), 1) + 1;
      update(0, 300000, 1, a[i], val);
    }
    cout << tree[1];
  }
  cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC
       << "ms\\n";
  return 0;
}