// Coded by Abhijay Mitra
#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <vector>
// #include <bits/stdc++.h>
#define double long double
#define int long long int
#define ll int
#define ibs ios_base::sync_with_stdio(false)
#define cti cin.tie(0)
#define bp __builtin_popcount
#define pb emplace_back
#define koto_memory(a) cout << (sizeof(a) / 1048576.0) << " MB";
#define res(v) sort(all(v)), v.erase(unique(all(v)), v.end());
#define timer                                                                  \\
  cerr << "Time elapsed : " << 1.0 * clock() / CLOCKS_PER_SEC << " sec "       \\
       << endl;
#define deb(x) cout << endl << "[" << #x << " = " << x << "]" << endl;
using vi = std::vector<int>;
using vvi = std::vector<vi>;
using pii = std::pair<int, int>;
using vpii = std::vector<pii>;
using vvpii = std::vector<vpii>;
#define mp make_pair
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, b, a) for (int i = b; i >= a; i--)
#define all(x) x.begin(), x.end()
using namespace std;
const int N = 6e6 + 10;
const int inf = /*0x3f3f3f3f*/ 1e18 + 10;
// const ll M = 998244353 ; // Mulo
// const int M = 1e9+7 ; // Mulo
const double Pi = 3.14159265;
#define F first
#define S second
int n, k, a[N], ans = 1, z = 1;
map<int, int> t;
// queries
int sum(int l, int r, int v = 1, int tl = 0, int tr = N) {
  if (l > r)
    return 0;
  if (l == tl && r == tr)
    return t[v];
  int tm = (tl + tr) / 2;
  return max(sum(l, min(r, tm), v * 2, tl, tm),
             sum(max(l, tm + 1), r, v * 2 + 1, tm + 1, tr));
}
//
void update(int pos, int new_val, int v = 1, int tl = 0, int tr = N) {
  if (tl == tr) {
    t[v] = new_val;
  } else {
    int tm = (tl + tr) / 2;
    if (pos <= tm)
      update(pos, new_val, v * 2, tl, tm);
    else
      update(pos, new_val, v * 2 + 1, tm + 1, tr);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
}
void solve() {
  cin >> n >> k;
  rep(i, 1, n) {
    cin >> a[i];
    z = sum(max(a[i] - k, 0LL), min(a[i] + k, N)) + 1;
    update(a[i], max(z, 1LL));
    ans = max(ans, z);
  }
  cout << ans;
}
int32_t main() {
  ibs;
  cti;
  solve();
  return 0;
  int xx = 0;
  int t;
  cin >> t;
  while (t--) { /*xx++;cout<<"Case "<<xx<<": "*/
    ;
    solve();
    cout << endl;
  }
  return 0;
}

// Coded by Abhijay Mitra
#include <algorithm>
#include <bits/stdc++.h>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <vector>
#define double long double
#define int long long int
#define ll int
#define ibs ios_base::sync_with_stdio(false)
#define cti cin.tie(0)
#define bp __builtin_popcount
#define pb emplace_back
#define koto_memory(a) cout << (sizeof(a) / 1048576.0) << " MB";
#define res(v) sort(all(v)), v.erase(unique(all(v)), v.end());
#define timer                                                                  \\
  cerr << "Time elapsed : " << 1.0 * clock() / CLOCKS_PER_SEC << " sec "       \\
       << endl;
#define deb(x) cout << endl << "[" << #x << " = " << x << "]" << endl;
using vi = std::vector<int>;
using vvi = std::vector<vi>;
using pii = std::pair<int, int>;
using vpii = std::vector<pii>;
using vvpii = std::vector<vpii>;
#define mp make_pair
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, b, a) for (int i = b; i >= a; i--)
#define all(x) x.begin(), x.end()
using namespace std;
const int N = 3e6 + 10;
const int inf = /*0x3f3f3f3f*/ 1e18 + 10;
// const ll M = 998244353 ; // Mulo
// const int M = 1e9+7 ; // Mulo
const double Pi = 3.14159265;
#define F first
#define S second
int n, k, a[N], ans = 1, z = 1;
unordered_map<int, int> t;
// queries
int sum(int l, int r, int v = 1, int tl = 0, int tr = N) {
  if (l > r)
    return 0;
  if (l == tl && r == tr)
    return t[v];
  int tm = (tl + tr) / 2;
  return max(sum(l, min(r, tm), v * 2, tl, tm),
             sum(max(l, tm + 1), r, v * 2 + 1, tm + 1, tr));
}
//
void update(int pos, int new_val, int v = 1, int tl = 0, int tr = N) {
  if (tl == tr) {
    t[v] = new_val;
  } else {
    int tm = (tl + tr) / 2;
    if (pos <= tm)
      update(pos, new_val, v * 2, tl, tm);
    else
      update(pos, new_val, v * 2 + 1, tm + 1, tr);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
}
void solve() {
  cin >> n >> k;
  rep(i, 1, n) {
    cin >> a[i];
    z = sum(max(a[i] - k, 0LL), min(a[i] + k, N)) + 1;
    update(a[i], max(z, 1LL));
    ans = max(ans, z);
  }
  cout << ans;
}
int32_t main() {
  ibs;
  cti;
  solve();
  return 0;
  int xx = 0;
  int t;
  cin >> t;
  while (t--) { /*xx++;cout<<"Case "<<xx<<": "*/
    ;
    solve();
    cout << endl;
  }
  return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
using namespace std;
using namespace __gnu_pbds;
auto random_address = [] {
  char *p = new char;
  delete p;
  return uint64_t(p);
};
const uint64_t SEED = chrono::steady_clock::now().time_since_epoch().count() *
                      (random_address() | 1);
mt19937_64 rng(SEED);
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
ll arb[1000001], x, n, k, ans;
void update(int nod, int st, int dr, int poz, int val) {
  if (poz < st || poz > dr)
    return;
  if (poz >= st && poz <= dr)
    arb[nod] = val;
  if (st != dr) {
    int mij = (st + dr) / 2;
    if (poz <= mij)
      update(nod * 2, st, mij, poz, val);
    if (poz > mij)
      update(nod * 2 + 1, mij + 1, dr, poz, val);
    arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
  }
}
int query(int nod, int st, int dr, int a, int b) {
  if (a <= st && b >= dr)
    return arb[nod];
  else {
    int mij = (st + dr) / 2;
    int ans = 0;
    if (a <= mij)
      ans = max(ans, query(nod * 2, st, mij, a, b));
    if (b > mij)
      ans = max(ans, query(nod * 2 + 1, mij + 1, dr, a, b));
    return ans;
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> x;
    ll st = max(0LL, x - k);
    ll dr = min(300000LL, x + k);
    ll val = query(1, 0, 300000, st, dr) + 1;
    update(1, 0, 300000, x, val);
    ans = max(ans, val);
  }
  cout << ans;
  return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
using namespace std;
using namespace __gnu_pbds;
auto random_address = [] {
  char *p = new char;
  delete p;
  return uint64_t(p);
};
const uint64_t SEED = chrono::steady_clock::now().time_since_epoch().count() *
                      (random_address() | 1);
mt19937_64 rng(SEED);
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
ll arb[3000001], x, n, k, answer;
void update(int nod, int st, int dr, int poz, int val) {
  if (poz < st || poz > dr)
    return;
  if (poz >= st && poz <= dr)
    arb[nod] = val;
  if (st != dr) {
    int mij = (st + dr) / 2;
    if (poz <= mij)
      update(nod * 2, st, mij, poz, val);
    if (poz > mij)
      update(nod * 2 + 1, mij + 1, dr, poz, val);
    arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
  }
}
int query(int nod, int st, int dr, int a, int b) {
  if (a <= st && b >= dr)
    return arb[nod];
  else {
    int mij = (st + dr) / 2;
    int ans = 0;
    if (a <= mij)
      ans = max(ans, query(nod * 2, st, mij, a, b));
    if (b > mij)
      ans = max(ans, query(nod * 2 + 1, mij + 1, dr, a, b));
    return ans;
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> x;
    ll l = max(0LL, x - k);
    ll r = min(300000LL, x + k);
    ll val = query(1, 0, 300000, l, r) + 1;
    update(1, 0, 300000, x, val);
    answer = max(answer, val);
  }
  cout << answer;
  return 0;
}


#include <bits/stdc++.h>
#ifdef _DEBUG
#include "_DEBUG.hpp"
#endif
#define int long long
using namespace std;
using P = pair<int, int>;
const int inf = 2e18;
const int mod = 1e9 + 7;

template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v)
    is >> in;
  return is;
}

template <class T> vector<T> make_vec(size_t a) { return vector<T>(a); }

template <class T, class... Ts> auto make_vec(size_t a, Ts... ts) {
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}

template <class T, class V>
typename enable_if<is_class<T>::value == 0>::type fill(T &t, const V &v) {
  t = v;
}

template <class T, class V>
typename enable_if<is_class<T>::value != 0>::type fill(T &t, const V &v) {
  for (auto &e : t)
    fill(e, v);
}

template <class T> struct SegmentTree {
  using F = function<T(T, T)>;
  F f;
  T inf;
  int n;
  vector<T> node;

  SegmentTree() {}
  SegmentTree(vector<T> v, T inf, F f) : inf(inf), f(f) {
    n = 1;
    while (n < v.size())
      n *= 2;
    node.resize(2 * n - 1, inf);
    for (int i = 0; i < v.size(); i++)
      node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = f(node[2 * i + 1], node[2 * i + 2]);
  }

  void update(int k, T val) {
    k += n - 1;
    node[k] = val;
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = f(node[2 * k + 1], node[2 * k + 2]);
    }
  }

  void add(int k, T val) {
    k += n - 1;
    node[k] += val;
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = f(node[2 * k + 1], node[2 * k + 2]);
    }
  }

  // 区間[a, b)の値を返す
  T operator[](int x) { return getval(x, x + 1); }
  T getval(int a, int b) { return getval(a, b, 0, 0, n); }
  T getval(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return inf;
    if (a <= l && r <= b)
      return node[k];
    T vl = getval(a, b, 2 * k + 1, l, (l + r) / 2);
    T vr = getval(a, b, 2 * k + 2, (l + r) / 2, r);
    return f(vl, vr);
  }

  void print(int n) {
    for (int i = 0; i < n; i++) {
      cout << getval(i, i + 1) << " ";
    }
    cout << endl;
  }
};

signed main() {

  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  cin >> a;

  SegmentTree<int> seg(vector<int>(n + 10, 0), -inf,
                       [&](int x, int y) { return max(x, y); });
  for (int i = 0; i < n; i++) {
    int l = max(0ll, a[i] - k);
    int r = min(n, a[i] + k);
    seg.update(a[i], seg.getval(l, r + 1) + 1);
  }
  int ans = seg.getval(0, n + 1);
  cout << ans << endl;

  return 0;
}

#include <bits/stdc++.h>
#ifdef _DEBUG
#include "_DEBUG.hpp"
#endif
#define int long long
using namespace std;
using P = pair<int, int>;
const int inf = 2e18;
const int mod = 1e9 + 7;

template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v)
    is >> in;
  return is;
}

template <class T> vector<T> make_vec(size_t a) { return vector<T>(a); }

template <class T, class... Ts> auto make_vec(size_t a, Ts... ts) {
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}

template <class T, class V>
typename enable_if<is_class<T>::value == 0>::type fill(T &t, const V &v) {
  t = v;
}

template <class T, class V>
typename enable_if<is_class<T>::value != 0>::type fill(T &t, const V &v) {
  for (auto &e : t)
    fill(e, v);
}

