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 :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;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;
for w:=0 to N-2 do
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 coppie:=coppie+1; accoppiata[w]:=true; accoppiata[v]:=true; end;
end;
writeln(w,' ',v);
end;
end;
writeln (coppie);
for w:= 0 to N-1 do writeln(accoppiata[w]);
end.
cHJvZ3JhbSBjYXNpbm87ICAKVXNlcyBzeXN1dGlsczsKeyRIK30KY29uc3QgbHVuZz0xMDAwMDAwOwp0eXBlIGVsZW5jbz1hcnJheVswLi5sdW5nLTFdIG9mIFF3b3JkOwp2YXIgIE4sTSx3LHYsQyx0LGNvcHBpZSxpbmRleDpRd29yZDsKICAgICBTLFNfcnVvdGF0ZTphcnJheVswLi5sdW5nXSBvZiBBbnNpU3RyaW5nOwogICAgIGZ1bnpfZXJyb3JlOiBhcnJheVswLi4xMDAwMDAwXSBvZiBJbnQ2NDsKICAgICBIIDplbGVuY287CiAgICAgYWNjb3BwaWF0YTogYXJyYXlbMC4uMTAwMDAwMF0gb2YgYm9vbGVhbjsKICAgIApmdW5jdGlvbiBMZXhpY2FsTWluUm90YXRpb24odmFyIHg6IEFuc2lTdHJpbmcpOlF3b3JkOwp2YXIgCmxlbixLLGo6UXdvcmQ7Cmk6SW50NjQ7CgpiZWdpbgogICB4Oj14K3g7IAogICBsZW46PWxlbmd0aCh4KTsgCiAgIGZvciBpOj0wIHRvIGxlbiBkbyBmdW56X2Vycm9yZVtpXTo9LTE7IAogICBLOj0xOyAKICAgZm9yIGo6PTIgdG8gbGVuIGRvICAgCiAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgIGk6PSBmdW56X2Vycm9yZVtqLWstMV07CiAgICAgICAgICAgICB3aGlsZSAoaSA8PiAtMSApIGFuZCAoeFtqXSA8PiB4WyhrICsgaSsxICldKSBkbyAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgeFtqXSA8IHhbKGsgKyBpKzEgKV0gdGhlbiBrOj0gaiAtIGkgLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpOj1mdW56X2Vycm9yZVtpXTsgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZDsgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGkgPSAtMSkgYW5kICh4W2pdIDw+IHhbKGsgKyBpKzEgKV0pIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiB4W2pdIDwgeFsoayArIGkrMSApXSB0aGVuIGs6PSBqOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuel9lcnJvcmVbaiAtIGtdOj0gLTE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSAgIGZ1bnpfZXJyb3JlW2ogLSBrXTo9IGkgKyAxOwogICAgICAgICAgICAgICAKICAgICAgICAgZW5kOyAgIAogTGV4aWNhbE1pblJvdGF0aW9uOj1rOyAKICAgICAKZW5kOwoKZnVuY3Rpb24gUmFiaW4gKHZhciB4OiBBbnNpc3RyaW5nKSA6UXdvcmQ7CnZhciBsZW4sIGksIFIsYmFzZSxkLHE6UXdvcmQ7CmJlZ2luCiAgIGQ6PTE7IFI6PTA7IGxlbjo9bGVuZ3RoKHgpOyBiYXNlOj0yNjsgcTo9ODQ0Njc0NDA3MzcwOTU1MTYxNTsKICAgZm9yIGkgOj0gMSAgdG8gbGVuLTEgZG8gIGQgOj0gKGQgKiBiYXNlKSBtb2QgcSA7IAogICBmb3IgaSA6PSAxIHRvIGxlbiBkbyAgUjo9IChiYXNlKlIgKyAob3JkKHhbaV0pKSApIG1vZCBxOyAgCiAgIFJhYmluOj0gUjsgCmVuZDsgCgoKCmJlZ2luCiAgICgqYXNzaWduKGlucHV0LCAnaW5wdXQudHh0Jyk7IHJlc2V0KGlucHV0KTsKICAgYXNzaWduKG91dHB1dCwgJ291dHB1dC50eHQnKTsgcmV3cml0ZShvdXRwdXQpOyopCiAgIHJlYWRsbiAoTixNKTsKICAgZm9yIHc6PTAgdG8gTi0xIGRvIGJlZ2luIHJlYWRsbihTW3ddKTsgIFNbd106PVRyaW0oU1t3XSk7IGVuZDsKICAgZm9yIHc6PTAgdG8gTi0xIGRvIGJlZ2luIEhbd106PTA7IGFjY29wcGlhdGFbd106PWZhbHNlO2VuZDsKICAgY29wcGllOj0wOyAgCiAgZm9yIHc6PTAgdG8gTi0xIGRvCiAgICAgICAgICBiZWdpbgogICAgICAgICAgICBpbmRleDo9TGV4aWNhbE1pblJvdGF0aW9uKFNbd10pOwogICAgICAgICAgICBTX3J1b3RhdGVbd106PWNvcHkoU1t3XSxpbmRleCxNKTsgIAogICAgICAgICAgICBIW3ddOj1SYWJpbihTX3J1b3RhdGVbd10pOwogICAgICAgICAgZW5kOwogICBmb3Igdzo9MCB0byBOLTIgZG8gIAogICAgICBpZiBhY2NvcHBpYXRhW3ddPWZhbHNlIHRoZW4gYmVnaW4KICAgICAgICAgIGZvciB2Oj13KzEgdG8gTi0xIGRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChIW3ddPUhbdl0pIHRoZW4gIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDOj0gQ29tcGFyZVN0cihTX3J1b3RhdGVbd10sIFNfcnVvdGF0ZVt2XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBDPTAgdGhlbiBiZWdpbiBjb3BwaWU6PWNvcHBpZSsxOyBhY2NvcHBpYXRhW3ddOj10cnVlOyBhY2NvcHBpYXRhW3ZdOj10cnVlOyBlbmQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVsbih3LCcgJyx2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOwogICAgICAgICAgICAgCiAgICAgICAgICAgICAgZW5kOwogICAgICAgICAgICAgIAogICAgd3JpdGVsbiAoY29wcGllKTsKICAgIGZvciB3Oj0gMCB0byBOLTEgZG8gd3JpdGVsbihhY2NvcHBpYXRhW3ddKTsKZW5kLg==