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.util.ArrayDeque;
import java.util.NoSuchElementException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.io.IOException;
import java.io.InputStream;
import java.io.FilterInputStream;
import java.util.Random;
import java.io.BufferedInputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Zyflair Griffane
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputUtil in = new InputUtil(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    public void solve(int testNumber, InputUtil in, PrintWriter out) {
        int n = in.nextInt();
        long d = in.nextInt();

        int[] prev = new int[n];
        Pillar[] pillar = new Pillar[n];
        for (int i = 0; i < n; i++) {
            pillar[i] = new Pillar(i, in.nextLong(), 1);
        }

        SylvySet<Pillar> answers = new SylvySet<>(new PillarStatFactory());
        answers.add(pillar[n - 1]);

        Pillar searchPillar = new Pillar(-1, 0, -1);
        for (int i = n - 2; i > -1; i--) {
            long h = pillar[i].height;

            searchPillar.height = h - d;
//            if (answers.floorIdx(searchPillar) != -1 &&
//                    ((Pillar) answers.nodeAt(answers.floorIdx(searchPillar), answers.root).key).height > h - d) {
//                throw new RuntimeException("Floor idx of " + pillar[i] + " got a floor of " + answers.nodeAt(answers.floorIdx(searchPillar), answers.root).key);
//            }
            long res = (Long) answers.root.stats.query(0, 0, answers.floorIdx(searchPillar));

            searchPillar.height = h + d;
//            if (answers.ceilingIdx(searchPillar) != answers.size() &&
//                    ((Pillar) answers.nodeAt(answers.ceilingIdx(searchPillar), answers.root).key).height < h + d) {
//                throw new RuntimeException("Ceiling idx of " + pillar[i] + " got a ceil of " + answers.nodeAt(answers.ceilingIdx(searchPillar), answers.root).key);
//            }
            res = Math.max(res, (Long) answers.root.stats.query(0, answers.ceilingIdx(searchPillar), answers.size() - 1));

            pillar[i].answer = (int) (res >> PillarStats.SHIFT) + 1;
            prev[i] = (int) (res & ((1L << PillarStats.SHIFT) - 1));
//        if (pillar[i].answer > 1 && Math.abs(pillar[i].height - pillar[prev[i]].height) < d) {
//            throw new RuntimeException("Answer of " + pillar[i] + " is " + pillar[prev[i]]);
//        }

            answers.add(pillar[i]);
        }

        long res = (Long) answers.root.stats.query(0, 0, Integer.MAX_VALUE);
        int answer = (int) (res >> PillarStats.SHIFT);
        int maxIdx = (int) (res & ((1L << PillarStats.SHIFT) - 1));

        out.println(answer);
        IntDeque list = new IntDeque(answer);
        for (int i = 0; i < answer; i++) {
            list.add(maxIdx + 1);
            maxIdx = prev[maxIdx];
        }
        out.println(list);
    }

    public class PillarStatFactory implements SylvySet.StatFactory {
        public Object makeStats() {
            PillarStats stats = new PillarStats();
            return stats;
        }
    }

    public class PillarStats extends SylvySet.Stats {

        // Constants
        public static final int SHIFT = 30;

        // Stats
        public long answer;

        public Object merge(int queryType, Object leftAns, Object rightAns) {
            return Math.max((Long) leftAns, (Long) rightAns);
        }

        public Object onCurrentNodeAnswer(int queryType) {
            Pillar p = (Pillar) n.key;
            return (((long) p.answer) << SHIFT) + p.idx;
        }

        public Object outOfRangeAnswer(int queryType) {
            return 0L;
        }

        public Object overEntireRangeAnswer(int queryType) {
            return answer;
        }

        public void update() {
            Pillar p = (Pillar) n.key;
            answer = (((long) p.answer) << SHIFT) + p.idx;

            long leftAnswer = n.left == null ? 0 : ((PillarStats) n.left.stats).answer;
            long rightAnswer = n.right == null ? 0 : ((PillarStats) n.right.stats).answer;
            answer = Math.max(answer, Math.max(leftAnswer, rightAnswer));
        }

        public String toString() {
            int a = (int) (answer >> SHIFT);
            int idx = (int) (answer & ((1L << SHIFT) - 1));
            return "(PStats: " + a + ", " + idx + ")";
        }
    }

    public class Pillar implements Comparable<Pillar> {

        // Individual Pillar Stats
        public long height;
        public int answer;
        public int idx;

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

        public int compareTo(Pillar o) {
            return Long.compare(height, o.height);
        }

        public String toString() {
            return "Pillar " + idx + ": " + height + " " + answer;
        }
    }
}

class InputUtil {

    JoltyScanner in;

    public InputUtil(InputStream istream) {
        in = new JoltyScanner(istream);
    }

    public String next() {
        return in.nextOrNull();
    }

