// CF template, version 3.0
#include <bits/stdc++.h>
using namespace std;
#define improvePerformance ios_base::sync_with_stdio(false); cin.tie(0)
#define getTest int t; cin >> t
#define eachTest for (int _var=0;_var<t;_var++)
#define get(name) int (name); cin >> (name)
#define out(o) cout << (o)
#define getList(cnt, name) vector<int> (name); for (int _=0;_<(cnt);_++) { get(a); (name).push_back(a); }
#define sortl(name) sort((name).begin(), (name).end())
#define rev(name) reverse((name).begin(), (name).end())
#define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
#define decision(b) if (b){out("YES");}else{out("NO");}
#define int long long
int m;
void upd(vector<int>& tree, int i, int x, int l=0, int r=m-1, int v=1) {
if (l == r) tree[v] = max(tree[v], x);
else {
int middle = (l + r) / 2;
if (middle >= i) upd(tree, i, x, l, middle, 2 * v);
else upd(tree, i, x, middle + 1, r, 2 * v + 1);
tree[v] = max(tree[2 * v], tree[2 * v + 1]);
}
}
int query(vector<int>& tree, int ql, int qr, int l=0, int r=m-1, int v=1) {
if (ql <= l && r <= qr) return tree[v];
if (qr < l || r < ql) return 0;
int middle = (l + r) / 2;
return max(query(tree, ql, qr, l, middle, 2 * v), query(tree, ql, qr, middle + 1, r, 2 * v + 1));
}
signed main() {
//improvePerformance;
//getTest;
//eachTest {
get(n);
get(x);
getList(n, nums);
vector<int> sorted;
for (int num: nums) sorted.push_back(num);
sortl(sorted);
map<int, int> coord;
m = 0;
forto(n, i) {
if (coord.find(sorted[i]) == coord.end()) {
coord[sorted[i]] = m++;
}
}
coord[1e18] = m;
// assuming x is small enough...
vector<vector<vector<int>>> dp(n, vector<vector<int>>(3, vector<int>(2, -1)));
vector<int> segtree0(4 * m, 0);
vector<int> segtree1(4 * m, 0);
vector<int> segtree2(4 * m, 0);
// dp[i][s][d] = LIS in the first i elements if index i is before, in or outside the interval (s=0, 1, or 2 resp.) and we increase by d. LIS must end at index i.
forto(2, d) {
int dd;
if (d == 0) dd = 0;
else dd = 2 * x;
forto(4 * m, i) {
segtree0[i] = 0;
segtree1[i] = 0;
segtree2[i] = 0;
}
// calculate the DP values when delta = d.
int D = dd - x;
forto(n, i) {
forto(3, s) {
if (s == 0) {
int co = coord[nums[i]];
if (co == 0) dp[i][s][d] = 1;
else {
dp[i][s][d] = query(segtree0, 0, co - 1) + 1;
}
} else if (s == 1) {
auto it = lower_bound(sorted.begin(), sorted.end(), nums[i] + D);
int el = it == sorted.end()? 1e18: *it;
int co = coord[el];
int cur;
if (co == 0) cur = 1;
else {
cur = query(segtree0, 0, co - 1) + 1;
}
int curco = coord[nums[i]];
int second;
if (curco == 0) second = 1;
else {
second = query(segtree1, 0, curco - 1) + 1;
}
dp[i][s][d] = max(cur, second);
} else {
auto it = lower_bound(sorted.begin(), sorted.end(), nums[i] - D);
int el = it == sorted.end()? 1e18: *it;
int co = coord[el];
int cur;
if (co == 0) cur = 1;
else {
cur = query(segtree1, 0, co - 1) + 1;
}
int curco = coord[nums[i]];
int second;
if (curco == 0) second = 1;
else {
second = query(segtree2, 0, curco - 1) + 1;
}
dp[i][s][d] = max(cur, second);
}
}
upd(segtree0, coord[nums[i]], dp[i][0][d]);
upd(segtree1, coord[nums[i]], dp[i][1][d]);
upd(segtree2, coord[nums[i]], dp[i][2][d]);
}
}
int ans = 0;
forto(n, i) forto(3, s) forto(2, d) ans = max(ans, dp[i][s][d]);
out(ans);
//}
}