//开始对回溯有了点概念,
//即消除这点被取过造成的状态改变,使每次搜索都用的是最初的状态
#include <iostream>
#include <set>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int M = 1e3 + 1;
int a[M][M];
int vis[M][M];//标志,表示周围有多少个被取了的点
int n, m;
int mx = 0;//存储最大值
int ans;
inline void dfs(int x, int y)//x,y代表坐标
{//搜索方式为逐行逐个点的搜索
if (x > n) {//当已经越界
mx = max(mx, ans);//得到最大的值
return ;
}
if (y > m) {//换下一行,下一个点继续暴搜
dfs(x + 1, 1);
return;
}
dfs(x, y + 1);//搜索下一个点,表示直接跳过这个点,去搜索下一个点
if (vis[x][y] == 0) {//周围没有取过的点
ans += a[x][y];//加上改点
//把该点附近的值全部变1
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}
vis[x + i][y + j] ++;
}
}
dfs(x, y + 1);//变1后搜索
//回溯,使状态变回刚才那样
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}
vis[x + i][y + j] --;
}
}
ans -= a[x][y];
// dfs(x,y+1);
}
}
int main()
{
int t;
cin >> t;
while (t--) {
memset(a, 0, sizeof(a));//每次都要
memset(vis, 0, sizeof(vis));//千万别忘了
mx = 0;//每次都要归0,否则又是上一次的
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
dfs(1, 1);//从坐标1,1开始搜索
cout << mx << endl;
}
}