Problem p02537 (C++)

Buggy submission (status: Time Limit Exceeded):
#pragma GCC target("sse4.2")
#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second
#define PB push_back
#define ln "\n"
#define forn(i, e) for (ll i = 0; i < e; i++)
#define forsn(i, s, e) for (ll i = s; i < e; i++)
#define rforn(i, e) for (ll i = e; i >= 0; i--)
#define rforsn(i, e, s) for (ll i = e; i >= s; i--)
#define vasort(v) sort(v.begin(), v.end());
#define vdsort(v) sort(v.begin(), v.end(), greater<ll>());
#define fio                                                                    \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL)
#define mem(a, b) memset(a, b, sizeof(a))
#define sz(x) ((int)size(x))
#define EB emplace_back
#define flush fflush(stdout)
#define out1(x1) cout << x1 << ln
#define out2(x1, x2) cout << x1 << " " << x2 << endl
#define out3(x1, x2, x3) cout << x1 << " " << x2 << " " << x3 << endl
#define out4(x1, x2, x3, x4)                                                   \
  cout << x1 << " " << x2 << " " << x3 << " " << x4 << ln
#define all(d) d.begin(), d.end()
#define unordered_set(T) unordered_set<T, custom_hash>
#define unordered_map(T1, T2) unordered_map<T1, T2, custom_hash>

#define in1(x1) cin >> x1
#define in2(x1, x2) cin >> x1 >> x2
#define in3(x1, x2, x3) cin >> x1 >> x2 >> x3
#define in4(x1, x2, x3, x4) cin >> x1 >> x2 >> x3 >> x4

#define arrin(a, n) forn(i, n) cin >> a[i];
#define arrout(a, n)                                                           \
  forn(i, n) { cout << a[i] << " "; }                                          \
  cout << ln;

/* ---------------- IO ----------------*/

namespace IO {
const int BUFFER_SIZE = 1 << 15;
char input_buffer[BUFFER_SIZE];
int input_pos = 0, input_len = 0;
char output_buffer[BUFFER_SIZE];
int output_pos = 0;
char number_buffer[100];
uint8_t lookup[100];
void _update_input_buffer() {
  input_len = fread(input_buffer, sizeof(char), BUFFER_SIZE, stdin);
  input_pos = 0;
  if (input_len == 0)
    input_buffer[0] = EOF;
}
inline char next_char(bool advance = true) {
  if (input_pos >= input_len)
    _update_input_buffer();

  return input_buffer[advance ? input_pos++ : input_pos];
}

template <typename T> inline void read_int(T &number) {
  bool negative = false;
  number = 0;

  while (!isdigit(next_char(false)))
    if (next_char() == '-')
      negative = true;

  do {
    number = 10 * number + (next_char() - '0');
  } while (isdigit(next_char(false)));

  if (negative)
    number = -number;
}

template <typename T, typename... Args>
inline void read_int(T &number, Args &...args) {
  read_int(number);
  read_int(args...);
}

void _flush_output() {
  fwrite(output_buffer, sizeof(char), output_pos, stdout);
  output_pos = 0;
}

inline void write_char(char c) {
  if (output_pos == BUFFER_SIZE)
    _flush_output();

  output_buffer[output_pos++] = c;
}

template <typename T> inline void write_int(T number, char after = '\0') {
  if (number < 0) {
    write_char('-');
    number = -number;
  }
  int length = 0;
  while (number >= 10) {
    uint8_t lookup_value = lookup[number % 100];
    number /= 100;
    number_buffer[length++] = (lookup_value & 15) + '0';
    number_buffer[length++] = (lookup_value >> 4) + '0';
  }
  if (number != 0 || length == 0)
    write_char(number + '0');
  for (int i = length - 1; i >= 0; i--)
    write_char(number_buffer[i]);
  if (after)
    write_char(after);
}
void IOinit() {
  // Make sure _flush_output() is called at the end of the program.
  bool exit_success = atexit(_flush_output) == 0;
  assert(exit_success);
  for (int i = 0; i < 100; i++)
    lookup[i] = (i / 10 << 4) + i % 10;
}
} // namespace IO

using namespace IO;

/* ---------------- typedefs ----------------*/
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

/* ---------------- utility functions ---------------- */

int dr[] = {0, 1, -1, 0, 1, -1, 1, -1};
int dc[] = {1, 0, 0, -1, 1, -1, -1, 1};
int drr[] = {-2, -1, 0, 1, 2};
int dcc[] = {-2, -1, 0, 1, 2};
bool chk(int a, int b, int n, int m) {
  return 0 <= a && a < n && 0 <= b && b < m;
}