    public int nextInt() {
        String s = next();
        if (s == null) {
            throw new NoSuchElementException("Attempted to read integer that is not there.");
        }
        return Integer.parseInt(s);
    }

    public long nextLong() {
        String s = next();
        if (s == null) {
            throw new NoSuchElementException("Attempted to read long that is not there.");
        }
        return Long.parseLong(s);
    }

}

class SylvySet<K extends Comparable<K>> {

    /**
     * Note:
     * Reading and understanding this code may result in the access to fairy-like magic.
     * You have been warned.
     */

    // Fields
    public Node root;
    protected static Random random = new Random();
    protected static final long MASK = (1L << 50) - 1;
    protected static long root_value = MASK + 1;

    // FIXME - SUPER BAD. WORK ON AFTER SOLVING PROBLEM
    protected static StatFactory statFactory = null;

    public SylvySet(StatFactory factory) {
        if (factory != null) {
            statFactory = factory;
        }
    }

    /**
     * Methods
     */

    public void add(K key) {
        Node newRoot = getFloorEntryKing(root, key);
        if (newRoot == null) {
            root = meld(new Node(key), root);
        }
        else {
            Node left = newRoot.left;
            Node right = newRoot.right;
            if (newRoot.key.compareTo(key) == 0) {
                root = meld(left, new Node(key));
            } else {
                root = meld(left, new Node(newRoot.key));
                root = meld(root, new Node(key));
            }
            root = meld(root, right);
        }
    }

    public int ceilingIdx(K key) {
        int passed = 0;
        stk.clear();
        Node<K> n = root;
        while (n != null) {
            int cmp = key.compareTo(n.key);
            if (cmp < 0) {
                n = pushStk(n, n.left);
            } else if (cmp > 0) {
                if (n.right == null) {
                    while (!stk.isEmpty() && stk.peek().right == n) {
                        n = stk.pop();
                        passed -= getWeight(n.left) + 1;
                    }
                    break;
                }
                passed += getWeight(n.left) + 1;
                n = pushStk(n, n.right);
            } else return getWeight(n.left) + passed;
        }
        n = stk.poll();
        return n == null ? root.weight : getWeight(n.left) + passed;
    }

    public int floorIdx(K key) {
        int passed = 0;
        stk.clear();
        Node<K> n = root;
        while (n != null) {
            int cmp = key.compareTo(n.key);
            if (cmp > 0) {
                if (n.right == null) break;
                passed += getWeight(n.left) + 1;
                n = pushStk(n, n.right);
            } else if (cmp < 0) {
                if (n.left == null) {
                    while (!stk.isEmpty() && stk.peek().left == n) {
                        n = stk.pop();
                    }
                    if (!stk.isEmpty()) {
                        n = stk.pop();
                        passed -= getWeight(n.left) + 1;
                    } else n = null;
                    break;
                }
                n = pushStk(n, n.left);
            } else break;
        }
        return n == null ? -1 : getWeight(n.left) + passed;
    }

    public int size() {
        return root == null ? 0 : root.weight;
    }

    /**
     * Private
     */

    protected static int getWeight(Node n) {
        return n == null ? 0 : n.weight;
    }

    protected Node getFloorEntryKing(Node<K> n, K key) {
        if (n != null) {
            int cmp = key.compareTo(n.key);
            if (cmp < 0) {
                Node c = getFloorEntryKing(n.left, key);
                if (c != null) {
                    n.left = c;
                    return rotateLeft(n);
                }
                return null;
            } else if (cmp > 0) {
                Node c = getFloorEntryKing(n.right, key);
                if (c != null) {
                    n.right = c;
                    return rotateRight(n);
                }
            }
            n.heap = root_value++;
        }
        return n;
    }

    public Node meld(Node x, Node y) {
        if (x == null || y == null) {
            return x == null ? y : x;
        }
        if (x.heap > y.heap) {
            x.right = meld(x.right, y);
            x.push();
            return x;
        } else {
            y.left = meld(x, y.left);
            y.push();
            return y;
        }
    }

    protected ArrayDeque<Node> stk = new ArrayDeque<>();
    protected Node pushStk(Node n, Node newN) {
        stk.push(n);
        return newN;
    }

    protected Node rotateLeft(Node n) {
        Node c = n.left;
        n.left = c.right;
        c.right = n;
        n.push();
        c.push();
        return c;
    }

    protected Node rotateRight(Node n) {
        Node c = n.right;
        n.right = c.left;
        c.left = n;
        n.push();
        c.push();
        return c;
    }

    public String toString() {
        return toString(root, "");
    }

    public String toString(Node n, String prefix) {
        if (n == null) return prefix + "null\n";

        String res = prefix + n + "\n";
        res += toString(n.left, prefix + "  ");
        res += toString(n.right, prefix + "  ");
        return res;
    }

    protected static void update(Node n) {
        n.weight = 1 + getWeight(n.left) + getWeight(n.right);
    }

