//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
template<class T> using indexed_set=tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
const int N=2e5+7;
const int mod=1e9+7;
const int INF=1e18+7;
const double EPS=1e-12;
const int dx[]={-1,1,0,0}; // UDLR
const int dy[]={0,0,-1,1}; // UDLR
inline int maximum(int a,int b) {int c=a>b?a:b; return c;}
inline int minimum(int a,int b) {int c=a>b?b:a; return c;}

int r,c; bool visited [550][550]; vector<vector<int>> d(550,vector<int>(550,INF));
vector<vector<int>> A(550,vector<int>(550)),B(550,vector<int>(550));

int32_t main(){
    cin.tie(nullptr)->sync_with_stdio(false);

     cin>>r>>c; priority_queue<tuple<int,int,int>> q;
     for(int i=1;i<=r;i++){
        for(int j=1;j<=c-1;j++) cin>>A[i][j];
     }
     for(int i=1;i<=r-1;i++){
        for(int j=1;j<=c;j++) cin>>B[i][j];
     }
     q.push({0,1,1}); d[1][1]=0;
     while(!q.empty()){
       auto [cost,row,col]=q.top(); q.pop();
       if(row==r&&col==c){
         cout<<d[row][col]<<'\n'; break;
       }
       if(visited[row][col]) continue;
        visited[row][col]=true;
        for(int i=1;i<row;i++){
          if(d[row][col]+1+row-i<d[i][col]){
            d[i][col]=d[row][col]+1+row-i;  q.push({-d[i][col],i,col});
          }
        }
        if(row+1<=r&&d[row][col]+B[row][col]<d[row+1][col]){
          d[row+1][col]=d[row][col]+B[row][col];  q.push({-d[row+1][col],row+1,col});
        }
        if(col-1>=1&&d[row][col]+A[row][col-1]<d[row][col-1]){
          d[row][col-1]=d[row][col]+A[row][col-1];  q.push({-d[row][col-1],row,col-1});
        }
        if(col+1<=c&&d[row][col]+A[row][col]<d[row][col+1]){
          d[row][col+1]=d[row][col]+A[row][col];  q.push({-d[row][col+1],row,col+1});
        }
      }

 return 0;
}

#pragma GCC optimize("O3")
#pragma GCC target("avx")
#include <cstdio>
#include <functional>
#include <queue>
#include <tuple>
using namespace std;

int main() {
    int R, C;
    scanf("%d%d", &R, &C);
    int A[250000], B[250000];
    int dist[500000], seen[500000] = {0}, cost, pt, to_hide = R * C;
    int top, bottom, right, left, hide, i;
    priority_queue<pair<int, int>, vector<pair<int, int>>,
                   greater<pair<int, int>>>
        queue;
    for(i = 0; i < R * C; ++i)
        if(i % C != C - 1) scanf("%d", &A[i]);
    for(i = 0; i < (R - 1) * C; ++i) scanf("%d", &B[i]);
    for(i = 1; i < to_hide + to_hide; ++i) dist[i] = 10000000;
    queue.emplace(pair<int, int>(0, 0));
    while(!queue.empty()) {
        tie(cost, pt) = queue.top();
        queue.pop();
        seen[pt] = true;
        if(pt < to_hide) {
            left = pt - 1, right = pt + 1, top = pt + C, hide = pt + to_hide;
            if(!seen[right] && pt % C != C - 1) {
                if(cost + A[pt] < dist[pt + 1]) {
                    dist[right] = cost + A[pt];
                    queue.emplace(pair<int, int>(dist[right], right));
                }
            }
            if(!seen[left] && pt % C != 0) {
                if(cost + A[left] < dist[left]) {
                    dist[left] = cost + A[left];
                    queue.emplace(pair<int, int>(dist[left], left));
                }
            }
            if(!seen[top] && top < to_hide) {
                if(cost + B[pt] < dist[top]) {
                    dist[top] = cost + B[pt];
                    queue.emplace(pair<int, int>(dist[top], top));
                }
            }
            if(!seen[hide] && cost + 1 < dist[hide]) {
                dist[hide] = cost + 1;
                queue.emplace(pair<int, int>(dist[hide], hide));
            }
        } else {
            bottom = pt - C, hide = pt - to_hide;
            if(to_hide < bottom && !seen[bottom] && cost + 1 < dist[bottom]) {
                dist[bottom] = cost + 1;
                queue.emplace(pair<int, int>(cost + 1, bottom));
            }
            if(!seen[hide] && cost < dist[hide]) {
                dist[hide] = cost;
                queue.emplace(pair<int, int>(cost, hide));
            }
        }
    }
    printf("%d\n", dist[to_hide - 1]);
}