///******* In the name of ALLAH, Who is Most Gracious, Most Merciful *******///
///******* There is no God but ALLAH, MUHAMMAD(S.A.W) is the Messenger of ALLAH. *******///
///******* Every soul shall taste death.*******///
// AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH
// AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH
// AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH
// AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH
// AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH
/**************************************************************************************
___ _ _ _ ___ ___ ________ _ _ _ _____ _ _ ___ _ _
/ _ \| | | | | |/ _ \| \/ | _ | | | | | |_ _| | | | / _ \| | | |
/ /_\ | | ____ | |_| / /_\ | . . | | | | | | | | | | | | | | / /_\ | |_| |
| _ | | |____| | _ | _ | |\/| | | | | | | | | | | | | | | | _ | _ |
| | | | |____ | | | | | | | | | | |/ /| |_| | |____| |_| |___| |___| | | | | | |
\_| |_\_____/ \_| |_\_| |_\_| |_|___/ \___/\_____\___/\_____\_____\_| |_\_| |_/
***************************************************************************************/
// AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH
// AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH
// AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH // AL-HAMDULILLAH
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma")
//#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<string.h>
#include<math.h>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
#define ll long long
#define size1 1000001
#define bm 1000000007 //bigmod
#define reset(arr,n,i) fill(arr,arr+n,i) //cbrt(n) means cube root
#define rset(arr,x) memset(arr,x,sizeof(arr))
#define _ceil(x,y) ((x)/(y))+(((x)%(y))>0)
#define INF (ll)1e18 + 10
#define mod 1e9 + 7//998244353;
#define endl "\n"
#define _cpy(c,a,n) for(int i=0;i<n;i++) c[i]=a[i];
#define _iin(a,n) int a[n]; for(int i=0;i<n;i++) cin>>a[i]
#define _lin(a,n) ll a[n]; for(int i=0;i<n;i++) cin>>a[i]
#define _in(a,n) for(int i=0;i<n;i++) cin>>a[i]
#define _out(a,n) for(int i=0;i<n;i++) cout<<a[i]<<" "; cout<<endl
#define _celi(x,y) (x+y-1)/(y) //use this version of _ceil [note: ceil is risky]
#define eps 0.0000000001
#define fopr() freopen("input.txt", "r", stdin)
#define fopw() freopen("output.txt", "w", stdout)
#define FastIO ios_base::sync_with_stdio(false), cin.tie(0)
// Math :
void mns(int *x, int *y) {
if(*x>=*y) *x-=*y, *y=0;
else *y-=*x, *x=0;
}
int log_2(ll n) {
int cnt=0;
while(n/2) cnt++, n/=2;
return cnt;
}
int log2_(ll i) {
return i ? __builtin_clzll(1) - __builtin_clzll(i) : -1;
}
// Debuging :
#define _dbg(_x,_y,_z) cout<<_x<<" "<<_y<<" "<<_z<<endl
#define _dbl cout<<"_________________ "<<endl
#define _db(_x,_y) cout<<_x<<" "<<_y<<endl
#define OK cout<<"Ok"<<endl;
using namespace std;
//using namespace __gnu_pbds;
//typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
/*
void pbdserase(pbds &t, int v)
{
//normal erase function doesnt work in ordered multiset but this works
int rank = t.order_of_key(v);
auto it = t.find_by_order(rank);
t.erase(it);
}
*/
// MO's algorithm
/*const int N= 30007, M=200007;
struct st{
int l,r,in;
};
st qu[M];
int a[N]={0},fr[2000007]={0},sol[M]={0},uni=0;
void add(int x){
if(fr[x]==0) uni++;
fr[x]++;
}
void del(int x){
if(fr[x]==1) uni--;
fr[x]--;
}
bool cmp(st x,st y){
if(x.l/330!=y.l/330)
return x.l/330<y.l/330;
return x.r<y.r;
}
void mo(int query){
sort(qu,qu+query,cmp);
//array a[] 1-based index
int left=1,right=0; //int left=0,right=-1;
for(int i=0;i<query;i++){
int l=qu[i].l, r=qu[i].r;
while (right < r) add(a[++right]);
while (right > r) del(a[right--]);
while (left < l) del(a[left++]);
while (left > l) add(a[--left]);
sol[qu[i].in]=uni;
}
}*/
//Sparse Table
/*const int MAXN=200007;
const int LOG=18;
int min_st[MAXN][LOG];
int max_st[MAXN][LOG];
int log_table[MAXN + 7];
void buildSparseTables(int n,int arr[]) {
log_table[1]=0;
for (int i=2; i<=n;i++)
log_table[i]=log_table[i / 2]+1;
for (int i = 0;i<n;i++) {
min_st[i][0]=arr[i];
max_st[i][0]=arr[i];
}
for (int j = 1;(1 << j)<= n;j++)
for (int i=0; i+(1 << j)<= n; i++) {
min_st[i][j]=min(min_st[i][j - 1], min_st[i + (1 << (j - 1))][j - 1]);
max_st[i][j]=max(max_st[i][j - 1], max_st[i + (1 << (j - 1))][j - 1]);
}
}
int queryMin(int L, int R) {
int j = log_table[R - L + 1];
return min(min_st[L][j], min_st[R - (1 << j) + 1][j]);
}
int queryMax(int L, int R) {
int j = log_table[R - L + 1];
return max(max_st[L][j], max_st[R - (1 << j) + 1][j]);
}*/
/*const int N=200001;
map<int,int>id_col,mxber;
int n,m,k,col[N],mx=0,total=0;
vector<int>grp[N];
bool vis[N]= {0};
void dfs(int node) {
vis[node]=1;
total++;
mxber[col[node]]++;
mx=max(mx,mxber[col[node]]);
for(auto child:grp[node]) {
if(vis[child]) continue;
dfs(child);
}
return;
}
const int N=1001;
ll fact[N];
void facto(){
fact[1]=1;
for(int i=2;i<=N;i++){
fact[i]=fact[i-1]*i;
}
}
ll binexp(ll a, ll b) {
ll res = 1;
while (b > 0) {
if (b & 1)
res = (res * a)%mod;
a = (a * a)%mod;
b >>= 1;
}
return res;
}
ll MMI(ll den){
return binexp(den,mod-2);
}
ll nCr(ll n, ll r){
ll den=MMI((fact[n-r]%mod*fact[r]%mod)%mod);
return (fact[n]%mod*den)%mod;
}
ll lcm(ll a, ll b){
return (a/__gcd(a,b))*b;
}*/
void solve() {
ll n,m;
cin>>n>>m;
string str[n];
for(int i=0;i<n;i++)
cin>>str[i];
ll sol[n+2][m];
for(int i=0;i<=n;i++)
for(int j=0;j<m;j++)
sol[i][j]=0;
for(int j=0;j<m;j++){
ll pre[n][26], post[n][26];
for(int s=0;s<n;s++)
for(int k=0;k<26;k++)
pre[s][k]=0, post[s][k]=0;
for(int i=0;i<n;i++){
pre[i][str[i][j]-'a']++;
if(i>0)
for(int k=0;k<26;k++)
pre[i][k]+=pre[i-1][k];
}
for(int i=n-1;i>=0;i--){
post[i][str[i][j]-'a']++;
if(i<n-1)
for(int k=0;k<26;k++)
post[i][k]+=post[i+1][k];
}
for(int i=0;i<n-1;i++){
ll mpost=0,mpre=0;
for(int k=0;k<26;k++){
mpre=max(pre[i][k],mpre);
mpost=max(post[i+1][k],mpost);
}
sol[i+1][j]=max(sol[i+1][j],mpre+mpost);
}
for(int k=0;k<26;k++){
sol[n][j]=max(pre[n-1][k],sol[n][j]);
sol[0][j]=max(post[0][k],sol[0][j]);
}
}
ll mx=0;
for(int i=0;i<=n;i++){
ll sum=0;
for(int j=0;j<m;j++)
sum+=sol[i][j];
mx=max(sum,mx);
}
//_out(vec,vec.size());
cout<<mx<<endl;
}
int main() {
FastIO;
int n=1;
cin>>n;
while(n--) {
solve();
}
return 0;
}
//written by MAMUN
/* Cautions:
1.array out of bound!!! [check array size and last accessed index]
2.signed integer overflow!!! [int*int!=ll @typecast(ll) one of them or, multiply with 1LL]
3.floating point numbers numbers are equal if the difference between them is less than 1e-9 [better way to compare floating point numbers]
4.any square number when divided by 4 must have a remainder of either 0 or 1.
*/
/********************************************************************************************************************************************************
_ _ _ _ _____ _ _ _ _ _ _ ______ _ _ _
| \ | | | | | | | ___| | | | | | | (_) (_) | | ___ \ | | | | | |
| \| | ___ _ __| |_| |__ | |__ __ _ ___| |_ | | | |_ __ ___ _____ _ __ ___ _| |_ _ _ | |_/ / __ _ _ __ __ _| | __ _ __| | ___ ___| |__
| . ` |/ _ \| '__| __| '_ \ | __|/ _` / __| __| | | | | '_ \| \ \ / / _ \ '__/ __| | __| | | | | ___ \/ _` | '_ \ / _` | |/ _` |/ _` |/ _ \/ __| '_ \
| |\ | (_) | | | |_| | | | | |__| (_| \__ \ |_ | |_| | | | | |\ V / __/ | \__ \ | |_| |_| | | |_/ / (_| | | | | (_| | | (_| | (_| | __/\__ \ | | |
\_| \_/\___/|_| \__|_| |_| \____/\__,_|___/\__| \___/|_| |_|_| \_/ \___|_| |___/_|\__|\__, | \____/ \__,_|_| |_|\__, |_|\__,_|\__,_|\___||___/_| |_|
__/ | __/ |
|___/ |___/
*********************************************************************************************************************************************************/