ll exp(ll n, ll m, ll md) {
  ll a = 1;
  while (m > 0) {
    if (m & 1)
      a = (a * n % md) % md;
    m /= 2;
    n = (n * n) % md;
  }
  return a % md;
}

ll expm(ll n, ll m) {
  ll a = 1;
  while (m > 0) {
    if (a < 0 or a >= (1e18 + n - 1) / n) {
      return -1;
    }
    if (m & 1)
      a = (a * n);
    m /= 2;
    n = (n * n);
  }
  return a;
}

void disp(vi v) {
  for (auto u : v)
    cout << u << " ";
  cout << "\n";
}
void disp(vll v) {
  for (auto u : v)
    cout << u << " ";
  cout << endl;
}

int getSqr(int x) {
  if (x < 0)
    return -1;
  int l = sqrt(x);
  for (int i = -2; i <= 2; ++i)
    if (l + i >= 0 && (l + i) * (l + i) == x)
      return l;
  return -1;
}

const int NPRR = 1e7;
vi lp;
vector<int> prr;
void prfac(int n = NPRR) {
  assert(n <= NPRR);
  lp.assign(n + 1, 0);
  int i;
  for (i = 2; i <= n; ++i) {
    if (lp[i] == 0) {
      lp[i] = i;
      prr.push_back(i);
    }
    for (int u : prr) {
      if (i * u > n || u > lp[i])
        break;
      lp[i * u] = u;
    }
  }
}

bool check_composite_for_prime_function(ll n, ll a, ll d, int s) {
  ll x = exp(a, d, n);
  if (x == 1 || x == n - 1)
    return false;
  for (int r = 1; r < s; ++r) {
    x = x * x % n;
    x %= n;
    if (x == n - 1)
      return false;
  }
  return true;
}
bool prime(ll n) {
  if (n < 4)
    return n == 2 || n == 3;
  if (!(n & 1))
    return false;
  int s = 0;
  ll d = n - 1;
  while (!(d & 1)) {
    d >>= 1;
    s++;
  }
  for (int a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) {
    if (n == a)
      return true;
    if (check_composite_for_prime_function(n, a, d, s))
      return false;
  }
  return true;
}

ll binomialCoeff(ll n, ll k) {
  ll res = 1;

  // Since C(n, k) = C(n, n-k)
  if (k > n - k)
    k = n - k;

  // Calculate value of
  // [n * (n-1) *---* (n-k+1)] / [k * (k-1) *----* 1]
  for (ll i = 0; i < k; ++i) {
    res *= (n - i);
    res /= (i + 1);
  }

  return res;
}
/* custom hash for unordered map */
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};

inline void read(int &x) { scanf("%d", &x); }

auto random_address = [] {
  char *p = new char;
  delete p;
  return uint64_t(p);
};

const uint64_t SEED = chrono::steady_clock::now().time_since_epoch().count() *
                      (random_address() | 1);
mt19937_64 rng(SEED);

/* ---------------- constants ---------------- */
const ll MAXn = 1e6 + 33, MAXlg = __lg(MAXn) + 2;
const ll MOD = 1000000007;
const ll INF = ll(1e15);

/* ---------------- gcd_extended ---------------- */
/*
 * CAREFUL: Overflow at x *= c/g out of 10**18
 * Lookout for A = 0 or B = 0
 */
void shift(ll &x, ll &y, ll cnt, ll a, ll b) {
  x += cnt * b;
  y -= cnt * a;
}
ll gcd(ll a, ll b, ll &x, ll &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  ll x1, y1;
  ll d = gcd(b, a % b, x1, y1);
  x = y1;
  y = x1 - y1 * (a / b);
  return d;
}
bool give_range(ll a, ll b, ll c, ll mina, ll maxa, ll minb, ll maxb, ll &lx,
                ll &rx) {
  ll x, y;
  ll g = gcd(a, b, x, y);
  if (c % g != 0)
    return false;
  //    out2(x, y);
  x *= c / g;
  y *= c / g;
  //    out2(x, y);
  a /= g;
  b /= g;
  if (a == 0 || b == 0) {
    if (x >= mina && x <= maxa && y >= minb && y <= maxb) {
      lx = x;
      rx = x;
      return true;
    }
    return false;
  }
  ll sign_a = (a > 0 ? 1 : -1);
  ll sign_b = (b > 0 ? 1 : -1);
  ll lx1, lx2, rx1, rx2;
  {
    ll cnt = (mina - x) / b;
    shift(x, y, cnt, a, b);
    if (x < 0)
      shift(x, y, sign_a, a, b);
    if (x > maxa) {
      return false;
    }
    //        out2(x, y);

    lx1 = x;
  }
  {
    ll cnt = (maxa - x) / b;
    shift(x, y, cnt, a, b);
    //        out2(x, y);
    rx1 = x;
  }
  {
    ll cnt = -(minb - y) / a;
    shift(x, y, cnt, a, b);
    if (y < 0)
      shift(x, y, -sign_b, a, b);
    if (y > maxb) {
      return false;
    }
    //        out2(x, y);

    lx2 = x;
  }
  {
    ll cnt = -(maxb - y) / a;
    shift(x, y, cnt, a, b);
    //        out2(x, y);

    rx2 = x;
  }
  if (lx2 > rx2)
    swap(lx2, rx2);
  //    out4(lx1, lx2, rx1, rx2);

  ll lxx = max(lx1, lx2);
  ll rxx = min(rx1, rx2);
  if (lxx > rxx) {
    return false;
  }
  lx = lxx;
  rx = rxx;
  return true;
}

