// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
using namespace std;
#define FastRead ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
// #define int long long int
#define ll int
#define bits_count __builtin_popcountll
#define endl '\n'
#define double long double
#define ld double
#define FOR(i,a,n) for (ll i=(a);i<=(n);++i)
#define RFOR(i,a,n) for (ll i=(n);i>=(a);--i)
#define FI(i,n) for (ll i=0; i<(n); ++i)
#define ZERO(a) memset((a),0,sizeof((a)))
#define MINUS(a) memset((a),-1,sizeof((a)))
#define f first
#define s second
#define pb push_back
#define mk make_pair
#define all(g) g.begin(),g.end()
#define sz(x) (ll)x.size()
#define pr pair<int,int>
int fastMax(int x, int y) { return (((y-x)>>(32-1))&(x^y))^y; }
int fastMin(int x, int y) { return (((y-x)>>(32-1))&(x^y))^x; }

// #include <ext/pb_ds/assoc_container.hpp> // Common file
// #include <ext/pb_ds/tree_policy.hpp>     // Including tree_order_statistics_node_updat
// using namespace __gnu_pbds;
// typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;


void solve(){

    int n,m; cin>>n>>m;
    vector<vector<int>> a(n+1,vector<int>(m+1));
    set<int> rows[n+1];
    set<int> columns[m+1];
    
    FOR(i,1,n) FOR(j,1,m) cin>>a[i][j];
    
    int skillsum = 0;
    FOR(i,1,n) FOR(j,1,m) skillsum += a[i][j];
    int ans = skillsum;

    FOR(i,1,n) FOR(j,1,m) rows[i].insert(j);
    FOR(j,1,m) FOR(i,1,n) columns[j].insert(i);

    set<pair<int,int>> que;

    FOR(i,1,n){
        FOR(j,1,m){

            int cnt = 0,sum = 0;
            auto right = rows[i].lower_bound(j+1);  
            if(right != rows[i].end()) cnt++,sum += a[i][*right];
            auto left = rows[i].lower_bound(j); 
            if(left != rows[i].begin()) cnt++,sum += a[i][*(--left)];
            auto up = columns[j].lower_bound(i+1);
            if(up != columns[j].end()) cnt++,sum += a[*up][j];
            auto down = columns[j].lower_bound(i);
            if(down != columns[j].begin()) cnt++,sum += a[*(--down)][j];

            if(cnt == 0) continue;
            if(a[i][j]*cnt < sum) que.insert({i,j});
        }
    }

    while(sz(que) != 0){
        set<pair<int,int>> new_que;

        for(auto x:que){
            int i = x.f,j = x.s;
            auto right = rows[i].lower_bound(j+1);  
            if(right != rows[i].end()) new_que.insert({i,*right});
            auto left = rows[i].lower_bound(j); 
            if(left != rows[i].begin()) new_que.insert({i,*(--left)});
            auto up = columns[j].lower_bound(i+1);
            if(up != columns[j].end()) new_que.insert({*up,j});
            auto down = columns[j].lower_bound(i);
            if(down != columns[j].begin()) new_que.insert({*(--down),j});
            skillsum -= a[i][j];
            a[i][j] = 0; rows[i].erase(j); columns[j].erase(i);
        }

        ans += skillsum;
        que.clear();

        for(auto x:new_que){
            int i = x.f,j = x.s;
            if(a[i][j] == 0) continue;
           
            int cnt = 0,sum = 0;
            auto right = rows[i].lower_bound(j+1);  
            if(right != rows[i].end()) cnt++,sum += a[i][*right];
            auto left = rows[i].lower_bound(j); 
            if(left != rows[i].begin()) cnt++,sum += a[i][*(--left)];
            auto up = columns[j].lower_bound(i+1);
            if(up != columns[j].end()) cnt++,sum += a[*up][j];
            auto down = columns[j].lower_bound(i);
            if(down != columns[j].begin()) cnt++,sum += a[*(--down)][j];

            if(cnt == 0) continue;
            if(a[i][j]*cnt < sum) que.insert({i,j});
        }
    }

    cout<<ans<<endl;
}

signed main(){

   FastRead; 
   
    int t = 1; 
    cin>>t;
    FOR(i,1,t){
        cout<<"Case #"<<i<<": ";
        solve();
    }
}