template <class T> struct SegmentTree {
  using F = function<T(T, T)>;
  F f;
  T inf;
  int n;
  vector<T> node;

  SegmentTree() {}
  SegmentTree(vector<T> v, T inf, F f) : inf(inf), f(f) {
    n = 1;
    while (n < v.size())
      n *= 2;
    node.resize(2 * n - 1, inf);
    for (int i = 0; i < v.size(); i++)
      node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = f(node[2 * i + 1], node[2 * i + 2]);
  }

  void update(int k, T val) {
    k += n - 1;
    node[k] = val;
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = f(node[2 * k + 1], node[2 * k + 2]);
    }
  }

  void add(int k, T val) {
    k += n - 1;
    node[k] += val;
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = f(node[2 * k + 1], node[2 * k + 2]);
    }
  }

  // 区間[a, b)の値を返す
  T operator[](int x) { return getval(x, x + 1); }
  T getval(int a, int b) { return getval(a, b, 0, 0, n); }
  T getval(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return inf;
    if (a <= l && r <= b)
      return node[k];
    T vl = getval(a, b, 2 * k + 1, l, (l + r) / 2);
    T vr = getval(a, b, 2 * k + 2, (l + r) / 2, r);
    return f(vl, vr);
  }

  void print(int n) {
    for (int i = 0; i < n; i++) {
      cout << getval(i, i + 1) << " ";
    }
    cout << endl;
  }
};

signed main() {

  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  cin >> a;

  SegmentTree<int> seg(vector<int>(4e5 + 1, 0), -inf,
                       [&](int x, int y) { return max(x, y); });
  for (int i = 0; i < n; i++) {
    int l = max(0ll, a[i] - k);
    int r = min((int)4e5, a[i] + k);
    seg.update(a[i], seg.getval(l, r + 1) + 1);
  }
  int ans = seg.getval(0, 4e5);
  cout << ans << endl;

  return 0;
}


#include "bits/stdc++.h"
#include <boost/dynamic_bitset.hpp>
#include <boost/multi_array.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/numeric.hpp>
namespace adaptor = boost::adaptors;
using index_t = std::size_t;

namespace lib {
using graph_t = std::vector<std::set<index_t>>;
template <class T> using weighted_graph_t = std::vector<std::map<index_t, T>>;
template <class T> using pair = std::pair<T, T>;

struct max_t {
  template <class T> constexpr T operator()(T const &lhs, T const &rhs) const {
    return std::max(lhs, rhs);
  }
};
struct min_t {
  template <class T> constexpr T operator()(T const &lhs, T const &rhs) const {
    return std::min(lhs, rhs);
  }
};

constexpr max_t max;
constexpr min_t min;

template <class T> auto order_by(T func) {
  return [=](auto &&lhs, auto &&rhs) { return func(lhs) < func(rhs); };
}

template <class T> constexpr auto max_v = std::numeric_limits<T>::max();
template <class T> constexpr auto min_v = std::numeric_limits<T>::min();

template <class T>
using p_queue = std::priority_queue<T, std::vector<T>, std::greater<>>;

template <class T> constexpr T pow(T val, std::uint64_t p) {
  auto ret = T(1);
  auto s = 1ULL;
  for (auto i = 0; i < 63; ++i, s <<= 1) {
    if (p & s) {
      ret *= val;
    }
    val *= val;
  }
  return ret;
}
} // namespace lib

template <class T, class Op = std::plus<>> class seg_tree {
  std::vector<T> vec;
  T unit;
  std::size_t sz;
  Op op;
  static std::size_t get_size(std::size_t s) {
    std::size_t ret = 1;
    while (ret < s) {
      ret <<= 1;
    }
    return ret;
  }

public:
  seg_tree(std::size_t size, T u = T(), Op f = Op())
      : vec(), unit(u), sz(get_size(size)), op(f) {
    vec.assign(2 * sz, unit);
  }
  template <class Range, class = decltype(std::declval<Range>().size())>
  seg_tree(Range const &rng, T u = T(), Op f = Op())
      : seg_tree(rng.size(), u, f) {
    set(rng);
  }
  template <class Range> void set(Range const &rng) {
    std::size_t i = 0;
    for (auto &&v : rng) {
      vec[i + sz] = v;
      if (++i >= sz) {
        break;
      }
    }
    for (auto s = sz / 2; s > 0; s /= 2) {
      for (index_t i = 0; i < s; ++i) {
        vec[(i + s)] = op(vec[2 * (i + s)], vec[2 * (i + s) + 1]);
      }
    }
  }
  T operator()(std::size_t start, std::size_t end) const {
    T L = unit, R = unit;
    for (std::size_t a = start + sz, b = end + sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        L = op(L, vec[a++]);
      }
      if (b & 1) {
        R = op(vec[--b], R);
      }
    }
    return op(L, R);
  }
  void update(std::size_t i, T const &v) {
    auto k = i + sz;
    vec[k] = v;
    while (k >>= 1) {
      vec[k] = op(vec[2 * k], vec[2 * k + 1]);
    }
  }
};

template <class T> struct max_value {
  T v;
  max_value(T u = lib::min_v<T>) : v(u) {}
  auto &operator=(T const &u) {
    v = std::max(v, u);
    return *this;
  }
  auto &operator=(max_value const &u) {
    v = std::max(v, *u);
    return *this;
  }
  T operator*() const { return v; }
  void reset() { v = lib::min_v<T>; }
};

void Main() {
  int N, K;
  std::cin >> N >> K;
  seg_tree<int, lib::max_t> tree(N);
  max_value<int> max;
  for (auto _ : boost::irange(N)) {
    int p;
    std::cin >> p;
    auto left = std::max(0, p - K);
    auto right = std::min(N, p + K + 1);
    auto v = tree(left, right);
    max = v + 1;
    tree.update(p, v + 1);
  }
  std::cout << *max << std::endl;
}

int main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  std::cout << std::fixed << std::setprecision(15);
  Main();
}

#include "bits/stdc++.h"
#include <boost/dynamic_bitset.hpp>
#include <boost/multi_array.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/numeric.hpp>
namespace adaptor = boost::adaptors;
using index_t = std::size_t;

namespace lib {
using graph_t = std::vector<std::set<index_t>>;
template <class T> using weighted_graph_t = std::vector<std::map<index_t, T>>;
template <class T> using pair = std::pair<T, T>;

struct max_t {
  template <class T> constexpr T operator()(T const &lhs, T const &rhs) const {
    return std::max(lhs, rhs);
  }
};
struct min_t {
  template <class T> constexpr T operator()(T const &lhs, T const &rhs) const {
    return std::min(lhs, rhs);
  }
};

constexpr max_t max;
constexpr min_t min;

template <class T> auto order_by(T func) {
  return [=](auto &&lhs, auto &&rhs) { return func(lhs) < func(rhs); };
}

template <class T> constexpr auto max_v = std::numeric_limits<T>::max();
template <class T> constexpr auto min_v = std::numeric_limits<T>::min();

template <class T>
using p_queue = std::priority_queue<T, std::vector<T>, std::greater<>>;

template <class T> constexpr T pow(T val, std::uint64_t p) {
  auto ret = T(1);
  auto s = 1ULL;
  for (auto i = 0; i < 63; ++i, s <<= 1) {
    if (p & s) {
      ret *= val;
    }
    val *= val;
  }
  return ret;
}
} // namespace lib

template <class T, class Op = std::plus<>> class seg_tree {
  std::vector<T> vec;
  T unit;
  std::size_t sz;
  Op op;
  static std::size_t get_size(std::size_t s) {
    std::size_t ret = 1;
    while (ret < s) {
      ret <<= 1;
    }
    return ret;
  }

public:
  seg_tree(std::size_t size, T u = T(), Op f = Op())
      : vec(), unit(u), sz(get_size(size)), op(f) {
    vec.assign(2 * sz, unit);
  }
  template <class Range, class = decltype(std::declval<Range>().size())>
  seg_tree(Range const &rng, T u = T(), Op f = Op())
      : seg_tree(rng.size(), u, f) {
    set(rng);
  }
  template <class Range> void set(Range const &rng) {
    std::size_t i = 0;
    for (auto &&v : rng) {
      vec[i + sz] = v;
      if (++i >= sz) {
        break;
      }
    }
    for (auto s = sz / 2; s > 0; s /= 2) {
      for (index_t i = 0; i < s; ++i) {
        vec[(i + s)] = op(vec[2 * (i + s)], vec[2 * (i + s) + 1]);
      }
    }
  }
  T operator()(std::size_t start, std::size_t end) const {
    T L = unit, R = unit;
    for (std::size_t a = start + sz, b = end + sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        L = op(L, vec[a++]);
      }
      if (b & 1) {
        R = op(vec[--b], R);
      }
    }
    return op(L, R);
  }
  void update(std::size_t i, T const &v) {
    auto k = i + sz;
    vec[k] = v;
    while (k >>= 1) {
      vec[k] = op(vec[2 * k], vec[2 * k + 1]);
    }
  }
};

template <class T> struct max_value {
  T v;
  max_value(T u = lib::min_v<T>) : v(u) {}
  auto &operator=(T const &u) {
    v = std::max(v, u);
    return *this;
  }
  auto &operator=(max_value const &u) {
    v = std::max(v, *u);
    return *this;
  }
  T operator*() const { return v; }
  void reset() { v = lib::min_v<T>; }
};

void Main() {
  int N, K;
  std::cin >> N >> K;
  const int MAX = 300000;
  seg_tree<int, lib::max_t> tree(MAX + 1);
  max_value<int> max;
  for (auto _ : boost::irange(N)) {
    int p;
    std::cin >> p;
    auto left = std::max(0, p - K);
    auto right = std::min(MAX + 1, p + K + 1);
    auto v = tree(left, right);
    max = v + 1;
    tree.update(p, v + 1);
  }
  std::cout << *max << std::endl;
}

