#include<bits/stdc++.h>
#define db double
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
#define pii pair<int,int>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int inf=1e18,mxn=1e6+10;
int n,m,s,t,ans,cnt=1;
int id(int x,int y){
return (x-1)*m+y;
}
int head[mxn],dep[mxn],cur[mxn];
struct node{
int to,nxt,val;
}edge[mxn<<3];
void add(int u,int v,int w){
edge[++cnt]=(node){v,head[u],w};
head[u]=cnt;
edge[++cnt]=(node){u,head[v],0};
head[v]=cnt;
}
bool bfs(){
memset(dep,0,sizeof dep);
memcpy(cur,head,sizeof head);
queue<int>q;
q.push(s);
dep[s]=1;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(dep[v]||!edge[i].val)continue;
dep[v]=dep[u]+1;
q.push(v);
}
}
return dep[t];
}
int dfs(int now,int fl){
if(now==t)return fl;
int flow=0;
for(int i=cur[now];i&&fl;i=edge[i].nxt){
int v=edge[i].to;
cur[now]=i;
if(!edge[i].val||dep[v]!=dep[now]+1)continue;
int c=dfs(v,min(fl,edge[i].val));
fl-=c,flow+=c;
edge[i].val-=c,edge[i^1].val+=c;
}
return flow;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
n=read(),m=read();
s=id(1,1),t=id(n,m);
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++){
int x=read();
add(id(i,j),id(i,j+1),x);
}
for(int i=1;i<n;i++)
for(int j=1;j<=m;j++){
int x=read();
add(id(i,j),id(i+1,j),x);
}
for(int i=1;i<n;i++)
for(int j=1;j<m;j++){
int x=read();
add(id(i,j),id(i+1,j+1),x);
}
while(bfs()){
ans+=dfs(s,inf);
}
printf("%lld\n",ans);
return 0;
}