#include <bits/stdc++.h>
using namespace std;
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;
}
int main() {
  int n, k, i, ans = 1;
  cin >> n >> k;
  for (i = 1; i <= n; i++)
    cin >> a[i];
  build(0, n, 1);
  dp[1] = 1;
  change(1, 1, 1);
  for (i = 2; i <= n; i++) {
    dp[i] = max(1, ask(max(0, a[i] - k), min(n, a[i] + k), 1) + 1);
    change(a[i], 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 = 0;
  cin >> n >> k;
  for (i = 1; i <= n; i++)
    cin >> a[i];
  build(1, 300002, 1);
  for (i = 1; i <= n; i++) {
    dp[i] = 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;
}


//  RAKSHIT KADAM
// rax_coder
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp> 3
// #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>
#warning check the size of arrays!!!
// NUMERIC DEFINITIONS :
#define INF 1000000000000000005
#define inf 1000000004
#define MOD 1000000007
#define mod 998244353
#define MAX 300006
#define pi 3.1415926535897932384626433832795
#define ld long double
#define ll long long
#define int long long
#define P(gg)                                                                  \\
  for (auto rax : gg) {                                                        \\
    cout << rax << " ";                                                        \\
  }                                                                            \\
  cout << endl;
#define Need_for_speed(activated)                                              \\
  ios_base ::sync_with_stdio(0);                                               \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL)
#define satisfy                                                                \\
  ll ter;                                                                      \\
  cin >> ter;                                                                  \\
  while (ter--)
#define inp(n)                                                                 \\
  int n;                                                                       \\
  cin >> n
#define mp make_pair
#define pb push_back
#define endl "\\n"
#define x first
#define y second
#define fore(i, a, b) for (ll i = a; i < b; i++)
#define forci(i, n) for (ll i = 0; i < n; i++)
#define vi vector<ll>
#define Endl endl
#define lb lower_bound
#define ub upper_bound
#define pii pair<ll, ll>

#define input                                                                  \\
  freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout)
#define time                                                                   \\
  cerr << "\\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\\n";
using namespace std;

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

int power(int x, unsigned int y, unsigned int m) {
  if (y == 0)
    return 1;
  int p = power(x, y / 2, m) % m;
  p = (p * p) % m;
  return (y % 2 == 0) ? p : (x * p) % m;
}
ll modInverse(int a, int m) {
  { return power(a, m - 2, m); }
}
const int maxn = 500003;
// ll fact[300009];
// ll modIN[100009];
// void facto()
//{
//     ll lim =300005;fact[0]=1;
//     for(ll i=1;i<lim;i++)
//     {
//         fact[i]=(fact[i-1]*i)%mod;
//     }
//
// }
// ll ncr(ll a,ll b)
//{
//     ll ret = 0;
//     ret = fact[a]*(modInverse(fact[b],mod));
//
//     ret%=mod;
//     ret*=modInverse(fact[a-b],mod);
//     ret%=mod;
//
//     return ret;
// }
//   """""   1LL << x    """""

ll seg[maxn << 1];
ll arr[maxn];

void update(ll ind, ll l, ll r, ll pos, ll val) {
  if (l == r) {
    seg[ind] = val;
    //        cout<<ind<<" -- "<<val<<endl;
    return;
  }
  ll mid = l + r >> 1;
  if (mid >= pos) {
    update(ind * 2, l, mid, pos, val);
  } else
    update(ind * 2 + 1, mid + 1, r, pos, val);
  seg[ind] = max(seg[ind * 2], seg[ind * 2 + 1]);
}
ll cnt = 0;
ll query(ll l, ll r, ll ind, ll L, ll R) {
  if (L > R)
    return 0;
  if (l >= L && r <= R) {
    return seg[ind];
  }
  ll mid = l + r >> 1;
  ll ret = 0;
  ret = max(query(l, mid, ind * 2, L, min(R, mid)),
            query(mid + 1, r, ind * 2 + 1, max(L, mid + 1), R));
  return ret;
}
void solve() {
  ll n;
  cin >> n;
  ll x;
  ll k;
  cin >> k;
  ll ans = 0;
  for (ll i = 1; i <= n; i++) {
    cin >> x;
    ll p = query(1, 300000, 1, max(0LL, x - k), min(x + k, 600000LL));
    //        cout<<p<<endl;
    update(1, 1, 300000, x, p + 1);
  }
  cout << seg[1] << endl;
}

signed main() {
  Need_for_speed(activated);

  //    satisfy
  //    {
  // solve();
  //    }

  solve();
  return 0;
}

//  RAKSHIT KADAM
// rax_coder
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp> 3
// #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>
#warning check the size of arrays!!!
// NUMERIC DEFINITIONS :
#define INF 1000000000000000005
#define inf 1000000004
#define MOD 1000000007
#define mod 998244353
#define MAX 300006
#define pi 3.1415926535897932384626433832795
#define ld long double
#define ll long long
#define int long long
#define P(gg)                                                                  \\
  for (auto rax : gg) {                                                        \\
    cout << rax << " ";                                                        \\
  }                                                                            \\
  cout << endl;
#define Need_for_speed(activated)                                              \\
  ios_base ::sync_with_stdio(0);                                               \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL)
#define satisfy                                                                \\
  ll ter;                                                                      \\
  cin >> ter;                                                                  \\
  while (ter--)
#define inp(n)                                                                 \\
  int n;                                                                       \\
  cin >> n
#define mp make_pair
#define pb push_back
#define endl "\\n"
#define x first
#define y second
#define fore(i, a, b) for (ll i = a; i < b; i++)
#define forci(i, n) for (ll i = 0; i < n; i++)
#define vi vector<ll>
#define Endl endl
#define lb lower_bound
#define ub upper_bound
#define pii pair<ll, ll>

#define input                                                                  \\
  freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout)
#define time                                                                   \\
  cerr << "\\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\\n";
using namespace std;

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

int power(int x, unsigned int y, unsigned int m) {
  if (y == 0)
    return 1;
  int p = power(x, y / 2, m) % m;
  p = (p * p) % m;
  return (y % 2 == 0) ? p : (x * p) % m;
}
ll modInverse(int a, int m) {
  { return power(a, m - 2, m); }
}
const int maxn = 500003;
// ll fact[300009];
// ll modIN[100009];
// void facto()
//{
//     ll lim =300005;fact[0]=1;
//     for(ll i=1;i<lim;i++)
//     {
//         fact[i]=(fact[i-1]*i)%mod;
//     }
//
// }
// ll ncr(ll a,ll b)
//{
//     ll ret = 0;
//     ret = fact[a]*(modInverse(fact[b],mod));
//
//     ret%=mod;
//     ret*=modInverse(fact[a-b],mod);
//     ret%=mod;
//
//     return ret;
// }
//   """""   1LL << x    """""

ll seg[maxn * 4];
ll arr[maxn];

void update(ll ind, ll l, ll r, ll pos, ll val) {
  if (l == r) {
    seg[ind] = val;
    //        cout<<ind<<" -- "<<val<<endl;
    return;
  }
  ll mid = l + r >> 1;
  if (mid >= pos) {
    update(ind * 2, l, mid, pos, val);
  } else
    update(ind * 2 + 1, mid + 1, r, pos, val);
  seg[ind] = max(seg[ind * 2], seg[ind * 2 + 1]);
}
ll cnt = 0;
ll query(ll l, ll r, ll ind, ll L, ll R) {
  if (L > R)
    return 0;
  if (l >= L && r <= R) {
    return seg[ind];
  }
  ll mid = l + r >> 1;
  ll ret = 0;
  ret = max(query(l, mid, ind * 2, L, min(R, mid)),
            query(mid + 1, r, ind * 2 + 1, max(L, mid + 1), R));
  return ret;
}
void solve() {
  ll n;
  cin >> n;
  ll x;
  ll k;
  cin >> k;
  ll ans = 0;
  for (ll i = 1; i <= n; i++) {
    cin >> x;
    ll p = query(1, 300000, 1, max(0LL, x - k), min(x + k, 600000LL));
    update(1, 1, 300000, x, p + 1);
  }
  cout << seg[1] << endl;
}

