#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
#define R register
using namespace std;
int read(){
R int x=0;bool f=1;
R char ch=getchar();
while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=0;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
return f?x:-x;
}
const int N=1e6+10;
int n,m,S,T,head[N],dis[N],q[N*2];
struct node{
int v,next,f;
}e[N*12];int tot=1;
void add(int x,int y,int z){
e[++tot].v=y;e[tot].f=z;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].f=0;e[tot].next=head[y];head[y]=tot;
}
bool bfs(){
for(int i=1;i<=T;i++) dis[i]=inf;
int h=0,t=1;
q[1]=S;dis[S]=0;
while(h!=t){
int now=q[++h];
for(int i=head[now];i;i=e[i].next){
int v=e[i].v;
if(e[i].f&&dis[now]+1<dis[v]){
dis[v]=dis[now]+1;
if(v==T)return 1;
q[++t]=v;
}
}
}
return dis[T]<inf;
}
int dfs(int now,int f){
if(now==T) return f;
int rest=f;
for(int i=head[now];i;i=e[i].next){
int v=e[i].v;
if(e[i].f&&dis[v]==dis[now]+1&&rest){
int t=dfs(v,min(rest,e[i].f));
if(!t) dis[v]=0;
e[i].f-=t;
e[i^1].f+=t;
rest-=t;
}
}
return f-rest;
}
int dinic(){
int ans=0;
while(bfs()) ans+=dfs(S,inf);
return ans;
}
int main(){
n=read();m=read();S=0;T=n*m+1;
add(S,1,inf);add(n*m,T,inf);
for(int i=1,u,w;i<=n;i++){
for(int j=1;j<m;j++){
w=read();u=(i-1)*m+j;
add(u,u+1,w);
add(u+1,u,w);
}
}
for(int i=1,u,w;i<n;i++){
for(int j=1;j<=m;j++){
w=read();u=(i-1)*m+j;
add(u,u+m,w);
add(u+m,u,w);
}
}
for(int i=1,u,w;i<n;i++){
for(int j=1;j<m;j++){
w=read();u=(i-1)*m+j;
add(u,u+m+1,w);
add(u+m+1,u,w);
}
}
printf("%d",dinic());
return 0;
}