#include<bits/stdc++.h>
#define fr first
#define sc second
#define ll long long


using namespace std;

#define sim template < class c

#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

//
//#define MAX_N 1000010
//// second approach: O(n log n)
//struct SuffixArray {
//    char T[MAX_N]; // the input string, up to 100K characters
//    int n;  // the length of input string
//    int RA[MAX_N], tempRA[MAX_N]; // rank array and temporary rank array
//    int SA[MAX_N], tempSA[MAX_N]; // suffix array and temporary suffix array
//    int c[MAX_N]; // for counting/radix sort
//    int Phi[MAX_N], PLCP[MAX_N], LCP[MAX_N];
//    int RSA[MAX_N]; int ST[20][MAX_N];
//    int largestBit[MAX_N];
//    SuffixArray(){ }
//    SuffixArray(string s){
//        n = s.size(); // input T as per normal, without the ‘$’
//        for(int i = 0; i < n; i++) T[i] = s[i];
//        T[n++] = 1; // add terminating character
//        constructSA(); computeLCP();
//    }
//    void countingSort(int k) { // O(n)
//        int i, sum, maxi = max(300, n); // up to 255 ASCII chars or length of n
//        memset(c, 0, sizeof c); // clear frequency table
//        for (i = 0; i < n; i++) // count the frequency of each integer rank
//            c[i + k < n ? RA[i + k] : 0]++;
//            for (i = sum = 0; i < maxi; i++) {
//                    int t = c[i];
//                    c[i] = sum;
//                    sum += t;
//            }
//            for (i = 0; i < n; i++) // shuffle the suffix array if necessary
//                tempSA[c[SA[i] + k < n < n ? RA[SA[i] + k] : 0]++] = SA[i];
//            for (i = 0; i < n; i++) // update the suffix array SA
//                SA[i] = tempSA[i];
//    }
//    void constructSA() { // this version can go up to 100000 characters
//            int i, k, r;
//            for (i = 0; i < n; i++)
//                RA[i] = T[i]; // initial rankings
//            for (i = 0; i < n; i++)
//                SA[i] = i; // initial SA: {0, 1, 2, ..., n-1}
//            for (k = 1; k < n; k <<= 1) { // repeat sorting process log n times
//                countingSort(k); // actually radix sort: sort based on the second item
//                countingSort(0); // then (stable) sort based on the first item
//                tempRA[SA[0]] = r = 0; // re-ranking; start from rank r = 0
//                for (i = 1; i < n; i++) // compare adjacent suffixes
//                    tempRA[SA[i]] = // if same pair => same rank r; otherwise, increase r
//                    (RA[SA[i]] == RA[SA[i - 1]] && RA[SA[i] + k] == RA[SA[i - 1] + k]) ? r : ++r;
//                for (i = 0; i < n; i++) // update the rank array RA
//                    RA[i] = tempRA[i];
//                if (RA[SA[n - 1]] == n - 1)
//                    break;
//                    // nice optimization trick
//            }
//        }
//        void precalcLCP(){ // construct sparse table
//            for(int k = 0; k < 20; k++){
//                    for(int i = 0; i < n; i++) {
//                        if (!k) { ST[k][i] = LCP[i]; continue; }
//                        ST[k][i] = min(ST[k - 1][i], ST[k - 1][i + (1 << (k - 1))]);
//                        }
//                }
//            for(int i = 0; i < n; i++){ RSA[SA[i]] = i; } // precalc largest active bit for every mask
//            int cnt = 1, b = 0;
//            for(int mask = 1; mask < MAX_N; mask++){
//                    largestBit[mask] = b;
//                    if(mask == cnt) cnt *= 2, b++;
//            }
//        }
//        void computeLCP() {
//            int i, L; Phi[SA[0]] = -1; // default value
//            for (i = 1; i < n; i++) // compute Phi in O(n)
//                Phi[SA[i]] = SA[i - 1]; // remember which suffix is behind this suffix
//            for (i = L = 0; i < n; i++) { // compute Permuted LCP in O(n)
//                    if (Phi[i] == -1) { PLCP[i] = 0; continue; } // special case
//                    while (T[i + L] == T[Phi[i] + L]) L++; // L increased max n times
//                        PLCP[i] = L; L = max(L - 1, 0); // L decreased max n times
//             }
//             for (i = 0; i < n; i++) { // compute LCP in O(n)
//                    LCP[i] = PLCP[SA[i]]; // put the permuted LCP to the correct position
//             }
//             precalcLCP();
//        } // returns the Longest Common Prefix between suffixes starting at indices i and j
//        int lcp(int i, int j){
//            i = RSA[i], j = RSA[j];
//            if(i > j) swap(i, j);
//            i++;
//            int len = j - i + 1;
//            int b = largestBit[len];
//            int ans = min(ST[b][i], ST[b][j - (1 << b) + 1]);
//            return ans;
//        }
//};

//int lps[int(1e6 + 100)];
//
//void longestPrefixSuffix(string s)
//{
//    int n = s.length();
//
//    lps[0] = 0;
//
//    int len = 0;
//
//    int i = 1;
//    while (i < n)
//    {
//        if (s[i] == s[len])
//        {
//            len++;
//            lps[i] = len;
//            i++;
//        }
//        else
//        {
//            if (len != 0)
//            {
//                len = lps[len-1];
//
//            }
//            else
//            {
//                lps[i] = 0;
//                i++;
//            }
//        }
//    }
//}


const int MaxN = 82;

short A[MaxN][MaxN] , B[MaxN][MaxN] , N , M;

bool Dp[MaxN][MaxN][MaxN * MaxN * 2];


int main(){

     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
//
//     string Password;  cin >> Password;
//
//     int Length = Password.size();
//
//     longestPrefixSuffix(Password);
//
//     int tol = lps[Length - 1];
//
//     int ans = 0;
//
//     for(int i = 1;i < Length - 1;i++)
//        ans = max(ans ,min(lps[i] , tol));
//
//     if(ans == 0)
//        cout << "Just a legend\n";
//    else{
//        for(int i = 0;i < ans ;i++)
//            cout << Password[i];
//        cout << "\n";
//    }


    cin >> N >> M;

    N-- , M--;

    for(int i = 0;i <= N;i++)
        for(int j = 0;j <= M ;j++ )
            cin >> A[i][j];
    for(int i = 0;i <= N;i++)
        for(int j = 0;j <= M ;j++ )
            cin >> B[i][j];
    Dp[N + 1][M][0] = 1;
    Dp[N][M + 1][0] = 1;
    int MMM = 80 * 80 * 2;
    for(short I = N;I >= 0;I--)
        for(short J = M;J >= 0;J--)
        {
            for(short k = 0;k <= MMM ;k++)
            {

                short i = I + 1 , j = J ;
                short Sum1 = abs(k + abs(A[I][J] - B[I][J])) , Sum2 = abs(k - abs(A[I][J] - B[I][J]));
                Dp[I][J][k] |= Dp[i][j][Sum1];

                Dp[I][J][k] |= Dp[i][j][Sum2];

                i = I , j = J + 1;

                Dp[I][J][k] |= Dp[i][j][Sum1];

                Dp[I][J][k] |= Dp[i][j][Sum2];
            }
        }
    for(int i = 0;i <= MMM ;i++)
        if(Dp[0][0][i])
            return cout << i << '\n' , 0;

    return 0;
}


Measured memory_bytes: 88320