#[allow(unused_imports)]
use std::cmp::{max, min};
use std::io::{stdin, stdout, BufWriter, Write};

const K: usize = 7000;

fn main() {
    let stdin_obj = stdin();
    let mut scan = Scanner {
        stdin: stdin_obj.lock(),
    };
    let out = &mut BufWriter::new(stdout());

    let n: usize = scan.read();
    let m: usize = scan.read();
    let mut a: Vec<Vec<i32>> = vec![];
    let mut b: Vec<Vec<i32>> = vec![];
    for _ in 0..n {
        a.push(scan.read_vec(m));
    }
    for _ in 0..n {
        b.push(scan.read_vec(m));
    }

    let mut dp: Vec<Vec<Vec<bool>>> = vec![vec![vec![false; 2 * K as usize]; m]; n];

    for i in 0..n {
        for j in 0..m {
            if i == 0 && j == 0 {
                dp[i][j][(K as i32 + a[i][j] - b[i][j]) as usize] = true;
                continue;
            }
            for k in 0..2 * K {
                let new_index_1 = (k as i32 + a[i][j] - b[i][j]) as usize;
                if k as i32 + a[i][j] - b[i][j] >= 0 && new_index_1 < dp[i][j].len() {
                    if i > 0 {
                        dp[i][j][new_index_1] |= dp[i - 1][j][k as usize];
                    }
                    if j > 0 {
                        dp[i][j][new_index_1] |= dp[i][j - 1][k as usize];
                    }
                }

                let new_index_2 = (k as i32 + b[i][j] - a[i][j]) as usize;
                if k as i32 + b[i][j] - a[i][j] >= 0 && new_index_2 < dp[i][j].len() {
                    if i > 0 {
                        dp[i][j][new_index_2] |= dp[i - 1][j][k as usize];
                    }
                    if j > 0 {
                        dp[i][j][new_index_2] |= dp[i][j - 1][k as usize];
                    }
                }
            }
        }
    }

    for k in 0..K {
        if dp[n - 1][m - 1][K + k] || dp[n - 1][m - 1][K - k] {
            writeln!(out, "{}", k).ok();
            return;
        }
    }
}

#[derive(Default)]
pub struct Scanner<R> {
    stdin: R,
}
impl<R: std::io::Read> Scanner<R> {
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .stdin
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn read_line(&mut self) -> String {
        use std::io::Read;
        let buf = self
            .stdin
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b'\n' || b == b'\r')
            .take_while(|&b| b != b'\n' && b != b'\r')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn read_vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn read_chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}


Measured memory_bytes: 96508