#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>

using namespace std;

typedef pair<int, int> E;
const int N = 250005;
const int M = 1e8;
const int R = 505;

int n, m;
int h[N], e[M], ne[M], w[M], idx;
int dist[N];
set<E> q;

inline int id(int x, int y) {
    return (x - 1) * m + y;
}

inline void add(int a, int b, int c) {
    e[++idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx;
}

int dijkstra(int S, int T) {
    memset(dist, 0x3f, sizeof dist);
    dist[S] = 0, q.insert({0, S});
    while (q.size()) {
        int t = (*q.begin()).second;
        if (t == T) break;
        q.erase(q.begin());
        for (int i = h[t]; i; i = ne[i]) {
            if (dist[e[i]] > dist[t] + w[i]) {
                if (q.find({dist[e[i]], e[i]}) != q.end()) {
                    q.erase({dist[e[i]], e[i]});
                }
                dist[e[i]] = dist[t] + w[i];
                q.insert({dist[e[i]], e[i]});
            }
        }
    }
    return dist[T];
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1, j, x; i <= n; ++i) {
        for (j = 1; j < m; ++j) {
            scanf("%d", &x);
            add(id(i, j), id(i, j + 1), x);
            add(id(i, j + 1), id(i, j), x);
        }
    }
    for (int i = 1, j, x; i < n; ++i) {
        for (j = 1; j <= m; ++j) {
            scanf("%d", &x);
            add(id(i, j), id(i + 1, j), x);
        }
    }
    for (int x = 1; x <= n; ++x) {
        for (int y = 1; y <= m; ++y) {
            for (int r = 1; r < x; ++r) {
                add(id(x, y), id(x - r, y), r + 1);
            }
        }
    }
    printf("%d\n", dijkstra(id(1, 1), id(n, m)));
    return 0;
}
// 問題の URL を書いておく
// 

#include <bits/stdc++.h>

using namespace std;

#define ENABLE_PRINT

#if defined(ENABLE_PRINT)

#define Print(v) \
do {\
    cout << #v << ": " << v << endl; \
}while(0)

#define PrintVec(v) \
do {\
    for(int __i = 0; __i < v.size(); ++__i) \
    { \
        cout << #v << "[" << __i << "]: " << v[__i] << endl; \
    }\
}while(0)

#else

#define Print(v) ((void)0)
#define PrintVec(v) ((void)0)

#endif

#define rep(i, n) for(int i = 0; i < (int)(n); ++i)

using ll = long long;

struct D
{
    int to;
    int cost;
};

ll INF = 100100100100100100;

vector<ll> calc(int s, int vmax, vector<vector<D>>& g)
{
    vector<ll> dist(vmax, INF);
    using P = pair<int, int>;
    priority_queue<P, vector<P>, greater<P>> q;
    vector<bool> visit(vmax);
    q.push({0, s});
    while(!q.empty())
    {
        auto t = q.top();
        q.pop();
        auto index = t.second;
        auto cost = t.first;
        if(visit[index]) continue;
        visit[index] = true;
        if(cost >= dist[index]) continue;
        dist[index] = cost;
        for(auto to : g[index])
        {
            q.push({cost + to.cost, to.to});
        }
    }
    return dist;
}

int main(int, const char**)
{
    int R, C;
    cin >> R >> C;
    vector<vector<int>> A(R, vector<int>(C));
    vector<vector<int>> B(R, vector<int>(C));
    rep(i, R) rep(j, C - 1) cin >> A[i][j];
    rep(i, R - 1) rep(j, C) cin >> B[i][j];

    int vmax = R * C;

    vector<vector<D>> V(vmax * 2);
    rep(i, vmax)
    {
        auto& v = V[i];
        auto y = i / C;
        auto x = i % C;
        if(x < C - 1)
        {
            v.push_back({i + 1, A[y][x]});
        }
        if(x > 0)
        {
            v.push_back({i - 1, A[y][x - 1]});
        }
        if(y < R - 1)
        {
            v.push_back({i + C, B[y][x]});
        }
    }
    rep(i, C)
    {
        rep(j, R - 1)
        {
            auto ty = R - j - 1;
            auto toy = ty - 1;
            auto dty = ty + R;
            auto dtoy = dty - 1;

            auto& dv = V[dty * C + i];
            dv.push_back({dtoy * C + i, 1});

            auto& tdv = V[dtoy * C + i];
            tdv.push_back({toy * C + i, 1});

            auto& v = V[ty * C + i];
            v.push_back({dty * C + i, 0});
        }
    }

    auto dists = calc(0, vmax * 2, V);
#if 0
    rep(i, R)
    {
        rep(j, C)
        {
            printf("%lld ", dists[i * C + j]);
        }
        printf("\n");
    }
#endif
    cout << dists[vmax - 1] << endl;

    return 0;
}
