pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
impl<'a> Scanner<'a> {
    #[inline]
    pub fn new(s: &'a str) -> Self {
        let iter = s.split_ascii_whitespace();
        Self { iter }
    }
    #[inline]
    pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
        T::scan(&mut self.iter).unwrap()
    }
    #[inline]
    pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
        marker.mscan(&mut self.iter).unwrap()
    }
    #[inline]
    pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
        (0..size)
            .map(|_| T::scan(&mut self.iter).unwrap())
            .collect()
    }
    #[inline]
    pub fn scan_chars(&mut self) -> Vec<char> {
        self.iter.next().unwrap().chars().collect::<Vec<char>>()
    }
    #[inline]
    pub fn scan_chars_with(&mut self, base: char) -> Vec<usize> {
        self.iter
            .next()
            .unwrap()
            .chars()
            .map(|c| (c as u8 - base as u8) as usize)
            .collect::<Vec<usize>>()
    }
}
mod scanner_impls {
    use super::*;
    macro_rules !iter_scan_impls {($($t :ty ) *) =>{$(impl IterScan for $t {type Output =Self ;#[inline ] fn scan <'a ,I :Iterator <Item =&'a str >>(iter :&mut I ) ->Option <Self >{iter .next () ?.parse ::<$t >() .ok () } } ) *} ;}
    iter_scan_impls !(char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String ) ;
    macro_rules !iter_scan_tuple_impl {($($T :ident ) *) =>{impl <$($T :IterScan ) ,*>IterScan for ($($T ,) *) {type Output =($(<$T as IterScan >::Output ,) *) ;#[inline ] fn scan <'a ,It :Iterator <Item =&'a str >>(_iter :&mut It ) ->Option <Self ::Output >{Some (($($T ::scan (_iter ) ?,) *) ) } } } ;}
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl !(A B ) ;
    iter_scan_tuple_impl !(A B C ) ;
    iter_scan_tuple_impl !(A B C D ) ;
    iter_scan_tuple_impl !(A B C D E ) ;
    iter_scan_tuple_impl !(A B C D E F ) ;
    iter_scan_tuple_impl !(A B C D E F G ) ;
    iter_scan_tuple_impl !(A B C D E F G H ) ;
    iter_scan_tuple_impl !(A B C D E F G H I ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J K ) ;
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        fn next(&mut self) -> Option<Self::Item> {
            T::scan(&mut self.inner.iter)
        }
    }
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
}
pub mod marker {
    use super::*;
    pub struct Usize1;
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            usize::scan(iter).map(|x| x.wrapping_sub(1))
        }
    }
    pub struct Isize1;
    impl IterScan for Isize1 {
        type Output = isize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            isize::scan(iter).map(|x| x.wrapping_sub(1))
        }
    }
}
#[macro_export]
macro_rules !min {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::min ($e ,min !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmin {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::min ($dst ,min !($($src ) ,+) ) ;$dst =x ;} } ;}
#[macro_export]
macro_rules !max {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::max ($e ,max !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmax {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::max ($dst ,max !($($src ) ,+) ) ;$dst =x ;} } ;}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BitSet {
    size: usize,
    bits: Vec<u64>,
}
impl BitSet {
    pub fn new(size: usize) -> Self {
        Self {
            size,
            bits: vec![0; (size + 63) / 64],
        }
    }
    pub fn ones(size: usize) -> Self {
        let mut self_ = Self {
            size,
            bits: vec![std::u64::MAX; (size + 63) / 64],
        };
        self_.trim();
        self_
    }
    #[inline]
    pub fn get(&self, i: usize) -> bool {
        self.bits[i >> 6] & 1 << (i & 63) != 0
    }
    #[inline]
    pub fn set(&mut self, i: usize, b: bool) {
        if b {
            self.bits[i >> 6] |= 1 << (i & 63);
        } else {
            self.bits[i >> 6] &= !(1 << (i & 63));
        }
    }
    #[inline]
    pub fn count_ones(&self) -> u64 {
        self.bits.iter().map(|x| x.count_ones() as u64).sum()
    }
    #[inline]
    pub fn count_zeros(&self) -> u64 {
        self.size as u64 - self.count_ones()
    }
    #[inline]
    fn trim(&mut self) {
        if self.size & 63 != 0 {
            if let Some(x) = self.bits.last_mut() {
                *x &= 0xffffffffffffffff >> 64 - (self.size & 63);
            }
        }
    }
    #[inline]
    pub fn shl_bitor_assign(&mut self, rhs: usize) {
        let n = self.bits.len();
        let k = rhs >> 6;
        let d = rhs & 63;
        if k < n {
            if d == 0 {
                for i in (0..n - k).rev() {
                    self.bits[i + k] |= self.bits[i];
                }
            } else {
                for i in (1..n - k).rev() {
                    self.bits[i + k] |= self.bits[i] << d | self.bits[i - 1] >> 64 - d;
                }
                self.bits[k] |= self.bits[0] << d;
            }
            self.trim();
        }
    }
    #[inline]
    pub fn shr_bitor_assign(&mut self, rhs: usize) {
        let n = self.bits.len();
        let k = rhs >> 6;
        let d = rhs & 63;
        if k < n {
            if d == 0 {
                for i in k..n {
                    self.bits[i - k] |= self.bits[i];
                }
            } else {
                for i in k..n - 1 {
                    self.bits[i - k] |= self.bits[i] >> d | self.bits[i + 1] << 64 - d;
                }
                self.bits[n - k - 1] |= self.bits[n - 1] >> d;
            }
        }
    }
}
impl std::ops::ShlAssign<usize> for BitSet {
    #[inline]
    fn shl_assign(&mut self, rhs: usize) {
        let n = self.bits.len();
        let k = rhs >> 6;
        let d = rhs & 63;
        if k >= n {
            for x in self.bits.iter_mut() {
                *x = 0;
            }
        } else {
            if d == 0 {
                for i in (0..n - k).rev() {
                    self.bits[i + k] = self.bits[i];
                }
            } else {
                for i in (1..n - k).rev() {
                    self.bits[i + k] = self.bits[i] << d | self.bits[i - 1] >> 64 - d;
                }
                self.bits[k] = self.bits[0] << d;
            }
            for x in self.bits[..k].iter_mut() {
                *x = 0;
            }
            self.trim();
        }
    }
}
impl std::ops::Shl<usize> for BitSet {
    type Output = Self;
    #[inline]
    fn shl(mut self, rhs: usize) -> Self::Output {
        self <<= rhs;
        self
    }
}
impl std::ops::ShrAssign<usize> for BitSet {
    #[inline]
    fn shr_assign(&mut self, rhs: usize) {
        let n = self.bits.len();
        let k = rhs >> 6;
        let d = rhs & 63;
        if k >= n {
            for x in self.bits.iter_mut() {
                *x = 0;
            }
        } else {
            if d == 0 {
                for i in k..n {
                    self.bits[i - k] = self.bits[i];
                }
            } else {
                for i in k..n - 1 {
                    self.bits[i - k] = self.bits[i] >> d | self.bits[i + 1] << 64 - d;
                }
                self.bits[n - k - 1] = self.bits[n - 1] >> d;
            }
            for x in self.bits[n - k..].iter_mut() {
                *x = 0;
            }
        }
    }
}
impl std::ops::Shr<usize> for BitSet {
    type Output = Self;
    #[inline]
    fn shr(mut self, rhs: usize) -> Self::Output {
        self >>= rhs;
        self
    }
}
impl<'a> std::ops::BitOrAssign<&'a BitSet> for BitSet {
    #[inline]
    fn bitor_assign(&mut self, rhs: &'a Self) {
        for (l, r) in self.bits.iter_mut().zip(rhs.bits.iter()) {
            *l |= *r;
        }
        self.trim();
    }
}
impl<'a> std::ops::BitOr<&'a BitSet> for BitSet {
    type Output = Self;
    #[inline]
    fn bitor(mut self, rhs: &'a Self) -> Self::Output {
        self |= rhs;
        self
    }
}
impl<'a, 'b> std::ops::BitOr<&'b BitSet> for &'a BitSet {
    type Output = BitSet;
    #[inline]
    fn bitor(self, rhs: &'b BitSet) -> Self::Output {
        let mut res = self.clone();
        res |= rhs;
        res
    }
}
impl<'a> std::ops::BitAndAssign<&'a BitSet> for BitSet {
    #[inline]
    fn bitand_assign(&mut self, rhs: &'a Self) {
        for (l, r) in self.bits.iter_mut().zip(rhs.bits.iter()) {
            *l &= *r;
        }
    }
}
impl<'a> std::ops::BitAnd<&'a BitSet> for BitSet {
    type Output = Self;
    #[inline]
    fn bitand(mut self, rhs: &'a Self) -> Self::Output {
        self &= rhs;
        self
    }
}
impl<'a, 'b> std::ops::BitAnd<&'b BitSet> for &'a BitSet {
    type Output = BitSet;
    #[inline]
    fn bitand(self, rhs: &'b BitSet) -> Self::Output {
        let mut res = self.clone();
        res &= rhs;
        res
    }
}
impl<'a> std::ops::BitXorAssign<&'a BitSet> for BitSet {
    #[inline]
    fn bitxor_assign(&mut self, rhs: &'a Self) {
        for (l, r) in self.bits.iter_mut().zip(rhs.bits.iter()) {
            *l ^= *r;
        }
        self.trim();
    }
}
impl<'a> std::ops::BitXor<&'a BitSet> for BitSet {
    type Output = Self;
    #[inline]
    fn bitxor(mut self, rhs: &'a Self) -> Self::Output {
        self ^= rhs;
        self
    }
}
impl<'a, 'b> std::ops::BitXor<&'b BitSet> for &'a BitSet {
    type Output = BitSet;
    #[inline]
    fn bitxor(self, rhs: &'b BitSet) -> Self::Output {
        let mut res = self.clone();
        res ^= rhs;
        res
    }
}
impl std::ops::Not for BitSet {
    type Output = Self;
    #[inline]
    fn not(mut self) -> Self::Output {
        for x in self.bits.iter_mut() {
            *x = !*x;
        }
        self.trim();
        self
    }
}
impl<'a> std::ops::Not for &'a BitSet {
    type Output = BitSet;
    #[inline]
    fn not(self) -> Self::Output {
        !self.clone()
    }
}
fn main() {
    #[allow(unused_imports)]
    use std::io::{Read as _, Write as _};
    let __out = std::io::stdout();
    let mut __in_buf = String::new();
    std::io::stdin().read_to_string(&mut __in_buf).unwrap();
    let mut scanner = Scanner::new(&__in_buf);
    #[allow(unused_macros)]
    macro_rules !scan {() =>{scan !(usize ) } ;(($($t :tt ) ,*) ) =>{($(scan !($t ) ) ,*) } ;([$t :tt ;$len :expr ] ) =>{(0 ..$len ) .map (|_ |scan !($t ) ) .collect ::<Vec <_ >>() } ;({chars :$b :expr } ) =>{scanner .scan_chars_with ($b ) } ;({$t :tt =>$f :expr } ) =>{$f (scan !($t ) ) } ;(chars ) =>{scanner .scan_chars () } ;($t :ty ) =>{scanner .scan ::<$t >() } ;}
    let mut __out = std::io::BufWriter::new(__out.lock());
    #[allow(unused_macros)]
    macro_rules !print {($($arg :tt ) *) =>(::std ::write !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules !println {($($arg :tt ) *) =>(::std ::writeln !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules! echo {
        ($iter :expr ) => {
            echo!($iter, "\n")
        };
        ($iter :expr ,$sep :expr ) => {
            let mut iter = $iter.into_iter();
            if let Some(item) = iter.next() {
                print!("{}", item);
            }
            for item in iter {
                print!("{}{}", $sep, item);
            }
            println!();
        };
    }
    fn abs(x: usize, y: usize) -> usize {
        if x > y {
            x - y
        } else {
            y - x
        }
    }
    let h = scan!();
    let w = scan!();
    let a = scan!([[usize; w]; h]);
    let b = scan!([[usize; w]; h]);
    let c = (0..h)
        .map(|i| (0..w).map(|j| abs(a[i][j], b[i][j])).collect::<Vec<_>>())
        .collect::<Vec<_>>();
    let m = (h + w + 2) * 80;
    let mut dp = vec![vec![BitSet::new(m); w]; h];
    dp[0][0].set(c[0][0], true);
    for i in 0..h {
        for j in 0..w {
            for k in 0..m {
                if dp[i][j].get(k) {
                    if i + 1 < h {
                        dp[i + 1][j].set(k + c[i + 1][j], true);
                        dp[i + 1][j].set(abs(k, c[i + 1][j]), true);
                    }
                    if j + 1 < w {
                        dp[i][j + 1].set(k + c[i][j + 1], true);
                        dp[i][j + 1].set(abs(k, c[i][j + 1]), true);
                    }
                }
            }
        }
    }
    for k in 0..m {
        if dp[h - 1][w - 1].get(k) {
            println!("{}", k);
            return;
        }
    }
}

Measured memory_bytes: 12796