import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.TreeSet;
import java.util.StringTokenizer;
import java.io.InputStream;
/**
* Built using CHelper plug-in
* Actual solution is at the top
* @author Rubanenko
*/
public class Main {
public static void main
(String[] args
) { InputReader in = new InputReader(inputStream);
TaskB solver = new TaskB();
solver.solve(1, in, out);
out.close();
}
}
class TaskB {
public void solve
(int testNumber, InputReader in,
PrintWriter out
) { int n = in.nextInt();
int m = in.nextInt();
int k = in.nextInt();
long p = in.nextLong();
long[] h = new long[n], v = new long[m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int x = in.nextInt();
h[i] += x;
v[j] += x;
}
}
long[] a = new long[k + 1], b = new long[k + 1];
TreeSet<Long> s = new TreeSet<Long>();
for (int i = 0; i < n; i++) {
s.add(h[i]);
}
for (int i = 0; i < k; i++) {
a[i] = s.last();
// out.println(a[i]);
s.remove(a[i]);
s.add(a[i] - p * (long)m);
if (i > 0) a[i] = a[i - 1] + a[i];
}
s.clear();
long ans = a[k - 1], res = 0;
for (int i = 0; i < m; i++) {
s.add(v[i]);
}
// out.println("------");
for (int i = 0; i < k; i++) {
b[i] = s.last();
// out.println(b[i]);
s.remove(b[i]);
s.add(b[i] - p * (long)n);
res = res + b[i];
if (k - i - 2 >= 0) {
ans
= Math.
max(ans, res
+ a
[k
- i
- 2] - p
* ((long)(k
- i
- 1)) * ((long)(i
+ 1))); }
//out.println(ans);
}
ans
= Math.
max(ans, res
); out.println(ans);
}
}
class InputReader {
}
try {
line = reader.readLine();
}
return line;
}
while (tokenizer == null || !tokenizer.hasMoreTokens())
return tokenizer.nextToken();
}
public int nextInt() {
}
public long nextLong() {
return Long.
parseLong(next
()); }
}