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.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.TreeMap;

public class D {
  public static void main(String[] args){
    FastScanner sc = new FastScanner();
    int n = sc.nextInt();
    int m = sc.nextInt();
    int p = sc.nextInt();
    int[] a = new int[n];
    int[] b = new int[m];

    for(int i = 0; i < n; i++) {
      a[i] = sc.nextInt();
    }

    Seq bseq = new Seq();
    for(int i = 0; i < m; i++) {
      b[i] = sc.nextInt();
      bseq.add(b[i]);
    }

    long maxQ = n - (m - 1) * (long) p;
    if(maxQ <= 0) {
      System.out.println(0);
      return;
    }

    Boolean[] validQ = new Boolean[(int) maxQ];
    int totalQ = 0;
    for(int q = 0; q < maxQ; q++) {
      if(validQ[q] != null) {
        continue;
      }

      Seq qseq = new Seq();
      for(int i = 0; i < m; i++) {
        qseq.add(a[q + i * p]);
      }
      if(bseq.equals(qseq)) {
        validQ[q] = true;
        totalQ++;
      } else {
        validQ[q] = false;
      }

      int curQ = q;
      while(curQ + p < maxQ) {
        curQ += p;
        qseq.remove(a[curQ - p]);
        qseq.add(a[curQ + (m - 1) * p]);

        if(validQ[curQ] != null) {
          continue;
        }

        if(bseq.equals(qseq)) {
          validQ[curQ] = true;
          totalQ++;
        } else {
          validQ[curQ] = false;
        }
      }
    }

    System.out.println(totalQ);
    for(int i = 0; i < validQ.length; i++) {
      if(validQ[i] != null && validQ[i]) {
        System.out.print(i + 1 + " ");
      }
    }
  }

  public static class Seq {
    TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();

    void add(int v) {
      if(map.containsKey(v)) {
        map.put(v, map.get(v) + 1);
      } else {
        map.put(v, 1);
      }
    }

    void remove(int v) {
      if(map.get(v) == 1) {
        map.remove(v);
      } else {
        map.put(v, map.get(v) - 1);
      }
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      Seq seq = (Seq) o;

      if(map.size() != seq.map.size()) {
        return false;
      }

      for(int v : map.keySet()) {
        if(!seq.map.containsKey(v) || !map.get(v).equals(seq.map.get(v))) {
          return false;
        }
      }

      return true;
    }
  }

  public static class FastScanner {
    BufferedReader br;
    StringTokenizer st;

    public FastScanner(String s) {
      try {
        br = new BufferedReader(new FileReader(s));
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      }
    }

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

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

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

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

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