#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
typedef long long LL;
// 十字链表
struct Node{
int u, d, l, r;
int val;
Node(){
u = d = l = r = -1; val = 0;
}
};
vector<Node> ten_list;
int R, C;
// 获取 一维的 id
int getId(int x, int y) { return x * (C + 1) + y; }
// 删除 x 节点
void erase(int x) {
ten_list[ten_list[x].l].r = ten_list[x].r;
ten_list[ten_list[x].r].l = ten_list[x].l;
ten_list[ten_list[x].u].d = ten_list[x].d;
ten_list[ten_list[x].d].u = ten_list[x].u;
ten_list[x].val = 0;
}
vector<int> update(vector<int> &choosList, LL &ans, LL &origin) {
vector<int> needErase;
vector<int> newList, _newList;
ans += origin;
for(int i = 0, len = choosList.size(); i < len; ++ i) {
int x = choosList[i];
int neiNum = 0; int neiVal = 0;
if(ten_list[ten_list[x].r].val != 0) { neiNum ++; neiVal += ten_list[ten_list[x].r].val; }
if(ten_list[ten_list[x].l].val != 0) { neiNum ++; neiVal += ten_list[ten_list[x].l].val; }
if(ten_list[ten_list[x].u].val != 0) { neiNum ++; neiVal += ten_list[ten_list[x].u].val; }
if(ten_list[ten_list[x].d].val != 0) { neiNum ++; neiVal += ten_list[ten_list[x].d].val; }
if(neiVal > ten_list[x].val * neiNum) {
origin -= ten_list[x].val;
// 需要删除
needErase.push_back(x);
}
}
for(auto x : needErase) {
// 防止 re assert 现在很少用了 也可以不加
assert(ten_list[x].r != -1); assert(ten_list[x].l != -1); assert(ten_list[x].u != -1); assert(ten_list[x].d != -1);
if(ten_list[ten_list[x].r].val != 0) { _newList.push_back(ten_list[x].r); }
if(ten_list[ten_list[x].l].val != 0) { _newList.push_back(ten_list[x].l); }
if(ten_list[ten_list[x].u].val != 0) { _newList.push_back(ten_list[x].u); }
if(ten_list[ten_list[x].d].val != 0) { _newList.push_back(ten_list[x].d); }
erase(x);
}
for(auto it : _newList) newList.push_back(it);
sort(newList.begin(), newList.end());
newList.erase(unique(newList.begin(), newList.end()), newList.end());
return newList;
}
int main(){
int T;
scanf("%d", &T);
for(int cases = 1; cases <= T; ++ cases){
// 清空十字链表
ten_list.clear();
scanf("%d %d", &R, &C);
// 预开空间
ten_list.resize((R + 5) * (C + 5), Node());
// 统计和
LL origin = 0;
for(int i = 1; i <= R; ++ i){
for(int j = 1; j <= C; ++ j){
scanf("%d", &ten_list[getId(i , j)].val);
origin += ten_list[getId(i , j)].val;
}
}
// 初始化十字链表
for(int i = 1; i <= R; ++ i){
ten_list[getId(i, 1)].l = getId(i, 0);
for(int j = 1; j <= C; ++j){
ten_list[getId(i , j - 1)].r = getId(i, j);
ten_list[getId(i , j + 1)].l = getId(i, j);
}
ten_list[getId(i , C)].r = getId(i, C + 1);
}
for(int i = 1; i <= C; ++ i) {
ten_list[getId(1 , i)].u = getId(0, i);
for(int j = 1; j <= R; ++ j) {
ten_list[getId(j - 1, i)].d = getId(j, i);
ten_list[getId(j + 1, i)].u = getId(j, i);
}
ten_list[getId(R, i)].d = getId(R + 1, i);
}
vector<int> choosList;
for(int i = 1; i <= R; ++ i){
for(int j = 1; j <= C; ++ j){
choosList.push_back(getId(i, j));
}
}
LL ans = 0;
while(true){
choosList = update(choosList, ans, origin);
// 不需要修改 直接break 防止 tle
if(choosList.size() == 0) break;
}
printf("Case #%d: %lld\n", cases, ans);
}
return 0;
}