/* ---------------- start of code ---------------- */

/*vector<set<int> > ad;
vi par;
vi lev;
vi maxdepth;
int n;
void dfs_for_par(int s, int parent, int level) {
    par[s] = parent;
    lev[s] = level;
    for(auto u: ad[s]) {
        if(u==parent) continue;
        dfs_for_par(u, s, level+1);
    }
}
int dfsmaxdepth(int s, int e) {
    int res = 0;
    for(auto u: ad[s]) {
        if(u == e) continue;
        dfsmaxdepth(u,s);
        res = max(res, maxdepth[u]);
    }
    maxdepth[s] = ++res;
    return res;
}
vi ans;
void dfs(int s, int e) {
    vi res(n+1, 0);
    for(auto u: ad[s]) {
        if(u == e) continue;
        res[0]++;
        res[maxdepth[u]+1]--;
    }
    for(auto u: ad[e]) {
        if(u == s or u == par[e]) continue;
        res[0]++;
        res[maxdepth[u] + 1]--;
    }
    forn(i, n) res[i+1] += res[i];
    forn(i, n+1) ans[i] = max(ans[i], res[i]);
    for(auto u: ad[s]) {
        if(u == e) continue;
        dfs(u, s);
    }
}
void go2() {
    cin >> n;
    ad.assign(n, {});
    par.assign(n,0);
    ans.assign(n,0);
    lev.assign(n,0);
    maxdepth.assign(n,0);
    forn(i, n-1) {
        int r,s;in2(r,s);
        r--;s--;
        ad[r].insert(s);
        ad[s].insert(r);
    }
    if(n == 2) {
        out2(2, 2);
        return;
    }
    dfs_for_par(0,0,0);
    dfsmaxdepth(0,0);


}

void go1() {
    int n;
    string s;cin >> s;
    n = s.size();
    int i = 0;
    if(n <=3) {
        cout << s[0] << ln;
        return;
    }
    string ans;
    while(i < n/2) {
        if(n % 4 > 0 and i >= (n/4 * 4) / 2) break;
        int cnt[3] = {0};
        cnt[s[i] - 'a']++;
        cnt[s[i+1] - 'a']++;
        cnt[s[n-i-1] - 'a']++;
        cnt[s[n-i-2] - 'a']++;
        forn(j, 3) {
            if(cnt[j] > 1) {
                ans += (char)(j + 'a');
                break;
            }
        }
        i+=2;
    }

    string anss = ans;
    reverse(all(anss));
    if(n % 4 > 0) {
        ans += s[n/2];
    }
    ans += anss;
    assert(ans.size() >= n/2);
    cout << ans << ln;


}
ll md = 998244353;
void go3() {
    ll n;cin >> n;
    ll q;cin >> q;
    ll a[n];
    forn(i, n) cin >> a[i];
    if(n == 1) {
        cout << a[0] << ln;
        return;
    }
    if(n == 2) {
        cout << max(a[0], a[1]) << ln;
        return;
    }
    ll o[n], e[n];
    o[0] = a[0];
    e[0] = -1e9-7;
    o[1] = a[1];
    e[1] = a[0] - a[1];
    ll me = max(e[0], e[1]);
    ll mo = max(o[0], o[1]);
    ll prev[n];
    prev[0] = -1;
    prev[1] = -1;
    forsn(i, 2, n) {

        o[i] = max(a[i], me + a[i]);
        e[i] = mo - a[i];
        me = max(me, e[i]);
        mo = max(mo, o[i]);
    }
    cout << max(mo, me) << ln;
}
ll c(ll n, ll k) {
    if(n <= 0 or k > n) {
        return 0;
    }
    ll res = 1;
    k = min(k, n - k);
    forn(i, k) {
        res = (res * (ll)(n - i)) % md;
        res /= (ll)(i + 1);
        res %= md;
    }
    return res;
}*/
namespace SegmentTree {
int n;
pii t[4 * MAXn];
int mod[4 * MAXn] = {0};
vi a;

void pull(int v) {
  t[v] = {max(t[2 * v + 1].F, t[2 * v + 2].F),
          min(t[2 * v + 1].S, t[2 * v + 2].S)};
}

void apply(int v, int val) {
  t[v] = {max(t[v].F, val), val};
  mod[v] = val;
}

void push(int v) {
  if (mod[v] != 0) {
    apply(2 * v + 1, mod[v]);
    apply(2 * v + 2, mod[v]);
    mod[v] = 0;
  }
}

void build(int v, int l, int r) {
  if (l + 1 == r) {
    t[v] = {a[l], a[l]};
  } else {
    int m = (r + l) >> 1;
    build(2 * v + 1, l, m);
    build(2 * v + 2, m, r);
    pull(v);
  }
  //        out4(v, t[v], l, r);
}

void modify_max(int v, int l, int r, int ql, int qr, int val) {
  if (r <= ql || qr <= l) {
    return;
  } else if (ql <= l && r <= qr) {
    apply(v, val);
  } else {
    push(v);
    int m = (r + l) >> 1;
    modify_max(2 * v + 1, l, m, ql, qr, val);
    modify_max(2 * v + 2, m, r, ql, qr, val);
    pull(v);
  }
}
void modify_max(int l, int r, int val) { modify_max(0, 0, n, l, r, val); }
void modify_max(int pos, int val) { modify_max(0, 0, n, pos, pos + 1, val); }

void init(int n_) {
  n = n_;
  build(0, 0, n);
}
void init(const vi &b) {
  n = (int)b.size();
  a.clear();
  for (const auto &u : b)
    a.PB(u);
  build(0, 0, n);
}

int getval_max(int v, int ql, int qr, int l, int r) {
  if (r <= ql || qr <= l) {
    return 0;
  } else if (ql <= l && r <= qr) {
    return t[v].F;
  }
  push(v);
  int res = 0;
  int mid = (l + r) >> 1;
  res = max(res, getval_max(2 * v + 1, ql, qr, l, mid));
  res = max(res, getval_max(2 * v + 2, ql, qr, mid, r));
  pull(v);
  return res;
}
// ql, qr analogous to modify_max(). 0-indexed.
ll getval_max(int ql, int qr) { return getval_max(0, ql, qr, 0, n); }
} // namespace SegmentTree

