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 dp = new SegmentTree<int>(A.Max(),(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(N, v + K) + 1;
            var max = dp.prod(l, r);
            dp.set(v, max + 1);
        }
        Console.WriteLine(dp.prod(0, N + 1));
    }
}

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

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

        /// <summary>
        /// 値更新
        /// </summary>
        /// <param name="idx">ノードインデックス</param>
        /// <param name="val">更新値</param>
        public void set(int idx, val val)
        {
            idx += size;
            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);
            }
        }
    }
}
