/*
因为每一秒只能走一个单位长度,而每走一个单位长度又会消耗一个体力值,如果体力值没有了时间还有也只能按照体力值计算,反之一样,所以V对于时间和体力值取小
cnt记录有桃子的树的个数,node[cnt].c表示在第cnt颗树上每次可摘桃子的个数,node[cnt].v表示从起点到第cnt棵树来回的距离,wz[i][j]表示从(0,0)到(i,j)范围内树的个数
node[i]记录第i棵树可以摘的次数 dp方程式为ans[j]=max(ans[j],ans[j-k*node[i].v]+k*node[i].c),不摘第j棵树的第k次与摘了之后获得的桃子取大
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 1010
struct node{
int v,c,k;
}N[maxn*maxn];
int V;
int ans[maxn]={0},wz[maxn][maxn];
int cnt=0,n,m,t,a;
int main()
{
scanf("%d%d%d%d",&n,&m,&t,&a);
if(t<a-1) V=t;//因为最后要有剩余体力所以此处先减1
else V=a-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int u;
scanf("%d",&u);
if(u)
{
N[++cnt].c=u;
N[cnt].v=2*(i+j);
wz[i][j]=cnt;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int u;
scanf("%d",&u);
if(u)
N[wz[i][j]].k=u;
}
for(int i=1;i<=cnt;i++)
for(int j=V;j>=1;j--)
for(int k=1;k<=N[i].k;k++)
if(j-k*N[i].v>=0)
ans[j]=max(ans[j],ans[j-k*N[i].v]+k*N[i].c);
printf("%d",ans[V]);
return 0;
}