10 5 1000000000
1 1 1 2 2 1 2 2 2 2
 5 3 3
1 2 2 1 1
 2 4 1
1 1
 1 1000000000 1000000000
100000
 5 3 2
1 1 2 1 1
 5 2 4
1 2 3 2 1
 1 10 10
1

10000000000
 0
 2
 0
 7
 0
 0

import java.util.ArrayDeque;
import java.util.Arrays;

public class Main {

	static long k;
	private static void solve() {
		int n = ni();
		k = nl();
		long m = nl();
		long[] a = nal(n);
		
		if (m < 3) {
			ArrayDeque<long[]> q = sim(a, (int)m);
			System.out.println(sum(q));
		}
		ArrayDeque<long[]> q = sim(a, 3);

		long ret = 0;
		if (q.size() > 2) {
			long[] count = new long[3];
			
			int one = 0;
			for (long[] v : q) {
				count[(int)v[2]] += v[1];
				
				if (v[2] == 1) {
					one ++;
				}
			}
			if (one >= 2) {
				ret = count[0] + count[2] + count[1] * (m - 2);
			} else {
				count[1] = count[1] * m % k;

				if (count[1] == 0) {
					q = new ArrayDeque<long[]>();
					for (long[] v : q) {
						if (v[2] != 1) {
							next(q, v[1], 0);
						}
					}
					ret = sum(q);
				}
			}
		} else if (q.size() == 1) {
			ret = a.length * m % k;
		} else if (q.size() == 0) {
			long mod = m % 3;
			q = sim(a, (int)mod);
			ret = sum(q);
		}
		System.out.println(ret);
	}

	private static ArrayDeque<long[]> sim(long[] a, int m) {
		ArrayDeque<long[]> q = new ArrayDeque<>();
		int n = a.length;
		for (int i = 0; i < m; i ++) {
			for (int j = 0; j < n; j ++) {
				next(q, a[j], i);
			}
		}
		return q;
	}
	
	
	private static void next(ArrayDeque<long[]> q, long x, int i) {
		long[] now = q.peekLast();
		if (q.size() > 0 && now[0] == x) {
			now[1] ++;
		} else {
			now = new long[] {x, 1, i};
			q.addLast(now);
		}
		
		if (now[1] >= k) {
			now[1] -= k;
		}
		if (now[1] == 0) {
			q.pollLast();
		}
		
	}
	
	private static long sum(ArrayDeque<long[]> q) {
		long ret = 0;
		for (long[] v: q) {
			ret += v[1];
		}
		return ret;
	}

	
	public static void main(String[] args) {
		new Thread(null, new Runnable() {
			@Override
			public void run() {
				long start = System.currentTimeMillis();
				String debug = args.length > 0 ? args[0] : null;
				if (debug != null) {
					try {
						is = java.nio.file.Files.newInputStream(java.nio.file.Paths.get(debug));
					} catch (Exception e) {
						throw new RuntimeException(e);
					}
				}
				reader = new java.io.BufferedReader(new java.io.InputStreamReader(is), 32768);
				solve();
				out.flush();
				tr((System.currentTimeMillis() - start) + "ms");
			}
		}, "", 64000000).start();
	}

	private static java.io.InputStream is = System.in;
	private static java.io.PrintWriter out = new java.io.PrintWriter(System.out);
	private static java.util.StringTokenizer tokenizer = null;
	private static java.io.BufferedReader reader;

	public static String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new java.util.StringTokenizer(reader.readLine());
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	private static double nd() {
		return Double.parseDouble(next());
	}

	private static long nl() {
		return Long.parseLong(next());
	}

	private static int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private static char[] ns() {
		return next().toCharArray();
	}

	private static long[] nal(int n) {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = nl();
		return a;
	}

	private static int[][] ntable(int n, int m) {
		int[][] table = new int[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				table[i][j] = ni();
			}
		}
		return table;
	}

	private static int[][] nlist(int n, int m) {
		int[][] table = new int[m][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				table[j][i] = ni();
			}
		}
		return table;
	}

	private static int ni() {
		return Integer.parseInt(next());
	}

	private static void tr(Object... o) {
		if (is != System.in)
			System.out.println(java.util.Arrays.deepToString(o));
	}
}
