Ma5termind is crazy about Action Games. He just bought a new one and got down to play it. Ma5termind usually finishes all the levels of a game very fast. But, This time however he got stuck at the very first level of this new game. Can you help him play this game.  

To finish the game, Ma5termind has to cross $N$ levels. At each level of the game, Ma5termind has to face $\mbox{M}$ enemies. Each enemy has its associated power $\mbox{P}$ and some number of bullets $\mbox{B}$. To knock down an enemy, Ma5termind needs to shoot him with one or multiple bullets whose collective count is equal to the power of the enemy. If Ma5termind manages to knock down any one enemy at a level, the rest of them run away and the level is cleared.   

Here comes the challenging part of the game. 

Ma5termind acquires all the bullets of an enemy once he has knocked him down. Ma5termind can use the bullets acquired after killing an enemy at $i^{\mbox{th}}$ level only till the $(i+1)^{th}$ level.  

However, the bullets Ma5termind carried before the start of the game can be taken forward and can be used to kill more enemies.  

Now, Ma5termind has to guess the minimum number of bullets he must have before the start of the game so that he clears all the $N$ levels successfully.  

NOTE  

Bullets carried before the start of the game can be used to kill an enemy at any level.  
One bullet decreases the power of an enemy by 1 Unit.  
For better understanding of the problem look at the sample testcases.  

Input Format

First line of input contains a single integer $\mathbf{T}$ denoting the number of test cases. 

First line of each test case contains two space separated integers $N$ and $\mbox{M}$ denoting the number of levels and number of enemies at each level respectively. 

Each of next $N$ lines of a test case contain $\mbox{M}$ space separated integers, where $j^{th}$ integer in the $i^{\mbox{th}}$ line denotes the power $\mbox{P}$ of $j^{th}$ enemy on the $i^{\mbox{th}}$ level. 

Each of the next $N$ lines of a test case contains $\mbox{M}$ space separated integers, where $j^{th}$ integer in the $i^{\mbox{th}}$ line denotes the number of bullets $\mbox{B}$ $j^{th}$ enemy of $i^{\mbox{th}}$ level has.  

Constraints 

$1\leq T\leq100$ 

$1\leq N\leq100$ 

$1\leq M\leq5\times10^5$ 

$1\leq P,B\leq1000$ 

For each test file, sum of $N\times M$ over all the test cases does not exceed $5\times10^5$.   

Output Format

For each test case, print the required answer.  

Sample Input
2
3 3
3 2 1 
1 2 3
3 2 1
1 2 3
3 2 1
1 2 3
3 3 
3 2 5 
8 9 1 
4 7 6 
1 1 1 
1 1 1 
1 1 1 

Sample Output
1
5   

Explanation

For the First test case , Ma5termind kills the enemy in the following order:

Ma5termind kills the $3^{rd}$ enemy at the $1^{st}$ level, takes all his bullets and moves to the next level.
Ma5termind kills the $1^{st}$ enemy at the $2^{nd}$ level, takes all his bullets and moves to the next level.
Ma5termind kills the $1^{st}$ enemy at the $3^{rd}$ level, takes all his bullets and moves to the next level.

So this way Ma5termind can successfully finish this game with only $\mbox{I}$ bullet in hand before the start of the game.

For the second test case , Ma5termind kills the enemy in the following order:

Ma5termind kills the $2^{nd}$ enemy at the $1^{st}$ level, takes all his bullets and moves to the next level.
Ma5termind kills the $3^{rd}$ enemy at the $2^{nd}$ level, takes all his bullets and moves to the next level.
Ma5termind kills the $1^{st}$ enemy at the $3^{rd}$ level, takes all his bullets and moves to the next level.

So this way Ma5termind can successfully finish this game with only $5$ bullet in hand before the start of the game.

NOTE: 

There can be more than one way of getting the optimal answer but that does not matter in our case, because we need to answer the minimum number of bullets required.

Difficulty: MEDIUM_HARD
Tags: Dynamic programming
Skill types: Dynamic programming

Starter code:

