#include <bits/stdc++.h>
using namespace std;
const int N = 1000 + 1;
const int M = 1000 + 1;
const int K = 1000000 + 1;
typedef long long arr_d[K];
typedef long long arr_s[N];
inline void error(int n) { cout << fixed << setprecision(n + 1); }
inline long long gcd(long long a, long long b) {
  return (a ? gcd(b % a, a) : b);
}
inline bool is_prime(long long n) {
  for (long long i = 2; i * i <= n; i++)
    if (!(n % i)) return false;
  return (n > 1);
}
int n, m, k, p;
long long res, i, row[N], col[M], a[K], b[K], candidate;
inline void load_data() {
  long long i, j;
  int v;
  scanf("%d%d%d%d", &n, &m, &k, &p);
  memset(row, 0, sizeof(row));
  memset(col, 0, sizeof(col));
  for (i = (1); i <= (n); i++)
    for (j = (1); j <= (m); j++) {
      scanf("%d", &v);
      row[i] += v;
      col[j] += v;
    }
}
inline void init(arr_d &des, arr_s source, long long SIZE) {
  priority_queue<long long> heap;
  long long i, MAX;
  des[0] = 0;
  for (i = (1); i <= (SIZE); i++) heap.push(source[i]);
  for (i = (1); i <= (k); i++) {
    MAX = heap.top();
    heap.pop();
    des[i] = des[i - 1] + MAX;
    heap.push(MAX - (n + m - SIZE) * p);
  }
}
int main() {
  load_data();
  init(a, row, n);
  init(b, col, m);
  res = 1000000;
  res *= -res * 1000;
  for (i = (0); i <= (k); i++) {
    candidate = a[i] + b[k - i] - i * (k - i) * p;
    res = max(res, candidate);
  }
  cout << res;
}