    public static class Node<K extends Comparable<K>> {
        public long heap = random.nextLong() & MASK;
        public int weight = 1;
        public K key;
        public Stats stats;
        public Node left, right;

        public Node(K key) {
            this.key = key;

            stats = (Stats) statFactory.makeStats();
            stats.n = this;
            stats.update();
        }

        public void push() {
            update(this);
            stats.update();
        }

        public String toString() {
            return "[Heap, Weight: (" + heap + ", " + weight + ") " + key + " " + stats + "]";
        }
    }

    public static abstract class Stats {
        public Node n;

        public abstract Object merge(int queryType, Object leftAns, Object rightAns);
        public abstract Object onCurrentNodeAnswer(int queryType);
        public abstract Object outOfRangeAnswer(int queryType);
        public abstract Object overEntireRangeAnswer(int queryType);

        public Object query(int queryType, int l, int r) {
            if (r < l || l >= n.weight || r < 0) {
                return outOfRangeAnswer(queryType);
            } else if (l <= 0 && r >= n.weight - 1) {
                return overEntireRangeAnswer(queryType);
            }

            int leftWeight = getWeight(n.left);
            Object leftAnswer = n.left == null ? outOfRangeAnswer(queryType) :
                    n.left.stats.query(queryType, l, r);
            Object rightAnswer = n.right == null ? outOfRangeAnswer(queryType) :
                    n.right.stats.query(queryType, l - leftWeight - 1, r - leftWeight - 1);
            Object answer = merge(queryType, leftAnswer, rightAnswer);
            if (l <= leftWeight && r >= leftWeight) {
                answer = merge(queryType, answer, onCurrentNodeAnswer(queryType));
            }
            return answer;
        }

        public abstract void update();
    }

    public static interface StatFactory {
        public Object makeStats();
    }
}

class IntDeque implements Iterable<Integer> {

    private int capacity;
    private int size = 0;
    private int front = 0;
    private int back = 0;
    private int[] deque;

    public IntDeque(int capacity) {
        this.capacity = capacity;
        deque = new int[capacity];
    }

    public void add(int x) {
        addLast(x);
    }

    public void addLast(int x) {
        ensureCapacity();
        size++;
        deque[back++] = x;
        if (back == capacity) {
            back = 0;
        }
    }

    public void ensureCapacity() {
        if (size < capacity) {
            return;
        }
        int[] newDeque = new int[capacity << 1];
        for (int i = 0, j = front; i < size; i++, j++) {
            if (j == capacity) {
                j = 0;
            }
            newDeque[i] = deque[j];
        }
        deque = newDeque;
        capacity <<= 1;
        front = 0;
        back = size;
    }

    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int done = 0;
            int curr = front;
            public boolean hasNext() {
                return done < size;
            }
            public Integer next() {
                Integer res = deque[curr++];
                if (curr == capacity) {
                    curr = 0;
                }
                done++;
                return res;
            }
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    public String toString() {
        if (size == 0) {
            return "";
        }
        StringBuilder res = new StringBuilder();
        for (int i: this) {
            res.append(i);
            res.append(" ");
        }
        res.setLength(res.length() - 1);
        return res.toString();
    }
}

class JoltyScanner {
    public static final int BUFFER_SIZE = 1 << 16;
	public static final char NULL_CHAR = (char) -1;

    BufferedInputStream in;
	StringBuilder str = new StringBuilder();
	byte[] buffer = new byte[BUFFER_SIZE];
	boolean EOF_FLAG = false;

    char c = NULL_CHAR;
	int bufferIdx = 0;
    int size = 0;

	public JoltyScanner(InputStream in) {
		this.in = new BufferedInputStream(in, BUFFER_SIZE);
	}

    public String next() {
		checkEOF();
		for (c = c == NULL_CHAR ? nextChar() : c; Character.isWhitespace(c); checkEOF()) {
			c = nextChar();
		}
		str.setLength(0);
		for (; !EOF_FLAG && !Character.isWhitespace(c); c = nextChar()) {
			str.append(c);
		}
		return str.toString();
	}

	public String nextOrNull() {
		try {
			return next();
		} catch (EndOfFileException e) {
			return null;
		}
	}

    public char nextChar() {
		if (EOF_FLAG) {
			return NULL_CHAR;
		}
		while (bufferIdx == size) {
			try {
				size = in.read(buffer);
				if (size == -1) {
					throw new Exception();
				}
			} catch (Exception e) {
				EOF_FLAG = true;
				return NULL_CHAR;
			}
			if (size == -1) {
				size = BUFFER_SIZE;
			}
			bufferIdx = 0;
		}
		return (char) buffer[bufferIdx++];
	}

    public void checkEOF() {
		if (EOF_FLAG) {
			throw new EndOfFileException();
		}
	}

	public class EndOfFileException extends RuntimeException {
	}
}

