Problem: Due to the recent popularity of the Deep learning new countries are starting to look like Neural Networks. That is, the countries are being built deep with many layers, each layer possibly having many cities. They also have one entry, and one exit point.

There are exactly L layers, each having N cities. Let us look at the two adjacent layers L1 and L2. Each city from the layer L1 is connected to each city from the layer L2 with the traveling cost cij for <image>, and each pair of adjacent layers has the same cost in between their cities as any other pair (they just stacked the same layers, as usual). Also, the traveling costs to each city from the layer L2 are same for all cities in the L1, that is cij is the same for <image>, and fixed j.

Doctor G. needs to speed up his computations for this country so he asks you to find the number of paths he can take from entry to exit point such that his traveling cost is divisible by given number M.

Input

The first line of input contains N (1 ≤ N ≤ 106), L (2 ≤ L ≤ 105) and M (2 ≤ M ≤ 100), the number of cities in each layer, the number of layers and the number that travelling cost should be divisible by, respectively.

Second, third and fourth line contain N integers each denoting costs 0 ≤ cost ≤ M from entry point to the first layer, costs between adjacent layers as described above, and costs from the last layer to the exit point.

Output

Output a single integer, the number of paths Doctor G. can take which have total cost divisible by M, modulo 109 + 7.

Example

Input

2 3 13
4 6
2 1
3 4


Output

2

Note

<image>

This is a country with 3 layers, each layer having 2 cities. Paths <image>, and <image> are the only paths having total cost divisible by 13. Notice that input edges for layer cities have the same cost, and that they are same for all layers.

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.Arrays;
import java.io.BufferedInputStream;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

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

	static class TaskB {
		public void solve(int testNumber, BufferedInputStream _in, PrintWriter out) {
			InputReader in = new InputReader(_in);
			long startTime = System.currentTimeMillis();

			int n = in.nextInt();
			int l = in.nextInt();
			int m = in.nextInt();
			int[] cnt = new int[m];
			int[] firstLayer = new int[n];
			int[] midLayer = new int[n];
			for (int i = 0; i < n; ++i) firstLayer[i] = in.nextInt();
			for (int i = 0; i < n; ++i) {
				int val = in.nextInt();
				midLayer[i] = val;
				cnt[val % m] = Mod.addMod(cnt[val % m], 1);

			}

			int[] lastLayer = new int[n];
			for (int i = 0; i < n; ++i) {
				lastLayer[i] = in.nextInt();
			}

			int[][] a = new int[m][m];
			for (int i = 0; i < m; ++i) {
				for (int j = 0; j < m; ++j) {
					int k = (i + j) % m;
					a[i][k] = Mod.addMod(a[i][k], cnt[j]);
				}
			}

			int[][] aa = MathUtils.powMatrixMod(a, l - 2);
			Arrays.fill(cnt, 0);
			for (int i = 0; i < n; ++i) {
				cnt[firstLayer[i] % m]++;
			}

			for (int i = 0; i < m; ++i) {
				for (int j = 0; j < m; ++j) {
					a[i][j] = Mod.mulMod(cnt[i], aa[i][j]);
				}
			}


			int re = 0;
			for (int j = 0; j < m; ++j) {
				int sum = 0;
				for (int i = 0; i < m; ++i) {
					sum = Mod.addMod(sum, a[i][j]);
				}
				cnt[j] = sum;
			}


			for (int i = 0; i < n; ++i) {
				int t = (m - lastLayer[i] % m) % m;
				int t2 = midLayer[i] % m;
				int x = t - t2;
				if (x < 0) x += m;
				re = Mod.addMod(re, cnt[x]);
			}


			out.println(re);

			in.close();
			System.err.println("Time: " + (System.currentTimeMillis() - startTime) + " miliseconds");
		}

	}

	static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public static boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public void close() {

		}

	}

	static class Mod {
		public static final long MOD = 1000000007L;
		public static final boolean DEBUG = false;

		public static int addMod(int a, int b, long MOD) {
			if (DEBUG) return a + b;

			while (a < 0)
				a += MOD;
			while (b < 0)
				b += MOD;
			return (int) (((long) a + (long) b) % MOD);
		}

		public static int addMod(int a, int b) {
			return addMod(a, b, MOD);
		}

		public static int mulMod(int a, int b, long MOD) {
			if (DEBUG) return a * b;

			while (a < 0)
				a += MOD;
			while (b < 0)
				b += MOD;
			return (int) (((long) a) * ((long) b) % MOD);
		}

		public static int mulMod(int a, int b) {
			return mulMod(a, b, MOD);
		}

	}

	static class MathUtils {
		public static void mulMatrixMod(int[][] a, int[][] b, int[][] ret) {
			for (int i = 0; i < ret.length; ++i)
				for (int j = 0; j < ret[0].length; ++j) {
					int sum = 0;
					for (int k = 0; k < a[0].length; ++k)
						sum = Mod.addMod(sum, Mod.mulMod(a[i][k], b[k][j]));
					ret[i][j] = sum;
				}

		}

		public static int[][] powMatrixMod(int[][] mt, long n) {

			if (n == 0) {
				int[][] ret = new int[mt.length][mt.length];
				for (int i = 0; i < mt.length; ++i) ret[i][i] = 1;
				return ret;
			}

			int[][] temp = powMatrixMod(mt, n / 2);
			int[][] t2 = new int[mt.length][mt.length];
			mulMatrixMod(temp, temp, t2);

			if (n % 2 == 1) {
				mulMatrixMod(t2, mt, temp);
				return temp;
			}

			return t2;

		}

	}
}