Marmot found a row with n pillars. The i-th pillar has the height of hi meters. Starting from one pillar i1, Marmot wants to jump on the pillars i2, ..., ik. (1 ≤ i1 < i2 < ... < ik ≤ n). From a pillar i Marmot can jump on a pillar j only if i < j and |hi - hj| ≥ d, where |x| is the absolute value of the number x.

Now Marmot is asking you find out a jump sequence with maximal length and print it.

Input

The first line contains two integers n and d (1 ≤ n ≤ 105, 0 ≤ d ≤ 109).

The second line contains n numbers h1, h2, ..., hn (1 ≤ hi ≤ 1015).

Output

The first line should contain one integer k, the maximal length of a jump sequence.

The second line should contain k integers i1, i2, ..., ik (1 ≤ i1 < i2 < ... < ik ≤ n), representing the pillars' indices from the maximal length jump sequence.

If there is more than one maximal length jump sequence, print any.

Examples

Input

5 2
1 3 6 7 4


Output

4
1 2 3 5 


Input

10 3
2 1 3 6 9 11 7 3 20 18


Output

6
1 4 6 7 8 9 

Note

In the first example Marmot chooses the pillars 1, 2, 3, 5 with the heights 1, 3, 6, 4. Another jump sequence of length 4 is 1, 2, 4, 5.

import java.io.*;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.StringTokenizer;

/**
 * CodeForces 474E - Pillars
 * Created by Darren on 14-10-6.
 */
public class E {
    Reader in = new Reader(System.in);
    PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) throws IOException {
        new E().run();
    }

    int n, d;
    long[] h;
    Pillar[] pillars;
    int[] dp;
    int[] prev;

    void run() throws IOException {
        n = in.nextInt();
        d = in.nextInt();
        h = new long[n+1];
        pillars = new Pillar[n+1];
        for (int i = 1; i <= n; i++) {
            h[i] = in.nextLong();
            pillars[i] = new Pillar(h[i], i);
        }

        Arrays.sort(pillars, 1, n+1);

        int[] newPos = new int[n+1];
        for (int i = 1; i <= n; i++)
            newPos[pillars[i].index] = i;

        SegmentTree st = new SegmentTree(n);

        dp = new int[n+1];
        prev = new int[n+1];

        int last = 0;
        for (int i = 1; i <= n; i++) {
            dp[i] = 1;
            int greaterLower = binaryLower(h[i]+d);
            if (greaterLower != -1)
                dp[i] = Math.max(dp[i], st.get(st.query(1, 1, n, greaterLower, n))+1);
            int smallerUpper = binaryUpper(h[i]-d);
            if (smallerUpper != -1)
                dp[i] = Math.max(dp[i], st.get(st.query(1, 1, n, 1, smallerUpper))+1);
            st.update(1, 1, n, newPos[i], dp[i]);
            if (dp[i] > dp[last])
                last = i;
        }

        out.println(dp[last]);
        Deque<Integer> stack = new ArrayDeque<Integer>();
        stack.push(last);
        for (int i = last-1; i > 0; i--) {
            if (dp[i]+1 == dp[last] && Math.abs(h[i]-h[last]) >= d) {
                stack.push(i);
                last = i;
            }
        }
        for (int i : stack) {
            out.print(i);
            out.print(' ');
        }
        out.flush();
    }

    int binaryLower(long target) {
        int lower = 1, upper = n;
        while (lower < upper) {
            int mid = (lower+upper) / 2;
            if (pillars[mid].height < target)
                lower = mid + 1;
            else
                upper = mid;
        }
        if (pillars[upper].height >= target)
            return upper;
        return -1;
    }

    int binaryUpper(long target) {
        int lower = 1, upper = n;
        while (lower < upper) {
            int mid = (lower+upper+1) / 2;
            if (pillars[mid].height > target)
                upper = mid - 1;
            else
                lower = mid;
        }
        if (pillars[lower].height <= target)
            return lower;
        return -1;
    }

