#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf (1LL<<50)
#define p(x,y) (x-1)*m+y
using namespace std;
const int xx[4]={0,0,1,-1};
const int yy[4]={1,-1,0,0};
long long s0,s1;
int c0,c1,test,n,m,cnt,S,T;
int a[45][45],last[2005],h[2005],q[2005],cur[2005];
bool color[45][45];
struct edge{
int to,next;
long long v;
}e[20005];
void insert(int u,int v,long long w){
e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;
e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;e[cnt].v=0;
}
bool bfs(){
int head=0,tail=1;
memset(h,-1,sizeof(h));
q[0]=S;h[S]=0;
while(head!=tail){
int now=q[head];head++;
for(int i=last[now];i;i=e[i].next){
if(e[i].v&&h[e[i].to]==-1){
h[e[i].to]=h[now]+1;
q[tail++]=e[i].to;
}
}
}
return h[T]!=-1;
}
long long dfs(int x,long long f){
if(x==T){
return f;
}
long long w,used=0;
for(int i=cur[x];i;i=e[i].next){
if(h[e[i].to]==h[x]+1){
w=dfs(e[i].to,min(f-used,e[i].v));
e[i].v-=w;e[i^1].v+=w;
if(e[i].v){
cur[x]=i;
}
used+=w;
if(used==f){
return f;
}
}
}
if(!used){
h[x]=-1;
}
return used;
}
long long dinic(){
long long tmp=0;
while(bfs()){
for(int i=S;i<=T;i++){
cur[i]=last[i];
}
tmp+=dfs(S,inf);
}
return tmp;
}
bool check(long long x){
memset(last,0,sizeof(last));
cnt=1;
S=0;
T=n*m+1;
long long tot=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(color[i][j]){
insert(S,p(i,j),x-a[i][j]);
tot+=x-a[i][j];
for(int k=0;k<4;k++){
int nowx=i+xx[k];
int nowy=j+yy[k];
if(nowx<1||nowy<1||nowx>n||nowy>m){
continue;
}
insert(p(i,j),p(nowx,nowy),inf);
}
}else{
insert(p(i,j),T,x-a[i][j]);
}
}
}
if(dinic()==tot){
return 1;
}
return 0;
}
int main(){
cin>>test;
while(test--){
c0=c1=s0=s1=0;
cin>>n>>m;
int mx=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
color[i][j]=(i+j)&1;
mx=max(mx,a[i][j]);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(color[i][j]){
s1+=a[i][j],c1++;
}else{
s0+=a[i][j],c0++;
}
}
}
if(c0!=c1){
long long x=(s0-s1)/(c0-c1);
if(x>=mx){
if(check(x)){
cout<<x*c1-s1<<endl;
continue;
}
}
cout<<"-1"<<endl;
}else{
if(s0!=s1){
cout<<"-1"<<endl;
continue;
}
long long l=mx,r=inf;
while(l<=r){
long long mid=(l+r)>>1;
if(check(mid)){
r=mid-1;
}else{
l=mid+1;
}
}
cout<<(long long)l*c1-s1<<endl;
}
}
return 0;
}
/*
in:
2
2 2
1 2
2 3
3 3
1 2 3
2 3 4
4 3 2
out:
2
-1
*/
直接二分一下最大的值,然后最大流判断就可以了