#include <iostream>
#include <cstring>
#include <unordered_set>
#define int long long
using namespace std;
const int N = 100010, M = 1000010;
const int INF = 0x3f3f3f3f3f3f3f3f;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
int n, m, r, D, S, T;
int h[N], e[M], ne[M], f[M], idx;
int d[N], q[N], cur[M];
inline void add(int a, int b, int c)
{
e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
e[idx] = a, f[idx] = 0, ne[idx] = h[b], h[b] = idx ++ ;
}
bool bfs()
{
memset(d, 0, sizeof d);
int hh = 0, tt = 0;
q[0] = S, d[S] = 1, cur[S] = h[S];
while (hh <= tt)
{
int t = q[hh ++ ];
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i];
if (!d[j] && f[i])
{
d[j] = d[t] + 1;
cur[j] = h[j];
if (j == T) return true;
q[ ++ tt] = j;
}
}
}
return false;
}
int find(int u, int lim)
{
if (u == T) return lim;
int flow = 0;
for (int i = cur[u]; ~i && flow < lim; cur[u] = i, i = ne[i])
{
int j = e[i];
if (d[j] == d[u] + 1 && f[i])
{
int t = find(j, min(f[i], lim - flow));
if (!t) d[j] = -1;
f[i] -= t, f[i ^ 1] += t, flow += t;
}
}
return flow;
}
int dinic()
{
for (int i = 0; i < idx; i += 2)
f[i] += f[i ^ 1], f[i ^ 1] = 0;
int r = 0, flow = 0;
while (bfs()) while ((flow = find(S, INF))) r += flow;
return r;
}
inline int get(int i, int j, int k)
{
return (i - 1) * n * m + (j - 1) * m + k;
}
signed main()
{
int x;
memset(h, -1, sizeof h);
scanf("%lld%lld%lld%lld", &n, &m, &r, &D);
S = 0, T = n * m * (r + 1) + 1;
for (int i = 1; i <= r; i ++ )
for (int j = 1; j <= n; j ++ )
for (int k = 1; k <= m; k ++ )
{
scanf("%lld", &x);
add(get(i, j, k), get(i + 1, j, k), x);
}
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
add(S, get(1, i, j), INF), add(get(r + 1, i, j), T, INF);
for (int i = D + 1; i <= r + 1; i ++ )
for (int j = 1; j <= n; j ++ )
for (int k = 1; k <= m; k ++ )
for (int it = 0; it < 4; it ++ )
{
int a = j + dx[it], b = k + dy[it];
if (a >= 1 && a <= n && b >= 1 && b <= m)
add(get(i, j, k), get(i - D, a, b), INF);
}
printf("%lld\n", dinic());
return 0;
}