signed main() {
  Need_for_speed(activated);

  //    satisfy
  //    {
  // solve();
  //    }

  solve();
  return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define per(i, a, b) for (int i = a; i >= b; --i)
#define mem0(x) memset(x, 0, sizeof(x))
#define meminf(x) memset(x, 0x3f, sizeof(x))
#define VI vector<int>
#define VL vector<ll>
using namespace std;

const int N = 3e5 + 5;
int a[N];
int dp[N];
int ans = 0;
int n, k;
void dfs(int x, int len) {
  if (len == n)
    return;
  ans = max(ans, dp[x]);
  for (int ad = 1; x + ad <= n; ++ad) {
    if (abs(a[x + ad] - a[x]) > 3) {
      if (dp[x + ad])
        ans = max(ans, dp[x + ad]);
      else
        dfs(x + ad, 1);
    } else {
      dp[x + ad] = len + 1;
      dfs(x + ad, len + 1);
      break;
    }
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> k;
  rep(i, 1, n) { cin >> a[i]; }
  dp[1] = 1;
  dfs(1, 1);
  cout << ans;
}

#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define per(i, a, b) for (int i = a; i >= b; --i)
#define mem0(x) memset(x, 0, sizeof(x))
#define meminf(x) memset(x, 0x3f, sizeof(x))
#define VI vector<int>
#define VL vector<ll>
using namespace std;

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

#define lson(x) ((x) << 1)
#define rson(x) ((x) << 1 | 1)
int maxx[N << 2];

void push_up(int i) { maxx[i] = max(maxx[lson(i)], maxx[rson(i)]); }
int qMax(int i, int tl, int tr, int l, int r) {
  if (tl <= l && r <= tr) {
    return maxx[i];
  }
  int mid = (l + r) >> 1;
  int ans1 = 0, ans2 = 0;
  if (tl <= mid) {
    ans1 = qMax(lson(i), tl, tr, l, mid);
  }
  if (mid < tr) {
    ans2 = qMax(rson(i), tl, tr, mid + 1, r);
  }
  return max(ans1, ans2);
}

void updateS(int i, int l, int r, int idx, int val) {
  if (l == r) {
    maxx[i] = val;
    return;
  }
  int mid = (l + r) >> 1;
  if (idx <= mid) {
    updateS(lson(i), l, mid, idx, val);
  } else {
    updateS(rson(i), mid + 1, r, idx, val);
  }
  push_up(i);
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> k;
  rep(i, 1, n) { cin >> a[i]; }
  int ans = 0;
  rep(i, 1, n) {
    int l = max(0, a[i] - k) + 1, r = min(N - 5, a[i] + k) + 1;
    int res = qMax(1, l, r, 1, N - 4);
    res++;
    ans = max(res, ans);
    // cout<<"res:"<<res<<'\\n';
    // cout<<"ans:"<<ans<<'\\n';
    updateS(1, 1, N - 4, a[i] + 1, res);
  }

  cout << ans;
}


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

set<int> S;

int A[100005], B[100005];
int tree[400005];

int get_max(int left, int right, int L, int R, int root) {
  if (left > right || left > R || right < L)
    return 0;

  if (left >= L && right <= R)
    return tree[root];

  int mid = (left + right) / 2;

  return max(get_max(left, mid, L, R, root * 2),
             get_max(mid + 1, right, L, R, root * 2 + 1));
}

void update(int left, int right, int x, int val, int root) {
  if (left > right || left > x || right < x)
    return;

  if (left == right && right == x) {
    tree[root] = val;
    return;
  }

  int mid = (left + right) / 2;

  update(left, mid, x, val, root * 2);
  update(mid + 1, right, x, val, root * 2 + 1);

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

int main() {

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

  for (int i = 1; i <= N; i++) {
    cin >> A[i];
    S.insert(A[i]);
  }

  int k = 1;

  for (set<int>::iterator it = S.begin(); it != S.end(); it++)
    B[k++] = *it;

  k--;
  int ans = 0;

  for (int i = 1; i <= N; i++) {
    int x = lower_bound(B + 1, B + 1 + k, A[i]) - B;
    int y = lower_bound(B + 1, B + 1 + k, A[i] - K) - B;
    int z = upper_bound(B + 1, B + 1 + k, A[i] + K) - B - 1;

    int new_ans = get_max(1, N, y, z, 1) + 1;
    ans = max(ans, new_ans);

    update(1, N, x, new_ans, 1);
  }

  cout << ans << endl;

  return 0;
}

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

set<int> S;

int A[300005], B[300005];
int tree[3 * 400005];

int get_max(int left, int right, int L, int R, int root) {
  if (left > right || left > R || right < L)
    return 0;

  if (left >= L && right <= R)
    return tree[root];

  int mid = (left + right) / 2;

  return max(get_max(left, mid, L, R, root * 2),
             get_max(mid + 1, right, L, R, root * 2 + 1));
}

void update(int left, int right, int x, int val, int root) {
  if (left > right || left > x || right < x)
    return;

  if (left == right && right == x) {
    tree[root] = val;
    return;
  }

  int mid = (left + right) / 2;

  update(left, mid, x, val, root * 2);
  update(mid + 1, right, x, val, root * 2 + 1);

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

int main() {

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

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

  for (int i = 1; i <= N; i++) {
    cin >> A[i];
    S.insert(A[i]);
  }

  int k = 1;

  for (set<int>::iterator it = S.begin(); it != S.end(); it++)
    B[k++] = *it;

  k--;
  int ans = 0;

  for (int i = 1; i <= N; i++) {
    int x = lower_bound(B + 1, B + 1 + k, A[i]) - B;
    int y = lower_bound(B + 1, B + 1 + k, A[i] - K) - B;
    int z = upper_bound(B + 1, B + 1 + k, A[i] + K) - B - 1;

    int new_ans = get_max(1, N, y, z, 1) + 1;
    ans = max(ans, new_ans);

    update(1, N, x, new_ans, 1);
  }

  cout << ans << endl;

  return 0;
}


#include <algorithm>
#include <stdio.h>
int n, k;
int a[100010];
int DT[100010];
int ans;
int max_a;
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
struct seg {
  int tree[2000010], lim;
  void init(int n) {
    for (lim = 1; lim <= n; lim <<= 1)
      ;
    for (int i = 0; i < 2 * lim; i++) {
      tree[i] = 0;
    }
  }
  void add(int x, int v) {
    x += lim;
    tree[x] = v;
    while (x > 1) {
      x >>= 1;
      tree[x] = max(tree[2 * x], tree[2 * x + 1]);
    }
  }
  int query(int s, int e) {
    s += lim;
    e += lim;
    int ret = 0;
    while (s < e) {
      if (s % 2 == 1)
        ret = max(ret, tree[s++]);
      if (e % 2 == 0)
        ret = max(ret, tree[e--]);
      s >>= 1;
      e >>= 1;
    }
    if (s == e)
      ret = max(ret, tree[s]);
    return ret;
  }
} seg;
int main() {
  scanf("%d %d", &n, &k);
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    max_a = max_a > a[i] ? max_a : a[i];
  }
  seg.init(max_a);
  for (int i = n - 1; i >= 0; i--) {
    int t = seg.query(max(0, a[i] - k), min(max_a, a[i] + k)) + 1;
    ans = max(ans, t);
    seg.add(a[i], t);
  }
  printf("%d\\n", ans);
}

#include <algorithm>
#include <stdio.h>
int n, k;
int a[300010];
int ans;
int max_a;
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
struct seg {
  int tree[2000010], lim;
  void init(int n) {
    for (lim = 1; lim <= n; lim <<= 1)
      ;
    for (int i = 0; i < 2 * lim; i++) {
      tree[i] = 0;
    }
  }
  void add(int x, int v) {
    x += lim;
    tree[x] = v;
    while (x > 1) {
      x >>= 1;
      tree[x] = max(tree[2 * x], tree[2 * x + 1]);
    }
  }
  int query(int s, int e) {
    s += lim;
    e += lim;
    int ret = 0;
    while (s < e) {
      if (s % 2 == 1)
        ret = max(ret, tree[s++]);
      if (e % 2 == 0)
        ret = max(ret, tree[e--]);
      s >>= 1;
      e >>= 1;
    }
    if (s == e)
      ret = max(ret, tree[s]);
    return ret;
  }
} seg;
int main() {
  scanf("%d %d", &n, &k);
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    max_a = max_a > a[i] ? max_a : a[i];
  }
  seg.init(max_a);
  for (int i = n - 1; i >= 0; i--) {
    int t = seg.query(max(0, a[i] - k), min(max_a, a[i] + k)) + 1;
    ans = max(ans, t);
    seg.add(a[i], t);
  }
  printf("%d\\n", ans);
}


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

// #pragma GCC optimize("Ofast")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define eb emplace_back
#define pb push_back
#define size(s) (int)s.size()
// #define int long long
#define INF 1000000000000000000
#define vi vector<int>
#define vs vector<string>
#define vv vector<vector<int>>
#define pii pair<int, int>
#define m_p(x, y) make_pair(x, y)
#define vp vector<pair<int, int>>
#define setbits(x) __builtin_popcountll(x)
#define f first
#define se second
#define inc(v, n, x) v.assign(n, x)
#define incd(v, n) v.resize(n)
#define iniz(n) memset(n, 0, sizeof(n))
#define inin(n) memset(n, -1, sizeof(n))
#define inimi(n) memset(n, 0xc0, sizeof(n))
#define inima(n) memset(n, 0x3f, sizeof(n))
#define all(v) (v).begin(), (v).end()

using namespace std;

template <typename T1, typename T2>
istream &operator>>(istream &is, vector<pair<T1, T2>> &v) {
  for (pair<T1, T2> &t : v)
    is >> t.f >> t.se;
  return is;
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &t : v)
    is >> t;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &t : v) {
    os << t << " ";
  }
  os << '\\n';
  return os;
}

const int N = 1200004;
double pi = acos(-1.0);
int md = 1e9 + 7;
int dx1[] = {0, 0, -1, 1};
int dy1[] = {1, -1, 0, 0};
// const int N=2e5;

template <class T> T abst(T a) { return a < 0 ? -a : a; }

int Tree[N];
void build_max(int node, int start, int end, int a[]) {
  if (start == end) {
    Tree[node] = a[start];
    return;
  }
  int mid = ((start + end) >> 1);
  build_max(2 * node + 1, start, mid, a);
  build_max(2 * node + 2, mid + 1, end, a);
  // According to the question,change from here
  Tree[node] = max(Tree[2 * node + 1], Tree[2 * node + 2]);
}
void update_max(int node, int start, int end, int i, int val) {
  if (start == end) {
    Tree[node] = val;
    return;
  }
  int mid = ((start + end) >> 1);
  if (i <= mid)
    update_max(2 * node + 1, start, mid, i, val);
  else
    update_max(2 * node + 2, mid + 1, end, i, val);
  // According to the question,change from here
  Tree[node] = max(Tree[2 * node + 1], Tree[2 * node + 2]);
}
int query_max(int node, int start, int end, int l, int r) {
  if (start > end || end < l || start > r)
    return 0; // 0 in case of sum , high value in case of min , low value in
              // case of max and soooo on
  if (start >= l && end <= r)
    return (Tree[node]);
  int mid = (start + end) / 2;
  int p1 = query_max(node * 2 + 1, start, mid, l, r);
  int p2 = query_max(node * 2 + 2, mid + 1, end, l, r);
  return max(p1, p2);
}

void solve() {
  int n, k;
  cin >> n >> k;
  int ans = 1;
  for (int i = 0; i < n; i++) {
    int x;
    cin >> x;
    int l = max(0, x - k);
    int r = min(300000, x + k);
    int mx = query_max(1, 0, 300000, l, r);
    ans = max(ans, mx + 1);
    update_max(1, 0, 300000, x, mx + 1);
  }
  cout << ans;
}

int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  cout.tie(NULL);
  int t = 1;
  // cin>>t;
  for (int i = 1; i <= t; i++) {
    solve();
  }
  return 0;
}

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

// #pragma GCC optimize("Ofast")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define eb emplace_back
#define pb push_back
#define size(s) (int)s.size()
// #define int long long
#define INF 1000000000000000000
#define vi vector<int>
#define vs vector<string>
#define vv vector<vector<int>>
#define pii pair<int, int>
#define m_p(x, y) make_pair(x, y)
#define vp vector<pair<int, int>>
#define setbits(x) __builtin_popcountll(x)
#define f first
#define se second
#define inc(v, n, x) v.assign(n, x)
#define incd(v, n) v.resize(n)
#define iniz(n) memset(n, 0, sizeof(n))
#define inin(n) memset(n, -1, sizeof(n))
#define inimi(n) memset(n, 0xc0, sizeof(n))
#define inima(n) memset(n, 0x3f, sizeof(n))
#define all(v) (v).begin(), (v).end()

using namespace std;

template <typename T1, typename T2>
istream &operator>>(istream &is, vector<pair<T1, T2>> &v) {
  for (pair<T1, T2> &t : v)
    is >> t.f >> t.se;
  return is;
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &t : v)
    is >> t;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &t : v) {
    os << t << " ";
  }
  os << '\\n';
  return os;
}

const int N = 1200004;
double pi = acos(-1.0);
int md = 1e9 + 7;
int dx1[] = {0, 0, -1, 1};
int dy1[] = {1, -1, 0, 0};
// const int N=2e5;

template <class T> T abst(T a) { return a < 0 ? -a : a; }

int Tree[N];
void build_max(int node, int start, int end, int a[]) {
  if (start == end) {
    Tree[node] = a[start];
    return;
  }
  int mid = ((start + end) >> 1);
  build_max(2 * node + 1, start, mid, a);
  build_max(2 * node + 2, mid + 1, end, a);
  // According to the question,change from here
  Tree[node] = max(Tree[2 * node + 1], Tree[2 * node + 2]);
}
void update_max(int node, int start, int end, int i, int val) {
  if (start == end) {
    Tree[node] = val;
    return;
  }
  int mid = ((start + end) >> 1);
  if (i <= mid)
    update_max(2 * node + 1, start, mid, i, val);
  else
    update_max(2 * node + 2, mid + 1, end, i, val);
  // According to the question,change from here
  Tree[node] = max(Tree[2 * node + 1], Tree[2 * node + 2]);
}
int query_max(int node, int start, int end, int l, int r) {
  if (start > end || end < l || start > r)
    return 0; // 0 in case of sum , high value in case of min , low value in
              // case of max and soooo on
  if (start >= l && end <= r)
    return (Tree[node]);
  int mid = (start + end) / 2;
  int p1 = query_max(node * 2 + 1, start, mid, l, r);
  int p2 = query_max(node * 2 + 2, mid + 1, end, l, r);
  return max(p1, p2);
}

void solve() {
  int n, k;
  cin >> n >> k;
  int ans = 1;
  for (int i = 0; i < n; i++) {
    int x;
    cin >> x;
    int l = max(0, x - k);
    int r = min(300000, x + k);
    int mx = query_max(0, 0, 300000, l, r);
    ans = max(ans, mx + 1);
    update_max(0, 0, 300000, x, mx + 1);
  }
  cout << ans;
}

int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  cout.tie(NULL);
  int t = 1;
  // cin>>t;
  for (int i = 1; i <= t; i++) {
    solve();
  }
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 500100;

#define lson rt << 1     // == rt * 2	 左儿子
#define rson rt << 1 | 1 // == rt * 2 + 1 右儿子
#define int_mid int mid = tree[rt].l + tree[rt].r >> 1
int num[N];

struct node {
  int l, r;
  ll val, lazy;
} tree[N * 4];

