52
#include <iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
int n,m;
bool judge(int i,int j)//判断是否超出边界
{
if(i<n&&j<m&&i>0&j>0)
return 1;
else return 0;
}
int max(int a,int b)
{
int max=a;
if(b>max)max=b;
return max;
}
int main()
{
int i,j,k,t,a[21][1001];
int ans[21][1001];
cin>>t;
while(t--)
{
memset(a,0,sizeof(a));
memset(ans,0,sizeof(ans));
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(i=0;i<m;i++) //从1开始,防止破坏数据 覆上最小值
ans[0][i]=-100;
for(i=0;i<n;i++)
ans[i][0]=-100;
ans[0][1]=ans[1][0]=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
ans[i][j]=max(ans[i-1][j],ans[i][j-1]); //只与左边和上边有关
for(k=2;k<=m;k++) //向右可以走当前列的倍数
{
if(j%k==0)
ans[i][j]=max(ans[i][j],ans[i][j/k]);
}
ans[i][j]+=a[i][j];
}
cout<<ans[n][m]<<endl;
}
return 0;
}