import Foundation

class Scanner {
    static func readInt() -> Int {
        return Int(readLine()!)!
    }
    
    static func readIntArr() -> [Int] {
        return readLine()!.split(separator: " ").map { Int($0)! }
    }
    
    static func readM(_ n: Int) -> [[Int]] {
        var res = [[Int]]()
        for _ in 0..<n {
            res.append(readIntArr())
        }
        return res
    }
    
    static func readUknownIntMat() -> [[Int]] {
        var res = [[Int]]()
        while let line = readLine() {
            res.append(line.split(separator: " ").map { Int($0)! })
        }
        return res
    }
    
    static func readString() -> String {
        return readLine()!
    }
}

class Printer {
    static func printIntArray(_ arr: [Int]) {
        print(arr.map { String($0) }.joined(separator: " "))
    }
}


class Solution {
    func maxBalancedPath(_ arr: [[[Int]]], _ n: Int, _ m: Int) -> Int {
        let total = 6410
        var dp = [[[Bool]]](repeating: [[Bool]](repeating: [Bool](repeating: false, count: total), count: m+1), count: n+1)
        
        for i in stride(from: 0, to: m, by: 1) {
            for j in stride(from: 0, to: total, by: 1) {
                dp[0][i][j] = true
            }
        }
        
        for i in stride(from: 0, to: n, by: 1) {
            for j in stride(from: 0, to: total, by: 1) {
                dp[i][0][j] = true
            }
        }
        
        for i in stride(from: 1, through: n, by: 1) {
            for j in stride(from: 1, through: m, by: 1) {
                let val = abs(arr[i-1][j-1][0]-arr[i-1][j-1][1])
                if  i == 1 && j == 1 {
                    dp[i][j][val] = true
                    continue
                }
                //now setting dp[i][j]
                for k in stride(from: 0, to: total, by: 1) {
                    if k + val < total {
                        dp[i][j][k+val] = (dp[i][j][k+val] || (i-1 > 0 ? dp[i-1][j][k] : false) || (j-1 > 0 ? dp[i][j-1][k] : false) )
                    }
                    if i-1 > 0 {
                        dp[i][j][k] = (dp[i][j][k] || dp[i-1][j][abs(k-val)] || (k+val < total ? dp[i-1][j][k+val] : false))
                    }
                    if j-1 > 0 {
                        dp[i][j][k] = (dp[i][j][k] || dp[i][j-1][abs(k-val)] || (k+val < total ? dp[i][j-1][k+val] : false))
                    }
                }
            }
//            print("\(i)")
        }
        
        for i in stride(from: 0, to: total, by: 1) {
            if dp[n][m][i] {
                return i
            }
        }
        return 0
    }
    
}

let nm = Scanner.readIntArr()
let fs = Scanner.readM(nm[0])
let ss = Scanner.readM(nm[0])
var mat = [[[Int]]](repeating: [[Int]](repeating: [Int](repeating: 0, count: 2), count: nm[1]), count: nm[0])
var total = 0
//print(nm[0])
//print(nm[1])
for i in 0..<nm[0] {
//    print("i: \(i)")
    var rowMax = 0
    for j in 0..<nm[1] {
        mat[i][j][0] = fs[i][j]
        mat[i][j][1] = ss[i][j]
        
        rowMax = max(rowMax, abs(fs[i][j]-ss[i][j]))
    }
    total += rowMax
}
//print(total)

print(Solution().maxBalancedPath(mat, nm[0], nm[1]))


Measured memory_bytes: 55220