vi b(1000033, 0);
vi anss;
void go4() {
  int n, k;
  in2(n, k);
  vi a(n);
  anss.assign(n, 0);
  forn(i, n) cin >> a[i];
  SegmentTree::init(b);
  anss[0] = 1;
  int j = 3e5 + 1 + a[0];
  SegmentTree::modify_max(j, j + 1, 1);
  //    forn(i, 10) {
  //        cout << SegmentTree::getval_max(3e5+1+i, 3e5+1+i+1) << " ";
  //    }cout << ln;
  int ans = SegmentTree::getval_max(0, 1e6 + 30);
  forsn(i, 1, n) {
    int j = 3e5 + 1 + a[i];
    int p = SegmentTree::getval_max(j - k, j + k + 1);
    // cout << p << " ";
    p++;
    SegmentTree::modify_max(j, j + 1, p);
    anss[i] = p;
    ans = max(ans, p);
    forn(i, 12) {
      cerr << SegmentTree::getval_max(3e5 + 1 + i, 3e5 + 1 + i + 1) << " ";
    }
    cerr << ln;
  }
  //    cout << ln;
  //    forn(i, 10) {
  //        cout << SegmentTree::getval_max(3e5+1+i, 3e5+1+i+1) << " ";
  //    }cout << ln;
  // disp(anss);
  cout << ans << ln;
}

int main() {
  fio;
  fflush(stdout);
  cout << fixed << setprecision(0);
  cerr << fixed << setprecision(10);

  // freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

  ll tt = 1;

  /*

      cin >> tt;
      ll t = tt;

      //*/
  // forn(i, 100) cout << fac[i] << " ";

  auto start = std::chrono::high_resolution_clock::now();

  while (tt--) {
    // cout << "Case #" << t - tt << ": ";
    go4();
  }
  auto stop = std::chrono::high_resolution_clock::now();
  auto duration =
      std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);
  // cerr << "Time taken : " << ((long double)duration.count())/((long double)
  // 1e9) <<"s "<< endl;
  return 0;
}
/* ---------------- end of code ---------------- */


