program casino;
Uses sysutils;
{$H+}
const lung=1000000;
type elenco=array[0..lung-1] of Qword;
var N,M,w,v,C,t,coppie,index:Qword;
S,S_ruotate:array[0..lung] of AnsiString;
funz_errore: array[0..1000000] of Int64;
H, accoppiamenti:elenco;
accoppiata:array[0..1000000] of boolean;
function LexicalMinRotation(var x: AnsiString):Qword;
var
len,K,j:Qword;
i:Int64;
begin
x:=x+x;
len:=length(x);
for i:=0 to len do funz_errore[i]:=-1;
K:=1;
for j:=2 to len do
begin
i:= funz_errore[j-k-1];
while (i <> -1 ) and (x[j] <> x[(k + i+1 )]) do
begin
if x[j] < x[(k + i+1 )] then k:= j - i - 1;
i:=funz_errore[i];
end;
if (i = -1) and (x[j] <> x[(k + i+1 )]) then
begin
if x[j] < x[(k + i+1 )] then k:= j;
funz_errore[j - k]:= -1;
end
else funz_errore[j - k]:= i + 1;
end;
LexicalMinRotation:=k;
end;
function Rabin (var x: Ansistring) :Qword;
var len, i, R,base,d,q:Qword;
begin
d:=1; R:=0; len:=length(x); base:=26; q:=8446744073709551615;
for i := 1 to len-1 do d := (d * base) mod q ;
for i := 1 to len do R:= (base*R + (ord(x[i])) ) mod q;
Rabin:= R;
end;
begin
(*assign(input, 'input.txt'); reset(input);
assign(output, 'output.txt'); rewrite(output);*)
readln (N,M);
for w:=0 to N-1 do begin readln(S[w]); S[w]:=Trim(S[w]); end;
for w:=0 to N-1 do begin H[w]:=0; accoppiata[w]:=false; accoppiamenti[w]:=0; end;
coppie:=0;
for w:=0 to N-1 do
begin
index:=LexicalMinRotation(S[w]);
S_ruotate[w]:=copy(S[w],index,M);
H[w]:=Rabin(S_ruotate[w]);
end;
w:=0;
while w<N-1 do
begin
if accoppiata[w]=false then
begin
for v:=w+1 to N-1 do
begin
if H[w]=H[v] then
begin
C:= CompareStr(S_ruotate[w], S_ruotate[v]);
if C=0 then begin accoppiamenti[w]:=accoppiamenti[w]+1; accoppiata[w]:=true; accoppiata[v]:=true; end;
end;
end;
w:=w+1;
end
else begin w:=w+1; continue; end;
end;
for w:=0 to N-1 do
begin
if accoppiamenti[w] =1 then coppie:=coppie+1
else if accoppiamenti[w]>1 then coppie:=coppie+((accoppiamenti[w]+1)*(accoppiamenti[w]) div 2);
end;
writeln (coppie);
end.
cHJvZ3JhbSBjYXNpbm87ICAKVXNlcyBzeXN1dGlsczsKeyRIK30KY29uc3QgbHVuZz0xMDAwMDAwOwp0eXBlIGVsZW5jbz1hcnJheVswLi5sdW5nLTFdIG9mIFF3b3JkOwp2YXIgIE4sTSx3LHYsQyx0LGNvcHBpZSxpbmRleDpRd29yZDsKICAgICBTLFNfcnVvdGF0ZTphcnJheVswLi5sdW5nXSBvZiBBbnNpU3RyaW5nOwogICAgIGZ1bnpfZXJyb3JlOiBhcnJheVswLi4xMDAwMDAwXSBvZiBJbnQ2NDsKICAgICBILCBhY2NvcHBpYW1lbnRpOmVsZW5jbzsKICAgICBhY2NvcHBpYXRhOmFycmF5WzAuLjEwMDAwMDBdIG9mIGJvb2xlYW47CiAgICAKZnVuY3Rpb24gTGV4aWNhbE1pblJvdGF0aW9uKHZhciB4OiBBbnNpU3RyaW5nKTpRd29yZDsKdmFyIApsZW4sSyxqOlF3b3JkOwppOkludDY0OwoKYmVnaW4KICAgeDo9eCt4OyAKICAgbGVuOj1sZW5ndGgoeCk7IAogICBmb3IgaTo9MCB0byBsZW4gZG8gZnVuel9lcnJvcmVbaV06PS0xOyAKICAgSzo9MTsgCiAgIGZvciBqOj0yIHRvIGxlbiBkbyAgIAogICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgICBpOj0gZnVuel9lcnJvcmVbai1rLTFdOwogICAgICAgICAgICAgd2hpbGUgKGkgPD4gLTEgKSBhbmQgKHhbal0gPD4geFsoayArIGkrMSApXSkgZG8gICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHhbal0gPCB4WyhrICsgaSsxICldIHRoZW4gazo9IGogLSBpIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaTo9ZnVuel9lcnJvcmVbaV07ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChpID0gLTEpIGFuZCAoeFtqXSA8PiB4WyhrICsgaSsxICldKSB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgeFtqXSA8IHhbKGsgKyBpKzEgKV0gdGhlbiBrOj0gajsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bnpfZXJyb3JlW2ogLSBrXTo9IC0xOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgICBmdW56X2Vycm9yZVtqIC0ga106PSBpICsgMTsKICAgICAgICAgICAgICAgCiAgICAgICAgIGVuZDsgICAKIExleGljYWxNaW5Sb3RhdGlvbjo9azsgCiAgICAgCmVuZDsKCmZ1bmN0aW9uIFJhYmluICh2YXIgeDogQW5zaXN0cmluZykgOlF3b3JkOwp2YXIgbGVuLCBpLCBSLGJhc2UsZCxxOlF3b3JkOwpiZWdpbgogICBkOj0xOyBSOj0wOyBsZW46PWxlbmd0aCh4KTsgYmFzZTo9MjY7IHE6PTg0NDY3NDQwNzM3MDk1NTE2MTU7CiAgIGZvciBpIDo9IDEgIHRvIGxlbi0xIGRvICBkIDo9IChkICogYmFzZSkgbW9kIHEgOyAKICAgZm9yIGkgOj0gMSB0byBsZW4gZG8gIFI6PSAoYmFzZSpSICsgKG9yZCh4W2ldKSkgKSBtb2QgcTsgIAogICBSYWJpbjo9IFI7IAplbmQ7IAoKCgpiZWdpbgogICAoKmFzc2lnbihpbnB1dCwgJ2lucHV0LnR4dCcpOyByZXNldChpbnB1dCk7CiAgIGFzc2lnbihvdXRwdXQsICdvdXRwdXQudHh0Jyk7IHJld3JpdGUob3V0cHV0KTsqKQogICByZWFkbG4gKE4sTSk7CiAgIGZvciB3Oj0wIHRvIE4tMSBkbyBiZWdpbiByZWFkbG4oU1t3XSk7ICBTW3ddOj1UcmltKFNbd10pOyBlbmQ7CiAgIGZvciB3Oj0wIHRvIE4tMSBkbyBiZWdpbiBIW3ddOj0wOyBhY2NvcHBpYXRhW3ddOj1mYWxzZTsgYWNjb3BwaWFtZW50aVt3XTo9MDsgZW5kOwogICBjb3BwaWU6PTA7ICAKICBmb3Igdzo9MCB0byBOLTEgZG8KICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgIGluZGV4Oj1MZXhpY2FsTWluUm90YXRpb24oU1t3XSk7CiAgICAgICAgICAgIFNfcnVvdGF0ZVt3XTo9Y29weShTW3ddLGluZGV4LE0pOyAgCiAgICAgICAgICAgIEhbd106PVJhYmluKFNfcnVvdGF0ZVt3XSk7CiAgICAgICAgICBlbmQ7CiAgIHc6PTA7ICAgICAgIAogICB3aGlsZSB3PE4tMSBkbyAgCiAgICAgICBiZWdpbiAKICAgICAgICAgICBpZiBhY2NvcHBpYXRhW3ddPWZhbHNlIHRoZW4gCiAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIHY6PXcrMSB0byBOLTEgZG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgSFt3XT1IW3ZdIHRoZW4gIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDOj0gQ29tcGFyZVN0cihTX3J1b3RhdGVbd10sIFNfcnVvdGF0ZVt2XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBDPTAgdGhlbiBiZWdpbiBhY2NvcHBpYW1lbnRpW3ddOj1hY2NvcHBpYW1lbnRpW3ddKzE7IGFjY29wcGlhdGFbd106PXRydWU7IGFjY29wcGlhdGFbdl06PXRydWU7IGVuZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZDsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3Oj13KzE7ICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgICAgZWxzZSBiZWdpbiB3Oj13KzE7ICAgY29udGludWU7IGVuZDsgCiAgICAgICBlbmQ7ICAKICAgZm9yIHc6PTAgdG8gTi0xICBkbyAKICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICAgaWYgYWNjb3BwaWFtZW50aVt3XSA9MSB0aGVuIGNvcHBpZTo9Y29wcGllKzEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBhY2NvcHBpYW1lbnRpW3ddPjEgdGhlbiBjb3BwaWU6PWNvcHBpZSsoKGFjY29wcGlhbWVudGlbd10rMSkqKGFjY29wcGlhbWVudGlbd10pIGRpdiAyKTsKICAgICAgICAgICAgICAgZW5kOyAgICAgICAgIAogICB3cml0ZWxuIChjb3BwaWUpOwplbmQu