// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



using i64 = long long;

using P = pair<i64, i64>;



i64 u = 50000;

i64 v = 25000;



void solve(long long H, long long W, std::vector<std::vector<long long>> A, std::vector<std::vector<long long>> B){

    i64 h = H, w = W;

    auto a = A;

    auto b  = B;

    vector<vector<vector<bool>>> dp(h, vector<vector<bool>>(w, vector<bool>(u, false)));

    for(int i = 0; i < h; ++i){

        for(int j = 0; j < w; ++j){

            i64 d = abs(a[i][j] - b[i][j]);

            if(i == 0){

                if(j == 0){

                    dp[i][j][v + d] = true;

                    dp[i][j][v - d] = true;

                }else{

                    for(int k = 0; k < u; ++k){

                        if(k - d >= 0 && dp[i][j - 1][k - d]) dp[i][j][k] = true;

                        if(k + d < u && dp[i][j - 1][k + d]) dp[i][j][k] = true;

                    }

                }

            }else{

                if(j == 0){

                    for(int k = 0; k < u; ++k){

                        if(k - d >= 0 && dp[i - 1][j][k - d]) dp[i][j][k] = true;

                        if(k + d < u && dp[i - 1][j][k + d]) dp[i][j][k] = true;

                    }

                }else{

                    for(int k = 0; k < u; ++k){

                        if(k - d >= 0 && dp[i - 1][j][k - d]) dp[i][j][k] = true;

                        if(k + d < u && dp[i - 1][j][k + d]) dp[i][j][k] = true;

                        if(k - d >= 0 && dp[i][j - 1][k - d]) dp[i][j][k] = true;

                        if(k + d < u && dp[i][j - 1][k + d]) dp[i][j][k] = true;

                    }

                }

            }

        }

    }

    i64 ans = 10000;

    for(i64 i = 0; i < u; ++i){

        if(dp[h - 1][w - 1][i]) ans = min(ans, abs(i - v));

    }

    cout << ans << endl;

}



int main(){

    long long H;

    scanf("%lld",&H);

    long long W;

    scanf("%lld",&W);

    std::vector<std::vector<long long>> A(H, std::vector<long long>(W));

    for(int i = 0 ; i < H ; i++){

        for(int j = 0 ; j < W ; j++){

            scanf("%lld",&A[i][j]);

        }

    }

    std::vector<std::vector<long long>> B(H, std::vector<long long>(W));

    for(int i = 0 ; i < H ; i++){

        for(int j = 0 ; j < W ; j++){

            scanf("%lld",&B[i][j]);

        }

    }

    solve(H, W, std::move(A), std::move(B));

    return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



using i64 = long long;

using P = pair<i64, i64>;



#define overload3(_1, _2, _3, name, ...) name

#define rep1(i, n) for(i64 i = 0LL; i < (n); ++i)

#define rep2(i, a, b) for(i64 i = (a); i < (b); ++i)

#define rep(...) overload3(__VA_ARGS__, rep2, rep1)(__VA_ARGS__)

#define all(v) v.begin(), v.end()



struct IoSetup {

    IoSetup() {

        // cin.tie(nullptr);

        // ios::sync_with_stdio(false);

        cout << fixed << setprecision(10);

        cerr << fixed << setprecision(10);

    }

} iosetup;



struct edge{

    i64 src, to, cost, t;

    edge(i64 to, i64 cost) : src(-1), to(to), cost(cost) {}

    edge(i64 src, i64 to, i64 cost) : src(src), to(to), cost(cost) {}

    bool operator <(const edge &u){

        return this->cost < u.cost;

    };

};



using Graph = vector<vector<edge>>;

const i64 INF = numeric_limits<i64>::max();



struct UnionFind

{

  vector< int > data;



  UnionFind(int sz)

  {

    data.assign(sz, -1);

  }



  bool unite(int x, int y)

  {

    x = find(x), y = find(y);

    if(x == y) return(false);

    if(data[x] > data[y]) swap(x, y);

    data[x] += data[y];

    data[y] = x;

    return(true);

  }



  int find(int k)

  {

    if(data[k] < 0) return(k);

    return(data[k] = find(data[k]));

  }



  int size(int k)

  {

    return(-data[find(k)]);

  }

};





int main(){

    i64 h, w;

    cin >> h >> w;

    vector<vector<i64>> a(h, vector<i64>(w)), b(h, vector<i64>(w));

    rep(i, h) rep(j, w) cin >> a[i][j];

    rep(i, h) rep(j, w) cin >> b[i][j];

    i64 n = 80 * 80 * 2 + 200;

    vector<vector<vector<bool>>> dp(h, vector<vector<bool>>(w, vector<bool>(n)));

    i64 geta = 80 * 80 + 100;

    dp[0][0][geta + a[0][0] - b[0][0]] = true;

    rep(i, h){

        rep(j, w){

            if(i != h - 1){

                rep(k, n){

                    i64 d = a[i + 1][j] - b[i + 1][j];

                    if(0 <= k + d && k + d <= n) dp[i + 1][j][k + d] = dp[i + 1][j][k + d] || dp[i][j][k]; 

                    if(0 <= k - d && k - d <= n) dp[i + 1][j][k - d] = dp[i + 1][j][k - d] || dp[i][j][k]; 

                }

            }

            if(j != w - 1){

                rep(k, n + 1){

                    i64 d = a[i][j + 1] - b[i][j + 1];

                    if(0 <= k + d && k + d <= n) dp[i][j + 1][k + d] = dp[i][j + 1][k + d] || dp[i][j][k]; 

                    if(0 <= k - d && k - d <= n) dp[i][j + 1][k - d] = dp[i][j + 1][k - d] || dp[i][j][k]; 

                }

            }

        }

    }

    i64 ans = n * 10;

    rep(i, n){

        if(dp[h - 1][w - 1][i]) ans = min(ans, abs(i - geta));

    }

    cout << ans << endl;

}


// Fastest known solution for this problem: