#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;

const int MAX = 550;
const int MAXM = 1e8+50;
struct Edge{
    int v, w, next;
}es[MAXM];
int head[MAX*MAX], k, n, m;
int A[MAX][MAX], B[MAX][MAX];
int id[MAX][MAX], idx;
int d[MAX*MAX];
bool vis[MAX*MAX];

void add(int u, int v, int w) {
    es[++k].next = head[u]; es[k].v = v; es[k].w = w; head[u] = k;
}

int dij() {
    fill(d, d+n*m+1, 1e7);
    priority_queue<P, vector<P>, greater<P> > q;
    q.push(P(0, 1));
    d[1] = 0;
    while (q.size()) {
        int u = q.top().second; q.pop();
        if (vis[u]) continue;
        vis[u] = true;
        //if (u == n*m) return d[u];
        for (int i = head[u]; i; i = es[i].next) {
            int v = es[i].v;
            if (!vis[v] && d[v]>d[u]+es[i].w) {
                d[v] = d[u] + es[i].w;
                q.push(P(d[v], v));
            }
        }
    }
    return d[n*m];
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) id[i][j] = ++idx;
    for (int i = 1; i <= n; i++) for (int j = 1; j < m; j++) scanf("%d", &A[i][j]);
    for (int i = 1; i < n; i++) for (int j = 1; j <= m; j++) scanf("%d", &B[i][j]);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (j > 1) {
                add(id[i][j], id[i][j-1], A[i][j-1]);
                //add(id[i][j-1], id[i][j], A[i][j-1]);
            }
            if (j < m) {
                add(id[i][j], id[i][j+1], A[i][j]);
                //add(id[i][j+1], id[i][j], A[i][j]);
            }
            if (i < n) {
                add(id[i][j], id[i+1][j], B[i][j]);
                //add(id[i+1][j], id[i][j], B[i][j]);
            }
            if (i > 1) {
                for (int k = i-1; k >= 1; k--) {
                    add(id[i][j], id[k][j], i-k+1);
                }
            }
        }
    }
    printf("%d\n", dij());
    return 0;
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
//#pragma GCC optimize ("-O3")
using namespace std;
void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     @hamayanhamayan0
　　　　／　　　＼　 　  |　|
　　　 /　　 /￣￣￣￣/　　|
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿
　 　　　＼/＿＿＿＿/　（u　⊃
---------------------------------------------------------------------------------------------------*/












int H, W, A[505][505], B[505][505];
//---------------------------------------------------------------------------------------------------
template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
int vis[505][505];
ll D[505][505];
ll dijk() {
    rep(y, 0, H) rep(x, 0, W) D[y][x] = infl;
    rep(y, 0, H) rep(x, 0, W) vis[y][x] = 0;

    min_priority_queue<pair<ll, int>> que;

    D[0][0] = 0;
    que.push({ 0, 0 });

    while (!que.empty()) {
        auto q = que.top(); que.pop();

        ll cst = q.first;
        int x = q.second % W;
        int y = q.second / W;

        if (x == W - 1 && y == H - 1) return cst;

        if (vis[y][x]) continue;
        vis[y][x] = 1;

        if (x < W - 1) if (chmin(D[y][x + 1], cst + A[y][x])) que.push({ D[y][x + 1], y * W + x + 1 });
        if (0 < x) if (chmin(D[y][x - 1], cst + A[y][x - 1])) que.push({ D[y][x - 1], y * W + x - 1 });
        if (y < H - 1) if (chmin(D[y + 1][x], cst + B[y][x])) que.push({ D[y + 1][x], (y + 1) * W + x });
        rep(dy, 1, y + 1) if (chmin(D[y - dy][x], cst + 1 + dy)) que.push({ D[y - dy][x], (y - dy) * W + x });
    }
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> H >> W;
    rep(y, 0, H) rep(x, 0, W - 1) cin >> A[y][x];
    rep(y, 0, H - 1) rep(x, 0, W) cin >> B[y][x];

    cout << dijk() << endl;
}