Fixed submission:
#pragma GCC target("sse4.2")
#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second
#define PB push_back
#define ln "\n"
#define forn(i, e) for (ll i = 0; i < e; i++)
#define forsn(i, s, e) for (ll i = s; i < e; i++)
#define rforn(i, e) for (ll i = e; i >= 0; i--)
#define rforsn(i, e, s) for (ll i = e; i >= s; i--)
#define vasort(v) sort(v.begin(), v.end());
#define vdsort(v) sort(v.begin(), v.end(), greater<ll>());
#define fio                                                                    \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL)
#define mem(a, b) memset(a, b, sizeof(a))
#define sz(x) ((int)size(x))
#define EB emplace_back
#define flush fflush(stdout)
#define out1(x1) cout << x1 << ln
#define out2(x1, x2) cout << x1 << " " << x2 << endl
#define out3(x1, x2, x3) cout << x1 << " " << x2 << " " << x3 << endl
#define out4(x1, x2, x3, x4)                                                   \
  cout << x1 << " " << x2 << " " << x3 << " " << x4 << ln
#define all(d) d.begin(), d.end()
#define unordered_set(T) unordered_set<T, custom_hash>
#define unordered_map(T1, T2) unordered_map<T1, T2, custom_hash>

#define in1(x1) cin >> x1
#define in2(x1, x2) cin >> x1 >> x2
#define in3(x1, x2, x3) cin >> x1 >> x2 >> x3
#define in4(x1, x2, x3, x4) cin >> x1 >> x2 >> x3 >> x4

#define arrin(a, n) forn(i, n) cin >> a[i];
#define arrout(a, n)                                                           \
  forn(i, n) { cout << a[i] << " "; }                                          \
  cout << ln;

/* ---------------- IO ----------------*/

namespace IO {
const int BUFFER_SIZE = 1 << 15;
char input_buffer[BUFFER_SIZE];
int input_pos = 0, input_len = 0;
char output_buffer[BUFFER_SIZE];
int output_pos = 0;
char number_buffer[100];
uint8_t lookup[100];
void _update_input_buffer() {
  input_len = fread(input_buffer, sizeof(char), BUFFER_SIZE, stdin);
  input_pos = 0;
  if (input_len == 0)
    input_buffer[0] = EOF;
}
inline char next_char(bool advance = true) {
  if (input_pos >= input_len)
    _update_input_buffer();

  return input_buffer[advance ? input_pos++ : input_pos];
}

template <typename T> inline void read_int(T &number) {
  bool negative = false;
  number = 0;

  while (!isdigit(next_char(false)))
    if (next_char() == '-')
      negative = true;

  do {
    number = 10 * number + (next_char() - '0');
  } while (isdigit(next_char(false)));

  if (negative)
    number = -number;
}

template <typename T, typename... Args>
inline void read_int(T &number, Args &...args) {
  read_int(number);
  read_int(args...);
}

void _flush_output() {
  fwrite(output_buffer, sizeof(char), output_pos, stdout);
  output_pos = 0;
}

inline void write_char(char c) {
  if (output_pos == BUFFER_SIZE)
    _flush_output();

  output_buffer[output_pos++] = c;
}

template <typename T> inline void write_int(T number, char after = '\0') {
  if (number < 0) {
    write_char('-');
    number = -number;
  }
  int length = 0;
  while (number >= 10) {
    uint8_t lookup_value = lookup[number % 100];
    number /= 100;
    number_buffer[length++] = (lookup_value & 15) + '0';
    number_buffer[length++] = (lookup_value >> 4) + '0';
  }
  if (number != 0 || length == 0)
    write_char(number + '0');
  for (int i = length - 1; i >= 0; i--)
    write_char(number_buffer[i]);
  if (after)
    write_char(after);
}
void IOinit() {
  // Make sure _flush_output() is called at the end of the program.
  bool exit_success = atexit(_flush_output) == 0;
  assert(exit_success);
  for (int i = 0; i < 100; i++)
    lookup[i] = (i / 10 << 4) + i % 10;
}
} // namespace IO

using namespace IO;

/* ---------------- typedefs ----------------*/
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

/* ---------------- utility functions ---------------- */

int dr[] = {0, 1, -1, 0, 1, -1, 1, -1};
int dc[] = {1, 0, 0, -1, 1, -1, -1, 1};
int drr[] = {-2, -1, 0, 1, 2};
int dcc[] = {-2, -1, 0, 1, 2};
bool chk(int a, int b, int n, int m) {
  return 0 <= a && a < n && 0 <= b && b < m;
}