Solutions:
INF = 2 ** 29
BUL = 1000
T = int(input())
for t in range(T):
	(n, m) = (int(x) for x in input().split())
	dp = [[INF for x in range(BUL + 1)] for x in range(n)]
	dp1 = [[INF for x in range(BUL + 1)] for x in range(n)]
	dp2 = [[INF for x in range(BUL + 1)] for x in range(n)]
	s = [[int(x) for x in input().split()] for x in range(n)]
	g = [[int(x) for x in input().split()] for x in range(n)]
	for i in range(n):
		if i == 0:
			for j in range(m):
				dp[i][g[i][j]] = min(dp[i][g[i][j]], s[i][j])
		else:
			for j in range(m):
				dp[i][g[i][j]] = min(dp[i][g[i][j]], dp1[i - 1][s[i][j]] + s[i][j], dp2[i - 1][s[i][j]])
		dp1[i][1] = dp[i][1] - 1
		for j in range(2, BUL + 1):
			dp1[i][j] = min(dp1[i][j - 1], dp[i][j] - j)
		dp2[i][BUL] = dp[i][BUL]
		for j in reversed(range(1, BUL)):
			dp2[i][j] = min(dp2[i][j + 1], dp[i][j])
	print(dp2[n - 1][1])


import bisect

def levelExits(entries, level):
	exits = []
	for monster in level:
		exits.append(bestExit(entries, monster))
	return exits

def cost(entry, monster):
	return entry[1] + max(0, monster[0] - entry[0])

def bestExit(entries, monster):
	position = bisect.bisect(entries, (monster[0], -1))
	exits = [(cost(entry, monster), cost(entry, monster) - monster[1]) for entry in entries[max(0, position - 1):position + 1]]
	return min(exits)

def exitToEntry(exit):
	return (exit[0] - exit[1], exit[0])

def exitsToEntries(exits):
	exits.sort()
	last_exit = exits[0]
	entries = [exitToEntry(last_exit)]
	for exit in exits:
		if exit[1] < last_exit[1]:
			entries.append(exitToEntry(exit))
			last_exit = exit
	entries.sort()
	return entries

def minBullets(levels):
	entries = [(0, 0)]
	for level in levels:
		exits = levelExits(entries, level)
		entries = exitsToEntries(exits)
	return exits[0][0]

def readCase():
	(N, M) = map(int, input().split())
	powers = [list(map(int, input().split())) for i in range(N)]
	bullets = [list(map(int, input().split())) for i in range(N)]
	levels = [[(powers[i][j], bullets[i][j]) for j in range(M)] for i in range(N)]
	return levels
num_cases = int(input())
for case in range(num_cases):
	print(minBullets(readCase()))


Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))


MAXP = 1000

def main():
	ncases = int(input())
	for _ in range(ncases):
		print(solvecase(readcase()))

def readcase():
	(levels, enemies) = readints()
	(p, b) = ([], [])
	for _ in range(levels):
		p.append(readints())
	for _ in range(levels):
		b.append(readints())
	assert all((len(row) == enemies for pb in (p, b) for row in pb))
	return [list(zip(prow, brow)) for (prow, brow) in zip(p, b)]

def readints():
	return list(map(int, input().split()))

def solvecase(enemy):
	enemy = [reduce(row) for row in enemy]
	strat0 = [(0, 0)]
	for enem in enemy:
		strat0 = [(strat0[0][0], 0)] + strat0 + [(strat0[-1][0] + 1, strat0[-1][1])]
		istrat = 1
		((used0, yield0), (used1, yield1)) = strat0[:2]
		strat1 = []
		for (p, b) in enem:
			while p >= yield1 and istrat < len(strat0) - 1:
				istrat += 1
				((used0, yield0), (used1, yield1)) = ((used1, yield1), strat0[istrat])
			uses0 = used0 + max(0, p - yield0)
			uses1 = used1 + max(0, p - yield1)
			uses = min(uses0, uses1)
			if len(strat1) == 0 or uses - strat1[-1][0] < b - strat1[-1][1]:
				strat1.append((uses, b))
		strat0 = strat1
	return strat1[0][0]

def reduce(row):
	if 0 == len(row):
		return row
	row = [(p, -b) for (p, b) in sorted(((p, -b) for (p, b) in row))]
	(p0, b0) = row[0]
	newrow = row[:1]
	for (p, b) in row[1:]:
		if b > b0:
			newrow.append((p, b))
			b0 = b
	return newrow
main()


