include<bits/stdc++.h>
using namespace std;
const int maxn=20;
const int INF=2147483647;
int a[maxn][maxn];
int n,m,r,c,ans;
int vish[maxn],hc[maxn][maxn],lc[maxn],f[maxn][maxn];
void Memset() //预处理
{
for(int i=1; i<=m; i++)
lc[i]=0;
for(int i=1; i<=m; i++)
for(int j=1; j<=m; j++)
hc[i][j]=0;
for(int i=1; i<=m; i++)
for(int j=1; j<r; j++)
lc[i]+=abs(a[vish[j]][i]-a[vish[j+1]][i]);
for(int i=2; i<=m; i++)
for(int j=1; j<i; j++)
for(int k=1; k<=r; k++)
hc[i][j]+=abs(a[vish[k]][i]-a[vish[k]][j]);
}
void makeans()
{
f[1][1]=lc[1];
for(int i=2; i<=m; i++)
{
for(int j=1; j<=(i<c?i:c); j++)
{
f[i][j]=INF;
if(j==1) f[i][j]=lc[i]; //边界
else if(i==j) f[i][j]=f[i-1][j-1]+hc[i][j-1]+lc[i]; //边界*2
else
{
for(int k=i-1; k>=j-1; k--)
f[i][j]=min(f[i][j],f[k][j-1]+hc[i][k]+lc[i]); //状态转移方程
}
if(j==c) ans=min(ans,f[i][c]); //记录最小值
}
}
return ;
}
void dfs(int k,int j) //回溯法求组合数
{
if(k==r+1) {Memset();makeans();return ;}
for(int i=j+1; i<=n; i++)
{
vish[k]=i;
dfs(k+1,i);
}
}
int main()
{
ans=INF;
scanf("%d%d%d%d",&n,&m,&r,&c);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
scanf("%d",&a[i][j]);
dfs(1,0);
printf("%d",ans);
return 0;
}