#include <iostream>
#include <vector>
#include <string>
#include <cstring> // for memset
#include <algorithm>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while(T--){
int n, m;
cin >> n >> m;
vector<string> rounds(n);
for (int i = 0; i < n; i++){
cin >> rounds[i];
}
vector<long long> total(n+1, 0LL);
for (int col = 0; col < m; col++){
vector<int> prefix(n+1, 0);
int freq[26] = {0};
int currentMax = 0;
for (int i = 1; i <= n; i++){
char c = rounds[i-1][col];
int idx = c - 'a';
freq[idx]++;
currentMax = max(currentMax, freq[idx]);
prefix[i] = currentMax;
}
// suffix[i] = maximum frequency (in this column) among rounds i..n.
vector<int> suffix(n+2, 0); // suffix[n+1] = 0 (empty)
memset(freq, 0, sizeof(freq));
currentMax = 0;
for (int i = n; i >= 1; i--){
char c = rounds[i-1][col];
int idx = c - 'a';
freq[idx]++;
currentMax = max(currentMax, freq[idx]);
suffix[i] = currentMax;
}
// For each possible partition k (0 <= k <= n):
// - Rounds 1..k use the guess-string chosen to maximize matches in that column (prefix part).
// - Rounds k+1..n use a (possibly new) guess-string (suffix part).
// So, add prefix[k] + suffix[k+1] to the total contribution for this column.
for (int k = 0; k <= n; k++){
total[k] += prefix[k] + suffix[k+1];
}
}
// The answer is the maximum total score we can get over all possible partitions.
long long ans = 0;
for (int k = 0; k <= n; k++){
ans = max(ans, total[k]);
}
cout << ans << "\n";
}
return 0;
}