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



#define M_PI       3.14159265358979323846   // pi



using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef vector<int> VI;

typedef pair<ll, ll> P;



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

#define repi(a,b,n) for(int a = b;a < n;a++)



const ull mod = 1000000007;



int main(void)

{

	ll h, w;

	cin >> h >> w;

	vector<vector<ll>> r(h, vector<ll>(w));

	vector<vector<ll>> b(h, vector<ll>(w));

	vector<vector<ll>> diff(h, vector<ll>(w));

	rep(i, h) {

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

	}

	rep(i, h) {

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

	}

	rep(i, h) {

		rep(j, w) diff[i][j] = abs(r[i][j] - b[i][j]);

	}

	vector<vector<vector<int>>> visit(h,vector<vector<int>>(w,vector<int>(12800, 0)));

	visit[0][0][diff[0][0]] = true;

	for (int y = 1; y < h;y++) {

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

			auto e = visit[y-1][0][k];

			if (e) {

				visit[y][0][k + diff[y][0]] = true;

				visit[y][0][abs(k - diff[y][0])] = true;

			}

		}

	}

	for (int x = 1; x < w; x++) {

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

			auto e = visit[0][x - 1][k];

			if(e){

				visit[0][x][k + diff[0][x]] = true;

				visit[0][x][abs(k - diff[0][x])] = true;

			}

		}

	}

	for (int y = 1; y < h; y++) {

		for (int x = 1; x < w; x++) {

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

				auto e = visit[y][x - 1][k];

				if (e) {

					visit[y][x][k + diff[y][x]] = true;

					visit[y][x][abs(k - diff[y][x])] = true;

				}

			}

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

				auto e = visit[y - 1][x][k];

				if (e) {

					visit[y][x][k + diff[y][x]] = true;

					visit[y][x][abs(k - diff[y][x])] = true;

				}

			}

		}

	}

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

		auto e = visit[h - 1][w - 1][k];

		if(e){

			cout << k << endl;

			return 0;

		}

	}

	return 0;

}


// Optimized solution to the same problem (faster):


#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;

}


// Fastest known solution for this problem: