program casino; (*con Algoritmo di Booth*)
Uses sysutils;
{$H+}
const lung=1000000;
var N,M,C,w,v,coppie,index:Int64;
S,S_ruotate:array[0..lung] of AnsiString;
funz_errore : array[0..2000000] of Int64;
accoppiamenti:array[0..lung] of int64;
accoppiata: array[0..lung] of boolean;
function LexicalMinRotation(var x: AnsiString):Int64;
var
len,K,i,j:Int64;
begin
x:=x+x; (*concatenare la stringa con se stessa*)
len:=length(x);
for i:=0 to len do funz_errore[i]:=-1; (*inizializzare il vettore, di dimensione doppia della lunghezza della stringa,chiamato funzione_errore a -1*)
K:=1; (*indice che corrisponde al candidato corrente alla rotazione più piccola. Ricordare che le Ansistring iniziano da 1*)
for j:=2 to len do (*confronta il carattere in j con il carattere in K+funz_errore[k]*)
begin
i:= funz_errore[j-k-1];
while (i <> -1 ) and (x[j] <> x[(k + i+1 )]) do (*Se c'è una discrepanza aggiorna il valore di k*)
begin
if x[j] < x[(k + i+1 )] then k:= j - i - 1;
i:=funz_errore[i]; (*modificare la funzione errore in base al confronto effettuato *)
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; (*dopo aver completato il processo k indica indice della rotazione minima*)
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]); accoppiamenti[w]:=0; accoppiata[w]:=false; end;
coppie:=0;
for w:=0 to N-1 do
begin
index:=LexicalMinRotation(S[w]);
S_ruotate[w]:=copy(S[w],index,M);
end;
for w:=0 to N-2 do
begin
if accoppiata[w]= false then
for v:=w+1 to N-1 do
begin
if accoppiata[v]=false 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
else 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.
cHJvZ3JhbSBjYXNpbm87ICgqY29uIEFsZ29yaXRtbyBkaSBCb290aCopClVzZXMgc3lzdXRpbHM7CnskSCt9CmNvbnN0IGx1bmc9MTAwMDAwMDsKdmFyICBOLE0sQyx3LHYsY29wcGllLGluZGV4OkludDY0OwogICAgIFMsU19ydW90YXRlOmFycmF5WzAuLmx1bmddIG9mIEFuc2lTdHJpbmc7CiAgICAgZnVuel9lcnJvcmUgOiBhcnJheVswLi4yMDAwMDAwXSBvZiBJbnQ2NDsKICAgICBhY2NvcHBpYW1lbnRpOmFycmF5WzAuLmx1bmddIG9mIGludDY0OwogICAgIGFjY29wcGlhdGE6IGFycmF5WzAuLmx1bmddIG9mIGJvb2xlYW47CiAgICAKZnVuY3Rpb24gTGV4aWNhbE1pblJvdGF0aW9uKHZhciB4OiBBbnNpU3RyaW5nKTpJbnQ2NDsKdmFyIApsZW4sSyxpLGo6SW50NjQ7CgpiZWdpbgogICB4Oj14K3g7ICgqY29uY2F0ZW5hcmUgbGEgc3RyaW5nYSBjb24gc2Ugc3Rlc3NhKikKICAgbGVuOj1sZW5ndGgoeCk7IAogICBmb3IgaTo9MCB0byBsZW4gZG8gZnVuel9lcnJvcmVbaV06PS0xOyAoKmluaXppYWxpenphcmUgaWwgdmV0dG9yZSwgZGkgZGltZW5zaW9uZSBkb3BwaWEgZGVsbGEgbHVuZ2hlenphIGRlbGxhIHN0cmluZ2EsY2hpYW1hdG8gZnVuemlvbmVfZXJyb3JlIGEgLTEqKQogICBLOj0xOyAoKmluZGljZSBjaGUgY29ycmlzcG9uZGUgYWwgY2FuZGlkYXRvIGNvcnJlbnRlIGFsbGEgcm90YXppb25lIHBpw7kgcGljY29sYS4gUmljb3JkYXJlIGNoZSBsZSBBbnNpc3RyaW5nIGluaXppYW5vIGRhIDEqKQogICBmb3Igajo9MiB0byBsZW4gZG8gICAoKmNvbmZyb250YSBpbCBjYXJhdHRlcmUgaW4gaiBjb24gaWwgY2FyYXR0ZXJlIGluIEsrZnVuel9lcnJvcmVba10qKQogICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgICBpOj0gZnVuel9lcnJvcmVbai1rLTFdOwogICAgICAgICAgICAgd2hpbGUgKGkgPD4gLTEgKSBhbmQgKHhbal0gPD4geFsoayArIGkrMSApXSkgZG8gICAoKlNlIGMnw6ggdW5hIGRpc2NyZXBhbnphIGFnZ2lvcm5hIGlsIHZhbG9yZSBkaSBrKikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHhbal0gPCB4WyhrICsgaSsxICldIHRoZW4gazo9IGogLSBpIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaTo9ZnVuel9lcnJvcmVbaV07ICAgICAgICAgICAgICAgKCptb2RpZmljYXJlIGxhIGZ1bnppb25lIGVycm9yZSBpbiBiYXNlIGFsIGNvbmZyb250byBlZmZldHR1YXRvICopCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChpID0gLTEpIGFuZCAoeFtqXSA8PiB4WyhrICsgaSsxICldKSB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgeFtqXSA8IHhbKGsgKyBpKzEgKV0gdGhlbiBrOj0gajsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bnpfZXJyb3JlW2ogLSBrXTo9IC0xOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgICBmdW56X2Vycm9yZVtqIC0ga106PSBpICsgMTsKICAgICAgICAgICAgICAgCiAgICAgICAgIGVuZDsgICAKIExleGljYWxNaW5Sb3RhdGlvbjo9azsgKCpkb3BvIGF2ZXIgY29tcGxldGF0byBpbCBwcm9jZXNzbyBrIGluZGljYSBpbmRpY2UgZGVsbGEgcm90YXppb25lIG1pbmltYSopCiAgICAgCmVuZDsKCmJlZ2luCiAgICgqYXNzaWduKGlucHV0LCAnaW5wdXQudHh0Jyk7IHJlc2V0KGlucHV0KTsKICAgYXNzaWduKG91dHB1dCwgJ291dHB1dC50eHQnKTsgcmV3cml0ZShvdXRwdXQpOyopCiAgIHJlYWRsbiAoTixNKTsKICAgZm9yIHc6PTAgdG8gTi0xIGRvIGJlZ2luIHJlYWRsbihTW3ddKTsgIFNbd106PVRyaW0oU1t3XSk7IGFjY29wcGlhbWVudGlbd106PTA7IGFjY29wcGlhdGFbd106PWZhbHNlOyBlbmQ7CiAgIGNvcHBpZTo9MDsgIAogIGZvciB3Oj0wIHRvIE4tMSBkbwogICAgICAgICAgYmVnaW4KICAgICAgICAgICAgaW5kZXg6PUxleGljYWxNaW5Sb3RhdGlvbihTW3ddKTsKICAgICAgICAgICAgU19ydW90YXRlW3ddOj1jb3B5KFNbd10saW5kZXgsTSk7CiAgICAgICAgICBlbmQ7CiAgIGZvciB3Oj0wIHRvIE4tMiBkbyAgCiAgICAgICAgICAgICAgIGJlZ2luIAogICAgICAgICAgICAgICAgICBpZiBhY2NvcHBpYXRhW3ddPSBmYWxzZSB0aGVuCiAgICAgICAgICAgICAgICAgICAgZm9yIHY6PXcrMSB0byBOLTEgZG8KICAgICAgICAgICAgICAgICAgICAgICBiZWdpbgogICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGFjY29wcGlhdGFbdl09ZmFsc2UgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQzo9IENvbXBhcmVTdHIoU19ydW90YXRlW3ddLCBTX3J1b3RhdGVbdl0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBDPTAgdGhlbiBiZWdpbiAgYWNjb3BwaWFtZW50aVt3XTo9YWNjb3BwaWFtZW50aVt3XSsxOyBhY2NvcHBpYXRhW3ddOj10cnVlOyBhY2NvcHBpYXRhW3ZdOj10cnVlOyBlbmQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICBlbmQ7CiAgICAgICAgICAgICAgIGVuZDsgICAgICAgICAKICAgIGZvciB3Oj0wIHRvIE4tMSBkbyAKICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICBpZiBhY2NvcHBpYW1lbnRpW3ddPTEgdGhlbiBjb3BwaWU6PWNvcHBpZSsxCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYWNjb3BwaWFtZW50aVt3XT4xIHRoZW4gY29wcGllOj1jb3BwaWUrKChhY2NvcHBpYW1lbnRpW3ddKzEpKihhY2NvcHBpYW1lbnRpW3ddKSBkaXYgMik7CiAgICAgICAgICAgICAgIGVuZDsKICAgIHdyaXRlbG4gKGNvcHBpZSk7CmVuZC4=