void push_up(int rt) {
  // tree[rt].val = min(tree[lson].val, tree[rson].val);
  tree[rt].val = max(tree[lson].val, tree[rson].val);
  // tree[rt].val = tree[lson].val + tree[rson].val;
}

void push_down(int rt) {
  if (tree[rt].lazy) {
    tree[lson].lazy += tree[rt].lazy;
    tree[rson].lazy += tree[rt].lazy;
    { // 维护最大最小值
      tree[lson].val += tree[rt].lazy;
      tree[rson].val += tree[rt].lazy;
    }
    // { // 维护和
    // 	int l = tree[rt].l, r = tree[rt].r;
    // 	int mid = l + r >> 1;
    // 	tree[lson].val += 1ll * (mid - l + 1) * tree[rt].lazy;
    // 	tree[rson].val += 1ll * (r - mid) * tree[rt].lazy;
    // }
    tree[rt].lazy = 0;
  }
}

void build(int rt, int l, int r) { // 建树
  tree[rt].l = l, tree[rt].r = r;
  tree[rt].lazy = 0;
  if (l == r) {
    tree[rt].val = 0; // 给定一个初始值
    return;
  } else {
    int mid = l + r >> 1; // (l + r) / 2
    build(lson, l, mid);
    build(rson, mid + 1, r);
    push_up(rt);
  }
}

void update_point(int rt, int pos, ll val) { // 单点更新
  if (tree[rt].l == tree[rt].r && pos == tree[rt].l) {
    tree[rt].val = val;
    return;
  }
  int_mid;
  if (pos <= mid)
    update_point(lson, pos, val);
  else
    update_point(rson, pos, val);
  push_up(rt);
}

// void update_interval(int rt, int l, int r, ll val) { // 区间更新
// 	if (l <= tree[rt].l && r >= tree[rt].r) {
// 		tree[rt].lazy += val;
// 		//tree[rt].val += val; // 维护最大最小值
// 		tree[rt].val += 1ll * (tree[rt].r - tree[rt].l + 1) * val; //
// 维护和 		return;
// 	}
// 	push_down(rt);
// 	int_mid;
// 	if (l <= mid) update_interval(lson, l, r, val);
// 	if (r > mid) update_interval(rson, l, r, val);
// 	push_up(rt);
// }

// ll query_point(int rt, int pos) { // 单点查询
// 	if (tree[rt].l == tree[rt].r && tree[rt].l == pos)
// 		return tree[rt].val;
// 	push_down(rt);
// 	int_mid;
// 	if (pos <= mid) query_point(lson, pos);
// 	else query_point(rson, pos);
// }

ll query_interval(int rt, int l, int r) { // 区间查询
  if (l <= tree[rt].l && r >= tree[rt].r)
    return tree[rt].val;
  push_down(rt);
  int_mid;
  if (r <= mid)
    return query_interval(lson, l, r);
  else if (l > mid)
    return query_interval(rson, l, r);
  else {
    // return min(query_interval(lson, l, mid), query_interval(rson, mid + 1,
    // r));
    return max(query_interval(lson, l, mid), query_interval(rson, mid + 1, r));
    // return query_interval(lson, l, mid) + query_interval(rson, mid + 1, r);
  }
}
void solve(int T) {
  int n, k;
  scanf("%d %d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &num[i]);
  }
  build(1, 0, n);
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int t = num[i];
    int l = max(0, t - k), r = min(300000, t + k);
    int q = query_interval(1, l, r);
    ans = max(ans, q + 1);
    update_point(1, t, q + 1);
  }
  printf("%d", ans);
}

signed main() {
  int t = 1;
  // scanf("%d",&t);
  for (int i = 1; i <= t; i++) {
    solve(i);
  }
  return 0;
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 500100;

#define lson rt << 1     // == rt * 2	 左儿子
#define rson rt << 1 | 1 // == rt * 2 + 1 右儿子
#define int_mid int mid = tree[rt].l + tree[rt].r >> 1
int num[N];

struct node {
  int l, r;
  ll val, lazy;
} tree[N * 4];

void push_up(int rt) {
  // tree[rt].val = min(tree[lson].val, tree[rson].val);
  tree[rt].val = max(tree[lson].val, tree[rson].val);
  // tree[rt].val = tree[lson].val + tree[rson].val;
}

void push_down(int rt) {
  if (tree[rt].lazy) {
    tree[lson].lazy += tree[rt].lazy;
    tree[rson].lazy += tree[rt].lazy;
    { // 维护最大最小值
      tree[lson].val += tree[rt].lazy;
      tree[rson].val += tree[rt].lazy;
    }
    // { // 维护和
    // 	int l = tree[rt].l, r = tree[rt].r;
    // 	int mid = l + r >> 1;
    // 	tree[lson].val += 1ll * (mid - l + 1) * tree[rt].lazy;
    // 	tree[rson].val += 1ll * (r - mid) * tree[rt].lazy;
    // }
    tree[rt].lazy = 0;
  }
}

void build(int rt, int l, int r) { // 建树
  tree[rt].l = l, tree[rt].r = r;
  tree[rt].lazy = 0;
  if (l == r) {
    tree[rt].val = 0; // 给定一个初始值
    return;
  } else {
    int mid = l + r >> 1; // (l + r) / 2
    build(lson, l, mid);
    build(rson, mid + 1, r);
    push_up(rt);
  }
}

void update_point(int rt, int pos, ll val) { // 单点更新
  if (tree[rt].l == tree[rt].r && pos == tree[rt].l) {
    tree[rt].val = val;
    return;
  }
  int_mid;
  if (pos <= mid)
    update_point(lson, pos, val);
  else
    update_point(rson, pos, val);
  push_up(rt);
}

// void update_interval(int rt, int l, int r, ll val) { // 区间更新
// 	if (l <= tree[rt].l && r >= tree[rt].r) {
// 		tree[rt].lazy += val;
// 		//tree[rt].val += val; // 维护最大最小值
// 		tree[rt].val += 1ll * (tree[rt].r - tree[rt].l + 1) * val; //
// 维护和 		return;
// 	}
// 	push_down(rt);
// 	int_mid;
// 	if (l <= mid) update_interval(lson, l, r, val);
// 	if (r > mid) update_interval(rson, l, r, val);
// 	push_up(rt);
// }

// ll query_point(int rt, int pos) { // 单点查询
// 	if (tree[rt].l == tree[rt].r && tree[rt].l == pos)
// 		return tree[rt].val;
// 	push_down(rt);
// 	int_mid;
// 	if (pos <= mid) query_point(lson, pos);
// 	else query_point(rson, pos);
// }

ll query_interval(int rt, int l, int r) { // 区间查询
  if (l <= tree[rt].l && r >= tree[rt].r)
    return tree[rt].val;
  push_down(rt);
  int_mid;
  if (r <= mid)
    return query_interval(lson, l, r);
  else if (l > mid)
    return query_interval(rson, l, r);
  else {
    // return min(query_interval(lson, l, mid), query_interval(rson, mid + 1,
    // r));
    return max(query_interval(lson, l, mid), query_interval(rson, mid + 1, r));
    // return query_interval(lson, l, mid) + query_interval(rson, mid + 1, r);
  }
}
void solve(int T) {
  int n, k;
  scanf("%d %d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &num[i]);
  }
  build(1, 0, 300000);
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int t = num[i];
    int l = max(0, t - k), r = min(300000, t + k);
    int q = query_interval(1, l, r);
    ans = max(ans, q + 1);
    update_point(1, t, q + 1);
  }
  printf("%d", ans);
}

signed main() {
  int t = 1;
  // scanf("%d",&t);
  for (int i = 1; i <= t; i++) {
    solve(i);
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
ll mod2 = 998244353;
ll mod = 1e9 + 7;
vector<int> seg;
vector<int> dp;
void update(int v, int tl, int tr, int pos, int val) {
  if (tl == tr)
    seg[v] = val;
  else {
    int mid = (tl + tr) / 2;
    if (pos <= mid)
      update(2 * v, tl, mid, pos, val);
    else {
      update(2 * v + 1, mid + 1, tr, pos, val);
    }
    seg[v] = max(seg[2 * v], seg[2 * v + 1]);
  }
}
int get(int v, int tl, int tr, int l, int r) {
  if (tl > r || tr < l)
    return 0;
  if (tl >= l && tr <= r)
    return seg[v];
  int mid = (tl + tr) / 2;
  return max(get(2 * v, tl, mid, l, r), get(2 * v + 1, mid + 1, tr, l, r));
}
int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n + 1);
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  int p = *max_element(begin(a), end(a));
  seg.resize(p + 6, 0);
  int ans = 1;
  for (int i = 1; i <= n; i++) {
    int val = get(1, 1, p, max(0, a[i] - k), min(p, a[i] + k));
    update(1, 1, p, a[i], val + 1);
    ans = max(ans, val + 1);
  }
  cout << ans << endl;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
ll mod2 = 998244353;
ll mod = 1e9 + 7;
vector<int> seg;
vector<int> dp;
void update(int v, int tl, int tr, int pos, int val) {
  if (tl == tr)
    seg[v] = val;
  else {
    int mid = (tl + tr) / 2;
    if (pos <= mid)
      update(2 * v, tl, mid, pos, val);
    else {
      update(2 * v + 1, mid + 1, tr, pos, val);
    }
    seg[v] = max(seg[2 * v], seg[2 * v + 1]);
  }
}
int get(int v, int tl, int tr, int l, int r) {
  if (tl > r || tr < l)
    return 0;
  if (tl >= l && tr <= r)
    return seg[v];
  int mid = (tl + tr) / 2;
  return max(get(2 * v, tl, mid, l, r), get(2 * v + 1, mid + 1, tr, l, r));
}
int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n + 1);
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  int p = 3e5;
  seg.resize(4 * p, 0);
  int ans = 1;
  for (int i = 1; i <= n; i++) {
    int val = get(1, 1, p, max(0, a[i] - k), min(p, a[i] + k));
    update(1, 1, p, a[i], val + 1);
    ans = max(ans, val + 1);
  }
  cout << ans << endl;
}


#include <bits/stdc++.h>
#define ls ch[x][0]
#define rs ch[x][1]
#define ll long long
using namespace std;

inline ll read() {
  ll num = 0, neg = 1;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-')
      neg = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    num = (num << 3) + (num << 1) + c - '0';
    c = getchar();
  }
  return num * neg;
}

int n, k, tree[300010 << 2], a[300010], f[300010];

inline void push_up(int x) { tree[x] = max(tree[x << 1], tree[x << 1 | 1]); }
inline void update(int u, int l, int r, int x, int k) {
  if (l == r) {
    tree[x] = max(tree[x], k);
    return;
  }
  int mid = l + r >> 1;
  if (u <= mid)
    update(u, l, mid, x << 1, k);
  else
    update(u, mid + 1, r, x << 1 | 1, k);
  push_up(x);
  return;
}
inline int query(int ql, int qr, int l, int r, int x) {
  if (ql <= l && qr >= r)
    return tree[x];
  int mid = l + r >> 1, res = 0;
  if (ql <= mid)
    res = max(res, query(ql, qr, l, mid, x << 1));
  if (qr > mid)
    res = max(res, query(ql, qr, mid + 1, r, x << 1 | 1));
  return res;
}

int main() {
  n = read(), k = read();
  for (int i = 1; i <= n; i++)
    a[i] = read();
  for (int i = 1; i <= n; i++) {
    f[i] = query(max(a[i] - k, 0), min(300000, a[i] + k), 1, n, 1) + 1;
    update(a[i], 1, n, 1, f[i]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++)
    ans = max(f[i], ans);
  cout << ans;
  return 0;
}

#include <bits/stdc++.h>
#define ls ch[x][0]
#define rs ch[x][1]
#define ll long long
using namespace std;

inline ll read() {
  ll num = 0, neg = 1;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-')
      neg = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    num = (num << 3) + (num << 1) + c - '0';
    c = getchar();
  }
  return num * neg;
}

