// Arup Guha
// 12/30/2025
// Solution to 2025 SER D1 Problem H: Rows of Stars

import java.util.*;
import java.io.*;

public class rowsofstars {

	public static void main(String[] args) throws Exception {
		
		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer tok = new StringTokenizer(stdin.readLine());
		
		// Get basic input.
		int n = Integer.parseInt(tok.nextToken());
		int k = Integer.parseInt(tok.nextToken());
		int r = Integer.parseInt(tok.nextToken());
		int c = Integer.parseInt(tok.nextToken());
		
		// This is dumb.
		k = k%n;
		
		// Store original twice so wraparound is easy.
		long[] orig = new long[2*n];
		for (int i=0; i<n; i++)
			orig[i] = Integer.parseInt(stdin.readLine());
		for (int i=n; i<2*n; i++)
			orig[i] = orig[i-n];
					
		// csums[i] will store sum of the c consecutive items starting at index i.
		long[] csums = new long[n];
		for (int i=0; i<c; i++)
			csums[0] += orig[i];
		for (int i=1; i<n; i++)
			csums[i] = csums[i-1] - orig[i-1] + orig[i-1+c];
		
		// The sums come in some different groups, each with the same size.
		// eg. if n = 10, k = 4, then there are 2 groups of 5 possible row sums.
		int groups = gcd(n, k);
		int gSize = n/groups;
		
		// Now, get these sums of c items in the order that they show up in that rectangle.
		long[] permcsums = new long[2*n];
		
		int[] map = new int[n];
		Arrays.fill(map, -1);
		
		// Each group is separate.
		for (int z=0; z<groups; z++) {
			
			// This is the first index in the group.
			int idx = z;
			
			// This is the number of unique items in the group.
			for (int i=0; i<gSize; i++) {
				permcsums[z*gSize+i] = csums[idx];
				if (idx <= n-c) map[idx] = i;
				idx = (idx + k)%n;
			}
		}
		
		// Wrap around.
		for (int i=n; i<2*n; i++)
			permcsums[i] = permcsums[i-n];
		
		// This is safe.
		long res = -1000000000000000000L;
		
		// Each group generates different possible sums. We cam think of the groups as 
		// starting at row 0, columns 0, 1, 2, ..., gcd(n,k)-1.
		for (int z=0; z<groups; z++) {
			
			// This falls off the end.
			if (z>n-c) break; 
		
			// Here are the rolling sums of each box we could form.
			long[] sumrows = new long[2*gSize];
			
			// This is the "leftover" that gets added one more time than the cycle.
			for (int i=0; i<r%gSize; i++)
				sumrows[0] += permcsums[z*gSize+i];
			
			// This is for efficiency.
			if (r >= gSize) {
				long cycleSum = 0;
				for (int i=0; i<gSize; i++)
					cycleSum += permcsums[z*gSize+i];
				sumrows[0] += cycleSum*(r/gSize);
			}
			
			// Now do the rest of the rectangle sums, sliding our window, going down.
			for (int i=1; i<gSize; i++) 
				sumrows[i] = sumrows[i-1] - permcsums[z*gSize+i-1] + permcsums[z*gSize + (i-1+r)%gSize];
			for (int i=gSize; i<2*gSize; i++)
				sumrows[i] = sumrows[i-gSize];
			
			// Note: sumrows[i] stores the sum of the values in the r by c rectangle 
			//       with top left item in row i column z.
			
			// If map[i] is 3, for example, this means that i is a valid start column and that
			// the value originally in that column would end up in column 0 after i rotations
			// of length k. This helps us determine the subset of values in the array sumrows
			// that correspond to actual rectangles that don't fall off the end.
			ArrayList<Integer> starts = new ArrayList<Integer>();
			for (int i=0; i<n; i+=groups)
				if (map[i] != -1)
					starts.add(map[i]);
			Collections.sort(starts);
			
			ArrayList<Integer> uStarts = new ArrayList<Integer>();
			ArrayList<Integer> uEnds = new ArrayList<Integer>();
			
			// What we're doing here is collating all of the valid ranges into the sumrows array
			// into disjoint sets so that we can efficiently look at the values that are possible.
			uStarts.add(starts.get(0));
			int curE = n-r;
			for (int i=1; i<starts.size(); i++) {
				
				int nextS = starts.get(i);
				if (nextS > curE+1) {
					uStarts.add(nextS);
					uEnds.add(curE);
				}
				
				curE = nextS + n - r;
				
				// This is very important! This means the rest of the range is covered.
				if (curE >= gSize) break;
			}
			uEnds.add(curE);
			
			// Now, basically we want the largest answer of any item in the sumrows array
			// that is in between index s and index e, inclusive, where [s,e] are each of
			// the disjoint ranges that were calculated above.
			res = Math.max(res, sumrows[0]);
			for (int i=0; i<uStarts.size(); i++) {
				int s = uStarts.get(i);
				int e = uEnds.get(i);
				for (int x=s; x<=e && x<sumrows.length; x++)
					res = Math.max(res, sumrows[x]);
			}
			
		}
		
		// Ta da!
		System.out.println(res);
	}
	
	public static int gcd(int a, int b) {
		return b == 0 ? a : gcd(b, a%b);
	}
}