Sereja has two sequences a and b and number p. Sequence a consists of n integers a1, a2, ..., an. Similarly, sequence b consists of m integers b1, b2, ..., bm. As usual, Sereja studies the sequences he has. Today he wants to find the number of positions q (q + (m - 1)·p ≤ n; q ≥ 1), such that sequence b can be obtained from sequence aq, aq + p, aq + 2p, ..., aq + (m - 1)p by rearranging elements.

Sereja needs to rush to the gym, so he asked to find all the described positions of q.

Input

The first line contains three integers n, m and p (1 ≤ n, m ≤ 2·105, 1 ≤ p ≤ 2·105). The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109). The next line contains m integers b1, b2, ..., bm (1 ≤ bi ≤ 109).

Output

In the first line print the number of valid qs. In the second line, print the valid values in the increasing order.

Examples

Input

5 3 1
1 2 3 2 1
1 2 3


Output

2
1 3


Input

6 3 2
1 3 2 2 3 1
1 2 3


Output

2
1 2
import java.io.*;
import java.util.*;

public class Task1 {

    static StreamTokenizer in;

    static int nextInt() throws IOException {
        in.nextToken();
        return (int)in.nval;
    }

    static class Counter extends HashMap<Integer, Integer> {
        public int incGet(int key) {
            Integer v = get(key);
            int val = v == null ? 0 : (int)v;
            val++;
            put(key, val);
            return val;
        }

        public int decGet(int key) {
            Integer v = get(key);
            int val = v == null ? 0 : (int)v;
            val--;
            put(key, val);
            return val;
        }
    }