ll exp(ll n, ll m, ll md) {
  ll a = 1;
  while (m > 0) {
    if (m & 1)
      a = (a * n % md) % md;
    m /= 2;
    n = (n * n) % md;
  }
  return a % md;
}

ll expm(ll n, ll m) {
  ll a = 1;
  while (m > 0) {
    if (a < 0 or a >= (1e18 + n - 1) / n) {
      return -1;
    }
    if (m & 1)
      a = (a * n);
    m /= 2;
    n = (n * n);
  }
  return a;
}

void disp(vi v) {
  for (auto u : v)
    cout << u << " ";
  cout << "\n";
}
void disp(vll v) {
  for (auto u : v)
    cout << u << " ";
  cout << endl;
}

int getSqr(int x) {
  if (x < 0)
    return -1;
  int l = sqrt(x);
  for (int i = -2; i <= 2; ++i)
    if (l + i >= 0 && (l + i) * (l + i) == x)
      return l;
  return -1;
}

const int NPRR = 1e7;
vi lp;
vector<int> prr;
void prfac(int n = NPRR) {
  assert(n <= NPRR);
  lp.assign(n + 1, 0);
  int i;
  for (i = 2; i <= n; ++i) {
    if (lp[i] == 0) {
      lp[i] = i;
      prr.push_back(i);
    }
    for (int u : prr) {
      if (i * u > n || u > lp[i])
        break;
      lp[i * u] = u;
    }
  }
}

bool check_composite_for_prime_function(ll n, ll a, ll d, int s) {
  ll x = exp(a, d, n);
  if (x == 1 || x == n - 1)
    return false;
  for (int r = 1; r < s; ++r) {
    x = x * x % n;
    x %= n;
    if (x == n - 1)
      return false;
  }
  return true;
}
bool prime(ll n) {
  if (n < 4)
    return n == 2 || n == 3;
  if (!(n & 1))
    return false;
  int s = 0;
  ll d = n - 1;
  while (!(d & 1)) {
    d >>= 1;
    s++;
  }
  for (int a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) {
    if (n == a)
      return true;
    if (check_composite_for_prime_function(n, a, d, s))
      return false;
  }
  return true;
}

ll binomialCoeff(ll n, ll k) {
  ll res = 1;

  // Since C(n, k) = C(n, n-k)
  if (k > n - k)
    k = n - k;

  // Calculate value of
  // [n * (n-1) *---* (n-k+1)] / [k * (k-1) *----* 1]
  for (ll i = 0; i < k; ++i) {
    res *= (n - i);
    res /= (i + 1);
  }

  return res;
}
/* custom hash for unordered map */
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};

inline void read(int &x) { scanf("%d", &x); }

auto random_address = [] {
  char *p = new char;
  delete p;
  return uint64_t(p);
};

const uint64_t SEED = chrono::steady_clock::now().time_since_epoch().count() *
                      (random_address() | 1);
mt19937_64 rng(SEED);

/* ---------------- constants ---------------- */
const ll MAXn = 1e6 + 33, MAXlg = __lg(MAXn) + 2;
const ll MOD = 1000000007;
const ll INF = ll(1e15);

/* ---------------- gcd_extended ---------------- */
/*
 * CAREFUL: Overflow at x *= c/g out of 10**18
 * Lookout for A = 0 or B = 0
 */
void shift(ll &x, ll &y, ll cnt, ll a, ll b) {
  x += cnt * b;
  y -= cnt * a;
}
ll gcd(ll a, ll b, ll &x, ll &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  ll x1, y1;
  ll d = gcd(b, a % b, x1, y1);
  x = y1;
  y = x1 - y1 * (a / b);
  return d;
}
bool give_range(ll a, ll b, ll c, ll mina, ll maxa, ll minb, ll maxb, ll &lx,
                ll &rx) {
  ll x, y;
  ll g = gcd(a, b, x, y);
  if (c % g != 0)
    return false;
  //    out2(x, y);
  x *= c / g;
  y *= c / g;
  //    out2(x, y);
  a /= g;
  b /= g;
  if (a == 0 || b == 0) {
    if (x >= mina && x <= maxa && y >= minb && y <= maxb) {
      lx = x;
      rx = x;
      return true;
    }
    return false;
  }
  ll sign_a = (a > 0 ? 1 : -1);
  ll sign_b = (b > 0 ? 1 : -1);
  ll lx1, lx2, rx1, rx2;
  {
    ll cnt = (mina - x) / b;
    shift(x, y, cnt, a, b);
    if (x < 0)
      shift(x, y, sign_a, a, b);
    if (x > maxa) {
      return false;
    }
    //        out2(x, y);

    lx1 = x;
  }
  {
    ll cnt = (maxa - x) / b;
    shift(x, y, cnt, a, b);
    //        out2(x, y);
    rx1 = x;
  }
  {
    ll cnt = -(minb - y) / a;
    shift(x, y, cnt, a, b);
    if (y < 0)
      shift(x, y, -sign_b, a, b);
    if (y > maxb) {
      return false;
    }
    //        out2(x, y);

    lx2 = x;
  }
  {
    ll cnt = -(maxb - y) / a;
    shift(x, y, cnt, a, b);
    //        out2(x, y);

    rx2 = x;
  }
  if (lx2 > rx2)
    swap(lx2, rx2);
  //    out4(lx1, lx2, rx1, rx2);

  ll lxx = max(lx1, lx2);
  ll rxx = min(rx1, rx2);
  if (lxx > rxx) {
    return false;
  }
  lx = lxx;
  rx = rxx;
  return true;
}