int n, k, tree[300010 << 2], a[300010], f[300010];

inline void push_up(int x) { tree[x] = max(tree[x << 1], tree[x << 1 | 1]); }
inline void update(int u, int l, int r, int x, int k) {
  if (l == r) {
    tree[x] = max(tree[x], k);
    return;
  }
  int mid = l + r >> 1;
  if (u <= mid)
    update(u, l, mid, x << 1, k);
  else
    update(u, mid + 1, r, x << 1 | 1, k);
  push_up(x);
  return;
}
inline int query(int ql, int qr, int l, int r, int x) {
  if (ql <= l && qr >= r)
    return tree[x];
  int mid = l + r >> 1, res = 0;
  if (ql <= mid)
    res = max(res, query(ql, qr, l, mid, x << 1));
  if (qr > mid)
    res = max(res, query(ql, qr, mid + 1, r, x << 1 | 1));
  return res;
}

int main() {
  n = read(), k = read();
  for (int i = 1; i <= n; i++)
    a[i] = read();
  for (int i = 1; i <= n; i++) {
    f[i] = query(max(a[i] - k, 0), min(300000, a[i] + k), 1, 300000, 1) + 1;
    update(a[i], 1, 300000, 1, f[i]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++)
    ans = max(f[i], ans);
  cout << ans;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> p_ll;

template <class T> void debug(T itr1, T itr2) {
  auto now = itr1;
  while (now < itr2) {
    cout << *now << " ";
    now++;
  }
  cout << endl;
}
#define repr(i, from, to) for (ll i = (ll)from; i < (ll)to; i++)
#define all(vec) vec.begin(), vec.end()
#define rep(i, N) repr(i, 0, N)
#define per(i, N) for (ll i = (ll)N - 1; i >= 0; i--)

const ll MOD = pow(10, 9) + 7;
const ll LLINF = pow(2, 61) - 1;
const ll INF = pow(2, 30) - 1;

vector<ll> fac;
void c_fac(ll x = pow(10, 6) + 10) {
  fac.resize(x, true);
  rep(i, x) fac[i] = i ? (fac[i - 1] * i) % MOD : 1;
}
ll inv(ll a, ll m = MOD) {
  ll b = m, x = 1, y = 0;
  while (b != 0) {
    ll d = a / b;
    a -= b * d;
    swap(a, b);
    x -= y * d;
    swap(x, y);
  }
  return (x + m) % m;
}
ll nck(ll n, ll k) { return fac[n] * inv(fac[k] * fac[n - k] % MOD) % MOD; }
ll modpow(ll x, ll p) {
  ll result = 1, now = 1, pm = x;
  while (now <= p) {
    if (p & now) {
      result = result * pm % MOD;
    }
    now *= 2;
    pm = pm * pm % MOD;
  }
  return result;
}
ll gcd(ll a, ll b) {
  if (a < b)
    swap(a, b);
  return b == 0 ? a : gcd(b, a % b);
}
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

struct SegTree {
  ll size;
  vector<ll> pos;
  SegTree(ll N) {
    size = 1;
    while (size < N)
      size <<= 1;
    pos.resize(2 * size, 0);
  }
  ll operator[](const ll &x) const { return pos[x + size]; }

  void set(ll x, const ll v) { pos[x + size] = v; }
  void update(ll x, const ll v) {
    set(x, v);
    x += size;
    while (x >>= 1)
      operate(x);
  }
  ll query(ll a, ll b) {
    ll L = 0, R = 0;
    for (a += size, b += size; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        L = q(L, pos[a]);
        a++;
      }
      if (b & 1) {
        b--;
        R = q(pos[b], R);
      }
    }
    return q(L, R);
  }
  void operate(ll i) { pos[i] = q(pos[i * 2], pos[i * 2 + 1]); }
  ll q(ll x, ll y) { return max(x, y); }
};

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

int main() {
  ll N, K;
  cin >> N >> K;
  ll A[N];
  rep(i, N) cin >> A[i];

  ll MA = 10;
  SegTree st(MA);
  rep(i, N) {
    st.update(A[i],
              st.query(max(0ll, A[i] - K), min(MA - 1, A[i] + K) + 1) + 1);
    // rep(i,MA) cout << st[i] << " "; cout << endl;
  }

  ll result = st.query(0, MA);
  cout << result << endl;
  return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> p_ll;

template <class T> void debug(T itr1, T itr2) {
  auto now = itr1;
  while (now < itr2) {
    cout << *now << " ";
    now++;
  }
  cout << endl;
}
#define repr(i, from, to) for (ll i = (ll)from; i < (ll)to; i++)
#define all(vec) vec.begin(), vec.end()
#define rep(i, N) repr(i, 0, N)
#define per(i, N) for (ll i = (ll)N - 1; i >= 0; i--)

const ll MOD = pow(10, 9) + 7;
const ll LLINF = pow(2, 61) - 1;
const ll INF = pow(2, 30) - 1;

vector<ll> fac;
void c_fac(ll x = pow(10, 6) + 10) {
  fac.resize(x, true);
  rep(i, x) fac[i] = i ? (fac[i - 1] * i) % MOD : 1;
}
ll inv(ll a, ll m = MOD) {
  ll b = m, x = 1, y = 0;
  while (b != 0) {
    ll d = a / b;
    a -= b * d;
    swap(a, b);
    x -= y * d;
    swap(x, y);
  }
  return (x + m) % m;
}
ll nck(ll n, ll k) { return fac[n] * inv(fac[k] * fac[n - k] % MOD) % MOD; }
ll modpow(ll x, ll p) {
  ll result = 1, now = 1, pm = x;
  while (now <= p) {
    if (p & now) {
      result = result * pm % MOD;
    }
    now *= 2;
    pm = pm * pm % MOD;
  }
  return result;
}
ll gcd(ll a, ll b) {
  if (a < b)
    swap(a, b);
  return b == 0 ? a : gcd(b, a % b);
}
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

struct SegTree {
  ll size;
  vector<ll> pos;
  SegTree(ll N) {
    size = 1;
    while (size < N)
      size <<= 1;
    pos.resize(2 * size, 0);
  }
  ll operator[](const ll &x) const { return pos[x + size]; }

  void set(ll x, const ll v) { pos[x + size] = v; }
  void update(ll x, const ll v) {
    set(x, v);
    x += size;
    while (x >>= 1)
      operate(x);
  }
  ll query(ll a, ll b) {
    ll L = 0, R = 0;
    for (a += size, b += size; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        L = q(L, pos[a]);
        a++;
      }
      if (b & 1) {
        b--;
        R = q(pos[b], R);
      }
    }
    return q(L, R);
  }
  void operate(ll i) { pos[i] = q(pos[i * 2], pos[i * 2 + 1]); }
  ll q(ll x, ll y) { return max(x, y); }
};

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

int main() {
  ll N, K;
  cin >> N >> K;
  ll A[N];
  rep(i, N) cin >> A[i];

  ll MA = 300010;
  SegTree st(MA);
  rep(i, N) {
    st.update(A[i],
              st.query(max(0ll, A[i] - K), min(MA - 1, A[i] + K) + 1) + 1);
    // rep(i,MA) cout << st[i] << " "; cout << endl;
  }

  ll result = st.query(0, MA);
  cout << result << endl;
  return 0;
}


#include <bits/stdc++.h>
#define pp pair<int, int>
#define ppp pair<pp, int>
#define fi first
#define si second
#define N int(3e5 + 10)
using namespace std;
int seg[4 * N], lazy[4 * N], v;
void build(int l, int h, int pos) {
  if (l == h) {
    seg[pos] = lazy[pos] = 0;
    return;
  }
  int mid = (l + h) / 2;
  build(l, mid, 2 * pos);
  build(mid + 1, h, 2 * pos + 1);
  seg[pos] = lazy[pos] = 0;
}
void update(int l, int h, int x, int y, int pos) {
  if (lazy[pos]) {
    seg[pos] = lazy[pos];
    if (l != h) {
      lazy[2 * pos] = lazy[pos];
      lazy[2 * pos + 1] += lazy[pos];
    }
    lazy[pos] = 0;
  }
  if (h < x || l > y)
    return;
  if (x <= l && h <= y) {
    seg[pos] = v;

    // cout << l << " D " << h << ' ' << x << ' ' << y << ' ' << seg[pos] <<
    // endl;
    if (l != h) {
      lazy[2 * pos] = v;
      lazy[2 * pos + 1] = v;
    }
    return;
  }
  int mid = (l + h) / 2;
  update(l, mid, x, y, 2 * pos);
  update(mid + 1, h, x, y, 2 * pos + 1);
  seg[pos] = max(seg[2 * pos], seg[2 * pos + 1]);
  //	cout << l << " D " << h << ' ' << seg[pos] << endl;
}
int query(int l, int h, int x, int pos) {
  if (lazy[pos]) {
    seg[pos] = lazy[pos];
    if (l != h) {
      lazy[2 * pos] = lazy[pos];
      lazy[2 * pos + 1] = lazy[pos];
    }
    lazy[pos] = 0;
  }
  if (h < x || l > x)
    return 0;
  if (l == h) {
    return seg[pos];
  }
  int mid = (l + h) / 2;
  int q1 = query(l, mid, x, 2 * pos);
  int q2 = query(mid + 1, h, x, 2 * pos + 1);
  return max(q1, q2);
}
int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cout.precision(10);
  int n, k;
  cin >> n >> k;
  int a[n + 1], dp[n + 1];
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    a[i]++;
  }
  int g[n + 1], s[n + 1];
  for (int i = 1; i <= n; i++) {
    s[i] = query(1, N, a[i], 1);
    v = i;
    update(1, N, a[i], min(N - 1, a[i] + k), 1);
    //	cout << a[i] << " F " << a[i] + k << ' ' << s[i] << endl;
    //	cout << s[i] << ' ';
  }
  // cout << endl;
  build(1, N, 1);
  for (int i = 1; i <= n; i++) {
    g[i] = query(1, N, a[i], 1);
    v = i;
    update(1, N, max(1, a[i] - k), a[i], 1);
  }
  for (int i = 1; i <= n; i++) {
    dp[i] = 1;
    if (s[i])
      dp[i] = max(dp[i], dp[s[i]] + 1);
    if (g[i])
      dp[i] = max(dp[i], dp[g[i]] + 1);
  }
  cout << *max_element(dp + 1, dp + n + 1) << endl;
  return 0;
}

