玄关
#include<bits/stdc++.h>
#define int long long
using namespace std;
using ll=long long;
using ull=unsigned long long;
using ld=long double;
using pii=pair<int,int>;
#define fi first
#define se second
constexpr int N=45,INF=1e18;
int n,m,r,d,a[N][N][N],s,t,ans;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
inline int getnum(int x,int y,int k) {
return (k-1)*n*m+(x-1)*m+y;
}
struct enode {
int nxt,to,val;
} edge[500005];
int tot=1,head[100005];
void add(int u,int v,int w) {
edge[++tot]={head[u],v,w};
head[u]=tot;
}
int dep[100005],now[100005];
bool bfs() {
for(int i=s;i<=t;i++) dep[i]=INF;
dep[s]=0,now[s]=head[s];
queue<int> q;q.push(s);
while(!q.empty()) {
int u=q.front();q.pop();
for(int i=head[u];i;i=edge[i].nxt) {
int v=edge[i].to,w=edge[i].val;
if(dep[v]==INF&&w>0) {
dep[v]=dep[u]+1,now[v]=head[v];
if(v==t) return 1;
q.push(v);
}
}
}
return 0;
}
int dfs(int u,int sum) {
if(u==t) return sum;
int k,flow=0;
for(int i=now[u];i&&sum>0;i=edge[i].nxt) {
now[u]=i;
int v=edge[i].to,w=edge[i].val;
if(dep[v]==dep[u]+1&&w>0) {
k=dfs(v,min(sum,w));
if(!k) dep[v]=INF;
edge[i].val-=k,edge[i^1].val+=k;
sum-=k,flow+=k;
}
}
return flow;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m>>r>>d;
for(int k=1;k<=r;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j][k];
s=0,t=n*m*r;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
add(s,getnum(i,j,1),INF);
add(getnum(i,j,1),s,0);
}
for(int k=1;k<r;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
add(getnum(i,j,k),getnum(i,j,k+1),a[i][j][k]);
add(getnum(i,j,k+1),getnum(i,j,k),0);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
add(getnum(i,j,r),t,a[i][j][r]);
add(t,getnum(i,j,r),0);
}
for(int k=d+1;k<=r;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int delta=0;delta<4;delta++) {
int nx=i+dx[delta],ny=j+dy[delta];
if(nx<1||nx>n||ny<1||ny>m) continue;
add(getnum(i,j,k),getnum(nx,ny,k-d),INF);
add(getnum(nx,ny,k-d),getnum(i,j,k),0);
}
while(bfs()) ans+=dfs(s,INF);
cout<<ans<<"\n";
return 0;
}