import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N, D, K, C, maxCnt, cnt;
static int[] belt, sushi;
public static void main(String[] args) throws IOException {
init();
// 1. 처음부터 k개 만큼 먹었을 때의 초기화
initCnt();
// 2. 1번부터 n-1 번까지 start 만 이동 시킬경우 K 는 고정
process();
print();
}
private static void init() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
D = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken()) - 1;
belt = new int[N];
sushi = new int[D];
for (int i = 0; i < N; i++) {
belt[i] = Integer.parseInt(br.readLine()) - 1;
}
}
private static void initCnt() {
for (int i = 0; i < K; i++) {
if (sushi[belt[i]] == 0) {
cnt++;
}
sushi[belt[i]]++;
}
}
private static void process() {
for (int start = 0; start < N; start++) {
updateMax();
moveEndPointer(start);
moveStartPointer(start);
}
}
private static void updateMax() {
if (maxCnt <= cnt) {
if (sushi[C] == 0) {
maxCnt = cnt + 1;
} else {
maxCnt = cnt;
}
}
}
private static void moveEndPointer(int start) {
int end = (start + K) % N;
if (sushi[belt[end]] == 0) {
cnt++;
}
sushi[belt[end]]++;
}
private static void moveStartPointer(int start) {
sushi[belt[start]]--;
if (sushi[belt[start]] == 0) {
cnt--;
}
}
private static void print() {
System.out.println(maxCnt);
}
}
K
개 만큼의 접시를 먹었을 때의 cnt
값을 초기화를 해준다.end
포인터를 이동시킨다. 이때, 해당 위치의 초밥이 먹지 않은 종류의 초밥이면 cnt
값을 증가시킨다.end
포인터 계산 시에는 나머지 연산을 사용해 계산해준다.start
포인터를 이동시킨다. 이때, 해당 위치의 초밥 종류 한개를 먹지 않은 상태로 변경하고, 해당 종류 초밥을 아예 먹지 않은 상황이 될 경우 cnt
값을 감소 시킨다.