int main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  std::cout << std::fixed << std::setprecision(15);
  Main();
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int MAX_N = 10;
int node[4 * MAX_N], segtree_size;
void segtree_init(int n) {
  segtree_size = 1;
  while (segtree_size < n)
    segtree_size *= 2;
  for (int i = 0; i < 2 * segtree_size - 1; ++i)
    node[i] = 0;
}
void segtree_update(int a, int x) {
  a += segtree_size - 1;
  node[a] = x;
  while (a > 0) {
    a = (a - 1) / 2;
    node[a] = max(node[2 * a + 1], node[2 * a + 2]);
  }
}
int segtree_query(int a, int b, int k = 0, int l = 0, int r = segtree_size) {
  // [a, b] の最大値w
  if (b <= l || r <= a) {

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

// segtree[a] = (最後の値がaになるような、条件を満たす最長の数列の長さ)

int main() {
  int n, k;
  cin >> n >> k;
  segtree_init(MAX_N + 1);
  for (int i = 0; i < n; ++i) {
    int a;
    cin >> a;
    int l = segtree_query(a - k, a + k + 1);
    segtree_update(a, l + 1);
  }
  cout << segtree_query(0, n + 1);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int MAX_N = 300001;
int node[4 * MAX_N], segtree_size;
void segtree_init(int n) {
  segtree_size = 1;
  while (segtree_size < n)
    segtree_size *= 2;
  for (int i = 0; i < 2 * segtree_size - 1; ++i)
    node[i] = 0;
}
void segtree_update(int a, int x) {
  a += segtree_size - 1;
  node[a] = max(node[a], x);
  while (a > 0) {
    a = (a - 1) / 2;
    node[a] = max(node[2 * a + 1], node[2 * a + 2]);
  }
}
int segtree_query(int a, int b, int k = 0, int l = 0, int r = segtree_size) {
  if (b <= l || r <= a) {
    return 0;
  }
  if (a <= l && r <= b) {
    return node[k];
  }
  int vl = segtree_query(a, b, 2 * k + 1, l, (l + r) / 2);
  int vr = segtree_query(a, b, 2 * k + 2, (l + r) / 2, r);
  return max(vl, vr);
}

int solve_naive(const vector<int> &va, const int k) {
  vector<int> dp(va.size(), 1);
  for (int i = 0; i < va.size(); ++i) {
    for (int j = 0; j < i; ++j) {
      if (abs(va[i] - va[j]) <= k)
        dp[i] = max(dp[i], dp[j] + 1);
    }
  }
  return *max_element(dp.begin(), dp.end());
}

int main() {
  int n, k;
  cin >> n >> k;
  segtree_init(MAX_N + 1);
  vector<int> va(n);
  for (int i = 0; i < n; ++i)
    cin >> va[i];
  // cout << solve_naive(va, k) << endl;
  for (int i = 0; i < n; ++i) {
    int a = va[i];
    int l = segtree_query(a - k, a + k + 1);
    segtree_update(a, l + 1);
  }
  cout << segtree_query(0, segtree_size);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 1;
const int N = 6e5 + 7;
inline int ls(int p) { return p << 1; }
inline int rs(int p) { return p << 1 | 1; }
int n, k, a[maxn];
struct node {
  int l, r, pre;
} t[4 * N];

void update(int pos, int v, int l, int r, int p) {
  if (l == r) {
    t[p].pre = v;
    return;
  }
  int mid = l + r >> 1;
  if (pos <= mid)
    update(pos, v, l, mid, ls(p));
  else
    update(pos, v, mid + 1, r, rs(p));
  t[p].pre = max(t[ls(p)].pre, t[rs(p)].pre);
}
int query(int x, int y, int l, int r, int p) {
  if (x <= l && y >= r) {
    return t[p].pre;
  }
  int mid = l + r >> 1;
  int ans = 0;
  if (x <= mid)
    ans = max(ans, query(x, y, l, mid, ls(p)));
  if (y > mid)
    ans = max(ans, query(x, y, mid + 1, r, rs(p)));
  return ans;
}
int main() {
  scanf("%d %d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int res = query(max(a[i] - k, 0), a[i] + k, 0, N, 1) + 1;
    ans = max(ans, res);
    update(a[i], res, 0, N, 1);
  }
  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 6e5 + 7;

int n, a[N], k, tree[4 * N];

#define m (l + r) / 2
#define lson 2 * node
#define rson 2 * node + 1

void update(int pos, int v, int l, int r, int node) {
  if (l == r) {
    tree[node] = v;
    return;
  }
  if (pos <= m)
    update(pos, v, l, m, lson);
  else
    update(pos, v, m + 1, r, rson);
  tree[node] = max(tree[lson], tree[rson]);
}

int query(int ql, int qr, int l, int r, int node) {
  if (ql <= l && qr >= r) {
    return tree[node];
  }
  int ans = 0;
  if (ql <= m)
    ans = max(ans, query(ql, qr, l, m, lson));
  if (qr > m)
    ans = max(ans, query(ql, qr, m + 1, r, rson));
  return ans;
}

int main() {
  scanf("%d %d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int res = query(max(a[i] - k, 0), a[i] + k, 0, N, 1) + 1;
    ans = max(ans, res);
    update(a[i], res, 0, N, 1);
  }
  cout << ans << endl;
}


#include <bits/stdc++.h>

using namespace std;

namespace tt {

template <typename T> class SegmentTree {
public:
  using Op = function<T(const T &a, const T &b)>;

private:
  vector<T> data_;
  int size_;
  Op op_;
  T e_;

  T QuerySub(int left, int right, int k, int k_left, int k_right) {
    if (right <= k_left || k_right <= left) {
      return e_;
    } else if (left <= k_left && k_right <= right) {
      return data_[k];
    } else {
      int mid = (k_left + k_right) / 2;
      return op_(QuerySub(left, right, k * 2 + 1, k_left, mid),
                 QuerySub(left, right, k * 2 + 2, mid, k_right));
    }
  }

public:
  T operator[](int pos) { return data_[pos + size_ - 1]; }

  SegmentTree(int size, T e, Op op) : op_(op), e_(e) {
    size_ = 1;
    while (size_ < size) {
      size_ *= 2;
    }

    data_.resize(size_ * 2 - 1);
  };

  void Update(int pos, T val) {
    pos += size_ - 1;
    data_[pos] = val;
    while (pos > 0) {
      pos = (pos - 1) / 2;
      data_[pos] = op_(data_[pos * 2 + 1], data_[pos * 2 + 2]);
    }
  }

  T Query(int left, int right) { return QuerySub(left, right, 0, 0, size_); }
};

} // namespace tt

int solve(vector<int> &va, int i, int pre, int k) {
  if (i == va.size()) {
    return 0;
  }

  if (pre < 0 || abs(va[i] - pre) <= k) {
    return max(solve(va, i + 1, va[i], k) + 1, solve(va, i + 1, pre, k));
  } else {
    return solve(va, i + 1, pre, k);
  }
}

int main(int argc, const char *argv[]) {
  int n, k;
  cin >> n >> k;

  int max_el = 3 * pow(10, 5);
  tt::SegmentTree<int> seg_tree(
      n, 0, [](const int &a, const int &b) { return max(a, b); });

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

    int max_n = seg_tree.Query(max(0, a - k), min(max_el, a + k + 1));
    seg_tree.Update(a, max_n + 1);
  }

  cout << seg_tree.Query(0, n) << '\\n';
}

#include <bits/stdc++.h>

using namespace std;

namespace tt {

template <typename T> class SegmentTree {
public:
  using Op = function<T(const T &a, const T &b)>;

private:
  vector<T> data_;
  int size_;
  Op op_;
  T e_;

  T QuerySub(int left, int right, int k, int k_left, int k_right) {
    if (right <= k_left || k_right <= left) {
      return e_;
    } else if (left <= k_left && k_right <= right) {
      return data_[k];
    } else {
      int mid = (k_left + k_right) / 2;
      return op_(QuerySub(left, right, k * 2 + 1, k_left, mid),
                 QuerySub(left, right, k * 2 + 2, mid, k_right));
    }
  }

public:
  T operator[](int pos) { return data_[pos + size_ - 1]; }

  SegmentTree(int size, T e, Op op) : op_(op), e_(e) {
    size_ = 1;
    while (size_ < size) {
      size_ *= 2;
    }

    data_.resize(size_ * 2 - 1);
  };

  void Update(int pos, T val) {
    pos += size_ - 1;
    data_[pos] = val;
    while (pos > 0) {
      pos = (pos - 1) / 2;
      data_[pos] = op_(data_[pos * 2 + 1], data_[pos * 2 + 2]);
    }
  }

  T Query(int left, int right) { return QuerySub(left, right, 0, 0, size_); }
  T QueryAll() { return QuerySub(0, size_, 0, 0, size_); }
};

} // namespace tt

int main(int argc, const char *argv[]) {
  int n, k;
  cin >> n >> k;

  int max_el = 5 * pow(10, 5);
  tt::SegmentTree<int> seg_tree(
      max_el, 0, [](const int &a, const int &b) { return max(a, b); });

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

    int max_n = seg_tree.Query(max(0, a - k), min(max_el, a + k + 1));
    seg_tree.Update(a, max_n + 1);
  }

  cout << seg_tree.QueryAll() << '\\n';
}


#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll INF = 1e18;

struct UnionFind {
  vector<int> d;
  UnionFind(int n) : d(n, -1) {} //-1で初期化
  int root(int x) {
    if (d[x] < 0)
      return x; // rootを負にする（構成node数x(-1))
    // root以外は親の番号
    return d[x] = root(d[x]);
    // return(root(d[x]))とするとメモできないが上の書き方だとメモができる
  }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (d[x] > d[y])
      swap(x, y);
    // swapすることで小さい方を大きい方につけられ計算量減らせる
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  // 同じグループ化
  int size(int x) { return -d[root(x)]; }
  // グループのnode数
  int group_num(int n) {
    set<int> s;
    for (int i = 0; i < n; ++i) {
      s.insert(root(i));
    }
    return int(s.size());
  }
};

int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  vector<ll> d(n + 5, 1);

  rep(i, n) cin >> a[i];
  rep(i, n - 1) {
    rep(j, i + 1) {
      if (abs(a[i + 1] - a[j]) <= k) {
        //    cout<<'i'<<i+1<<'j'<<j<<endl;
        d[i + 1] = max(d[i + 1], d[j] + 1);
      }
    }
  }
  ll ans = 0;
  rep(i, n + 1) {
    //  cout<<d[i];
    ans = max(ans, d[i]);
  }
  cout << ans;
}

#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll INF = 1e18;

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

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

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

int e() { return 0; }

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  segtree<int, op, e> d(300005);

  rep(i, n) {
    cin >> a[i];
    int l = a[i] - k;
    int r = a[i] + k + 1;
    l = max(l, 0);
    r = min(r, 300005);
    ll now = d.prod(l, r);
    d.set(a[i], now + 1);
  }
  int ans = d.prod(0, 300005);
  cout << ans;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 3e5 + 5;
int n, k, a[N], dp[N][5];

int solve(int i, int pre, int f) {
  if (i == n) {
    return 0;
  }
  int &re = dp[i][f];
  if (re != -1) {
    return re;
  }
  re = solve(i + 1, pre, 0);
  if (pre == -1) {
    re = max(re, solve(i + 1, a[i], 1) + 1);
  } else {
    for (int j = i; j < n; j++) {
      if (a[j] - pre <= k && a[j] - pre >= 0) {
        re = max(re, solve(j + 1, a[j], 1) + 1);
        break;
      }
    }
    for (int j = i; j < n; j++) {
      if (pre - a[j] <= k && pre - a[i] >= 0) {
        re = max(re, solve(j + 1, a[j], 2) + 1);
        break;
      }
    }
  }
  return re;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  cin >> n >> k;
  memset(dp, -1, sizeof(dp));
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  cout << solve(0, -1, 0) << endl;
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 3e5 + 5;
int n, k, a[N], dp[N][5];

int solve(int i, int pre, int f) {
  if (i == n) {
    return 0;
  }
  int &re = dp[i][f];
  if (re != -1) {
    return re;
  }
  re = 0;
  if (pre == -1) {
    re = max(re, solve(i + 1, pre, 0));
    re = max(re, solve(i + 1, a[i], 1) + 1);
  } else {
    for (int j = i; j < n; j++) {
      if (a[j] - pre <= k && a[j] - pre >= 0) {
        re = max(re, solve(j + 1, a[j], 1) + 1);
        break;
      }
    }
    for (int j = i; j < n; j++) {
      if (pre - a[j] <= k && pre - a[j] >= 0) {
        re = max(re, solve(j + 1, a[j], 2) + 1);
        break;
      }
    }
  }
  return re;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  cin >> n >> k;
  memset(dp, -1, sizeof(dp));
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  cout << solve(0, -1, 0) << endl;
  return 0;
}


#pragma GCC optimize(3)
#pragma GCC optimize("Ofast", "unroll-loops", "omit-frame-pointer", "inline")
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <unordered_map>
using namespace std;
const int N = 3e5 + 10;

int a[N], n, m, k, len, dp[N], ans, tr[N << 2];
int query(int x, int y, int l, int r, int rt) {
  int mid = (l + r) / 2;
  int maxn = 0;
  if (x <= l && r <= y)
    return tr[rt];
  if (x <= mid)
    maxn = max(maxn, query(x, y, l, mid, rt << 1));
  if (y > mid)
    maxn = max(maxn, query(x, y, mid + 1, r, rt << 1 | 1));
  return maxn;
}
void pushup(int rt) { tr[rt] = max(tr[rt << 1], tr[rt << 1 | 1]); }
void change(int nt, int l, int r, int rt, int k) {
  if (l == r) {
    tr[rt] = max(tr[rt], k);
    return;
  }
  int mid = (l + r) >> 1;
  if (nt <= mid)
    change(nt, l, mid, rt << 1, k);
  else
    change(nt, mid + 1, r, rt << 1 | 1, k);
  pushup(rt);
}
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    len = max(len, a[i] + k);
  }
  for (int i = 1; i <= n; i++)
    a[i]++;
  for (int i = 1; i <= n; i++) {
    int l = max(a[i] - k, 1), r = a[i] + k;
    dp[i] = query(l, r, 1, len, 1) + 1;
    change(a[i], 1, len, 1, dp[i]);
    ans = max(ans, dp[i]);
  }
  printf("%d\\n", ans);
  return 0;
}

#pragma GCC optimize(3)
#pragma GCC optimize("Ofast", "unroll-loops", "omit-frame-pointer", "inline")
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <unordered_map>
using namespace std;
const int N = 3e5 + 10, M = 1e7 + 10;

int a[N], n, m, k, len, dp[N], ans, tr[M];
int query(int x, int y, int l, int r, int rt) {
  int mid = (l + r) / 2;
  int maxn = 0;
  if (x <= l && r <= y)
    return tr[rt];
  if (x <= mid)
    maxn = max(maxn, query(x, y, l, mid, rt << 1));
  if (y > mid)
    maxn = max(maxn, query(x, y, mid + 1, r, rt << 1 | 1));
  return maxn;
}
void pushup(int rt) { tr[rt] = max(tr[rt << 1], tr[rt << 1 | 1]); }
void change(int nt, int l, int r, int rt, int k) {
  if (l == r) {
    tr[rt] = max(tr[rt], k);
    return;
  }
  int mid = (l + r) >> 1;
  if (nt <= mid)
    change(nt, l, mid, rt << 1, k);
  else
    change(nt, mid + 1, r, rt << 1 | 1, k);
  pushup(rt);
}
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    len = max(len, a[i] + k);
  }
  for (int i = 1; i <= n; i++)
    a[i]++;
  for (int i = 1; i <= n; i++) {
    int l = max(a[i] - k, 1), r = a[i] + k;
    dp[i] = query(l, r, 1, len, 1) + 1;
    change(a[i], 1, len, 1, dp[i]);
    ans = max(ans, dp[i]);
  }
  printf("%d\\n", ans);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll tree[1000000];