#include <bits/stdc++.h>
#define pp pair<int, int>
#define ppp pair<pp, int>
#define fi first
#define si second
#define N 300100
using namespace std;
int seg[4 * N], lazy[4 * N], v, m;
void build(int l, int h, int pos) {
  if (l == h) {
    seg[pos] = lazy[pos] = 0;
    return;
  }
  int mid = (l + h) / 2;
  build(l, mid, 2 * pos);
  build(mid + 1, h, 2 * pos + 1);
  seg[pos] = lazy[pos] = 0;
}
void update(int l, int h, int x, int y, int pos) {
  if (lazy[pos]) {
    seg[pos] = lazy[pos];
    if (l != h) {
      lazy[2 * pos] = lazy[pos];
      lazy[2 * pos + 1] = lazy[pos];
    }
    lazy[pos] = 0;
  }
  if (h < x || l > y)
    return;
  if (x <= l && h <= y) {
    seg[pos] = v;

    // cout << l << " D " << h << ' ' << x << ' ' << y << ' ' << seg[pos] <<
    // endl;
    if (l != h) {
      lazy[2 * pos] = v;
      lazy[2 * pos + 1] = v;
    }
    return;
  }
  int mid = (l + h) / 2;
  update(l, mid, x, y, 2 * pos);
  update(mid + 1, h, x, y, 2 * pos + 1);
  seg[pos] = max(seg[2 * pos], seg[2 * pos + 1]);
  //	cout << l << " D " << h << ' ' << seg[pos] << endl;
}
int query(int l, int h, int x, int pos) {
  if (lazy[pos]) {
    seg[pos] = lazy[pos];
    if (l != h) {
      lazy[2 * pos] = lazy[pos];
      lazy[2 * pos + 1] = lazy[pos];
    }
    lazy[pos] = 0;
  }
  if (h < x || l > x)
    return 0;
  if (l == h) {
    return seg[pos];
  }
  int mid = (l + h) / 2;
  int q1 = query(l, mid, x, 2 * pos);
  int q2 = query(mid + 1, h, x, 2 * pos + 1);
  return max(q1, q2);
}
int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cout.precision(10);
  int n, k;
  cin >> n >> k;
  int a[n + 1], dp[n + 1];
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    a[i]++;
    assert(a[i] < N);
  }
  int g[n + 1], s[n + 1];
  for (int i = 1; i <= n; i++) {
    s[i] = query(1, N, a[i], 1);
    v = i;
    update(1, N, a[i], min(N - 1, a[i] + k), 1);
    //	cout << a[i] << " F " << a[i] + k << ' ' << s[i] << endl;
    //	cout << s[i] << ' ';
  }
  // cout << endl;
  build(1, N, 1);
  for (int i = 1; i <= n; i++) {
    g[i] = query(1, N, a[i], 1);
    v = i;
    update(1, N, max(1, a[i] - k), a[i], 1);
  }
  for (int i = 1; i <= n; i++) {
    dp[i] = 1;
    if (s[i])
      dp[i] = max(dp[i], dp[s[i]] + 1);
    if (g[i])
      dp[i] = max(dp[i], dp[g[i]] + 1);
  }
  cout << *max_element(dp + 1, dp + n + 1) << endl;
  return 0;
}


#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
using namespace std;

const int maxn = 5e5 + 10;
int dp[maxn];
int a[maxn];
void solved() {
  int n, k;
  cin >> n >> k;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  for (int i = 1; i <= n; i++) {
    int m = 0;
    for (int j = 1; j < i; j++) {
      if (abs(a[j] - a[i]) <= k) {
        m = max(m, dp[j]);
      }
    }
    dp[i] = m + 1;
  }
  cout << dp[n] << endl;
}
int main() {
  solved();
  return 0;
}

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
using namespace std;

const int maxn = 6e5 + 10;
int a[maxn];
int m[maxn << 2];
int query(int rt, int l, int r, int ll, int rr) {
  if (ll >= l && rr <= r) {
    return m[rt];
  }
  int mid = ll + rr >> 1;
  int ans = 0;
  if (r <= mid)
    ans = max(ans, query(rt * 2, l, r, ll, mid));
  else if (l > mid)
    ans = max(ans, query(rt * 2 + 1, l, r, mid + 1, rr));
  else
    ans = max(ans, max(query(rt * 2, l, r, ll, mid),
                       query(rt * 2 + 1, l, r, mid + 1, rr)));
  return ans;
}
void update(int rt, int l, int r, int v, int ll, int rr) {
  if (l == ll && r == rr) {
    m[rt] = v;
    return;
  }
  int mid = ll + rr >> 1;
  if (l <= mid)
    update(rt << 1, l, r, v, ll, mid);
  else
    update(rt * 2 + 1, l, r, v, mid + 1, rr);
  m[rt] = max(m[rt << 1], m[rt * 2 + 1]);
}
void solved() {
  int n, k;
  cin >> n >> k;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), a[i]++;
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int res = query(1, max(a[i] - k, 0), a[i] + k, 1, maxn) + 1;
    update(1, a[i], a[i], res, 1, maxn);
    ans = max(ans, res);
  }
  cout << ans << endl;
}
int main() {
  solved();
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5 + 1000;
int n, k;
vector<int> t;

void build() {
  for (int i = n - 1; i > 0; i--)
    t[i] = max(t[2 * i], t[2 * i + 1]);
}
void update(int pos, int val) {
  pos += n;
  t[pos] = val;
  for (; pos > 1; pos /= 2)
    t[pos / 2] = max(t[pos], t[pos ^ 1]);
}
int query(int l, int r) { // interval on [l,r]
  r++;
  l = max(0, l);
  r = min(N, r);
  int res = 0;
  for (l += n, r += n; l < r; l /= 2, r /= 2) {
    if (l & 1)
      res = max(res, t[l++]);
    if (r & 1)
      res = max(res, t[--r]);
  }
  return res;
}

void solve() {
  cin >> n >> k;
  int ans = 0;
  t.resize(N, 0);
  for (int i = 0; i < n; i++) {
    int cur;
    cin >> cur;
    int mx = query(cur - k, cur + k);
    update(cur, mx + 1);
  }
  for (int i = 0; i < N; i++)
    ans = max(ans, t[i]);
  cout << ans;
}

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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct segmentTree {
  int n;
  vector<ll> t;
  segmentTree(int N) {
    n = N;
    t.resize(2 * N, 0);
  }

  void build() {
    for (int i = 0; i < n; i++)
      cin >> t[i + n];
    for (int i = n - 1; i > 0; i--)
      t[i] = max(t[2 * i], t[2 * i + 1]);
  }
  void update(int pos, int val) {
    pos += n;
    t[pos] = val;
    for (; pos > 1; pos /= 2)
      t[pos / 2] = max(t[pos], t[pos ^ 1]);
  }
  ll query(int l, int r) { // interval on [l,r]
    r++;
    ll res = 0;
    for (l += n, r += n; l < r; l /= 2, r /= 2) {
      if (l & 1)
        res = max(res, 1ll * t[l++]);
      if (r & 1)
        res = max(res, 1ll * t[--r]);
    }
    return res;
  }
};

void solve() {
  int mx = 3e5 + 1;
  int n, k;
  cin >> n >> k;
  segmentTree temp(mx);
  for (int i = 0; i < n; i++) {
    int cur;
    cin >> cur;
    int wow = temp.query(max(0, cur - k), min(cur + k, mx)) + 1;
    temp.update(cur, wow);
  }
  cout << temp.query(0, mx);
}

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


// #include <atcoder/all>
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>

#define rep2(x, fr, to) for (int x = (fr); x < (to); x++)
#define rep(x, to) for (int x = 0; x < (to); x++)
#define repr(x, fr, to) for (int x = (fr); x >= (to); x--)
#define all(c) c.begin(), c.end()
#define sz(v) (int)v.size()

using namespace std;
// using namespace atcoder;

typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef vector<ll> VL;
const int MD = 1e9 + 7;
void dbg() { cerr << "\\n"; }
template <class F, class... S> void dbg(const F &f, const S &...s) {
  cerr << f << ": ";
  dbg(s...);
}

// using mint = static_modint<MD>;

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  VI a(n);
  rep(i, n) cin >> a[i];
  VI dp(n + 10);
  dp[0] = 1;
  rep(i, n) {
    rep2(j, i + 1, n) {
      if (abs(a[i] - a[j]) <= k)
        dp[j] = max(dp[j], dp[i] + 1);
    }
  }
  int ans = 0;
  rep(i, n) ans = max(ans, dp[i]);
  cout << ans << "\\n";
  return 0;
}

// #include <atcoder/all>
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>

#define rep2(x, fr, to) for (int x = (fr); x < (to); x++)
#define rep(x, to) for (int x = 0; x < (to); x++)
#define repr(x, fr, to) for (int x = (fr); x >= (to); x--)
#define all(c) c.begin(), c.end()
#define sz(v) (int)v.size()

using namespace std;
// using namespace atcoder;
struct Segtree {
  typedef int sgT;
  vector<sgT> seg;
  int nbn;
  sgT INF;
  void init(int n) {
    for (nbn = 1; nbn < n + 2; nbn <<= 1)
      ;
    INF = 0; // min:+inf,max:-inf,0
    seg.assign(nbn * 2, INF);
  }
  sgT comp(sgT l, sgT r) { return max(l, r); } // min<->max
  void update(int k, sgT x) {
    k += nbn - 1;
    seg[k] = x;
    while (k > 0) {
      k = (k - 1) / 2;
      seg[k] = comp(seg[k * 2 + 1], seg[k * 2 + 2]);
    }
  }
  sgT query2(int a, int b, int l, int r, int k) {
    if (b <= l || r <= a)
      return INF;
    if (a <= l && r <= b)
      return seg[k];
    return comp(query2(a, b, l, (l + r) / 2, k * 2 + 1),
                query2(a, b, (l + r) / 2, r, k * 2 + 2));
  }
  sgT query(int a, int b) { return query2(a, b, 0, nbn, 0); }
  sgT get(int a) { return seg[nbn + a - 1]; } // =query(a,a+1)
  // void disp(){ for(auto x :seg) cout<<x<<", "; puts("");}
  int getpos(sgT v, int l, int r) { // vの最左位置を二分探で求める
    int lo = l - 1, hi = r;
    while (hi - lo > 1) {
      int md = (hi + lo) >> 1;
      if (query(lo, md + 1) == v)
        hi = md;
      else
        lo = md;
    }
    return hi;
  }
};

typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef vector<ll> VL;
const int MD = 1e9 + 7;
void dbg() { cerr << "\\n"; }
template <class F, class... S> void dbg(const F &f, const S &...s) {
  cerr << f << ": ";
  dbg(s...);
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  const int zsz = 301000;
  int n, k;
  cin >> n >> k;
  VI a(n);
  rep(i, n) cin >> a[i];
  Segtree sg;
  sg.init(zsz + 1);
  rep(i, n) {
    int cr = sg.query(max(0, a[i] - k), min(zsz, a[i] + k + 1)) + 1;
    sg.update(a[i], cr);
  }
  cout << sg.query(0, zsz) << "\\n";
  return 0;
}


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

// #pragma GCC optimize "trapv"//  WA to RE int!!
#include <bits/stdc++.h>
#define FOR(i, n) for (int i = 0; i < n; i++)
#define FORR(i, n) for (int i = n; i >= 0; i--)
#define pb push_back
#define vint vector<int>
#define sint set<int>
#define mint map<int, int>
#define pint pair<int, int>
#define int long long int
#define test                                                                   \\
  int tt1234;                                                                  \\
  cin >> tt1234;                                                               \\
  while (tt1234--)
#define endl "\\n"
#define SI(a, n)                                                               \\
  int a[n];                                                                    \\
  FOR(i, n) cin >> a[i];
#define input(a, n)                                                            \\
  int n;                                                                       \\
  cin >> n;                                                                    \\
  SI(a, n)