/* ---------------- start of code ---------------- */

/*vector<set<int> > ad;
vi par;
vi lev;
vi maxdepth;
int n;
void dfs_for_par(int s, int parent, int level) {
    par[s] = parent;
    lev[s] = level;
    for(auto u: ad[s]) {
        if(u==parent) continue;
        dfs_for_par(u, s, level+1);
    }
}
int dfsmaxdepth(int s, int e) {
    int res = 0;
    for(auto u: ad[s]) {
        if(u == e) continue;
        dfsmaxdepth(u,s);
        res = max(res, maxdepth[u]);
    }
    maxdepth[s] = ++res;
    return res;
}
vi ans;
void dfs(int s, int e) {
    vi res(n+1, 0);
    for(auto u: ad[s]) {
        if(u == e) continue;
        res[0]++;
        res[maxdepth[u]+1]--;
    }
    for(auto u: ad[e]) {
        if(u == s or u == par[e]) continue;
        res[0]++;
        res[maxdepth[u] + 1]--;
    }
    forn(i, n) res[i+1] += res[i];
    forn(i, n+1) ans[i] = max(ans[i], res[i]);
    for(auto u: ad[s]) {
        if(u == e) continue;
        dfs(u, s);
    }
}
void go2() {
    cin >> n;
    ad.assign(n, {});
    par.assign(n,0);
    ans.assign(n,0);
    lev.assign(n,0);
    maxdepth.assign(n,0);
    forn(i, n-1) {
        int r,s;in2(r,s);
        r--;s--;
        ad[r].insert(s);
        ad[s].insert(r);
    }
    if(n == 2) {
        out2(2, 2);
        return;
    }
    dfs_for_par(0,0,0);
    dfsmaxdepth(0,0);


}

void go1() {
    int n;
    string s;cin >> s;
    n = s.size();
    int i = 0;
    if(n <=3) {
        cout << s[0] << ln;
        return;
    }
    string ans;
    while(i < n/2) {
        if(n % 4 > 0 and i >= (n/4 * 4) / 2) break;
        int cnt[3] = {0};
        cnt[s[i] - 'a']++;
        cnt[s[i+1] - 'a']++;
        cnt[s[n-i-1] - 'a']++;
        cnt[s[n-i-2] - 'a']++;
        forn(j, 3) {
            if(cnt[j] > 1) {
                ans += (char)(j + 'a');
                break;
            }
        }
        i+=2;
    }

    string anss = ans;
    reverse(all(anss));
    if(n % 4 > 0) {
        ans += s[n/2];
    }
    ans += anss;
    assert(ans.size() >= n/2);
    cout << ans << ln;


}
ll md = 998244353;
void go3() {
    ll n;cin >> n;
    ll q;cin >> q;
    ll a[n];
    forn(i, n) cin >> a[i];
    if(n == 1) {
        cout << a[0] << ln;
        return;
    }
    if(n == 2) {
        cout << max(a[0], a[1]) << ln;
        return;
    }
    ll o[n], e[n];
    o[0] = a[0];
    e[0] = -1e9-7;
    o[1] = a[1];
    e[1] = a[0] - a[1];
    ll me = max(e[0], e[1]);
    ll mo = max(o[0], o[1]);
    ll prev[n];
    prev[0] = -1;
    prev[1] = -1;
    forsn(i, 2, n) {

        o[i] = max(a[i], me + a[i]);
        e[i] = mo - a[i];
        me = max(me, e[i]);
        mo = max(mo, o[i]);
    }
    cout << max(mo, me) << ln;
}
ll c(ll n, ll k) {
    if(n <= 0 or k > n) {
        return 0;
    }
    ll res = 1;
    k = min(k, n - k);
    forn(i, k) {
        res = (res * (ll)(n - i)) % md;
        res /= (ll)(i + 1);
        res %= md;
    }
    return res;
}*/
namespace SegmentTree {
int n;
pii t[4 * MAXn];
int mod[4 * MAXn] = {0};
vi a;

void pull(int v) {
  t[v] = {max(t[2 * v + 1].F, t[2 * v + 2].F),
          min(t[2 * v + 1].S, t[2 * v + 2].S)};
}

void apply(int v, int val) {
  t[v] = {max(t[v].F, val), val};
  mod[v] = val;
}

void push(int v) {
  if (mod[v] != 0) {
    apply(2 * v + 1, mod[v]);
    apply(2 * v + 2, mod[v]);
    mod[v] = 0;
  }
}

void build(int v, int l, int r) {
  if (l + 1 == r) {
    t[v] = {a[l], a[l]};
  } else {
    int m = (r + l) >> 1;
    build(2 * v + 1, l, m);
    build(2 * v + 2, m, r);
    pull(v);
  }
  //        out4(v, t[v], l, r);
}

void modify_max(int v, int l, int r, int ql, int qr, int val) {
  if (r <= ql || qr <= l) {
    return;
  } else if (ql <= l && r <= qr) {
    apply(v, val);
  } else {
    push(v);
    int m = (r + l) >> 1;
    modify_max(2 * v + 1, l, m, ql, qr, val);
    modify_max(2 * v + 2, m, r, ql, qr, val);
    pull(v);
  }
}
void modify_max(int l, int r, int val) { modify_max(0, 0, n, l, r, val); }
void modify_max(int pos, int val) { modify_max(0, 0, n, pos, pos + 1, val); }

void init(int n_) {
  n = n_;
  build(0, 0, n);
}
void init(const vi &b) {
  n = (int)b.size();
  a.clear();
  for (const auto &u : b)
    a.PB(u);
  build(0, 0, n);
}

int getval_max(int v, int ql, int qr, int l, int r) {
  if (r <= ql || qr <= l) {
    return 0;
  } else if (ql <= l && r <= qr) {
    return t[v].F;
  }
  push(v);
  int res = 0;
  int mid = (l + r) >> 1;
  res = max(res, getval_max(2 * v + 1, ql, qr, l, mid));
  res = max(res, getval_max(2 * v + 2, ql, qr, mid, r));
  pull(v);
  return res;
}
// ql, qr analogous to modify_max(). 0-indexed.
ll getval_max(int ql, int qr) { return getval_max(0, ql, qr, 0, n); }
} // namespace SegmentTree