void updatetree(ll ind, ll l, ll h, ll i, ll val) {
  if (i < l || i > h || l > h)
    return;
  if (l == h) {
    tree[ind] = val;
    return;
  }
  ll md = l + (h - l) / 2;
  updatetree(2 * ind + 1, l, md, i, val);
  updatetree(2 * ind + 2, md + 1, h, i, val);
  tree[ind] = max(tree[2 * ind + 1], tree[2 * ind + 2]);
}
ll query(ll ind, ll l, ll r, ll i, ll j) {
  if (l > r || l > j || r < i)
    return 0;
  if (i <= l && j >= r) {
    return tree[ind];
  }
  ll md = l + (r - l) / 2;
  ll l1 = query(2 * ind + 1, l, md, i, j);
  ll r1 = query(2 * ind + 2, md + 1, r, i, j);
  return max(l1, r1);
}
int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> v(n);
  for (ll i = 0; i < n; i++)
    cin >> v[i];
  ll dp[n][2];
  updatetree(0, 0, 300000, v[0], 1);
  dp[0][0] = 1;
  dp[0][1] = 1;
  ll ans = 1;
  for (ll i = 1; i < n; i++) {
    ll x = query(0, 0, 300000, v[i] - k, v[i]);
    dp[i][0] = x + 1;
    ll y = query(0, 0, 300000, v[i], v[i] + k);
    dp[i][1] = y + 1;
    // cout<<dp[i][0]<<" "<<dp[i][1]<<endl;
    ans = max(ans, max(dp[i][0], dp[i][1]));
    updatetree(0, 0, 300000, v[i], max(tree[v[i]], max(dp[i][0], dp[i][1])));
  }
  cout << ans;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll tree[2000000];
void updatetree(ll ind, ll l, ll h, ll i, ll val) {
  if (i < l || i > h || l > h)
    return;
  if (l == h) {
    tree[ind] = val;
    return;
  }
  ll md = l + (h - l) / 2;
  updatetree(2 * ind + 1, l, md, i, val);
  updatetree(2 * ind + 2, md + 1, h, i, val);
  tree[ind] = max(tree[2 * ind + 1], tree[2 * ind + 2]);
}
ll query(ll ind, ll l, ll r, ll i, ll j) {
  if (l > r || l > j || r < i)
    return 0;
  if (i <= l && j >= r) {
    return tree[ind];
  }
  ll md = l + (r - l) / 2;
  ll l1 = query(2 * ind + 1, l, md, i, j);
  ll r1 = query(2 * ind + 2, md + 1, r, i, j);
  return max(l1, r1);
}
int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> v(n);
  for (ll i = 0; i < n; i++)
    cin >> v[i];
  ll dp[n][2];
  updatetree(0, 0, 1000000, v[0], 1);
  dp[0][0] = 1;
  dp[0][1] = 1;
  ll ans = 1;
  for (ll i = 1; i < n; i++) {
    ll x = query(0, 0, 1000000, v[i] - k, v[i]);
    dp[i][0] = x + 1;
    ll y = query(0, 0, 1000000, v[i], v[i] + k);
    dp[i][1] = y + 1;

    ans = max(ans, max(dp[i][0], dp[i][1]));
    updatetree(0, 0, 1000000, v[i], max(dp[i][0], dp[i][1]));
  }
  cout << ans;
  return 0;
}


#pragma GCC optimize(2)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#define read(a) scanf("%d", &a)
#define readf(a) scanf("%lf", &a)
#define pb push_back
#define mk make_pair
#define _rand mt19937 RAND(time(0))
#define mem(a) memset(a, 0, sizeof(a))
#define Buff ios::sync_with_stdio(false)
typedef long long ll;
using namespace std;
const int INF = 1e9 + 7;
const int N = 2e5 + 7;
const int M = 1e6 + 7;
int a[N];
signed main() {
  Buff;
  int n, k;
  cin >> n >> k;
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  int ans = 0;
  int g = 0;
  for (int i = 2; i <= n; i++) {
    int f = g + (a[i] - a[i - 1]);
    if (abs(f) <= abs(a[i] - a[i - 1]))
      g += a[i] - a[i - 1];
    else
      g = a[i] - a[i - 1];
    if (abs(g) <= k) {
      ans++;
      g = 0;
    }
  }
  cout << ans + 1 << endl;
  return 0;
}
/**
 **/

#pragma GCC optimize(2)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#define read(a) scanf("%d", &a)
#define readf(a) scanf("%lf", &a)
#define pb push_back
#define mk make_pair
#define _rand mt19937 RAND(time(0))
#define mem(a) memset(a, 0, sizeof(a))
#define Buff ios::sync_with_stdio(false)
typedef long long ll;
using namespace std;
const int INF = 1e9 + 7;
const int N = 3e5 + 7;
const int M = 1e6 + 7;

#define lson rt << 1
#define rson rt << 1 | 1
template <class T> class SegTree {
public:
  T maxv[N << 2];
  void init() { mem(maxv); }
  inline void pushup(int rt) { maxv[rt] = max(maxv[lson], maxv[rson]); }
  void update(int rt, int l, int r, int pos, T val) {
    if (l == r) {
      maxv[rt] = max(maxv[rt], val);
      return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid)
      update(lson, l, mid, pos, val);
    else
      update(rson, mid + 1, r, pos, val);
    pushup(rt);
  }

  T query(int rt, int l, int r, int L, int R) {
    if (L <= l && r <= R)
      return maxv[rt];
    int mid = (l + r) >> 1;
    T ans = 0;
    if (L <= mid)
      ans = max(ans, query(lson, l, mid, L, R));
    if (R > mid)
      ans = max(ans, query(rson, mid + 1, r, L, R));
    return ans;
  }
};
SegTree<int> tree;

int a[N];
signed main() {
  tree.init();
  int n, k;
  read(n);
  read(k);

  int ans = 0, maxx = 0;
  for (int i = 1; i <= n; i++) {
    read(a[i]);
    maxx = max(maxx, a[i]);
  }
  for (int i = 1; i <= n; i++) {
    int l = max(0, a[i] - k);
    int r = min(maxx, a[i] + k);
    int tmp = tree.query(1, 1, maxx, l, r);
    //        cout << "tmp = " << tmp << "\\n";
    ans = max(ans, tmp + 1);
    tree.update(1, 1, maxx, a[i], tmp + 1);
  }
  printf("%d\\n", ans);
  return 0;
}
/**
 **/


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

#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i)
#define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i)

namespace IO {
#define gc getchar()
template <typename T> inline void read(T &x) {
  x = 0;
  bool f = 1;
  char ch;
  for (ch = gc; ch < '0' || '9' < ch; ch = gc)
    if (ch == '-')
      f ^= 1;
  for (; '0' <= ch && ch <= '9'; ch = gc)
    x = (x << 3) + (x << 1) + (ch ^ 48);
  x = f ? x : -x;
}
#undef gc
} // namespace IO

const int MAXN = 1e6 + 10;
const int MAXVAL = 3e5;

int n, arr[MAXN], K, f[MAXN], ans;

struct Segment_Tree {
#define mid ((l + r) >> 1)
#define ls k << 1, l, mid
#define rs k << 1 | 1, mid + 1, r
  struct Node {
    int val;
  } t[MAXN << 2];
  void pushup(int k) { t[k].val = max(t[k << 1 | 1].val, t[k << 1].val); }
  void modify(int k, int l, int r, int pos, int val) {
    if (l == r)
      return t[k].val = val, void();
    if (pos <= mid)
      modify(ls, pos, val);
    else
      modify(rs, pos, val);
    pushup(k);
  }
  int query(int k, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr)
      return t[k].val;
    int res = 0;
    if (ql <= mid)
      res = max(res, query(ls, ql, qr));
    if (qr > mid)
      res = max(res, query(rs, ql, qr));
    return res;
  }
} sgt;

int main() {
  IO::read(n), IO::read(K);
  rep(i, 1, n) IO::read(arr[i]);
  rep(i, 1, n) {
    f[i] = sgt.query(1, 1, n, max(0, arr[i] - K) + 1,
                     min(MAXVAL, arr[i] + K) + 1) +
           1;
    sgt.modify(1, 1, n, arr[i] + 1, f[i]);
    ans = max(ans, f[i]);
  }
  printf("%d\\n", ans);
  return 0;
}

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

#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i)
#define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i)

namespace IO {
#define gc getchar()
template <typename T> inline void read(T &x) {
  x = 0;
  bool f = 1;
  char ch;
  for (ch = gc; ch < '0' || '9' < ch; ch = gc)
    if (ch == '-')
      f ^= 1;
  for (; '0' <= ch && ch <= '9'; ch = gc)
    x = (x << 3) + (x << 1) + (ch ^ 48);
  x = f ? x : -x;
}
#undef gc
} // namespace IO

const int MAXN = 1e6 + 10;
const int MAXVAL = 3e5;

int n, arr[MAXN], K, f[MAXN], ans;

struct Segment_Tree {
#define mid ((l + r) >> 1)
#define ls k << 1, l, mid
#define rs k << 1 | 1, mid + 1, r
  struct Node {
    int val;
  } t[MAXN << 2];
  void pushup(int k) { t[k].val = max(t[k << 1 | 1].val, t[k << 1].val); }
  void modify(int k, int l, int r, int pos, int val) {
    if (l == r)
      return t[k].val = val, void();
    if (pos <= mid)
      modify(ls, pos, val);
    else
      modify(rs, pos, val);
    pushup(k);
  }
  int query(int k, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr)
      return t[k].val;
    int res = 0;
    if (ql <= mid)
      res = max(res, query(ls, ql, qr));
    if (qr > mid)
      res = max(res, query(rs, ql, qr));
    return res;
  }
} sgt;

int main() {
  IO::read(n), IO::read(K);
  rep(i, 1, n) IO::read(arr[i]);
  rep(i, 1, n) {
    f[i] = sgt.query(1, 1, MAXVAL, max(0, arr[i] - K) + 2,
                     min(MAXVAL, arr[i] + K) + 2) +
           1;
    sgt.modify(1, 1, MAXVAL, arr[i] + 2, f[i]);
    ans = max(ans, f[i]);
  }
  printf("%d\\n", ans);
  return 0;
}