#define all(zz) zz.begin(), zz.end()
#define rep(i, begin, end)                                                     \\
  for (__typeof(end) i = (begin) - ((begin) > (end));                          \\
       i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define error(x) cerr << #x << " is " << x << endl;
#define Error(a, b)                                                            \\
  cerr << "( " << #a << " , " << #b << " ) = ( " << (a) << " , " << (b)        \\
       << " )\\n";
#define precision(x) cout << fixed << setprecision(x);
#define fast                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);
#define present(container, element) (container.find(element) != container.end())
#define fint                                                                   \\
  fast;                                                                        \\
  test
#define set(a, x) memset(a, x, sizeof(a))
#define L(x) ((x) << 1)
#define R(x) (((x) << 1) + 1)
#define ft first
#define se second
#define MOD 1000000007
using namespace std;
template <typename... T> void rd(T &...args) { ((cin >> args), ...); }
template <typename... T> void pp(T... args) {
  ((cout << args << " "), ...);
  cout << "\\n";
}

void solve() {
  int n, k;
  rd(n, k);
  vint dp(n, 1);
  vint arr(n);
  for (int &v : arr)
    rd(v);
  for (int i = 1; i < n; i++) {
    for (int j = 0; j < i; j++) {
      if (abs(arr[i] - arr[j]) <= k)
        dp[i] = max(dp[i], 1ll + dp[j]);
    }
  }
  pp(*max_element(all(dp)));

  return;
}

int32_t main() {
  // fint{
  fast;
  solve();
  // }
  return 0;
}

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

// #pragma GCC optimize "trapv"//  WA to RE int!!
#include <bits/stdc++.h>
#define FOR(i, n) for (int i = 0; i < n; i++)
#define FORR(i, n) for (int i = n; i >= 0; i--)
#define pb push_back
#define vint vector<int>
#define sint set<int>
#define mint map<int, int>
#define pint pair<int, int>
#define int long long int
#define test                                                                   \\
  int tt1234;                                                                  \\
  cin >> tt1234;                                                               \\
  while (tt1234--)
#define endl "\\n"
#define SI(a, n)                                                               \\
  int a[n];                                                                    \\
  FOR(i, n) cin >> a[i];
#define input(a, n)                                                            \\
  int n;                                                                       \\
  cin >> n;                                                                    \\
  SI(a, n)
#define all(zz) zz.begin(), zz.end()
#define rep(i, begin, end)                                                     \\
  for (__typeof(end) i = (begin) - ((begin) > (end));                          \\
       i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define error(x) cerr << #x << " is " << x << endl;
#define Error(a, b)                                                            \\
  cerr << "( " << #a << " , " << #b << " ) = ( " << (a) << " , " << (b)        \\
       << " )\\n";
#define precision(x) cout << fixed << setprecision(x);
#define fast                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);
#define present(container, element) (container.find(element) != container.end())
#define fint                                                                   \\
  fast;                                                                        \\
  test
#define set(a, x) memset(a, x, sizeof(a))
#define L(x) ((x) << 1)
#define R(x) (((x) << 1) + 1)
#define ft first
#define se second
#define MOD 1000000007
using namespace std;
template <typename... T> void rd(T &...args) { ((cin >> args), ...); }
template <typename... T> void pp(T... args) {
  ((cout << args << " "), ...);
  cout << "\\n";
}

void solve() {
  int n, k;
  rd(n, k);
  vint dp(n, 1);
  vint arr(n);
  for (int &v : arr)
    rd(v);
  for (int i = 1; i < n; i++) {
    int L = max(0ll, i - 99);
    for (int j = L; j < i; j++) {
      if (abs(arr[i] - arr[j]) <= k)
        dp[i] = max(dp[i], 1ll + dp[j]);
    }
  }
  pp(*max_element(all(dp)));

  return;
}

int32_t main() {
  // fint{
  fast;
  solve();
  // }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
template <class T1, class T2> ostream &operator<<(ostream &s, pair<T1, T2> P) {
  return s << '<' << P.first << ", " << P.second << '>';
}
template <class T> ostream &operator<<(ostream &s, vector<T> P) {
  for (int i = 0; i < P.size(); ++i) {
    if (i > 0) {
      s << " ";
    }
    s << P[i];
  }
  return s;
}
template <class T> ostream &operator<<(ostream &s, vector<vector<T>> P) {
  for (int i = 0; i < P.size(); ++i) {
    s << endl << P[i];
  }
  return s << endl;
}
template <class T> ostream &operator<<(ostream &s, set<T> P) {
  for (auto it : P) {
    s << "<" << it << "> ";
  }
  return s << endl;
}
template <class T1, class T2> ostream &operator<<(ostream &s, map<T1, T2> P) {
  for (auto it : P) {
    s << "<" << it.first << "->" << it.second << "> ";
  }
  return s << endl;
}

template <class Monoid> struct SegTree {
  using Func = function<Monoid(Monoid, Monoid)>;
  const Func F;
  const Monoid UNITY;
  int SIZE_R;
  vector<Monoid> dat;

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

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

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

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

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

int solve(int N, int K) {
  const int MAX = 10; // 510000;
  auto func = [&](int a, int b) { return max(a, b); };
  SegTree<int> seg(N, func, 0);
  for (int i = 0; i < N; ++i) {
    int a;
    cin >> a;
    int left = max(0, a - K);
    int right = min(N, a + K + 1);
    int val = seg.get(left, right);
    seg.update(a, val + 1);

    // seg.print(); COUT(val);
  }
  return seg.get(0, MAX);
}

int main() {
  int N, K;
  while (cin >> N >> K)
    cout << solve(N, K) << endl;
}

#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
template <class T1, class T2> ostream &operator<<(ostream &s, pair<T1, T2> P) {
  return s << '<' << P.first << ", " << P.second << '>';
}
template <class T> ostream &operator<<(ostream &s, vector<T> P) {
  for (int i = 0; i < P.size(); ++i) {
    if (i > 0) {
      s << " ";
    }
    s << P[i];
  }
  return s;
}
template <class T> ostream &operator<<(ostream &s, vector<vector<T>> P) {
  for (int i = 0; i < P.size(); ++i) {
    s << endl << P[i];
  }
  return s << endl;
}
template <class T> ostream &operator<<(ostream &s, set<T> P) {
  for (auto it : P) {
    s << "<" << it << "> ";
  }
  return s << endl;
}
template <class T1, class T2> ostream &operator<<(ostream &s, map<T1, T2> P) {
  for (auto it : P) {
    s << "<" << it.first << "->" << it.second << "> ";
  }
  return s << endl;
}

template <class Monoid> struct SegTree {
  using Func = function<Monoid(Monoid, Monoid)>;
  const Func F;
  const Monoid UNITY;
  int SIZE_R;
  vector<Monoid> dat;

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

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

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

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

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

int solve(int N, int K) {
  const int MAX = 510000;
  auto func = [&](int a, int b) { return max(a, b); };
  SegTree<int> seg(MAX, func, 0);
  for (int i = 0; i < N; ++i) {
    int a;
    cin >> a;
    int left = max(0, a - K);
    int right = min(MAX, a + K + 1);
    int val = seg.get(left, right);
    seg.update(a, val + 1);

    // seg.print(); COUT(val);
  }
  return seg.get(0, MAX);
}

int main() {
  int N, K;
  while (cin >> N >> K)
    cout << solve(N, K) << endl;
}


#include <bits/stdc++.h>
#include <iostream>
using namespace std;
#define ll long long
#define pb push_back
#define mk make_pair
#define MAX 1000001
ll prime[MAX];
#define FAST                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define mod 1000000007
#define gcd __gcd
// ll rec(vector<vector<ll> >& dp,vector<ll>& arr,int n,int i,int k,int w)
// {
//   ll ans=0;
//   if(i>=n)
//     return 0;

//   if(dp[i][k]!=-1)
//     return dp[i][k];

//   if(k!=0)
//   ans=max(rec(dp,arr,n,i+1,w,w),arr[i]+rec(dp,arr,n,i+1,k-1,w));
//   else
//   ans=max(rec(dp,arr,n,i+1,k,w),rec(dp,arr,n,i+1,w,w));

//   return dp[i][k]=ans;

// }

// ll t[400008];
//  void build(vector<ll>& a, int v, int tl, int tr) {
//      if (tl == tr) {
//          t[v] = a[tl];
//      } else {
//          int tm = (tl + tr) / 2;
//          build(a, v*2, tl, tm);
//          build(a, v*2+1, tm+1, tr);
//          t[v] = max(t[v*2] ,t[v*2+1]);
//      }
//  }

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

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

struct hash_pair {
  template <class T1, class T2> size_t operator()(const pair<T1, T2> &p) const {
    auto hash1 = hash<T1>{}(p.first);
    auto hash2 = hash<T2>{}(p.second);
    return hash1 ^ hash2;
  }
};

int temp[1000002] = {0};

void sieve() {

  for (int i = 1; i < 1000002; i++)
    temp[i] = 1;

  for (int i = 2; i < 1000002; i++) {
    temp[i]++;
    for (int j = i * 2; j < 1000002; j += i) {
      temp[j]++;
      ;
    }
  }
}
int k;
int rec(vector<int> &a, int i, int n, vector<int> &dp) {

  if (i >= n)
    return 0;

  if (dp[i] != -1)
    return dp[i];

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

int main() {

  int n;
  cin >> n >> k;

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

  cout << rec(a, 0, n, dp);

  return 0;
}
/*

*/

#include <bits/stdc++.h>
#include <iostream>
using namespace std;
#define ll long long
#define pb push_back
#define mk make_pair
#define MAX 1000001
ll prime[MAX];
#define FAST                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define mod 1000000007
#define gcd __gcd
// ll rec(vector<vector<ll> >& dp,vector<ll>& arr,int n,int i,int k,int w)
// {
//   ll ans=0;
//   if(i>=n)
//     return 0;

//   if(dp[i][k]!=-1)
//     return dp[i][k];

//   if(k!=0)
//   ans=max(rec(dp,arr,n,i+1,w,w),arr[i]+rec(dp,arr,n,i+1,k-1,w));
//   else
//   ans=max(rec(dp,arr,n,i+1,k,w),rec(dp,arr,n,i+1,w,w));

//   return dp[i][k]=ans;

// }

ll t[1200002] = {0};
void build(vector<ll> &a, int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = a[tl];
  } else {
    int tm = (tl + tr) / 2;
    build(a, v * 2, tl, tm);
    build(a, v * 2 + 1, tm + 1, tr);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
}

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

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

struct hash_pair {
  template <class T1, class T2> size_t operator()(const pair<T1, T2> &p) const {
    auto hash1 = hash<T1>{}(p.first);
    auto hash2 = hash<T2>{}(p.second);
    return hash1 ^ hash2;
  }
};

// int temp[1000002]={0};

// void sieve()
// {

//   for(int i=1;i<1000002;i++)
//     temp[i]=1;

//   for(int i=2;i<1000002;i++)
//   {
//      temp[i]++;
//       for(int j=i*2;j<1000002;j+=i)
//       {
//         temp[j]++;;
//       }
//   }

// }

int main() {

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

  int m = 300000;
  int l, r;
  int ans = 0, temp;
  for (int i = 0; i < n; i++) {
    temp = a[i] - k;
    l = max(1, temp);
    temp = a[i] + k;
    r = min(m, temp);
    temp = maxi(1, 1, m, l, r);
    update(1, 1, m, a[i], temp + 1);
    ans = max(ans, temp + 1);
  }
  cout << ans;

  return 0;
}
/*

*/


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int INF = 1e9;
const ll LINF = 1e18;
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &o) {
  out << "(" << o.first << "," << o.second << ")";
  return out;
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &V) {
  for (int i = 0; i < V.size(); i++) {
    out << V[i];
    if (i != V.size() - 1)
      out << " ";
  }
  return out;
}
template <class T>
ostream &operator<<(ostream &out, const vector<vector<T>> &Mat) {
  for (int i = 0; i < Mat.size(); i++) {
    if (i != 0)
      out << endl;
    out << Mat[i];
  }
  return out;
}
template <class S, class T>
ostream &operator<<(ostream &out, const map<S, T> &mp) {
  out << "{ ";
  for (auto it = mp.begin(); it != mp.end(); it++) {
    out << it->first << ":" << it->second;
    if (mp.size() - 1 != distance(mp.begin(), it))
      out << ", ";
  }
  out << " }";
  return out;
}
template <typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t)
    fill_v(e, v);
}
/*
 <url:>
 問題文============================================================
 =================================================================
 解説=============================================================
 ================================================================
 */

/*
 抽象化SegTree
 ref : https://ei1333.github.io/algorithm/segment-tree.html
 */
template <typename Monoid> struct SegmentTree {
public:
  using Type = typename Monoid::Type;
  int sz; // Array size
  int _n;
  vector<Type> node;
  SegmentTree(int n) : _n(n) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    node.assign(2 * sz, Monoid::id());
  }
  void set(int k, const Type &val) { node[k + sz] = val; }
  void build() {
    for (int k = sz - 1; k > 0; k--) {
      node[k] = Monoid::op(node[2 * k], node[2 * k + 1]);
    }
  }
  inline void update(int k, const Type &val) {
    k += sz;
    node[k] = val;
    while (k >>= 1) {
      node[k] = Monoid::op(node[2 * k], node[2 * k + 1]);
    }
  }
  inline Type query(int l, int r) {
    if (l >= r)
      return Monoid::id();
    Type vl = Monoid::id(), vr = Monoid::id();
    for (l += sz, r += sz; l != r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = Monoid::op(vl, node[l++]);
      if (r & 1)
        vr = Monoid::op(node[--r], vr);
    }
    return Monoid::op(vl, vr);
  }

  /*
   * max_right
   *
   * bool を返す評価関数fを用いて
   * 以下の条件を両方満たす rを（いずれか1つ返す)
   * - r = l もしくは f(op(a[l], a[l + 1], ..., a[r - 1])) = true
   * - r = n もしくは f(op(a[l], a[l + 1], ..., a[r])) = false
   *
   * fの単調性を許せば
   * "f(op(a[l], a[l + 1], ..., a[r - 1])) = true となる最大のr"を返す
   */
  template <bool (*f)(Type)> int max_right(int l) {
    return max_right(l, [](Type x) { return f(x); });
  }
  template <class F> int max_right(int l, F f) {
    assert(0 <= l && l <= _n);
    assert(f(Monoid::id()));
    if (l == _n)
      return _n;
    l += sz;
    Type sm = Monoid::id();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!f(Monoid::op(sm, node[l]))) {
        while (l < sz) {
          l = (2 * l);
          if (f(Monoid::op(sm, node[l]))) {
            sm = Monoid::op(sm, node[l]);
            l++;
          }
        }
        return l - sz;
      }
      sm = Monoid::op(sm, node[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }

  /*
   * min_left
   *
   * bool を返す評価関数lを用いて
   * 以下の条件を両方満たす lを（いずれか1つ返す)
   * - l = r もしくは f(op(a[l], a[l + 1], ..., a[r - 1])) = true
   * - l = 0 もしくは f(op(a[l - 1], a[l + 1], ..., a[r - 1])) = false
   *
   * fの単調性を許せば
   * "f(op(a[l], a[l + 1], ..., a[r - 1])) = true となる最小のl"を返す
   */
  template <bool (*f)(Type)> int min_left(int r) {
    return min_left(r, [](Type x) { return f(x); });
  }
  template <class F> int min_left(int r, F f) {
    assert(0 <= r && r <= _n);
    assert(f(Monoid::id()));
    if (r == 0)
      return 0;
    r += sz;
    Type sm = Monoid::id();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!f(Monoid::op(node[r], sm))) {
        while (r < sz) {
          r = (2 * r + 1);
          if (f(Monoid::op(node[r], sm))) {
            sm = Monoid::op(node[r], sm);
            r--;
          }
        }
        return r + 1 - sz;
      }
      sm = Monoid::op(node[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

  Type operator[](int i) { return node[i + sz]; }
};

struct Monoid {
  using Type = int; /* Monoidに乗せる型 */
  static Type id() { return 0; /* モノイドの初期値 */ };

  //  =========  //
  //  マージ処理  //
  //  =========  //
  static Type op(const Type &l, const Type &r) {
    Type ret;
    ret = max(l, r);
    return ret;
  }
};

template <class Type> Type solve(Type res = Type()) {
  int MAX_V = 300'00;
  int N, K;
  cin >> N >> K;
  SegmentTree<Monoid> ST(MAX_V);
  for (int i = 0; i < N; i++) {
    int A;
    cin >> A;
    A--;

    int L = max(0, A - K);
    int R = min(MAX_V - 1, A + K);

    ST.update(A, ST.query(L, R + 1) + 1);
  }
  res = ST.query(0, MAX_V);
  return res;
}
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // solve<ll>(0);
  cout << fixed << setprecision(12) << solve<ll>() << endl;
  return 0;
}

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int INF = 1e9;
const ll LINF = 1e18;
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &o) {
  out << "(" << o.first << "," << o.second << ")";
  return out;
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &V) {
  for (int i = 0; i < V.size(); i++) {
    out << V[i];
    if (i != V.size() - 1)
      out << " ";
  }
  return out;
}
template <class T>
ostream &operator<<(ostream &out, const vector<vector<T>> &Mat) {
  for (int i = 0; i < Mat.size(); i++) {
    if (i != 0)
      out << endl;
    out << Mat[i];
  }
  return out;
}
template <class S, class T>
ostream &operator<<(ostream &out, const map<S, T> &mp) {
  out << "{ ";
  for (auto it = mp.begin(); it != mp.end(); it++) {
    out << it->first << ":" << it->second;
    if (mp.size() - 1 != distance(mp.begin(), it))
      out << ", ";
  }
  out << " }";
  return out;
}
template <typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t)
    fill_v(e, v);
}
/*
 <url:>
 問題文============================================================
 =================================================================
 解説=============================================================
 ================================================================
 */

/*
 抽象化SegTree
 ref : https://ei1333.github.io/algorithm/segment-tree.html
 */
template <typename Monoid> struct SegmentTree {
public:
  using Type = typename Monoid::Type;
  int sz; // Array size
  int _n;
  vector<Type> node;
  SegmentTree(int n) : _n(n) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    node.assign(2 * sz, Monoid::id());
  }
  void set(int k, const Type &val) { node[k + sz] = val; }
  void build() {
    for (int k = sz - 1; k > 0; k--) {
      node[k] = Monoid::op(node[2 * k], node[2 * k + 1]);
    }
  }
  inline void update(int k, const Type &val) {
    k += sz;
    node[k] = val;
    while (k >>= 1) {
      node[k] = Monoid::op(node[2 * k], node[2 * k + 1]);
    }
  }
  inline Type query(int l, int r) {
    if (l >= r)
      return Monoid::id();
    Type vl = Monoid::id(), vr = Monoid::id();
    for (l += sz, r += sz; l != r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = Monoid::op(vl, node[l++]);
      if (r & 1)
        vr = Monoid::op(node[--r], vr);
    }
    return Monoid::op(vl, vr);
  }

  /*
   * max_right
   *
   * bool を返す評価関数fを用いて
   * 以下の条件を両方満たす rを（いずれか1つ返す)
   * - r = l もしくは f(op(a[l], a[l + 1], ..., a[r - 1])) = true
   * - r = n もしくは f(op(a[l], a[l + 1], ..., a[r])) = false
   *
   * fの単調性を許せば
   * "f(op(a[l], a[l + 1], ..., a[r - 1])) = true となる最大のr"を返す
   */
  template <bool (*f)(Type)> int max_right(int l) {
    return max_right(l, [](Type x) { return f(x); });
  }
  template <class F> int max_right(int l, F f) {
    assert(0 <= l && l <= _n);
    assert(f(Monoid::id()));
    if (l == _n)
      return _n;
    l += sz;
    Type sm = Monoid::id();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!f(Monoid::op(sm, node[l]))) {
        while (l < sz) {
          l = (2 * l);
          if (f(Monoid::op(sm, node[l]))) {
            sm = Monoid::op(sm, node[l]);
            l++;
          }
        }
        return l - sz;
      }
      sm = Monoid::op(sm, node[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }

  /*
   * min_left
   *
   * bool を返す評価関数lを用いて
   * 以下の条件を両方満たす lを（いずれか1つ返す)
   * - l = r もしくは f(op(a[l], a[l + 1], ..., a[r - 1])) = true
   * - l = 0 もしくは f(op(a[l - 1], a[l + 1], ..., a[r - 1])) = false
   *
   * fの単調性を許せば
   * "f(op(a[l], a[l + 1], ..., a[r - 1])) = true となる最小のl"を返す
   */
  template <bool (*f)(Type)> int min_left(int r) {
    return min_left(r, [](Type x) { return f(x); });
  }
  template <class F> int min_left(int r, F f) {
    assert(0 <= r && r <= _n);
    assert(f(Monoid::id()));
    if (r == 0)
      return 0;
    r += sz;
    Type sm = Monoid::id();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!f(Monoid::op(node[r], sm))) {
        while (r < sz) {
          r = (2 * r + 1);
          if (f(Monoid::op(node[r], sm))) {
            sm = Monoid::op(node[r], sm);
            r--;
          }
        }
        return r + 1 - sz;
      }
      sm = Monoid::op(node[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

  Type operator[](int i) { return node[i + sz]; }
};

struct Monoid {
  using Type = int; /* Monoidに乗せる型 */
  static Type id() { return 0; /* モノイドの初期値 */ };

  //  =========  //
  //  マージ処理  //
  //  =========  //
  static Type op(const Type &l, const Type &r) {
    Type ret;
    ret = max(l, r);
    return ret;
  }
};

template <class Type> Type solve(Type res = Type()) {
  int MAX_V = 600'010;
  int N, K;
  cin >> N >> K;
  SegmentTree<Monoid> ST(MAX_V);
  for (int i = 0; i < N; i++) {
    int A;
    cin >> A;
    int L = max(0, A - K);
    int R = A + K;

    ST.update(A, ST.query(L, R + 1) + 1);
  }
  res = ST.query(0, MAX_V);
  return res;
}
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // solve<ll>(0);
  cout << fixed << setprecision(12) << solve<ll>() << endl;
  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;
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
#define fi first
#define se second
#define endl '\\n'
#define int int64_t
#define double long double
// template<int D, typename T>struct dense:public
// vector<dense<D-1,T>>{static_assert(D>=1,"dim err");template<typename...
// Args>dense(int n=0,Args...
// args):vector<dense<D-1,T>>(n,dense<D-1,T>(args...)){}}; template<typename
// T>struct dense<1,T>:public vector<T>{dense(int n=0,const T&
// val=T()):vector<T>(n,val){}}; template<typename T> using ordered_set =
// tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// template<typename T> using reverse_queue = priority_queue<T, vector<T>,
// greater<T>>; mt19937_64 rnd(time(0)); const int FIXED_RANDOM = rnd();
// template<typename T> struct custom_hash{T operator()(T x)const{return (T)
// x^FIXED_RANDOM;}}; // check hash in whether int64 or int32 template<typename
// T1, typename T2> using hash_map = gp_hash_table<T1, T2, custom_hash<T1>>;
const int MAXN = (int)3e5 + 2;
const int INF = numeric_limits<int>::max() >> 1;
const int MOD = (int)1000000007;
// Tao luyện kỹ thuật trong 8 năm mày luyện kỹ thuật trong buồng tắm nam
int it[MAXN];
void update(int id, int l, int r, int p, int val) {
  if (l > p || r < p || l > r)
    return;
  if (l == p && r == p) {
    if (it[id] < val)
      it[id] = val;
    return;
  }
  int mid = (l + r) / 2;
  update(id << 1, l, mid, p, val);
  update(id << 1 | 1, mid + 1, r, p, val);
  it[id] = max(it[id << 1], it[id << 1 | 1]);
}
int get(int id, int l, int r, int L, int R) {
  if (l > r || l > R || r < L)
    return -INF;
  if (L <= l && r <= R)
    return it[id];
  int mid = (l + r) / 2;
  return max(get(id << 1, l, mid, L, R), get(id << 1 | 1, mid + 1, r, L, R));
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  freopen("FDT.txt", "r", stdin);
  fill(it, it + MAXN, -INF);
  int n, k;
  cin >> n >> k;
  vector<int> a(n + 1);
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  for (int i = n; i >= 1; i--) {
    int lf = a[i] - k;
    if (lf < 0)
      lf = 0;
    int rt = a[i] + k;
    if (rt > n)
      rt = n;
    int d = get(1, 1, n, lf, rt);
    if (d < 0)
      d = 0;
    d++;
    update(1, 1, n, a[i], d);
  }
  cout << get(1, 1, n, 0, n);
}

#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;
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
#define fi first
#define se second
#define endl '\\n'
#define int int64_t
#define double long double
// template<int D, typename T>struct dense:public
// vector<dense<D-1,T>>{static_assert(D>=1,"dim err");template<typename...
// Args>dense(int n=0,Args...
// args):vector<dense<D-1,T>>(n,dense<D-1,T>(args...)){}}; template<typename
// T>struct dense<1,T>:public vector<T>{dense(int n=0,const T&
// val=T()):vector<T>(n,val){}}; template<typename T> using ordered_set =
// tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// template<typename T> using reverse_queue = priority_queue<T, vector<T>,
// greater<T>>; mt19937_64 rnd(time(0)); const int FIXED_RANDOM = rnd();
// template<typename T> struct custom_hash{T operator()(T x)const{return (T)
// x^FIXED_RANDOM;}}; // check hash in whether int64 or int32 template<typename
// T1, typename T2> using hash_map = gp_hash_table<T1, T2, custom_hash<T1>>;
const int MAXN = (int)3e5 + 2;
const int INF = numeric_limits<int>::max() >> 1;
const int MOD = (int)1000000007;
// Tao luyện kỹ thuật trong 8 năm mày luyện kỹ thuật trong buồng tắm nam
struct lazy_segment_tree {
  using it_type = long long;
  int n;
  vector<it_type> it;
  vector<long long> lz;
  const it_type FAILED_STAGE = -INF;
  void init(int _) {
    n = _;
    it.resize((n << 2) | 1, -INF);
    lz.resize((n << 2) | 1, -INF); // check init lazy
  }
  it_type merge(it_type a, it_type b) { return max(a, b); }
  // it_type build(int u, int l, int r, auto &a){ // 1 indexed
  //   if(l == r) return it[u] = a[l];
  //   return it[u] = merge(build(u << 1, l, ((l + r)>>1), a), build((u << 1)|1,
  //   ((l + r)>>1) + 1, r, a)); // merge stage
  // }
  void lazy(int u, int l, int r) { // lazy
    if (lz[u] == -INF)
      return;
    it[u] = max(it[u], lz[u]);
    if (l != r) {
      lz[u << 1] = max(lz[u << 1], lz[u]);
      lz[(u << 1) | 1] = max(lz[(u << 1) | 1], lz[u]);
    }
    lz[u] = -INF;
  }
  void update(int u, int l, int r, int L, int R, int val) {
    if (R < L)
      return;
    lazy(u, l, r);
    if (l > R || r < L)
      return;
    if (L <= l && r <= R) {
      lz[u] = val; // lazy update
      lazy(u, l, r);
      return;
    }
    update(u << 1, l, ((l + r) >> 1), L, R, val);
    update((u << 1) | 1, ((l + r) >> 1) + 1, r, L, R, val);
    it[u] = merge(it[u << 1], it[(u << 1) | 1]); // merge stage
  }
  it_type get(int u, int l, int r, int L, int R) {
    if (l > R || r < L)
      return FAILED_STAGE; // check for failed stage
    lazy(u, l, r);
    if (L <= l && r <= R)
      return it[u];
    return merge(get(u << 1, l, ((l + r) >> 1), L, R),
                 get((u << 1) | 1, ((l + r) >> 1) + 1, r, L, R)); // merge stage
  }
};
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  // freopen("FDT.txt", "r", stdin);
  lazy_segment_tree tr;
  int n, k;
  cin >> n >> k;
  tr.init(300001);
  vector<int> a(n + 1);
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  for (int i = n; i >= 1; i--) {
    int lf = a[i] - k;
    if (lf < 0)
      lf = 0;
    int rt = a[i] + k;
    if (rt > 300000)
      rt = 300000;
    int d = tr.get(1, 1, 300001, lf + 1, rt + 1);
    if (d < 0)
      d = 0;
    d++;
    tr.update(1, 1, 300001, a[i] + 1, a[i] + 1, d);
  }
  cout << tr.get(1, 1, 300001, 1, 300001);
}

terminate called after throwing an instance of 'std::length_error'
  what():  cannot create std::vector larger than max_size()


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

int n, k, a[N], f[N << 2];
void pushup(int o) { f[o] = max(f[o << 1], f[o << 1 | 1]); }
int ask(int l, int r, int o, int ld, int rd) {
  if (l == r)
    return f[o];
  int mid = l + r >> 1, ans = 0;
  if (rd > mid)
    ans = max(ans, ask(mid + 1, r, o << 1 | 1, ld, rd));
  if (ld <= mid)
    ans = max(ans, ask(l, mid, o << 1, ld, rd));
  return ans;
}
void modify(int l, int r, int o, int x, int y) {
  if (l == r) {
    f[o] = y;
    return;
  }
  int mid = l + r >> 1;
  if (x <= mid)
    modify(l, mid, o << 1, x, y);
  else
    modify(mid + 1, r, o << 1 | 1, x, y);
  pushup(o);
}
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), a[i]++;
  for (int i = 1; i <= n; i++) {
    int x = ask(1, 300001, 1, max(1, a[i] - k), min(300001, a[i] + k)) + 1;
    modify(1, 300001, 1, a[i], x);
  }
  printf("%d\\n", f[1]);
}

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

