#include <bits/stdc++.h>

#define Fast cin.tie(0), ios::sync_with_stdio(0)
#define All(x) x.begin(), x.end()
#define louisfghbvc int t; cin >> t; for(int tt = 0; tt < t; ++tt)
#define sz(x) (int)(x).size()
#define sort_unique(x) sort(x.begin(), x.end()); x.erase(unique(x.begin(), x.end()));
using namespace std;
typedef long long LL;
typedef pair<LL, LL> ii;
typedef vector<LL> vi;

template<typename T> istream& operator>>(istream &is, vector<T> &v) { for(auto &it : v) is >> it; return is; }
template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep = ""; for(const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }

void dbg_out() { cerr << " end.\n"; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }

const int N = 5e2+5;
const int INF = 0x3f3f3f3f;
/**
Read problem statement carefully
**/
int dp[N][N];
LL A[N][N], B[N][N];

int r, c;
void solve(int x){
    memset(dp, 0x3f, sizeof dp);
    
    cin >> r >> c;
    for(int i = 1; i <= r; ++i)
        for(int j= 1; j < c; ++j)
            cin >> A[i][j];
    
    for(int i = 1; i < r; ++i)
        for(int j = 1; j <= c; ++j)
            cin >> B[i][j];

    dp[1][1] = 0;
    priority_queue<ii, vector<ii>, greater<ii>> pq;
    pq.push({0, 0});

    while(sz(pq)){
        auto [cost, idx] = pq.top(); pq.pop();
        int x = idx/c, y = idx%c;
        x++, y++;
        if(cost > dp[x][y]) continue;
        dp[x][y] = cost;
        if(y < c){
            if(dp[x][y+1] > dp[x][y] + A[x][y]){
                dp[x][y+1] = dp[x][y] + A[x][y];
                pq.push({dp[x][y+1], (x-1) * c + y});
            }
        }
        if(y > 1){
            if(dp[x][y-1] > dp[x][y] + A[x][y-1]){
                dp[x][y-1] = dp[x][y] + A[x][y-1];
                pq.push({dp[x][y-1], (x-1) * c + y - 2});
            }
        }
        if(x < r){
            if(dp[x+1][y] > dp[x][y] + B[x][y]){
                dp[x+1][y] = dp[x][y] + B[x][y];
                pq.push({dp[x+1][y], x * c + y - 1});
            }
        }
        for(int i = 1; i < r && x - i > 0; ++i){
            int ga = 1 + i;
            if(dp[x][y] + ga < dp[x-i][y]){
                dp[x-i][y] = dp[x][y] + ga;
                pq.push({dp[x-i][y], (x - i - 1) * c + y-1}); 
            }
        }
    }

    cout << dp[r][c] << "\n";
}

int main()
{
    // Fast;
    // louisfghbvc
        solve(1);
    return 0;
}

/**
Enjoy the problem.
**/

//#include <atcoder/all>
#include <iostream>
#include <numeric>
#include <cmath>
#include <limits>
#include <stdio.h>
#include <iomanip>
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <cctype> // isupper, islower, isdigit, toupper, tolower
using namespace std;
//using namespace atcoder;
using ll = long long;
#define all(A) A.begin(),A.end()
using vll = vector<ll>;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
using Graph = vector<vector<pair<ll, ll>>>;
int main(){
    ll R,C;
    cin>>R>>C;
    Graph G(2*R*C);
    rep(r,R){
        rep(c,C-1){
            ll A;
            cin>>A;
            G[r*C+c].push_back(make_pair(r*C+c+1,A));
            G[r*C+c+1].push_back(make_pair(r*C+c,A));
        }
    }
    rep(r,R-1){
        rep(c,C){
            ll A;
            cin>>A;
            G[r*C+c].push_back(make_pair((r+1)*C+c,A));
            G[R*C+(r+1)*C+c].push_back(make_pair(R*C+(r)*C+c,1));
        }
    }
    rep(r,R){
        rep(c,C){
            G[r*C+c].push_back(make_pair(R*C+r*C+c,1));
            G[R*C+r*C+c].push_back(make_pair(r*C+c,0));
        }
    }

    priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>> Q;
    vll dist(2*R*C,1e17);
    dist[0]=0;
    Q.push(make_pair(0,0));
    while(!Q.empty()){
        auto p=Q.top();
        Q.pop();
        ll v=p.second;
        for(auto q:G[v]){
            ll nv=q.first;
            if(dist[nv]<=dist[v]+q.second)continue;

            dist[nv]=dist[v]+q.second;
            Q.push(make_pair(dist[nv],nv));
        }
    }
    cout<<dist[R*C-1]<<endl;
}