Problem:
Score : 400 points

Problem Statement

You are given a sequence A_1, A_2, ..., A_N and an integer K.

Print the maximum possible length of a sequence B that satisfies the following conditions:

B is a (not necessarily continuous) subsequence of A.

For each pair of adjacents elements of B, the absolute difference of the elements is at most K.

Constraints

1 \leq N \leq 300,000

0 \leq A_i \leq 300,000

0 \leq K \leq 300,000

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K
A_1
A_2
:
A_N

Output

Print the answer.

Sample Input 1

10 3
1
5
4
3
8
6
9
7
2
4

Sample Output 1

7

For example, B = (1, 4, 3, 6, 9, 7, 4) satisfies the conditions.

It is a subsequence of A = (1, 5, 4, 3, 8, 6, 9, 7, 2, 4).

All of the absolute differences between two adjacent elements (|1-4|, |4-3|, |3-6|, |6-9|, |9-7|, |7-4|) are at most K = 3.

Solution in C# (Mono-mcs 6.8.0.105) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

using static Input;
using static Util;
class Program
{
    static void Main(string[] args)
    {
        var N = NextInt();
        var K = NextInt();
        var A = new int[N];
        for (int n = 0; n < N; n++)
        {
            A[n] = NextInt();
        }
        var size = A.Max() + 1;
        var dp = new SegmentTree<int>(size, (a,b) => Math.Max(a, b), 0);
        for (int i = 0; i < N; i++)
        {
            var v = A[i];
            var l = Math.Max(0, v - K);
            var r = Math.Min(size, v + K) + 1;
            var max = dp.prod(l, r);
            dp.set(v, max + 1);
        }
        Console.WriteLine(dp.prod(0, size));
    }
}

public class Input
{
    public const long MOD = 1000000007;
    public const int INF = 1000000007;
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
}

class Util
{
    public class SegmentTree<val>
        where val : struct
    {
        private int size;
        private val[] vals;
        private Func<val, val, val> op;
        private val def;
        /// <summary>
        /// SegmentTree
        /// </summary>
        /// <param name="n">ノード数</param>
        /// <param name="op">更新処理</param>
        /// <param name="def">初期値</param>
        public SegmentTree(int n, Func<val, val, val> op, val def)
        {
            this.op = op;
            this.def = def;

            size = 1;
            while (size < n) size <<= 1;
            
            vals = new val[size * 2 - 1];

            for (int i = 0; i < vals.Length; i++)
            {
                vals[i] = def;
            }
        }

        /// <summary>
        /// 値更新
        /// </summary>
        /// <param name="idx">ノードインデックス</param>
        /// <param name="val">更新値</param>
        public void set(int idx, val val)
        {
            idx += size - 1;
            vals[idx] = val;
            while (idx > 0)
            {
                idx = (idx - 1) / 2;
                vals[idx] = op(vals[idx * 2 + 1], vals[idx * 2 + 2]);
            }
        }

        /// <summary>
        /// 値取得 [a,b)
        /// </summary>
        /// <param name="a">左インデックス [</param>
        /// <param name="b">右インデックス )</param>
        /// <returns></returns>
        public val prod(int a, int b)
        {
            return prod(a, b, 0, 0, size);
        }
        private val prod(int a, int b, int k, int l, int r)
        {
            if (r <= a || b <= l) return def;
            if (a <= l && r <= b) return vals[k];
            else
            {
                var vl = prod(a, b, k * 2 + 1, l, (l + r) / 2);
                var vr = prod(a, b, k * 2 + 2, (l + r) / 2, r);
                return op(vl, vr);
            }
        }
    }
}