#include <iostream>
#include <vector>
using namespace std;

int main() {
  int N, K, i, j, ans = 1;
  cin >> N >> K;
  vector<int> a(N), b(N, 1);
  for (i = 0; i < N; i++) {
    cin >> a[i];
  }
  for (i = 1; i < N; i++) {
    for (j = i - 1; j >= 0; j--) {
      if (abs(a[i] - a[j]) <= K) {
        b[i] = max(b[i], b[j] + 1);
        if (ans < b[i])
          break;
      }
    }
    ans = max(ans, b[i]);
  }
  cout << ans << endl;
  return 0;
}

#include <iostream>
#include <vector>
using namespace std;
#include <atcoder/segtree>
using namespace atcoder;

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

int e() { return 0; }

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

  segtree<int, op, e> sg(300001);
  for (i = 0; i < N; i++) {
    int l = max(a[i] - K, 0);
    int r = min(a[i] + K, 300000);
    sg.set(a[i], sg.prod(l, r + 1) + 1);
  }
  cout << sg.all_prod() << endl;
  return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define rep(i, n, m) for (int i = (n); i < (int)(m); i++)
#define reps(i, n, m) for (int i = (n); i <= (int)(m); i++)
#define all(v) v.begin(), v.end()
#define allr(v) v.rbegin(), v.rend()
#define SZ(x) ((int)(x).size())
#define pb push_back
#define fs first
#define sc second
#define lb lower_bound
#define ub upper_bound
#define LB(a, x) lb(all(a), x) - a.begin()
#define UB(a, x) ub(all(a), x) - a.begin()
#define printfdouble(x) printf("%.20f\\n", (x))
#define chartoint(c) (int)((c) - '0')
#define chartoll(c) (long long)((c) - '0')
#define MOD 1000000007
#define itn int
#define enld endl
#define ednl endl
#define icn cin
#define cotu cout
#define Endl endl
#define stirng string
using namespace std;
typedef long long ll;
const double pi = 3.141592653589793;
using Graph = vector<vector<int>>;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}

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

  T _query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return def;

    if (a <= l && r <= b)
      return data[k];
    else {
      T c1 = _query(a, b, 2 * k + 1, l, (l + r) / 2);
      T c2 = _query(a, b, 2 * k + 2, (l + r) / 2, r);
      return operation(c1, c2);
    }
  }

public:
  SegTree(int _n, T _def, function<T(T, T)> _operation,
          function<T(T, T)> _update)
      : def(_def), operation(_operation), update(_update) {
    n = 1;
    while (n < _n) {
      n *= 2;
    }
    data = vector<T>(2 * n - 1, def);
  }

  void change(int i, T x) {
    i += n - 1;
    data[i] = update(data[i], x);
    while (i > 0) {
      i = (i - 1) / 2;
      data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
    }
  }

  T query(int a, int b) { return _query(a, b, 0, 0, n); }

  T operator[](int i) { return data[i + n - 1]; }

  T get(int i) { return data[i + n - 1]; }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  SegTree<int> st(
      n + 1, 0, [](int a, int b) { return max(a, b); },
      [](int a, int b) { return b; });
  int a[300100];
  rep(i, 0, n) cin >> a[i];
  rep(i, 0, n) {
    int l = max(0, a[i] - k);
    int r = min(n, a[i] + k + 1);
    int tmp = st.query(l, r);
    if (st.get(a[i]) < tmp + 1) {
      st.change(a[i], tmp + 1);
    }
  }

  int ans = st.query(0, n);
  cout << ans << endl;
  return 0;
}

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define rep(i, n, m) for (int i = (n); i < (int)(m); i++)
#define reps(i, n, m) for (int i = (n); i <= (int)(m); i++)
#define all(v) v.begin(), v.end()
#define allr(v) v.rbegin(), v.rend()
#define SZ(x) ((int)(x).size())
#define pb push_back
#define fs first
#define sc second
#define lb lower_bound
#define ub upper_bound
#define LB(a, x) lb(all(a), x) - a.begin()
#define UB(a, x) ub(all(a), x) - a.begin()
#define printfdouble(x) printf("%.20f\\n", (x))
#define chartoint(c) (int)((c) - '0')
#define chartoll(c) (long long)((c) - '0')
#define MOD 1000000007
#define itn int
#define enld endl
#define ednl endl
#define icn cin
#define cotu cout
#define Endl endl
#define stirng string
using namespace std;
typedef long long ll;
const double pi = 3.141592653589793;
using Graph = vector<vector<int>>;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}

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

  T _query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return def;

    if (a <= l && r <= b)
      return data[k];
    else {
      T c1 = _query(a, b, 2 * k + 1, l, (l + r) / 2);
      T c2 = _query(a, b, 2 * k + 2, (l + r) / 2, r);
      return operation(c1, c2);
    }
  }

public:
  SegTree(int _n, T _def, function<T(T, T)> _operation,
          function<T(T, T)> _update)
      : def(_def), operation(_operation), update(_update) {
    n = 1;
    while (n < _n) {
      n *= 2;
    }
    data = vector<T>(2 * n - 1, def);
  }

  void change(int i, T x) {
    i += n - 1;
    data[i] = update(data[i], x);
    while (i > 0) {
      i = (i - 1) / 2;
      data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
    }
  }

  T query(int a, int b) { return _query(a, b, 0, 0, n); }

  T operator[](int i) { return data[i + n - 1]; }

  T get(int i) { return data[i + n - 1]; }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  SegTree<int> st(
      300100, 0, [](int a, int b) { return max(a, b); },
      [](int a, int b) { return b; });
  int a[300100];
  rep(i, 0, n) cin >> a[i];
  rep(i, 0, n) {
    int l = max(0, a[i] - k);
    int r = min(300100, a[i] + k + 1);
    int tmp = st.query(l, r);
    if (st.get(a[i]) < tmp + 1) {
      st.change(a[i], tmp + 1);
    }
  }

  int ans = st.query(0, 300100);
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define rep(i, a, n) for (int i = (a); i < (n); i++)
#define per(i, a, n) for (int i = (a); i > (n); i--)
typedef long long ll;
const int maxn = 2e5 + 5;
const int mod = 1e9 + 7;
using namespace std;

ll a[maxn];

void solve() {
  ll n, k;
  cin >> n >> k;
  rep(i, 0, n) { cin >> a[i]; }
  ll ans = -1;
  rep(i, 0, n) {
    if (n - i <= ans)
      break;
    ll res = 1;
    ll pos = i;
    rep(j, i + 1, n) {
      if (abs(a[pos] - a[j]) <= k) {
        pos = j;
        res++;
        ans = max(ans, res);
      }
    }
  }
  cout << ans << '\\n';
}

int main(int argc, char *argv[]) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
#ifdef DEBUG
  freopen("C:/Users/Fish_Brother/Desktop/in", "r", stdin);
  // freopen("C:/Users/Fish_Brother/Desktop/out", "w", stdout);
#endif

  // int t; cin >> t; while(t--)
  solve();

  return 0;
}

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define rep(i, a, n) for (int i = (a); i < (n); i++)
#define per(i, a, n) for (int i = (a); i > (n); i--)
typedef long long ll;
const int maxn = 3e5 + 5;
const int mod = 1e9 + 7;
using namespace std;

ll a[maxn], dp[maxn];

const int N = 300010;

struct TR {
  int l;
  int r;
  int sum;
  int maxv;
} tr[4 * N];
int w[N];
int n, m;

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

void build(int u, int l, int r) {
  if (l == r)
    tr[u] = {l, r, w[r], w[r]};
  else {
    int mid = (l + r) >> 1;
    tr[u] = {l, r};
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);
  }
}

int query(int u, int l, int r) {
  if (tr[u].l >= l && tr[u].r <= r)
    return tr[u].sum;
  int mid = (tr[u].r + tr[u].l) >> 1;
  int sum = 0;
  if (l <= mid)
    sum += query(u << 1, l, r);
  if (r > mid)
    sum += query(u << 1 | 1, l, r);
  return sum;
}

void modify(int u, int x, int v) {
  if (tr[u].l == tr[u].r) {
    tr[u].sum =
        v; // 直接把一点的值进行修改而不需要像树状数组那样+一个值再-一个值
    tr[u].maxv = v;
  } else {
    int mid = (tr[u].l + tr[u].r) >> 1;
    if (x <= mid)
      modify(u << 1, x, v);
    else
      modify(u << 1 | 1, x, v);
    pushup(u);
  }
}

int qmax(int u, int l, int r) { // 查找一段区间中的最大值
  if (tr[u].l >= l && tr[u].r <= r)
    return tr[u].maxv;
  int mid = (tr[u].l + tr[u].r) >> 1;
  int Max = -1;
  if (l <= mid)
    Max = qmax(u << 1, l, r);
  if (r > mid)
    Max = max(Max, qmax(u << 1 | 1, l, r));

  return Max;
}

void solve() {
  ll n, k, ans = 1;
  cin >> n >> k;
  rep(i, 0, n) { cin >> a[i]; }
  build(1, 1, 300006);
  // dp[0]=1;
  rep(i, 0, n) {
    ll t = qmax(1, max(a[i] + 1ll - k, 1ll), min(a[i] + 1ll + k, 300006ll));
    // cout << i << ' ' << t << '\\n';
    dp[i] = t + 1;
    modify(1, a[i] + 1, dp[i]);
  }
  rep(i, 0, n) { ans = max(dp[i], ans); }
  cout << ans << '\\n';
}

int main(int argc, char *argv[]) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
#ifdef DEBUG
  freopen("C:/Users/Fish_Brother/Desktop/in", "r", stdin);
  // freopen("C:/Users/Fish_Brother/Desktop/out", "w", stdout);
#endif

  // int t; cin >> t; while(t--)
  solve();

  return 0;
}


// Nihal Mittal - nihal_47
// Strike First , Strike Hard , No Mercy !!

/**⠀⠀⠀⠀⠀⠀⣀⣤⣤⣄⣀
⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣀
⠀⠀⠀⠀⣰⣿⣿⣿⣿⠿⠿⣿⣿⣿⣿⣿⣿⣿⣧⢀
⠀⠀⠀⣿⣿⣿⠋⠀⠀⠀⠀⠀⠙⠀⠙⣿⣿⣿⣷⢳⢀
⠀⠀⣠⣿⣿⣿⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⢀
⠀⠀⣸⣿⣿⣿⠸⠀⠀⠀⠒⠒⠒⠐⠀⠀⢿⣿⣿⣿⣿⣿
⠀⣴⣿⣿⣿⡿⠀⠒⣋⣙⡒⢰⠀⠤⣖⠒⢾⣿⣿⣿⣿⣧
⢺⣿⣿⣿⣿⢀⠀⠀⠉⠉⠉⠸⠀⡇⠉⠉⠀⢿⣿⣿⣿⣄
⠀⠙⣿⣿⣧⢻⠀⠀⠀⠀⠀⠠⠀⠰⠀⠀⠀⣸⠸⣿⣿⠿⠰
⠀⠀⠀⠹⣿⣿⣿⣷⠀⡠⠙⣲⣔⣅⢡⣰⣷⣿⣿⣿⣧
⠀⠀⠀⣼⣿⣿⣿⣿⠀⡿⠭⠭⠭⠭⢿⠀⣿⢻⣿⣿⠃
⠀⠀⠀⠙⠛⣿⢻⠹⣿⠐⠙⠛⠟⠉⢀⣴⡟⢿⣿⡏
⠀⠀⠀⠀⠀⠀⡟⠀⠀⠻⣦⣤⣶⠾⠋⠀⠀⠁⡦⢄⢀
⠀⠀⠀⠀⡠⠁⡇⠑⢄⠀⠀⠀⠀⠀⠀⠔⠀⠀⠁⠀⠀⠀⠉⠁
⠀⠔⠊⠁⠀⠀⣇⠀⠀⠀⠑⡤⠤⢎⠁⠀⠀⡘
⠀⠀⠀⠀⠀⠀⢢⠠⠀⡠⢆⠀⠀⡠⠙⢄⠀⡸
**/
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define mk make_pair
#define pb push_back
#define in insert
#define se second
#define fi first
#define mod 998244353
#define watch(x) cout << (#x) << " is " << (x) << "\\n"
#define all(v) (v).begin(), (v).end()
#define fast                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(0);
#define printclock                                                             \\
  cerr << "Time : " << 1000 * (ld)clock() / (ld)CLOCKS_PER_SEC << "ms\\n";