t = int(input())
while t > 0:
	str = input().split()
	n = int(str[0])
	m = int(str[1])
	ammunition = [-1] * 1001
	max_ammo_p = 0
	s = []
	for i in range(n * 2):
		s.append(input())
	for i in range(n):
		str = s[i].split()
		str2 = s[i + n].split()
		level = [-1] * 1001
		min_strength = 0
		max_strength = 0
		min_bullets = 0
		max_bullets = 0
		if i == 0:
			for j in range(m):
				max_ammo_p = max(max_ammo_p, int(str2[j]))
				if ammunition[int(str2[j])] == -1:
					ammunition[int(str2[j])] = int(str[j])
				ammunition[int(str2[j])] = min(ammunition[int(str2[j])], int(str[j]))
			for j in range(max_ammo_p, 1, -1):
				if ammunition[j - 1] == -1:
					ammunition[j - 1] = ammunition[j]
				ammunition[j - 1] = min(ammunition[j], ammunition[j - 1])
			for j in range(1, max_ammo_p, 1):
				ammunition[j + 1] = min(ammunition[j + 1], ammunition[j] + 1)
			continue
		ammunition_next = [-1] * 1001
		max_ammo = -1
		for j in range(m):
			strength = int(str[j])
			bullets = int(str2[j])
			max_ammo = max(max_ammo, bullets)
			if max_ammo_p < strength:
				if ammunition_next[bullets] == -1:
					ammunition_next[bullets] = ammunition[max_ammo_p] + (strength - max_ammo_p)
				ammunition_next[bullets] = min(ammunition_next[bullets], ammunition[max_ammo_p] + (strength - max_ammo_p))
			else:
				if ammunition_next[bullets] == -1:
					ammunition_next[bullets] = ammunition[strength]
				ammunition_next[bullets] = min(ammunition_next[bullets], ammunition[strength])
		max_ammo_p = max_ammo
		ammunition = ammunition_next
		for j in range(max_ammo_p, 1, -1):
			if ammunition[j - 1] == -1:
				ammunition[j - 1] = ammunition[j]
			ammunition[j - 1] = min(ammunition[j], ammunition[j - 1])
		for j in range(1, max_ammo_p, 1):
			ammunition[j + 1] = min(ammunition[j + 1], ammunition[j] + 1)
	res = -1
	for i in range(1, max_ammo_p + 1, 1):
		if res == -1 and ammunition[i] != -1:
			res = ammunition[i]
		if ammunition[i] != -1:
			res = min(res, ammunition[i])
	print(res)
	t -= 1


import sys

def binarysearch(arr, x):
	if x < arr[0]:
		return -1
	elif x >= arr[-1]:
		return len(arr) - 1
	else:
		left = 0
		right = len(arr) - 1
		while right - left > 1:
			mid = (left + right) // 2
			if arr[mid] > x:
				right = mid
			else:
				left = mid
		return left
nooftestcases = sys.stdin.readline()
T = int(nooftestcases.rstrip())
for q in range(0, T):
	(N, M) = map(int, sys.stdin.readline().split())
	P = []
	B = []
	for i in range(0, N):
		row = [int(i) for i in sys.stdin.readline().split()]
		P.append(row)
	for i in range(0, N):
		row = [int(i) for i in sys.stdin.readline().split()]
		B.append(row)
	for i in range(0, N):
		level = []
		for j in range(0, M):
			level.append([P[i][j], B[i][j]])
		level = sorted(level)
		for j in range(0, M):
			P[i][j] = level[j][0]
			B[i][j] = level[j][1]
	dp = [[0] * M]
	mindplevel = [0] * M
	mindppricelevel = [0] * M
	mindppricelevel[-1] = P[-1][-1]
	for i in range(M - 2, -1, -1):
		mindppricelevel[i] = min(mindppricelevel[i + 1], P[-1][i])
	for i in range(N - 2, -1, -1):
		row = []
		for j in range(0, M):
			ind = binarysearch(P[i + 1], B[i][j])
			if ind == -1:
				row.append(mindppricelevel[0] - B[i][j])
			elif ind == M - 1:
				row.append(mindplevel[-1])
			else:
				row.append(min(mindplevel[ind], mindppricelevel[ind + 1] - B[i][j]))
		dp.append(row)
		mindplevel = [row[0]]
		for j in range(1, M):
			mindplevel.append(min(row[j], mindplevel[j - 1]))
		mindppricelevel[-1] = row[-1] + P[i][-1]
		for j in range(M - 2, -1, -1):
			mindppricelevel[j] = min(mindppricelevel[j + 1], row[j] + P[i][j])
	print(mindppricelevel[0])


