@file:Suppress("DuplicatedCode")

import java.io.IOException
import java.io.InputStream
import java.io.PrintWriter
import java.lang.Math.min
import java.util.*

fun main(args: Array<String>) {
    PrintWriter(System.out).use { out ->
        E.solve(E.FastScanner(), out)
        out.flush()
    }
}

private fun E.solve(sc: E.FastScanner, out: PrintWriter) {
    val h = sc.nextInt()
    val w = sc.nextInt()
    val a = Array(h) { sc.readIntArray(w) }
    val b = Array(h) { sc.readIntArray(w) }

    val mid = (h + w) * 80
    val diff = Array(h) { i -> IntArray(w) { j -> a[i][j] - b[i][j] } }

    fun newBitset() = E.BitSet(mid * 2 + 1)

    val tmp = Array(w) { newBitset() }
    tmp[0][diff[0][0] + mid] = true

    for (width in 1 until w) {
        val bs = tmp[width]

        tmp[width - 1].trueIterator().forEach {
            bs[it + diff[0][width]] = true
            bs[it - diff[0][width]] = true
        }
    }

    for (height in 1 until h) {
        val bs = newBitset()
        tmp[0].trueIterator().forEach {
            bs[it + diff[height][0]] = true
            bs[it - diff[height][0]] = true
        }
        tmp[0] = bs

        for (width in 1 until w) {
            val bs = newBitset()

            tmp[width].or(tmp[width - 1])

            tmp[width].trueIterator().forEach {
                bs[it + diff[height][width]] = true
                bs[it - diff[height][width]] = true
            }

            tmp[width] = bs
        }
    }

    val ans = tmp[w - 1]

    val next = ans.trueIterator(mid).next() - mid
    val prev = mid - ans.trueIteratorReversed(mid).next()
    if (next < 0) {
        println(prev)
    } else {
        println(min(next, prev))
    }
}

@Suppress("MemberVisibilityCanBePrivate")
private object E {
    private const val zeroCode = '0'.toInt()
    private const val nineCode = '9'.toInt()

    class FastScanner {
        private val `in`: InputStream = System.`in`
        private val buffer = ByteArray(1024)
        private var ptr = 0
        private var buflen = 0
        private fun hasNextByte(): Boolean {
            if (ptr < buflen) {
                return true
            } else {
                ptr = 0
                try {
                    buflen = `in`.read(buffer)
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                if (buflen <= 0) {
                    return false
                }
            }
            return true
        }

        private fun readByte(): Int {
            return if (hasNextByte()) buffer[ptr++].toInt() else -1
        }

        operator fun hasNext(): Boolean {
            while (hasNextByte() && !isPrintableChar(buffer[ptr].toInt())) ptr++
            return hasNextByte()
        }

        operator fun next(): String {
            if (!hasNext()) throw NoSuchElementException()

            return buildString {
                var b = readByte()

                while (isPrintableChar(b)) {
                    appendCodePoint(b)
                    b = readByte()
                }
            }
        }

        fun nextLong(): Long {
            if (!hasNext()) throw NoSuchElementException()
            var n: Long = 0
            var minus = false
            var b = readByte()

            if (b == '-'.toInt()) {
                minus = true
                b = readByte()
            }

            if (b !in zeroCode..nineCode) {
                throw NumberFormatException()
            }

            while (true) {
                if (b in zeroCode..nineCode) {
                    n *= 10
                    n += b - zeroCode.toLong()
                } else if (b == -1 || !isPrintableChar(b)) {
                    return if (minus) -n else n
                } else {
                    throw NumberFormatException()
                }

                b = readByte()
            }
        }

        fun nextInt(): Int {
            val nl = nextLong()
            if (nl < Int.MIN_VALUE || nl > Int.MAX_VALUE) throw NumberFormatException()
            return nl.toInt()
        }

        fun nextDouble(): Double {
            return next().toDouble()
        }

        fun readIntArray(n: Int): IntArray {
            val arr = IntArray(n)

            for (i in 0 until n) {
                arr[i] = nextInt()
            }

            return arr
        }

        fun readBigInt(capacity: Int): IntArray {
            if (!hasNext()) throw NoSuchElementException()

            val arr = IntArray(capacity)
            var len = 0
            arr[0] = readByte() - zeroCode
            while (arr[len] in 0..9) {
                len++
                arr[len] = readByte() - zeroCode
            }

            return arr.sliceArray(0 until len)
        }

        companion object {
            private fun isPrintableChar(c: Int): Boolean {
                return c in 33..126
            }
        }
    }

    class BitSet(capacity: Int) {
        val bitset = java.util.BitSet(capacity)

        val cardinality = bitset.cardinality()

        override fun equals(other: Any?) = (other as? BitSet)?.let { it.bitset == bitset } ?: false

        operator fun set(n: Int, f: Boolean) {
            if (f) {
                bitset.set(n)
            } else {
                bitset.clear(n)
            }
        }

        operator fun get(n: Int) = bitset[n]

        fun trueIterator(startIndex: Int = 0) = object: IntIterator() {
            var nextPos = bitset.nextSetBit(startIndex)

            override fun hasNext() = nextPos in 0 until Int.MAX_VALUE

            override fun nextInt(): Int {
                val value = nextPos
                nextPos = bitset.nextSetBit(nextPos + 1)
                return value
            }
        }

        fun falseIterator(startIndex: Int = 0) = object: IntIterator() {
            var nextPos = bitset.nextClearBit(startIndex)

            override fun hasNext() = nextPos in 0 until Int.MAX_VALUE

            override fun nextInt(): Int {
                val value = nextPos
                nextPos = bitset.nextClearBit(nextPos + 1)
                return value
            }
        }

        fun trueIteratorReversed(startIndex: Int = bitset.length() - 1) = object: IntIterator() {
            var nextPos = bitset.previousSetBit(startIndex)

            override fun hasNext() = nextPos >= 0

            override fun nextInt(): Int {
                val value = nextPos
                nextPos = bitset.previousSetBit(nextPos - 1)
                return value
            }
        }

        fun falseIteratorReversed(startIndex: Int = bitset.length() - 1) = object: IntIterator() {
            var nextPos = bitset.previousClearBit(startIndex)

            override fun hasNext() = nextPos >= 0

            override fun nextInt(): Int {
                val value = nextPos
                nextPos = bitset.previousClearBit(nextPos - 1)
                return value
            }
        }

        fun and(other: BitSet) {
            bitset.and(other.bitset)
        }

        fun or(other: BitSet) {
            bitset.or(other.bitset)
        }

        fun xor(other: BitSet) {
            bitset.xor(other.bitset)
        }

        fun andNot(other: BitSet) {
            bitset.andNot(other.bitset)
        }
    }
}


Measured memory_bytes: 46256