#pragma GCC optimize("Ofast")
#include "bits/stdc++.h"
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;


/*
                     Keep trying ..!!!!
                     The journey is more important
*/

#define eprintf(...)   fprintf(stderr, __VA_ARGS__)
#define umapii unordered_map < int , int >
#define umapll unordered_map<ll,ll>
#define mapll map<ll,ll>
#define mapii map<int,int>
#define ll long long
#define pi pair<int,int>
#define pll pair<ll,ll>
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define vs vector<string>
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pi>
#define vpll vector<pll>
#define vvi vector<vi>
#define vvll vector<vll>
#define FOR(i,a,b) for(int i = a;i <= b; i++)

// debug templates 
#define debug(x)       cerr<< #x <<" : "<< x << endl;
#define debuga(A,N)    cerr<< #A <<" : [";for(int i = 0; i<N;i++) cerr<<A[i]<<" "; cerr<<"]\n";
#define debuga2(A,N,M) cerr<< #A << " : \n"; for(int i=0;i<N;i++){cerr<<"[";for(int j=0;j<M;++j) cerr<<A[i][j]<<" ";cerr<<"]\n";}
#define debugp(p)      cerr<< #p <<" : "<<"("<<(p).first<<","<<(p).second<<")\n";
#define debugv(v)      cerr<< #v <<" : "<<"[";for(int i = 0; i< (v).size(); i++) cerr<<v[i]<<" "; cerr<<"]\n";
#define debugv2(v)     cerr<< #v << " : \n"; for(int i=0;i<v.size();i++){cerr<<"[";for(int j=0;j<(v[0].size());++j) cerr<<v[i][j]<<" ";cerr<<"]\n";}
#define debugs(m)      cerr<< #m <<" : [ "; for(auto itr = m.begin(); itr!=m.end();itr++) cerr<<*itr<<" "; cerr<<"]\n";
#define debugm(m)      cerr<< #m <<" : [ "; for(auto itr = m.begin();itr!=m.end(); itr++) cerr<<"("<<itr->first<<","<<itr->second<<") ";cerr<<"]\n";

const ll mod = 1000000007;
ll modexp(ll x, ll ex) {
    ll ans = 1ll;
    while (ex > 0) {
        if (ex & 1ll) ans = (ans * x) % mod;
        ex >>= 1ll;
        x = (x * x) % mod;
    }
    return ans;
}

const int N = 81;
const int MAX = 2 * 160 * 80 + 5;
int COLL = 160 * 80;
const int inf = 1e9 + 7;
int A[N][N] , B[N][N];
int H , W;
bool dp[N][N][MAX];
int OFFSET(int k){
    return (COLL + k);
}
int main(){
    ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> H >> W;
    for(int i = 1; i <= H; i++){
       for(int j = 1; j <= W; j++){
           cin >> A[i][j];
       }
    }
    for(int i = 1; i <= H; i++){
        for(int j = 1; j <= W; j++){
            cin >> B[i][j];
        }
    }
    // dp[i][j][S] is true if it is possible to form difference S(red)-S(blue)=S
    // at position i,j

    for(int i = 1; i <= H; i++){
        for(int j = 1; j <= W; j++){
            for(int S = -COLL; S <= COLL; ++S){
                int cur = A[i][j] - B[i][j];
                int ab = OFFSET(S - cur); 
                int ba = OFFSET(S + cur);
                bool TOP = 0, LEF = 0;
                if(i - 1 >= 1) {
                    if(S - cur >= -COLL) TOP = (TOP || dp[i - 1][j][ab]);
                    if(S + cur <= COLL)  TOP = (TOP || dp[i - 1][j][ba]);
                }
                if(j - 1 >= 1) {
                    if(S - cur >= -COLL) LEF = (LEF || dp[i][j - 1][ab]);
                    if(S + cur <= COLL)  LEF = (LEF || dp[i][j - 1][ba]);
                }
                if(i == 1 && j == 1){
                    dp[i][j][OFFSET(cur)] = true; dp[i][j][OFFSET(-cur)] = true;
                } else dp[i][j][OFFSET(S)] = (TOP || LEF);
            }
        }
    }
    int mnSum = COLL+1;
    for(int S = -640; S <= 640; ++S){
        if(dp[H][W][OFFSET(S)] == true){
            // S can be obtained 
            mnSum = min(abs(S) , mnSum);
        }
    }
    cout << mnSum << '\n';
}

Measured memory_bytes: 162304