1 #include <stdio.h>
  2 #include <queue>
  3 #include <string.h>
  4 
  5 using namespace std;
  6 
  7 struct edge {
  8     int to,w,next;
  9 }e[6000100];
 10 struct node {
 11     int now, dist;
 12     node() { }
 13     node(int _now,int _dist) {
 14         now=_now;
 15         dist=_dist;
 16     }
 17     bool operator <(const node x) const {
 18         return dist > x.dist;
 19     }
 20 };
 21 
 22 int n, m, num, sum, head[2000100], d[2000100];
 23 bool flag[2000100];
 24 
 25 inline void add(int _x,int _y,int _w) {
 26     e[++num].to=_y;
 27     e[num].w=_w;
 28     e[num].next=head[_x];
 29     head[_x]=num;
 30 }
 31 
 32 inline void getint(int &_x) {
 33     int x=0,f=1;char ch=getchar();
 34     while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘) f=-1; ch=getchar();}
 35     while(ch>=‘0‘&&ch<=‘9‘) {x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
 36     _x=x*f;
 37 } 
 38 
 39 int main() {
 40     getint(n), getint(m);
 41     if (n==1 || m==1) {
 42         if(n>m) swap(n,m);
 43         int ans=2100000000;
 44         for (int i=1,_xy;i<m;++i) {
 45             getint(_xy);
 46             if(_xy<ans) ans=_xy;
 47         }
 48         printf("%d\n",ans);
 49         return 0;
 50     }
 51     int l=n-1,r=m-1;
 52     sum=2*l*r;
 53     for (int i=1,_xy;i<=n;++i) {
 54         for (int j=1,_t;j<m;++j) {
 55             getint(_xy);
 56             _t=(i-1)*r+j;
 57             int x,y;
 58             y=_t<<1;
 59             x=y-2*r-1;
 60             if(i==1) x=0;
 61             else if(i==n) y=sum+1;
 62             add(x,y,_xy);
 63             add(y,x,_xy);
 64         }
 65     }
 66     for (int i=1,_xy;i<n;++i) {
 67         for (int j=1,_t;j<=m;++j) {
 68             getint(_xy);
 69             _t=(i-1)*r+j-1;
 70             int x,y;
 71             x=_t<<1;
 72             y=x|1;
 73             if(j==1) x=sum+1;
 74             else if(j==m) y=0;
 75             add(x,y,_xy);
 76             add(y,x,_xy);
 77         }
 78     }
 79     for (int i=1,_xy;i<n;++i) {
 80         for (int j=1,_t;j<m;++j) {
 81             getint(_xy);
 82             _t=(i-1)*r+j;
 83             int x,y;
 84             y=_t<<1;
 85             x=y-1;
 86             add(x,y,_xy);
 87             add(y,x,_xy);
 88         }
 89     }
 90     priority_queue<node> q;
 91     for (int i=1;i<=sum+1;++i) d[i]=210000000;
 92     q.push(node(0,0));
 93     while(!q.empty()) {
 94         int x=q.top().now;
 95         q.pop();
 96         if(flag[x]) continue;
 97         for (int i=head[x];i;i=e[i].next) {
 98             int to=e[i].to;
 99             if(d[to]>d[x]+e[i].w) {
100                 d[to]=e[i].w+d[x];
101                 q.push(node(to,d[to]));
102             }
103         }
104     }
105     printf("%d\n",d[sum+1]);
106     return 0;
107 }