#define pii pair<ll, ll>
#define vi(x) vector<x>
using namespace std;
const ll maxn = 300000;
ll tree[4 * maxn + 20];
ll query(ll node, ll st, ll en, ll le, ll re) {

  if (st == le && en == re)
    return tree[node];
  ll mid = (st + en) / 2;
  if (re <= mid)
    return query(2 * node, st, mid, le, re);
  else if (le > mid)
    return query(2 * node + 1, mid + 1, en, le, re);
  else
    return max(query(2 * node, st, mid, le, mid),
               query(2 * node + 1, mid + 1, en, mid + 1, re));
}
void update(ll node, ll st, ll en, ll idx, ll val) {
  if (st == en) {
    tree[node] = val;
  } else {
    ll mid = (st + en) / 2;
    if (idx <= mid)
      update(2 * node, st, mid, idx, val);
    else
      update(2 * node + 1, mid + 1, en, idx, val);
    tree[node] = max(tree[2 * node], tree[2 * node + 1]);
  }
}
int32_t main() {
  fast;

  ll n, k, i, j;
  cin >> n >> k;
  for (i = 0; i < n; i++) {
    ll x;
    cin >> x;
    ll pmi = max(0LL, x - k);
    ll pma = min(maxn, x + k);
    ll num = query(1LL, 0LL, maxn, pmi, pma + 1);
    update(1LL, 0LL, maxn, x, num + 1);
  }
  ll ans = query(1LL, 0LL, maxn, 0LL, maxn);
  cout << ans;
}

#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define fast                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define printclock                                                             \\
  cerr << "Time : " << 1000 * (ld)clock() / (ld)CLOCKS_PER_SEC << "ms\\n";

using namespace std;
const ll maxn = 300000;
ll tree[4 * maxn + 20];
ll query(ll node, ll st, ll en, ll le, ll re) {
  if (le > en or re < st)
    return 0;
  if (le <= st and en <= re)
    return tree[node];
  if (st == le && en == re)
    return tree[node];
  ll mid = (st + en) / 2;
  return max(query(2 * node, st, mid, le, re),
             query(2 * node + 1, mid + 1, en, le, re));
}
void update(ll node, ll st, ll en, ll idx, ll val) {
  if (st == en) {
    tree[node] = max(val, tree[node]);
    return;
  }

  ll mid = (st + en) / 2;
  if (idx <= mid)
    update(2 * node, st, mid, idx, val);
  else
    update(2 * node + 1, mid + 1, en, idx, val);

  tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
signed main() {
  fast;

  ll n, k, i, j;
  cin >> n >> k;
  for (i = 0; i < n; i++) {
    ll x;
    cin >> x;
    ll pmi = max(0LL, x - k);
    ll pma = min(maxn, x + k);
    ll num = query(1LL, 0LL, maxn, pmi, pma);
    update(1LL, 0LL, maxn, x, num + 1);
  }
  ll ans = query(1LL, 0LL, maxn, 0LL, maxn);

  cout << ans;
}


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

#define faster                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define pb push_back
#define mp make_pair

typedef long long ll;
using namespace std;
int inf = 1e9;
const int N = 300005;
int n, k;
int a[N];
int pos[2 * N];

struct segtree {

  int size;
  vector<int> t;

  segtree(int n) {
    size = (int)n;
    t.assign(4 * n, 0);
  }

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

  int get_max(int v, int tl, int tr, int l, int r) {
    if (l > r)
      return -inf;
    if (l == tl && r == tr)
      return t[v];
    int tm = (tl + tr) >> 1;
    return max(get_max(2 * v, tl, tm, l, min(tm, r)),
               get_max(2 * v + 1, tm + 1, tr, max(tm + 1, l), r));
  }

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

  void build() { build(1, 0, size - 1); }

  int get_max(int l, int r) { return get_max(1, 0, size - 1, l, r); }

  void update(int pos, int val) { update(1, 0, size - 1, pos, val); }
};

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

  segtree tree(N);
  tree.build();

  for (int i = 0; i < n; i++) {
    int p = a[i];
    pos[p] = 1;
    tree.update(p, pos[p]);
    int temp = max(tree.get_max(max(0, p - k), p - 1),
                   tree.get_max(p + 1, min(p + k, 2 * N - 1)));
    pos[p] = max(pos[p], temp + 1);
    tree.update(p, pos[p]);
  }
  cout << tree.t[1] << endl;
  return 0;
}

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

#define faster                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define pb push_back
#define mp make_pair

typedef long long ll;
using namespace std;
int inf = 1e9;
const int N = 300005;
int n, k;
int a[N];
int pos[N];

struct segtree {

  int size;
  vector<int> t;

  segtree(int n) {
    size = (int)n;
    t.assign(4 * n, 0);
  }

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

  int get_max(int v, int tl, int tr, int l, int r) {
    if (l > r)
      return -inf;
    if (l == tl && r == tr)
      return t[v];
    int tm = (tl + tr) >> 1;
    return max(get_max(2 * v, tl, tm, l, min(tm, r)),
               get_max(2 * v + 1, tm + 1, tr, max(tm + 1, l), r));
  }

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

  void build() { build(1, 0, size - 1); }

  int get_max(int l, int r) { return get_max(1, 0, size - 1, l, r); }

  void update(int pos, int val) { update(1, 0, size - 1, pos, val); }
};

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

  segtree tree(N);
  tree.build();

  for (int i = 0; i < n; i++) {
    int l = max(0, a[i] - k);
    int r = min(300000, a[i] + k);
    int temp = tree.get_max(l, r);
    tree.update(a[i], temp + 1);
  }
  cout << tree.get_max(0, 300001) << endl;
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define ll long long
#define ull unsigned long long
#define MOD 1000000007
#define MAX 2e9
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(v) v.begin(), v.end()
const double PI = acos(-1);

using namespace std;
int A[300001];
int tr[1200001];

int mx(int x, int s, int e, int l, int r) {
  if (s > r || e < l)
    return 0;
  if (s >= l && e <= r)
    return tr[x];
  else
    return max(mx(x * 2, s, (s + e) / 2, l, r),
               mx(x * 2 + 1, (s + e) / 2 + 1, e, l, r));
}
void update(int x, int s, int e, int i, int val) {
  if (i < s || i > e)
    return;
  // tr[x] = max(val, tr[x]);
  if (s != e) {
    update(x * 2, s, (s + e) / 2, i, val);
    update(x * 2 + 1, (s + e) / 2 + 1, e, i, val);
  }
  tr[x] = max(tr[x * 2], tr[x * 2 + 1]);
}
int main(void) {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  //	freopen("input.txt", "r", stdin);

  int N, K;
  cin >> N >> K;
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    cin >> A[i];
    int cnt = mx(1, 1, 300000, max(0, A[i] - K), min(300000, A[i] + K)) + 1;
    update(1, 1, 300000, A[i], cnt);
    ans = max(ans, cnt);
  }
  cout << ans;
}

#include <algorithm>
#include <cmath>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define ll long long
#define ull unsigned long long
#define MOD 1000000007
#define MAX 2e9
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(v) v.begin(), v.end()
const double PI = acos(-1);

using namespace std;
int A[300001];
int tr[1200010];

int mx(int x, int s, int e, int l, int r) {
  if (s > r || e < l)
    return 0;
  if (s >= l && e <= r)
    return tr[x];
  else
    return max(mx(x * 2, s, (s + e) / 2, l, r),
               mx(x * 2 + 1, (s + e) / 2 + 1, e, l, r));
}
void update(int x, int s, int e, int i, int val) {
  if (i < s || i > e)
    return;
  tr[x] = max(val, tr[x]);
  if (s != e) {
    update(x * 2, s, (s + e) / 2, i, val);
    update(x * 2 + 1, (s + e) / 2 + 1, e, i, val);
  }
}
int main(void) {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  //	freopen("input.txt", "r", stdin);

  int N, K;
  cin >> N >> K;
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    cin >> A[i];
    A[i]++;
    int cnt = mx(1, 1, 300001, max(0, A[i] - K), min(300001, A[i] + K)) + 1;
    update(1, 1, 300001, A[i], cnt);
    ans = max(ans, cnt);
  }
  cout << ans;
}


/*
    Auther: ghoshashis545 Ashis Ghosh
    College: jalpaiguri Govt Enggineering College
    Date:13/06/2020
*/
#include <algorithm>
#include <bits/stdc++.h>
#include <string>
using namespace std;
#define ll long long
#define int long long
#define ld long double
#define ff first
#define clr(a, x) memset(a, x, sizeof(a))
#define ss string
#define se second
#define alt(v) v.begin(), v.end()
#define pb emplace_back
#define mp make_pair
#define ipair pair<int, int>
#define fab(i, a, b) for (ll i = (a); i < (b); i++)
#define fba(i, a, b) for (ll i = (b); i >= (a); i--)
#define arr(i, n) fab(i, 0, n)
ll mod = 1000000007;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, 1, -1};
const int inf = 1e12;
bool test = 0;

const int N = 3 * 1000 + 10;
int mx[4 * N];

void update(int n, int st, int end, int pos, int val) {

  if (st > pos or end < pos)
    return;
  if (st == end and st == pos) {
    mx[n] = max(mx[n], val);
    return;
  }
  int mid = (st + end) / 2;
  update(2 * n, st, mid, pos, val);
  update(2 * n + 1, mid + 1, end, pos, val);
  mx[n] = max(mx[2 * n], mx[2 * n + 1]);
}

int query(int n, int st, int end, int l, int r) {
  if (l <= st && end <= r)
    return mx[n];
  int m = (st + end) / 2;
  if (r <= m)
    return query(2 * n, st, m, l, r);
  else if (l > m)
    return query(2 * n + 1, m + 1, end, l, r);
  else {
    int p1, p2;
    p1 = query(2 * n, st, m, l, r);
    p2 = query(2 * n + 1, m + 1, end, l, r);
    return max(p1, p2);
  }
}

int st, last;
int n, k, x;
void solve() {
  cin >> n >> k;
  clr(mx, 0);
  st = 1, last = 300005;
  for (int i = 1; i <= n; ++i) {
    cin >> x;
    int l = max(st, x - k);
    int r = min(last, x + k);
    int x1 = query(1, st, last, l, r);
    update(1, st, last, x, x1 + 1);
  }
  cout << query(1, st, last, st, last);
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int t = 1;
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  // precompute();
  if (test)
    cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}

/*
    Auther: ghoshashis545 Ashis Ghosh
    College: jalpaiguri Govt Enggineering College
    Date:13/06/2020
*/
#include <algorithm>
#include <bits/stdc++.h>
#include <string>
using namespace std;
#define ll long long
#define int long long
#define ld long double
#define ff first
#define clr(a, x) memset(a, x, sizeof(a))
#define ss string
#define se second
#define alt(v) v.begin(), v.end()
#define pb emplace_back
#define mp make_pair
#define ipair pair<int, int>
#define fab(i, a, b) for (ll i = (a); i < (b); i++)
#define fba(i, a, b) for (ll i = (b); i >= (a); i--)
#define arr(i, n) fab(i, 0, n)
ll mod = 1000000007;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, 1, -1};
const int inf = 1e12;
bool test = 0;

