/*
特征值k=m-next[m]就是最小循环节的长度,
m%k就是去末尾遗留长度
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char strs[10005][100];
int r,c,w,h,f[1050],nxt[10005];//r是行,c是列
void kmp_pre1(char *s){//求一行的nxt数组
int nxtt[1005]={};
int m=strlen(s);
int i,j;
i=0;j=nxtt[0]=-1;
while(i<m){
while(j!=-1 && s[i]!=s[j]) j=nxtt[j];
nxtt[++i]=++j;
}
//把可行的长度都在f中+1
int tmp=m-nxtt[m],k=0;
while(k+tmp<=m){
k+=tmp;
f[k]++;
}
//剩下的串枚举一次开头就好
for(k=m%(m-nxtt[m]);k;k=nxtt[k]){
f[m-nxtt[k]]++;
}
}
void kmp_pre2(){
memset(nxt,0,sizeof nxt);
int i,j;
i=0,j=nxt[0]=-1;
while(i<r){
while(j!=-1 && strcmp(strs[i],strs[j])!=0)
j=nxt[j];
nxt[++i]=++j;
}
}
int main(){
while(scanf("%d%d",&r,&c)==2){
memset(f,0,sizeof f);//宽度为i的子串出现的次数
w=c,h=r;
for(int i=0;i<r;i++){
scanf("%s",strs[i]);
kmp_pre1(strs[i]);
}
for(int i=1;i<=c;i++)//找到矩阵最小宽度
if(f[i]==r){w=i;break;}
for(int i=0;i<r;i++)
strs[i][w]='\0';//截取前w个字符
kmp_pre2();//获取在行之间的next数组
h=r-nxt[r];//h就是列上的特征值
printf("%d\n",w*h);
}
return 0;
}