    public static void main(String[] args) throws Exception {
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

        int n = nextInt();
        int m = nextInt();
        int step = nextInt();

        int[] a = new int[n];
        int[] b = new int[m];
        for (int i = 0; i < n; i++) {
            a[i] = nextInt();
        }

        Counter counterOG = new Counter();
        for (int i = 0; i < m; i++) {
            b[i] = nextInt();
            counterOG.incGet(b[i]);
        }

        List<Integer> qs = new ArrayList<>();

        // System.out.println("OG : " + counterOG);

        if (n == 1 && m == 1) {
            if (a[0] == b[0])
                System.out.println("1\n1");
            else
                System.out.println("0");
            return;
        }

        OUT: for (int i = 0; i < step; i++) {
            int range = (m - 1) * step;
            // System.out.println("range = " + range);
            if (i + range > n) continue;
            // System.out.println("Iteration outer " + i);
            int missing = counterOG.size();
            Counter counter = new Counter();
            int j = i;
            int q = i;
            for (int c = 0; c < m; c++) {
                if (j >= n) continue OUT;
                int num = a[j];
                if (counterOG.containsKey(num)) {
                    int newval = counter.incGet(num);
                    if (newval == (int)counterOG.get(num)) {
                        missing--;
                    }
                }
                j += step;
            }
            if (counter.equals(counterOG)) qs.add(q+1);
            // if (missing == 0) qs.add(q+1);
            // int lastJ = j - step;
            // System.out.println("Initial counter: " + counter + ", missing = " + missing);

            // System.out.println("J before: " + j);
            for (; j < n; j += step) {
                q = j - range;
                // System.out.println("Testing for q = " + q);
                // System.out.println("Testing for j = " + j);
                // System.out.println("Testing for lastJ = " + lastJ);
                // q += step;

                // Remove previous
                int num = a[j - range - step];
                // int num = a[j - lastJ - step];
                if (counterOG.containsKey(num)) {
                    Integer oldV = counter.get(num);
                    int oldval = oldV == null ? 0 : (int)oldV;
                    int newval = counter.decGet(num);
                    if (oldval == (int)counterOG.get(num))
                        missing++;
                    if (newval == (int)counterOG.get(num))
                        missing--;
                }

                // Add new
                num = a[j];
                if (counterOG.containsKey(num)) {
                    Integer oldV = counter.get(num);
                    int oldval = oldV == null ? 0 : (int)oldV;
                    int newval = counter.incGet(num);
                    if (oldval == (int)counterOG.get(num))
                        missing++;
                    if (newval == (int)counterOG.get(num))
                        missing--;
                }

                // if (q == 13)
                //     System.out.println("For Q = " + q + ": " + counter + ", missing : " + missing);
                if (counter.equals(counterOG)) qs.add(q+1);
                // if (missing == 0) qs.add(q+1);
            }
        }

        Collections.sort(qs);
        // System.out.println(qs);

        // // Compress
        // int[] countsOG = new int[m];
        // int prev = -1;
        // int idx = -1;
        // int[] newB = new int[m];
        // for (int i = 0; i < m; i++) {
        //     int el = b[i];
        //     if (el != prev) {
        //         idx++;
        //         newB[idx] = el;
        //     }
        //     countsOG[idx]++;
        //     prev = el;
        // }
        // int newM = idx+1;

        // System.out.println(Arrays.toString(b));
        // System.out.println(Arrays.toString(newB));
        // System.out.println(Arrays.toString(countsOG));

        // int[] counts = new int[newM];
        // int missing = newM;

        // List<Integer> qs = new ArrayList<>();

        // int lastI = 0;
        // int j = 0;
        // for (int i = 0; i < m; i++) {
        //     int elFromA = a[i];
        //     // System.out.println("ELFROMA " + elFromA);
        //     int leftEdge = 0;
        //     int rightEdge = newM;
        //     int result = -1;
        //     while (true) {
        //         // System.out.println("LEFT " + leftEdge + " right " + rightEdge);
        //         if (rightEdge - leftEdge < 0) break;
        //         int guess = (leftEdge + rightEdge) / 2;
        //         int elFromB = newB[guess];
        //         if (elFromB == elFromA) {
        //             result = guess;
        //             break;
        //         } else if (leftEdge == rightEdge) break;
        //         else if (elFromB < elFromA)
        //             leftEdge = guess + 1;
        //         else
        //             rightEdge = guess;
        //     }
        //     System.out.println("RESULT " + result);
        //     if (result != -1) {
        //         counts[result]++;
        //         if (counts[result] == countsOG[result])
        //             missing--;
        //         else
        //             missing++;
        //     }
        //     lastI = j;
        //     j += step;
        // }
        // System.out.println("MISSING " + missing);
        // System.out.println("LASTI " + lastI);
        // if (missing == 0) qs.add(1);
        // int q = 1;

        // for (int i = lastI + step; i < n; i += step) {
        //     q++;
        //     // Remove previous
        //     // System.out.println("LASTI " + lastI);
        //     int elFromA = a[i - lastI - step];
        //     // System.out.println("TOREMOVE " + elFromA);
        //     int result = -1;
        //     int leftEdge = 0;
        //     int rightEdge = newM;
        //     while (true) {
        //         // System.out.println("LEFT " + leftEdge + " right " + rightEdge);
        //         if (rightEdge - leftEdge < 0) break;
        //         int guess = (leftEdge + rightEdge) / 2;
        //         int elFromB = newB[guess];
        //         if (elFromB == elFromA) {
        //             result = guess;
        //             break;
        //         } else if (leftEdge == rightEdge) break;
        //         else if (elFromB < elFromA)
        //             leftEdge = guess + 1;
        //         else
        //             rightEdge = guess;
        //     }
        //     if (result != -1) {
        //         counts[result]--;
        //         if (counts[result] == countsOG[result])
        //             missing--;
        //         else
        //             missing++;
        //     }

        //     // Add new
        //     elFromA = a[i];
        //     result = -1;
        //     leftEdge = 0;
        //     rightEdge = newM;
        //     while (true) {
        //         // System.out.println("LEFT " + leftEdge + " right " + rightEdge);
        //         if (rightEdge - leftEdge < 0) break;
        //         int guess = (leftEdge + rightEdge) / 2;
        //         int elFromB = newB[guess];
        //         if (elFromB == elFromA) {
        //             result = guess;
        //             break;
        //         } else if (leftEdge == rightEdge) break;
        //         else if (elFromB < elFromA)
        //             leftEdge = guess + 1;
        //         else
        //             rightEdge = guess;
        //     }
        //     if (result != -1) {
        //         counts[result]++;
        //         if (counts[result] == countsOG[result])
        //             missing--;
        //         else
        //             missing++;
        //     }
        //     if (missing == 0) qs.add(q);
        //     // System.out.println("MISSING " + missing);
        // }
        int size = qs.size();
        System.out.println(size);
        for (int i = 0; i < size; i++) {
            if (i == size - 1)
                System.out.print("" + qs.get(i));
            else
                System.out.print("" + qs.get(i) + " ");
        }
        System.out.println();

    }
}