//    int findLongest() {
//        length = new int[n+1];
//        next = new int[n+1];
//        int max = 0, maxIndex = 0;
//        for (int i = n; i > 0; i--) {
//            int submax = 0;
//            for (int j = i+1; j <= n; j++) {
//                if (Math.abs(h[i]-h[j]) >= d && length[j] > submax) {
//                    submax = length[j];
//                    next[i] = j;
//                }
//            }
//            length[i] = submax + 1;
//            if (length[i] > max) {
//                max = length[i];
//                maxIndex = i;
//            }
//        }
//        for (int i = 1; i <= n-max; i++) {
//            int len = dfs(i);
//            if (len > max) {
//                max = len;
//                maxIndex = i;
//            }
//        }
//        return maxIndex;
//    }

//    int dfs(int u) {
//        if (length[u] > 0)
//            return length[u];
//        for (int v = u+1; v <= n; v++) {
//            if (Math.abs(h[u]-h[v]) >= d) {
//                int pathLength = dfs(v);
//                if (pathLength > length[u]) {
//                    length[u] = pathLength;
//                    next[u] = v;
//                }
//            }
//        }
//        length[u]++;
//        return length[u];
//    }

    class SegmentTree {
        private int size;
        private int[] array;
        private int[] max;

        public SegmentTree(int size) {
            this.size = size;
            array = new int[size+1];
            max = new int[size<<2];     // 2^(ceil(log2(n))+1) suffices
        }

        public int get(int index) {
            return array[index];
        }

        public int query(int nodeID, int lower, int upper, int queryLower, int queryUpper) {
            // The current interval does not intersect with the query interval
            if (queryLower > upper || queryUpper < lower)
                return -1;

            // The current interval is included in the query interval
            if (queryLower <= lower && queryUpper >= upper)
                return max[nodeID];

            // Pass the query to left and right subtrees
            int mid = (lower + upper) / 2;
            int p1 = query(nodeID<<1, lower, mid, queryLower, queryUpper);
            int p2 = query((nodeID<<1)|1, mid+1, upper, queryLower, queryUpper);

            if (p1 == -1)   // The query interval intersects with the right subtree only
                return p2;
            else if (p2 == -1)  // The query interval intersects with the left subtree only
                return p1;
            else if (array[p1] >= array[p2])    // The query interval intersects with both subtrees
                return p1;
            else
                return p2;
        }

        public void update(int nodeID, int lower, int upper, int pos, int value) {
            // Invalid update
            if (pos < lower || pos > upper)
                return;

            // Single-value interval
            if (lower == upper) {
                array[pos] = value;
                max[nodeID] = pos;
                return;
            }

            // Pass the update to either left or right subtree
            int mid = (lower + upper) / 2;
            if (pos <= mid)
                update(nodeID<<1, lower, mid, pos, value);
            else
                update((nodeID<<1)|1, mid+1, upper, pos, value);

            // Update current node after
            if (array[max[nodeID<<1]] >= array[max[(nodeID<<1)|1]])
                max[nodeID] = max[nodeID<<1];
            else
                max[nodeID] = max[(nodeID<<1)|1];
        }
    }

    class Pillar implements Comparable<Pillar>{
        long height;
        int index;

        public Pillar(long height, int index) {
            this.height = height;
            this.index = index;
        }


        @Override
        public int compareTo(Pillar o) {
            if (this.height > o.height)
                return 1;
            if (this.height < o.height)
                return -1;
            return this.index - o.index;
        }
    }

    static class Reader {
        BufferedReader reader;
        StringTokenizer tokenizer;

        public Reader(InputStream input) {
            reader = new BufferedReader(new InputStreamReader(input));
            tokenizer = new StringTokenizer("");
        }

        /** get next word */
        String nextToken() throws IOException {
            while ( ! tokenizer.hasMoreTokens() ) {
                //TODO add check for eof if necessary
                tokenizer = new StringTokenizer( reader.readLine() );
            }
            return tokenizer.nextToken();
        }

        String readLine() throws IOException {
            return reader.readLine();
        }

        int nextInt() throws IOException {
            return Integer.parseInt( nextToken() );
        }

        long nextLong() throws IOException {
            return Long.parseLong( nextToken() );
        }

        double nextDouble() throws IOException {
            return Double.parseDouble( nextToken() );
        }
    }
}
