#include <bits/stdc++.h>

#define M_PI       3.14159265358979323846   // pi

using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef tuple<ll, ll, ll> t3;

#define rep(a,n) for(ll a = 0;a < n;a++)

static const ll INF = 1e15;
static const ll mod = 1e9+7;

template<typename T>
static inline void chmin(T& ref, const T  value) {
    if (ref > value) ref = value;
}

template<typename T>
static inline void chmax(T& ref, const T value) {
    if (ref < value) ref = value;
}

struct MaxFlowCalculator {
	int max_flow(int s, int t, const vector<vector<pair<int, int>>>& g) {
		struct edge_ { int to, cap, rev; };
		vector<bool> used(g.size(), false);
		vector<vector<edge_>> G(g.size());
		for (int i = 0; i < g.size(); i++) for (int j = 0; j < g[i].size(); j++)
		{
			int from = i, to = g[i][j].second;
			int cap = g[i][j].first;
			G[from].push_back({ to, cap, (int)G[to].size() });
			G[to].push_back({ from, 0, (int)G[from].size() - 1 });
		}
		auto dfs = [&](auto&& f, int v, int t, int fl)->int {
			if (v == t) return fl;
			used[v] = true;
			rep(i, G[v].size()) {
				edge_& e = G[v][i];
					if (!used[e.to] && e.cap > 0) {
					int d = f(f, e.to, t, min(fl, e.cap));
					if (d > 0) {
						e.cap -= d;
						G[e.to][e.rev].cap += d;
						return d;
					}
				}
			}
			return 0;
		};
		int flow = 0;
		while (1) {
			used.assign(used.size(), false);
			int f = dfs(dfs, s, t, INT_MAX);
			if (f == 0) return flow;
			flow += f;
		}
	}
};

class modint {
	static constexpr std::int_fast64_t Modulus = 1e9 + 7;
	using u64 = std::int_fast64_t;

public:
	u64 a;
	constexpr modint(const u64 x = 0) noexcept : a(x% Modulus) {}
	constexpr u64& value() noexcept { return a; }
	constexpr const u64& value() const noexcept { return a; }
	constexpr modint operator+(const modint rhs) const noexcept {
		return modint(*this) += rhs;
	}
	constexpr modint operator-(const modint rhs) const noexcept {
		return modint(*this) -= rhs;
	}
	constexpr modint operator*(const modint rhs) const noexcept {
		return modint(*this) *= rhs;
	}
	constexpr modint operator*(const ll rhs) const noexcept {
		return modint(*this) *= rhs;
	}
	constexpr modint& operator+=(const modint rhs) noexcept {
		a += rhs.a;
		if (a >= Modulus) {
			a -= Modulus;
		}
		return *this;
	}
	constexpr modint& operator-=(const modint rhs) noexcept {
		if (a < rhs.a) {
			a += Modulus;
		}
		a -= rhs.a;
		return *this;
	}
	constexpr modint& operator*=(const modint rhs) noexcept {
		a = a * rhs.a % Modulus;
		return *this;
	}
	constexpr operator u64() const { return a; }
};

template<int N>
void shift(bitset<N>& dest, bitset<N> source, int diff) {
	if (diff >= 0) {
		dest |= source << diff;
	}
	else {
		dest |= source >> (-diff);
	}
}

int main() {
	int h, w;
	cin >> h >> w;
	vector<vector<int>> as(h, vector<int>(w));
	vector<vector<int>> bs(h, vector<int>(w));
	rep(i, h) {
		rep(j, w) {
			cin >> as[i][j];
		}
	}
	rep(i, h) {
		rep(j, w) {
			cin >> bs[i][j];
		}
	}
	vector<vector<bitset<160 * 200>>> grid(h, vector<bitset<160 * 200>>(w));
	const int zero = 80 * 200;
	grid[0][0].set(zero + as[0][0] - bs[0][0]);
	grid[0][0].set(zero + bs[0][0] - as[0][0]);
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			if (i < h-1) {				
				shift<32000>(grid[i + 1][j],grid[i][j],(as[i + 1][j] - bs[i + 1][j]));
				shift<32000>(grid[i + 1][j], grid[i][j], (bs[i + 1][j] - as[i + 1][j]));
			}
			if (j < w - 1) {
				shift<32000>(grid[i][j+1], grid[i][j], (as[i][j+1] - bs[i][j+1]));
				shift<32000>(grid[i][j+1], grid[i][j], (bs[i][j+1] - as[i][j+1]));
			}
		}
	}
	int u = 1e6;
	for (int i = 0; i < 160 * 200;i++) {
		if (grid[h - 1][w - 1].test(i)) {
			chmin(u, abs(zero - i));
		}
	}
	cout << u << endl;
    return 0;
}


Measured memory_bytes: 28860