#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; ++i)
typedef long long ll;
using namespace std;

struct edge {
    int to;
    int cost;
};
using P = pair<ll, ll>;
vector<vector<edge>> G;
vector<ll> d;
void dijkstra(int s) {
    priority_queue<P, vector<P>, greater<P>> que;
    fill(d.begin(), d.end(), 1e18);
    d[s] = 0;
    que.push(P(0, s));
    while (!que.empty()) {
        P p = que.top();
        que.pop();
        int v = p.second;
        if (d[v] < p.first)
            continue;
        rep(i, G[v].size()) {
            edge e = G[v][i];
            if (d[e.to] > d[v] + e.cost) {
                d[e.to] = d[v] + e.cost;
                que.push(P(d[e.to], e.to));
            }
        }
    }
}

int main() {
    int R, C;
    cin >> R >> C;
    vector<vector<int>> A(R, vector<int>(C - 1));
    vector<vector<int>> B(R - 1, 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 N = R * C * 2;
    G.resize(N);
    d.resize(N);
    rep(i, R) rep(j, C) {
        int idx = C * i + j;

        if (j + 1 != C) G[idx].push_back({idx + 1, A[i][j]});
        if (j - 1 != -1) G[idx].push_back({idx - 1, A[i][j - 1]});
        if (i + 1 != R) G[idx].push_back({idx + C, B[i][j]});
        if (i - 1 != -1) G[idx + R * C].push_back({idx + R * C - C, 1});

        G[idx].push_back({idx + R * C, 1});
        G[idx + R * C].push_back({idx, 0});
    }

    dijkstra(0);
    cout << d[R * C - 1] << endl;

    return 0;
}
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define UniqueVector(vec) sort(vec.begin(), vec.end());vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define rep(i,n) for(ll i=0;i<n;i++)

int main(){
    int a,b;
    cin>>a>>b;
    for(int c=b;c>=1;c--){
        if(b/c-(a-1)/c>=2){
            cout<<c<<endl;
            return 0;
        }
    }
}