const int N = 3e5 + 5;
int mx[4 * N];

void update(int n, int st, int end, int pos, int val) {
  if (st == end && st == pos) {
    mx[n] = val;
    return;
  }
  int m = (st + end) / 2;
  if (pos <= m)
    update(2 * n, st, m, pos, val);
  if (pos > m)
    update(2 * n + 1, m + 1, end, pos, val);
  mx[n] = max(mx[2 * n], mx[2 * n + 1]);
}
int query(int n, int st, int end, int l, int r) {
  if (l <= st && end <= r)
    return mx[n];
  int m = (st + end) / 2;
  if (r <= m)
    return query(2 * n, st, m, l, r);
  else if (l > m)
    return query(2 * n + 1, m + 1, end, l, r);
  else {
    int p1, p2;
    p1 = query(2 * n, st, m, l, r);
    p2 = query(2 * n + 1, m + 1, end, l, r);
    return max(p1, p2);
  }
}

int st, last;
int n, k, x;
void solve() {
  cin >> n >> k;
  clr(mx, 0);
  st = 0, last = 300000;
  for (int i = 1; i <= n; ++i) {
    cin >> x;
    int l = max(st, x - k);
    int r = min(last, x + k);
    int x1 = query(1, st, last, l, r);
    update(1, st, last, x, x1 + 1);
  }
  cout << query(1, st, last, st, last);
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int t = 1;
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  // precompute();
  if (test)
    cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}


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

using tlll = tuple<ll, ll, ll>;

int main() {

  ll N, K;
  cin >> N >> K;
  vector<ll> A(N), G(N, 1);
  for (ll i = 0; i < N; i++) {
    cin >> A[i];
  }
  ll maxl = 0;
  for (ll i = N - 1; i >= 0; i--) {
    for (ll j = i + 1; j < N; j++) {

      if (abs(A[j] - A[i]) <= K) {

        G[i] = max(G[i], G[j] + 1);
        if (maxl < G[j] + 1) {
          maxl = G[j] + 1;
          break;
        }
      }
    }
  }

  sort(G.begin(), G.end());
  cout << G[G.size() - 1] << endl;
}

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

using tlll = tuple<ll, ll, ll>;

int main() {

  ll N, K;
  cin >> N >> K;
  vector<ll> A(N), G(N, 1), MV(N, 1e6);
  for (ll i = 0; i < N; i++) {
    cin >> A[i];
  }
  ll maxl = 0;
  MV[N - 1] = 1;
  for (ll i = N - 1; i >= 0; i--) {

    for (ll j = i + 1; j < N; j++) {

      if (abs(A[j] - A[i]) <= K) {

        G[i] = max(G[i], G[j] + 1);
        if (maxl < G[j] + 1) {
          maxl = G[j] + 1;
          MV[i] = maxl;
          break;
        }
        if (MV[j] <= G[i] - 1) {
          MV[i] = maxl;
          break;
        }
      }
    }
  }

  sort(G.begin(), G.end());
  cout << G[G.size() - 1] << endl;
}


// #pragma GCC optimize ("Ofast")
// #pragma GCC target
// ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include "bits/stdc++.h"
using namespace std;
#define ll long long
#define pb push_back
#define all(_obj) _obj.begin(), _obj.end()
#define F first
#define S second
#define INF 1e18
#define pll pair<ll, ll>
#define vll vector<ll>
ll n, m, a, b, c, k, temp, x, y;
const int MAXN = 1e5 + 11, mod = 1e9 + 7;
ll max(ll a, ll b) { return ((a > b) ? a : b); }
ll min(ll a, ll b) { return ((a > b) ? b : a); }
vll read(int n) {
  vll v(n);
  for (int i = 0; i < v.size(); i++)
    cin >> v[i];
  return v;
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int tree[4 * MAXN];
int qfst(int l, int r) {
  int res = 0;
  for (l += 300001, r += 300001; l < r; l >>= 1, r >>= 1) {
    if (l & 1)
      res = max(tree[l++], res);
    if (r & 1)
      res = max(tree[--r], res);
  }
  return res;
}
void modify(int p, int value) {
  for (tree[p += 300001] = value; p > 1; p >>= 1)
    tree[p >> 1] = max(tree[p], tree[p ^ 1]);
}
void sol(void) {
  cin >> n >> k;
  vll v = read(n);
  for (int i = 0; i < n; i++) {
    int mx = qfst(v[i], v[i] + 1);
    int ending = qfst(max(0, v[i] - k), min(v[i] + k + 1, 300001)) + 1;
    modify(v[i], max(mx, ending));
  }
  cout << qfst(0, 300001);
  return;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int test = 1;
  // cin>>test;
  for (int i = 1; i <= test; i++)
    sol();
}

// #pragma GCC optimize ("Ofast")
// #pragma GCC target
// ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include "bits/stdc++.h"
using namespace std;
#define ll long long
#define pb push_back
#define all(_obj) _obj.begin(), _obj.end()
#define F first
#define S second
#define INF 1e18
#define pll pair<ll, ll>
#define vll vector<ll>
ll n, m, a, b, c, k, temp, x, y;
const int MAXN = 1e5 + 11, mod = 1e9 + 7;
ll max(ll a, ll b) { return ((a > b) ? a : b); }
ll min(ll a, ll b) { return ((a > b) ? b : a); }
vll read(int n) {
  vll v(n);
  for (int i = 0; i < v.size(); i++)
    cin >> v[i];
  return v;
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int tree[6 * MAXN];
int qfst(int l, int r) {
  int res = 0;
  for (l += 300001, r += 300001; l < r; l >>= 1, r >>= 1) {
    if (l & 1)
      res = max(tree[l++], res);
    if (r & 1)
      res = max(tree[--r], res);
  }
  return res;
}
void modify(int p, int value) {
  for (tree[p += 300001] = value; p > 1; p >>= 1)
    tree[p >> 1] = max(tree[p], tree[p ^ 1]);
}
void sol(void) {
  cin >> n >> k;
  vll v = read(n);
  for (int i = 0; i < n; i++) {
    int mx = qfst(v[i], v[i] + 1);
    int ending = qfst(max(0, v[i] - k), min(v[i] + k + 1, 300001)) + 1;
    modify(v[i], max(mx, ending));
  }
  cout << qfst(0, 300001);
  return;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int test = 1;
  // cin>>test;
  for (int i = 1; i <= test; i++)
    sol();
}


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

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


#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;
#define ordered_set                                                            \\
  tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_Node_update>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define inf 1e18
#define mk make_pair
#define ld long double
#define mod 998244353
#define fi first
#define se second
#define fastIO                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
#define test                                                                   \\
  ll t;                                                                        \\
  cin >> t;                                                                    \\
  while (t--)
#define setbits __builtin_popcount
#define endl '\\n'
#define LOCAL
#define sim template <class c
#define ris return *this
#define dor > debug &operator<<
#define eni(x)                                                                 \\
  sim > typename enable_if<sizeof dud<c>(0) x 1, debug &>::type operator<<(    \\
            c i) {
sim > struct rge {
  c b, e;
};
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c *x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
  ~debug() { cerr << endl; }
  eni(!=) cerr << boolalpha << i;
  ris;
} eni(==) ris << range(begin(i), end(i));
}
sim, class b dor(pair<b, c> d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
  sim dor(const c &) { ris; }
#endif
}
;
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
const ll maxn = 600001;
ll seg[4 * maxn];
void build(ll v, ll l, ll r) {
  if (l == r) {
    seg[v] = 0;
    return;
  }
  ll mid = (l + r) / 2;
  build(2 * v, l, mid);
  build(2 * v + 1, mid + 1, r);
  seg[v] = max(seg[2 * v], seg[2 * v + 1]);
}
void update(ll v, ll l, ll r, ll pos, ll val) {
  if (l == r) {
    seg[v] = max(val, seg[v]);
    return;
  }
  ll mid = (l + r) / 2;
  if (pos <= mid) {
    update(2 * v, l, mid, pos, val);
  } else {
    update(2 * v + 1, mid + 1, r, pos, val);
  }
  seg[v] = max(seg[2 * v], seg[2 * v + 1]);
}
ll query(ll v, ll l, ll r, ll x, ll y) {
  if (y < x) {
    return -inf;
  }
  if (x <= l && r <= y) {
    return seg[v];
  }
  ll mid = (l + r) / 2;
  ll val, val1;
  val = query(2 * v, l, mid, x, min(mid, y));
  val1 = query(2 * v + 1, mid + 1, r, max(mid + 1, x), y);
  return max(val, val1);
}
int main() {
  fastIO;
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  build(1, 0, n - 1);
  ll x, y, val, val1;
  for (int i = 0; i < n; i++) {
    x = max((ll)0, a[i] - k);
    y = a[i] + k;
    val = query(1, 0, n - 1, x, y);
    update(1, 0, n - 1, a[i], val + 1);
  }
  cout << seg[1] << endl;
}

#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;
#define ordered_set                                                            \\
  tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_Node_update>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define inf 1e18
#define mk make_pair
#define ld long double
#define mod 998244353
#define fi first
#define se second
#define fastIO                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
#define test                                                                   \\
  ll t;                                                                        \\
  cin >> t;                                                                    \\
  while (t--)
#define setbits __builtin_popcount
#define endl '\\n'
#define LOCAL
#define sim template <class c
#define ris return *this
#define dor > debug &operator<<
#define eni(x)                                                                 \\
  sim > typename enable_if<sizeof dud<c>(0) x 1, debug &>::type operator<<(    \\
            c i) {
sim > struct rge {
  c b, e;
};
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c *x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
  ~debug() { cerr << endl; }
  eni(!=) cerr << boolalpha << i;
  ris;
} eni(==) ris << range(begin(i), end(i));
}
sim, class b dor(pair<b, c> d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
  sim dor(const c &) { ris; }
#endif
}
;
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
const ll maxn = 600001;
ll seg[4 * maxn];
void build(ll v, ll l, ll r) {
  if (l == r) {
    seg[v] = 0;
    return;
  }
  ll mid = (l + r) / 2;
  build(2 * v, l, mid);
  build(2 * v + 1, mid + 1, r);
  seg[v] = max(seg[2 * v], seg[2 * v + 1]);
}
void update(ll v, ll l, ll r, ll pos, ll val) {
  if (l == r) {
    seg[v] = val;
    return;
  }
  ll mid = (l + r) / 2;
  if (pos <= mid) {
    update(2 * v, l, mid, pos, val);
  } else {
    update(2 * v + 1, mid + 1, r, pos, val);
  }
  seg[v] = max(seg[2 * v], seg[2 * v + 1]);
}
ll query(ll v, ll l, ll r, ll x, ll y) {
  if (y < x) {
    return 0;
  }
  if (x <= l && r <= y) {
    return seg[v];
  }
  ll mid = (l + r) / 2;
  ll val, val1;
  val = query(2 * v, l, mid, x, min(mid, y));
  val1 = query(2 * v + 1, mid + 1, r, max(mid + 1, x), y);
  return max(val, val1);
}
int main() {
  fastIO;
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  build(1, 0, n - 1);
  ll x, y, val, val1;
  for (int i = 0; i < n; i++) {
    x = max((ll)0, a[i] - k);
    y = a[i] + k;
    val = query(1, 0, maxn, x, y);
    update(1, 0, maxn, a[i], val + 1);
  }
  cout << seg[1] << endl;
}


#include <cstdio>

int n, k, a[300010], lst, dis[300010], pre[300010];

template <class I> inline I abs(I x) { return x >= 0 ? x : -x; }
template <class I> inline I max(I a, I b) { return a > b ? a : b; }