int n, k, a[N], f[N << 2];
void pushup(int o) { f[o] = max(f[o << 1], f[o << 1 | 1]); }
int ask(int l, int r, int o, int ld, int rd) {
  if (l == r)
    return f[o];
  if (ld <= l && rd >= r)
    return f[o];
  int mid = l + r >> 1, ans = 0;
  if (rd > mid)
    ans = max(ans, ask(mid + 1, r, o << 1 | 1, ld, rd));
  if (ld <= mid)
    ans = max(ans, ask(l, mid, o << 1, ld, rd));
  return ans;
}
void modify(int l, int r, int o, int x, int y) {
  if (l == r) {
    f[o] = y;
    return;
  }
  int mid = l + r >> 1;
  if (x <= mid)
    modify(l, mid, o << 1, x, y);
  else
    modify(mid + 1, r, o << 1 | 1, x, y);
  pushup(o);
}
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), a[i]++;
  for (int i = 1; i <= n; i++) {
    int x = ask(1, 300001, 1, max(1, a[i] - k), min(300001, a[i] + k)) + 1;
    modify(1, 300001, 1, a[i], x);
  }
  printf("%d\\n", f[1]);
}


#include <bits/stdc++.h>
#define ll long long int
#define mk make_pair
#define pb push_back
#define INF (ll)1e18
#define pii pair<ll, ll>
#define mod 1000000007 // 998244353
#define f(i, a, b) for (ll i = a; i < b; i++)
#define fb(i, a, b) for (ll i = a; i > b; i--)
#define ff first
#define ss second
#define srt(v)                                                                 \\
  if (!v.empty())                                                              \\
  sort(v.begin(), v.end())
