#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#define len(X) ((int)(X).size())

#ifdef __LOCAL
#define DBG(X) cout << #X << "=" << (X) << '\n';
#define SAY(X) cout << (X) << '\n';
#else
#define DBG(X)
#define SAY(X)
#endif

#define M_PI       3.14159265358979323846

using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

const int INT_INF = (int)(2e9);
const ll  LL_INF = (ll)(2e18);

const int NIL = -1;
static mt19937 _g(time(nullptr));

std::string pad(int num)
{
    char buffer[4];
    std::snprintf(buffer, sizeof(buffer), "%03d", num);
    return buffer;
}

inline ll randint(ll a, ll b) { ll w = (_g() << 31LL) ^ _g(); return a + w % (b - a + 1); }
inline void fast_io() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); };
template<typename T> inline T sign(T x) { return T(x > 0) - T(x < 0); }
template<typename T, typename S> inline ostream& operator<<(ostream& os, const pair<T, S> p) { cout << "[" << p.first << ";" << p.second << "]"; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const vector<T>& v) { for (auto el : v) cout << el << " "; return os; }
template<typename T> inline T fetch() { T ret; cin >> ret; return ret; }
template<typename T> inline vector<T> fetch_vec(int sz) { vector<T> ret(sz); for (auto& elem : ret) cin >> elem; return ret; }

void rec(int r, int c, int rows, int cols, int red, int blue, int& bestDiff, vector<vector<vector<int>>>& grid,
         vector<vector<vector<bool>>>& visited)
{
    if (r == rows - 1 && c == cols - 1)
    {
        int diff = std::min(std::abs((red + grid[r][c][0]) - (blue + grid[r][c][1])),
            std::abs((red + grid[r][c][1]) - (blue + grid[r][c][0])));

        if (diff < bestDiff)
            bestDiff = diff;

        return;
    }

    if (visited[r][c][std::abs(red - blue)]) return;

    if (r + 1 < rows)
    {
        rec(r + 1, c, rows, cols, red + grid[r][c][0], blue + grid[r][c][1], bestDiff, grid, visited);
        rec(r + 1, c, rows, cols, red + grid[r][c][1], blue + grid[r][c][0], bestDiff, grid, visited);
    }

    if (c + 1 < cols)
    {
        rec(r, c + 1, rows, cols, red + grid[r][c][0], blue + grid[r][c][1], bestDiff, grid, visited);
        rec(r, c + 1, rows, cols, red + grid[r][c][1], blue + grid[r][c][0], bestDiff, grid, visited);
    }

    visited[r][c][std::abs(red - blue)] = true;
}


int solve()
{
    int H, W;
    cin >> H >> W;

    const int maxCol = 80*80*80 + 1;

    vector<vector<vector<int>>> grid(H, vector<vector<int>>(W, vector<int>(2, 0)));

    for (int i = 0; i < H; ++i)
        for (int j = 0; j < W; ++j)
            cin >> grid[i][j][0];
    
    for (int i = 0; i < H; ++i)
        for (int j = 0; j < W; ++j)
            cin >> grid[i][j][1];


    vector<vector<vector<bool>>> visited(H, vector<vector<bool>>(W, vector<bool>(maxCol, false)));

    int bestDiff = std::numeric_limits<int>::max();

    rec(0, 0, H, W, 0, 0, bestDiff, grid, visited);

    cout << bestDiff << endl;

    return 0;
}

int main()
{
    solve();

    return 0;
}

Measured memory_bytes: 408064