vi b(1000033, 0);
vi anss;
void go4() {
  int n, k;
  in2(n, k);
  vi a(n);
  anss.assign(n, 0);
  forn(i, n) cin >> a[i];
  SegmentTree::init(b);
  anss[0] = 1;
  int j = 3e5 + 1 + a[0];
  SegmentTree::modify_max(j, j + 1, 1);
  //    forn(i, 10) {
  //        cout << SegmentTree::getval_max(3e5+1+i, 3e5+1+i+1) << " ";
  //    }cout << ln;
  int ans = SegmentTree::getval_max(0, 1e6 + 30);
  forsn(i, 1, n) {
    int j = 3e5 + 1 + a[i];
    int p = SegmentTree::getval_max(j - k, j + k + 1);
    // cout << p << " ";
    p++;
    SegmentTree::modify_max(j, j + 1, p);
    anss[i] = p;
    ans = max(ans, p);
    //        forn(i, 12) {
    //            cerr << SegmentTree::getval_max(3e5+1+i, 3e5+1+i+1) << " ";
    //        }cerr << ln;
  }
  //    cout << ln;
  //    forn(i, 10) {
  //        cout << SegmentTree::getval_max(3e5+1+i, 3e5+1+i+1) << " ";
  //    }cout << ln;
  // disp(anss);
  cout << ans << ln;
}

int main() {
  fio;
  fflush(stdout);
  cout << fixed << setprecision(0);
  cerr << fixed << setprecision(10);

  // freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

  ll tt = 1;

  /*

      cin >> tt;
      ll t = tt;

      //*/
  // forn(i, 100) cout << fac[i] << " ";

  auto start = std::chrono::high_resolution_clock::now();

  while (tt--) {
    // cout << "Case #" << t - tt << ": ";
    go4();
  }
  auto stop = std::chrono::high_resolution_clock::now();
  auto duration =
      std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);
  // cerr << "Time taken : " << ((long double)duration.count())/((long double)
  // 1e9) <<"s "<< endl;
  return 0;
}
/* ---------------- end of code ---------------- */