INF = 2 ** 29
BUL = 1000
T = int(input())
for t in range(T):
	(n, m) = (int(x) for x in input().split())
	dp = [[INF for x in range(BUL + 1)] for x in range(n)]
	dp1 = [[INF for x in range(BUL + 1)] for x in range(n)]
	dp2 = [[INF for x in range(BUL + 1)] for x in range(n)]
	s = [[int(x) for x in input().split()] for x in range(n)]
	g = [[int(x) for x in input().split()] for x in range(n)]
	for i in range(n):
		if i == 0:
			for j in range(m):
				dp[i][g[i][j]] = min(dp[i][g[i][j]], s[i][j])
		else:
			for j in range(m):
				dp[i][g[i][j]] = min(dp[i][g[i][j]], dp1[i - 1][s[i][j]] + s[i][j], dp2[i - 1][s[i][j]])
		dp1[i][1] = dp[i][1] - 1
		for j in range(2, BUL + 1):
			dp1[i][j] = min(dp1[i][j - 1], dp[i][j] - j)
		dp2[i][BUL] = dp[i][BUL]
		for j in reversed(range(1, BUL)):
			dp2[i][j] = min(dp2[i][j + 1], dp[i][j])
	print(dp2[n - 1][1])


Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))


Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))


Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))


Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))


import math
import os
import random
import re
import sys
Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))


import math
import os
import random
import re
import sys
Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))


INF = 2 ** 29
BUL = 1000
T = int(input())
for t in range(T):
	(n, m) = (int(x) for x in input().split())
	dp = [[INF for x in range(BUL + 1)] for x in range(n)]
	dp1 = [[INF for x in range(BUL + 1)] for x in range(n)]
	dp2 = [[INF for x in range(BUL + 1)] for x in range(n)]
	s = [[int(x) for x in input().split()] for x in range(n)]
	g = [[int(x) for x in input().split()] for x in range(n)]
	for i in range(n):
		if i == 0:
			for j in range(m):
				dp[i][g[i][j]] = min(dp[i][g[i][j]], s[i][j])
		else:
			for j in range(m):
				dp[i][g[i][j]] = min(dp[i][g[i][j]], dp1[i - 1][s[i][j]] + s[i][j], dp2[i - 1][s[i][j]])
		dp1[i][1] = dp[i][1] - 1
		for j in range(2, BUL + 1):
			dp1[i][j] = min(dp1[i][j - 1], dp[i][j] - j)
		dp2[i][BUL] = dp[i][BUL]
		for j in reversed(range(1, BUL)):
			dp2[i][j] = min(dp2[i][j + 1], dp[i][j])
	print(dp2[n - 1][1])


Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))


import math
import os
import random
import re
import sys
Inf = 1000 * 5 * 100000 + 1

def solve(N, M, P, B):
	Bmax = max((max(b) for b in B)) + 1
	(s, sb) = ([Inf] * Bmax, [Inf] * Bmax)
	for m in range(M):
		b = B[0][m]
		while b >= 0 and P[0][m] < s[b]:
			s[b] = P[0][m]
			b -= 1
		b = B[0][m]
		while b < Bmax and P[0][m] - B[0][m] < sb[b]:
			sb[b] = P[0][m] - B[0][m]
			b += 1
	for n in range(1, N):
		(s_, sb_) = ([Inf] * Bmax, [Inf] * Bmax)
		for m in range(M):
			if P[n][m] < Bmax:
				v = min(sb[P[n][m]] + P[n][m], s[P[n][m]])
			else:
				v = sb[Bmax - 1] + P[n][m]
			b = B[n][m]
			while b >= 0 and v < s_[b]:
				s_[b] = v
				b -= 1
			b = B[n][m]
			while b < Bmax and v - B[n][m] < sb_[b]:
				sb_[b] = v - B[n][m]
				b += 1
		(s, sb) = (s_, sb_)
	return min(s)
T = int(input())
for _ in range(T):
	(N, M) = (int(_) for _ in input().split())
	P = [[int(_) for _ in input().split()] for _ in range(N)]
	B = [[int(_) for _ in input().split()] for _ in range(N)]
	print(solve(N, M, P, B))