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 Java (OpenJDK 11.0.6) (judge verdict: Accepted)

//package src.com.jetman.atcoder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

/**
 * @description:
 * @author: Jetman
 * @create: 2020-08-29 14:39
 **/
public class Main {

    FastReader sc = new FastReader();
    PrintWriter out = new PrintWriter(System.out);

    long MOD = 998244353L;

    long dp[];

    class Node {
        int l;
        int r;
        int index;
        int ans;
        public Node(int l,int r,int index) {
            this.l = l;
            this.r = r;
            this.index = index;
        }
    }


    int[] fa;
    int fa(int a) {
        return fa[a] == a ? a : (fa[a] = fa(fa[a]));
    }

    private void slove() {

        int n = sc.nextInt();
        int k = sc.nextInt();
        RangeTree rt = new RangeTree(300001);
        long ans = 0;
        for (int i = 0; i < n; i++) {
            int val = sc.nextInt();
            int l = val - k;
            int r = val + k;
            if (l < 0) l = 0;
            if (r > 300000) r = 300000;
            long max = rt.maxQuery(l,r);
            ans = Math.max(ans,max+1);
            long tmp = rt.maxQuery(val,val);
            rt.update(val,val,max+1-tmp);
        }
        out.println(ans);


        out.flush();


    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br =new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st==null || (!st.hasMoreElements()))
            {
                try
                {
                    st =new StringTokenizer(br.readLine());
                }
                catch(IOException e)
                {
                    e.printStackTrace();
                }

            }
            return st.nextToken();
        }

        String nextLine() {
            String str ="";

            try
            {
                str =br.readLine();
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }

            return str;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next()) ;
        }
    }



    private void build(Map<Integer, List<Integer>> edge, int l, int r) {
        List<Integer> list = edge.getOrDefault(l, new ArrayList<>());
        list.add(r);
        edge.put(l,list);
    }


    public static void main(String[] args) {
        new Main().slove();
    }
}

 class RangeTree {
    private long[] max;
    private long[] min;
    private long[] lazy;
    private long[] sum;
    private int size;
    public RangeTree(int size) {
        this.size = size;
        max = new long[4*size];
        min = new long[4*size];
        sum = new long[4*size];
        lazy = new long[4*size];
    }
    public void update(int l, int r, long inc) {
        update(1, 0, size-1, l, r, inc);
    }
    private void pushDown(int index, int l, int r) {
        min[index] += lazy[index];
        max[index] += lazy[index];
        sum[index] += lazy[index] * (r-l+1);
        if(l != r) {
            lazy[2*index] += lazy[index];
            lazy[2*index+1] += lazy[index];
        }
        lazy[index] = 0;
    }
    private void pullUp(int index, int l, int r) {
        int m = (l+r)/2;
        min[index] = Math.min(evaluateMin(2*index, l, m), evaluateMin(2*index+1, m+1, r));
        max[index] = Math.max(evaluateMax(2*index, l, m), evaluateMax(2*index+1, m+1, r));
        sum[index] = evaluateSum(2*index, l, m) + evaluateSum(2*index+1, m+1, r);
    }
    private long evaluateSum(int index, int l, int r) {
        return sum[index] + (r-l+1)*lazy[index];
    }
    private long evaluateMin(int index, int l, int r) {
        return min[index] + lazy[index];
    }
    private long evaluateMax(int index, int l, int r) {
        return max[index] + lazy[index];
    }
    private void update(int index, int l, int r, int left, int right, long inc) {
        if(r < left || l > right) return;
        if(l >= left && r <= right) {
            lazy[index] += inc;
            return;
        }
        pushDown(index, l, r);
        int m = (l+r)/2;
        update(2*index, l, m, left, right, inc);
        update(2*index+1, m+1, r, left, right, inc);
        pullUp(index, l, r);
    }
    public long minQuery(int l, int r) {
        return minQuery(1, 0, size-1, l, r);
    }
    private long minQuery(int index, int l, int r, int left, int right) {
        if(r < left || l > right) return Long.MAX_VALUE;
        if(l >= left && r <= right) {
            return evaluateMin(index, l, r);
        }
        pushDown(index, l, r);
        int m = (l+r)/2;
        long ret = Long.MAX_VALUE;
        ret = Math.min(ret, minQuery(2*index, l, m, left, right));
        ret = Math.min(ret, minQuery(2*index+1, m+1, r, left, right));
        pullUp(index, l, r);
        return ret;
    }
    public long maxQuery(int l, int r) {
        return maxQuery(1, 0, size-1, l, r);
    }
    private long maxQuery(int index, int l, int r, int left, int right) {
        if(r < left || l > right) return Long.MIN_VALUE;
        if(l >= left && r <= right) {
            return evaluateMax(index, l, r);
        }
        pushDown(index, l, r);
        int m = (l+r)/2;
        long ret = Long.MIN_VALUE;
        ret = Math.max(ret, maxQuery(2*index, l, m, left, right));
        ret = Math.max(ret, maxQuery(2*index+1, m+1, r, left, right));
        pullUp(index, l, r);
        return ret;
    }
    public long sumQuery(int l, int r) {
        return sumQuery(1, 0, size-1, l, r);
    }
    private long sumQuery(int index, int l, int r, int left, int right) {
        if(r < left || l > right) return 0;
        if(l >= left && r <= right) {
            return evaluateSum(index, l, r);
        }
        pushDown(index, l, r);
        int m = (l+r)/2;
        long ret = 0;
        ret += sumQuery(2*index, l, m, left, right);
        ret += sumQuery(2*index+1, m+1, r, left, right);
        pullUp(index, l, r);
        return ret;
    }
}

class FenwichTree {

    private int[] sums;
    private int[] nums;

    public FenwichTree(int[] nums) {
        this.sums = new int[nums.length + 1];
        this.nums = nums;
        for (int i = 0; i < nums.length; i++) {
            updateBit(i + 1, nums[i]);
        }
    }

    public void update(int i, int val) {
        updateBit(i + 1, val - nums[i]);
        nums[i] = val;
    }

    private void updateBit(int i, int diff) {
        while (i < sums.length) {
            sums[i] += diff;
            i += lowBit(i);
        }
    }

    public int sumRange(int i, int j) {
        return preSum(j + 1) - preSum(i);
    }

    private int preSum(int i) {
        int sum = 0;
        while (i > 0) {
            sum += sums[i];
            i -= lowBit(i);
        }
        return sum;
    }

    private int lowBit(int i) {
        return i & (-i);
    }
}