int main(void) {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
  for (int i = 1; i <= n; ++i) {
    dis[i] = 1, pre[i] = -1;
    for (int j = i - 1; j >= 1; --j)
      if (abs(a[i] - a[j]) <= k && dis[j] + 1 > dis[i])
        pre[i] = j, dis[i] = dis[j] + 1;
  }
  for (int i = 1; i <= n; ++i)
    lst = max(lst, dis[i]);
  printf("%d\\n", lst);
  return 0;
}

#include <cstdio>

int n, k, a[300010], lst, dis[300010];

template <class I> inline I abs(I x) { return x >= 0 ? x : -x; }
template <class I> inline I max(I a, I b) { return a > b ? a : b; }

inline bool cmp(int a, int b) { return abs(a - b) > k; }

int main(void) {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
  for (int i = 1; i <= n; ++i) {
    dis[i] = 1;
    for (int j = i - 1; i - j <= 100 && j >= 1; --j)
      if (abs(a[i] - a[j]) <= k && dis[j] + 1 > dis[i])
        dis[i] = dis[j] + 1;
  }
  for (int i = 1; i <= n; ++i)
    lst = max(lst, dis[i]);
  printf("%d\\n", lst);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
int val[N << 1];
int a[N];
void pushUp(int u) { val[u] = max(val[u << 1], val[u << 1 | 1]); }
void update(int u, int l, int r, int x, int d) {
  if (l == r) {
    val[u] += d;
    return;
  }
  int mid = l + r >> 1;
  if (x <= mid)
    update(u << 1, l, mid, x, d);
  else
    update(u << 1 | 1, mid + 1, r, x, d);
  pushUp(u);
}
int query(int u, int l, int r, int x, int y) {
  if (x <= l && r <= y) {
    return val[u];
  }
  int res = 0;
  int mid = l + r >> 1;
  if (x <= mid)
    res = max(res, query(u << 1, l, mid, x, y));
  if (y > mid)
    res = max(res, query(u << 1 | 1, mid + 1, r, x, y));
  return res;
}
int maxDog;
int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    maxDog = max(maxDog, a[i]);
  }
  for (int i = 1; i <= n; i++) {
    int t = 0;
    if (a[i] - k >= 0 && a[i] + k <= maxDog)
      t = query(1, 1, n, a[i] - k, a[i] + k) + 1;
    update(1, 1, n, a[i], t);
  }
  printf("%d\\n", query(1, 1, n, 1, n));
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
int val[N << 1];
int a[N];
void pushUp(int u) { val[u] = max(val[u << 1], val[u << 1 | 1]); }
void update(int u, int l, int r, int x, int d) {
  if (l == r) {
    val[u] = max(d, val[u]);
    return;
  }
  int mid = l + r >> 1;
  if (x <= mid)
    update(u << 1, l, mid, x, d);
  else
    update(u << 1 | 1, mid + 1, r, x, d);
  pushUp(u);
}
int query(int u, int l, int r, int x, int y) {
  if (x <= l && r <= y) {
    return val[u];
  }
  int res = 0;
  int mid = l + r >> 1;
  if (x <= mid)
    res = max(res, query(u << 1, l, mid, x, y));
  if (y > mid)
    res = max(res, query(u << 1 | 1, mid + 1, r, x, y));
  return res;
}
int maxDog;
int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    maxDog = max(maxDog, a[i]);
  }
  for (int i = 1; i <= n; i++) {
    int t = query(1, 1, maxDog, max(1, a[i] - k), min(maxDog, a[i] + k)) + 1;
    update(1, 1, maxDog, a[i], t);
  }
  printf("%d\\n", query(1, 1, maxDog, 1, maxDog));
  return 0;
}


#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f;
const double pi = 3.1415926535897932384626;
inline ll read() {
  ll x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
const int maxn = 3e5 + 5;
int n, k, a[maxn], ans = 1;
void dfs(int x, int val) {
  if (x == n) {
    ans = max(ans, val);
    return;
  }
  int i = n + 1;
  for (i = x + 1; i <= n; i++) {
    if (abs(a[x] - a[i]) <= k)
      break;
  }
  if (i <= n)
    dfs(i, val + 1);
  dfs(x + 1, 1);
}
int main() {
  n = read(), k = read();
  for (int i = 1; i <= n; i++)
    a[i] = read();
  dfs(1, 1);
  printf("%d\\n", ans);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f;
const double pi = 3.1415926535897932384626;
inline ll read() {
  ll x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
const int maxn = 3e5 + 5;
int n, k, tot, a[maxn], sum[maxn << 2];
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
void push_up(int rt) { sum[rt] = max(sum[rt << 1], sum[rt << 1 | 1]); }
void update(int x, int c, int l, int r, int rt) {
  if (l == r) {
    sum[rt] = max(sum[rt], c);
    return;
  }
  int m = (l + r) >> 1;
  if (x <= m)
    update(x, c, l, m, rt << 1);
  else
    update(x, c, m + 1, r, rt << 1 | 1);
  push_up(rt);
}
int query(int a, int b, int l, int r, int rt) {
  if (a <= l && b >= r)
    return sum[rt];
  int m = (l + r) >> 1;
  int ans = 0;
  if (a <= m)
    ans = max(ans, query(a, b, l, m, rt << 1));
  if (b > m)
    ans = max(ans, query(a, b, m + 1, r, rt << 1 | 1));
  return ans;
}
int main() {
  n = read(), k = read();
  for (int i = 1; i <= n; i++) {
    a[i] = read() + 1;
    tot = max(tot, a[i]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int tmp = query(max(1, a[i] - k), min(tot, a[i] + k), 1, tot, 1) + 1;
    update(a[i], tmp, 1, tot, 1);
    ans = max(ans, tmp);
  }
  printf("%d\\n", ans);
  return 0;
}


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

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;

// #define ordered_set tree<int, null_type,less<int>,
// rb_tree_tag,tree_order_statistics_node_update>

#define ll long long
#define fill fill_n
#define pf push_front
#define pb push_back
#define FOR(i, l, r) for (int i = l; i < r; i++)
#define ROF(i, r, l) for (int i = r; i >= l; i--)
#define all(v) (v).begin(), (v).end()
#define ff first
#define ss second
typedef vector<int> vi;
typedef vector<ll> vli;
typedef vector<pair<int, int>> vpi;

const int M = 1e9 + 7;
const int N = 2e5;
ll po(int, int);

vi e[N];
vector<bool> vis;
void dfs(int u) {
  vis[u] = 1;
  for (auto i : e[u]) {
    if (!vis[i])
      dfs(i);
  }
}

void solve() {
  int n, k;
  cin >> n >> k;
  int a[n];
  FOR(i, 0, n) { cin >> a[i]; }

  int dp[n];
  FOR(i, 0, n) { dp[i] = 1; }
  FOR(i, 1, n) {

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

  cout << ans << "\\n";
}

int main() {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

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

  int t = 1;
  // cin>>t;
  FOR(i, 1, t + 1) {
    // cout<<"Case #"<<i<<": ";
    solve();
  }

  return 0;
}

ll po(int a, int b) {
  if (b == 0)
    return 1;
  ll ans = 1;
  if (b % 2 == 0) {
    ans = po(a, b / 2) % M;
    ans = (ans % M * ans % M) % M;
  } else {
    ans = po(a, (b - 1) / 2) % M;
    ans = (ans % M * ans % M * a) % M;
  }
  return ans % M;
}

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

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;

// #define ordered_set tree<int, null_type,less<int>,
// rb_tree_tag,tree_order_statistics_node_update>

#define ll long long
#define fill fill_n
#define pf push_front
#define pb push_back
#define FOR(i, l, r) for (int i = l; i < r; i++)
#define ROF(i, r, l) for (int i = r; i >= l; i--)
#define all(v) (v).begin(), (v).end()
#define ff first
#define ss second
typedef vector<int> vi;
typedef vector<ll> vli;
typedef vector<pair<int, int>> vpi;

const int M = 1e9 + 7;
const int N = 3e5;
ll po(int, int);

int tree[4 * N + 5];

void update(int n, int s, int e, int id, int val) {
  if (s == e) {
    tree[n] = val;
    return;
  }
  int mid = (s + e) >> 1;
  if (id >= s && id <= mid) {
    update(2 * n, s, mid, id, val);

  } else
    update(2 * n + 1, mid + 1, e, id, val);

  tree[n] = max(tree[2 * n], tree[2 * n + 1]);
}
int query(int n, int s, int e, int l, int r) {
  if (s > r || e < l)
    return 0;
  if (s >= l && e <= r)
    return tree[n];
  int mid = (s + e) >> 1;
  return max(query(2 * n, s, mid, l, r), query(2 * n + 1, mid + 1, e, l, r));
}

void solve() {
  int n;
  cin >> n;
  int k;
  cin >> k;
  int el;
  int ans = 0;
  FOR(i, 0, n) {
    cin >> el;
    int x = query(1, 0, N, el - k, el + k);
    ans = max(ans, x + 1);
    update(1, 0, N, el, x + 1);
  }

  cout << ans << "\\n";
}

int main() {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

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

  int t = 1;
  // cin>>t;
  FOR(i, 1, t + 1) {
    // cout<<"Case #"<<i<<": ";
    solve();
  }

  return 0;
}

ll po(int a, int b) {
  if (b == 0)
    return 1;
  ll ans = 1;
  if (b % 2 == 0) {
    ans = po(a, b / 2) % M;
    ans = (ans % M * ans % M) % M;
  } else {
    ans = po(a, (b - 1) / 2) % M;
    ans = (ans % M * ans % M * a) % M;
  }
  return ans % M;
}


#include <algorithm>
#include <iostream>
#include <regex>
#include <set>
#include <vector>
using namespace std;

int N, K;
int A[303030];
int dp[303030];

int dp_dfs(int n) {
  if (dp[n] != 0)
    return dp[n];

  int max_len = 1;
  for (int i = n + 1; i < N; i++) {
    if (A[n] - K <= A[i] && A[i] <= A[n] + K) {
      max_len = max(max_len, dp_dfs(i) + 1);
    }
  }
  return dp[n] = max_len;
}

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

  int ans = 0;
  for (int i = 0; i < N; i++) {
    ans = max(ans, dp_dfs(i));
  }

  cout << ans << endl;

  return 0;
}

#include <algorithm>
#include <iostream>
#include <regex>
#include <set>
#include <vector>
using namespace std;

int N, K;
int A[303030];
int dp[303030];

const int MAX_N = 1 << 18;
int seg_n, dat[4 * MAX_N - 1];
void init(int n_) {
  seg_n = 1;
  while (seg_n < n_)
    seg_n *= 2;
  for (int i = 0; i < 2 * seg_n - 1; i++)
    dat[i] = INT32_MIN;
}
void update(int k, int a) {
  k += seg_n - 1;
  dat[k] = a;
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = max(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
}
int query(int a, int b, int k, int l, int r) {
  if (r <= a || b <= l)
    return INT32_MIN;
  if (a <= l && r <= b)
    return dat[k];
  else {
    int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
}

int dp_dfs(int n) {
  if (dp[n] != 0)
    return dp[n];

  int res = query(A[n] - K, A[n] + K + 1, 0, 0, seg_n);
  if (res == INT32_MIN) {
    return dp[n] = 1;
  } else {
    return dp[n] = res + 1;
  }
  // for (int i=n+1; i<N; i++) {
  //     if (A[n] - K <= A[i] && A[i] <= A[n] + K) {
  //         max_len = max(max_len, dp_dfs(i) + 1);
  //     }
  // }
}

int kmax[303030];

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

  // cout << 111 << endl;
  init(303030);
  // cout << 222 << endl;

  for (int i = N - 1; i >= 0; i--) {
    // cout << 333 << endl;
    int dp_ret = dp_dfs(i);
    // kmax[A[i]] = max(kmax[A[i]], dp_ret);
    update(A[i], dp_ret);
    // cout << 444 << endl;
  }

  cout << query(0, 303030, 0, 0, seg_n) << endl;

  return 0;
}