1 #include<bits/stdc++.h>
2 #define lowbit(a) ((a)&(-(a)))
3 #define clr(a,x) memset(a,x,sizeof(a))
4 #define rep(i,l,r) for(int i=l;i<(r);i++)
5 typedef long long ll;
6 using namespace std;
7 int read()
8 {
9 char c=getchar();
10 int ans=0,f=1;
11 while(!isdigit(c)){
12 if(c==‘-‘) f=-1;
13 c=getchar();
14 }
15 while(isdigit(c)){
16 ans=ans*10+c-‘0‘;
17 c=getchar();
18 }
19 return ans*f;
20 }
21 struct node{
22 int num,d;
23 inline bool operator<(const node&A)const{
24 return d>A.d;
25 }
26 };
27 struct edge{
28 int to,w;
29 };
30 const int maxn=2000009,inf=0x3fffffff;
31 int N,n,m,d[maxn];
32 vector<edge>e[maxn];
33 void addedge(int u,int v,int w){
34 edge ed;
35 ed.to=v,ed.w=w;
36 e[u].push_back(ed);
37 ed.to=u;
38 e[v].push_back(ed);
39 }
40 int dijkstra(int u,int v){
41 priority_queue<node>Q;
42 node start;
43 start.d=0;start.num=u;
44 Q.push(start);
45 rep(i,1,N+1) d[i]=inf;
46 d[0]=0;
47 while(!Q.empty()){
48 node now=Q.top();Q.pop();
49 int q=now.num;
50 if(now.d!=d[q]) continue;
51 rep(i,0,e[q].size()){
52 int to=e[q][i].to,w=e[q][i].w;
53 if(d[to]>d[q]+w){
54 d[to]=d[q]+w;
55 node next;
56 next.d=d[to];next.num=to;
57 Q.push(next);
58 }
59 }
60 }
61 return d[v];
62 }
63 int main()
64 {
65 n=read(),m=read();
66 N=(n-1)*(m-1)*2+1;
67 rep(i,0,n){
68 rep(j,1,m){
69 int w=read();
70 if(!i) addedge(N,j,w);
71 else if(i==n-1) addedge(0,i*(m-1)*2+j-m+1,w);
72 else addedge(i*(m-1)*2+j-m+1,i*(m-1)*2+j,w);
73 }
74 }
75 rep(i,1,n){
76 rep(j,0,m){
77 int w=read();
78 if(!j) addedge(0,i*(m-1)*2-m+2,w);
79 else if(j==m-1) addedge(N,i*(m-1)*2-m+1,w);
80 else addedge((i-1)*(m-1)*2+j,(i-1)*(m-1)*2+j+m,w);
81 }
82 }
83 rep(i,1,n){
84 rep(j,1,m){
85 int w=read();
86 addedge((i-1)*(m-1)*2+j,(i-1)*(m-1)*2+j+m-1,w);
87 }
88 }
89 printf("%d\n",dijkstra(0,N));
90 return 0;
91 }