#define PI 3.141592653589793238
#define pq priority_queue<ll>
#define pqr priority_queue<ll, vector<ll>, greater<ll>()>
using namespace std;
ll pow_mod(ll a, ll b) {
  ll res = 1;
  while (b != 0) {
    if (b & 1) {
      res = (res * a) % mod;
    }
    a = (a * a) % mod;
    b /= 2;
  }
  return res;
}
ll st[4 * 30000 + 2];
void solve() {

  // GENERAL PURPOSE SEGMENT TREE FOR RMQ

  ll n, k;

  cin >> n >> k;

  ll a[n];

  for (ll i = 0; i < n; i++)
    cin >> a[i];

  function<void(ll, ll, ll, ll, ll)> update = [&](ll ss, ll se, ll si, ll id,
                                                  ll val) {
    if (ss == se && ss == id) {
      st[si] = val;
      return;
    }

    if (id > se || id < ss)
      return;

    ll mid = (ss + se) / 2;

    update(ss, mid, 2 * si + 1, id, val);
    update(mid + 1, se, 2 * si + 2, id, val);

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

  function<ll(ll, ll, ll, ll, ll)> get_min = [&](ll ss, ll se, ll si, ll l,
                                                 ll r) {
    if (l > r)

      return 0LL;

    if (r < ss || se < l)
      return 0LL;

    if (ss >= l && se <= r)
      return st[si];

    ll mid = (ss + se) / 2;

    return max(get_min(ss, mid, 2 * si + 1, l, r),
               get_min(mid + 1, se, 2 * si + 2, l, r));
  };

  // build_sgt(0,30000,0);

  ll dp[30000 + 1];

  for (ll i = 0; i < 30000 + 1; i++) {
    update(0LL, 30000LL, 0LL, i, 0LL);

    dp[i] = 0;
  }

  ll ans = 0LL;

  for (ll i = 0; i < n; i++) {
    ll l = max(0LL, a[i] - k);
    ll r = min(30000LL, a[i] + k);

    ll res = get_min(0LL, 30000LL, 0LL, l, r);

    update(0LL, 30000LL, 0LL, a[i], 1LL);

    dp[a[i]] = max(dp[a[i]], 1 + res);

    update(0LL, 30000LL, 0LL, a[i], dp[a[i]]);
  }

  for (ll i = 0; i < n; i++)
    ans = max(ans, dp[a[i]]);

  cout << ans << endl;
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  // Start from Here.

  ll t;
  t = 1;
  // cin>>t;
  while (t--)
    solve();

  // Good Bye!
  return 0;
}

#include <bits/stdc++.h>
#define ll long long int
#define mk make_pair
#define pb push_back
#define INF (ll)1e18
#define pii pair<ll, ll>
#define mod 1000000007 // 998244353
#define f(i, a, b) for (ll i = a; i < b; i++)
#define fb(i, a, b) for (ll i = a; i > b; i--)
#define ff first
#define ss second
#define srt(v)                                                                 \\
  if (!v.empty())                                                              \\
  sort(v.begin(), v.end())
#define PI 3.141592653589793238
#define pq priority_queue<ll>
#define pqr priority_queue<ll, vector<ll>, greater<ll>()>
using namespace std;
ll pow_mod(ll a, ll b) {
  ll res = 1;
  while (b != 0) {
    if (b & 1) {
      res = (res * a) % mod;
    }
    a = (a * a) % mod;
    b /= 2;
  }
  return res;
}
ll st[4 * 300000 + 2];
void solve() {

  // GENERAL PURPOSE SEGMENT TREE FOR RMQ

  ll n, k;

  cin >> n >> k;

  ll a[n];

  for (ll i = 0; i < n; i++)
    cin >> a[i];

  function<void(ll, ll, ll, ll, ll)> update = [&](ll ss, ll se, ll si, ll id,
                                                  ll val) {
    if (ss == se && ss == id) {
      st[si] = val;
      return;
    }

    if (id > se || id < ss)
      return;

    ll mid = (ss + se) / 2;

    update(ss, mid, 2 * si + 1, id, val);
    update(mid + 1, se, 2 * si + 2, id, val);

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

  function<ll(ll, ll, ll, ll, ll)> get_min = [&](ll ss, ll se, ll si, ll l,
                                                 ll r) {
    if (l > r)

      return 0LL;

    if (r < ss || se < l)
      return 0LL;

    if (ss >= l && se <= r)
      return st[si];

    ll mid = (ss + se) / 2;

    return max(get_min(ss, mid, 2 * si + 1, l, r),
               get_min(mid + 1, se, 2 * si + 2, l, r));
  };

  // build_sgt(0,30000,0);

  ll dp[300000 + 1];

  for (ll i = 0; i < 300000LL + 1LL; i++) {
    update(0LL, 300000LL, 0LL, i, 0LL);

    dp[i] = 0;
  }

  ll ans = 0LL;

  for (ll i = 0; i < n; i++) {
    ll l = max(0LL, a[i] - k);
    ll r = min(300000LL, a[i] + k);

    ll res = get_min(0LL, 300000LL, 0LL, l, r);

    update(0LL, 300000LL, 0LL, a[i], 1LL);

    dp[a[i]] = max(dp[a[i]], 1 + res);

    update(0LL, 300000LL, 0LL, a[i], dp[a[i]]);
  }

  for (ll i = 0; i < n; i++)
    ans = max(ans, dp[a[i]]);

  cout << ans << endl;
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  // Start from Here.

  ll t;
  t = 1;
  // cin>>t;
  while (t--)
    solve();

  // Good Bye!
  return 0;
}