#include <stdio.h>
#include <stdlib.h>
struct dice_face {
int a;
int b;
int c;
int d;
};
struct dice_face translate_dice(char** list) {
int rows[6];
int count = 0;
for (int i = 0; i<5; i++) {
int empty = 1;
for (int j = 0; j<5; j++) {
if (list[i][j] != '.') empty = 0;
}
rows[i] = empty;
if (empty) count++;
}
rows[5] = count;
count = 0;
int columns[6];
for (int i = 0; i<5; i++) {
int empty = 1;
for (int j = 0; j<5; j++) {
if (list[j][i] != '.') empty = 0;
}
columns[i] = empty;
if (empty) count++;
}
columns[5] = count;
int special = 0;
if (columns[5] == 0 || rows[5] == 0) special = 1;
//printf("Rows: %d, columns: %d\n", rows[5], columns[5]);
int list2[4][3];
int list3[5][2];
if(special) {
for (int i = 0; i<5; i++) {
if (rows[i]) continue;
for (int j = 0; j<5;j++) {
if (columns[j]) continue;
//printf("%d - %d\n", i,j);
for (int k=0; k<5;k++) {
for (int l=0; l<2;l++) {
if (columns[5] == 0) {
//printf("%d %d %c\n",i+1-l,j+k,list[i+1-l][j+k]);
if (list[i+1-l][j+k] == '.') {
list3[k][l] = 0;
} else {
list3[k][l] = list[i+1-l][j+k]-'0';
}
}
if (rows[5] == 0) {
//printf("%d %d %c\n",i+k,j+l,list[i+k][j+l]);
if (list[i+k][j+l] == '.') {
list3[k][l] = 0;
} else {
list3[k][l] = list[i+k][j+l]-'0';
}
}
}
}
break;
}
break;
}
} else {
for (int i = 0; i<5; i++) {
if (rows[i]) continue;
for (int j = 0; j<5;j++) {
if (columns[j]) continue;
//printf("%d - %d\n", i,j);
for (int k=0; k<4;k++) {
for (int l=0; l<3;l++) {
if (rows[5] == 2 && columns[5] == 1) {
if (list[i+l][j+k] == '.') {
list2[k][2-l] = 0;
} else {
list2[k][2-l] = list[i+l][j+k]-'0';
}
}
if (rows[5] == 1 && columns[5] == 2) {
if (list[i+k][j+l] == '.') {
list2[k][l] = 0;
} else {
list2[k][l] = list[i+k][j+l]-'0';
}
}
}
}
break;
}
break;
}
}
int combinations[6][4] = {{5,4,6,3},{6,4,5,3},{5,1,6,2},{5,2,6,1},{2,4,1,3},{1,4,2,3}};
int axel1[2] = {0,0};
int axel2[2] = {0,0};
int axel3[2] = {0,0};
if (!special) {
axel1[0] = list2[1][1];
if (!axel1[1] && list2[3][1]) axel1[1] = list2[3][1];
if (!axel2[0] && list2[1][0]) axel2[0] = list2[1][0];
if (!axel2[1] && list2[1][2]) axel2[1] = list2[1][2];
if (!axel3[0] && list2[0][1]) axel3[0] = list2[0][1]; // trivial 1,2,3,4,5,6
if (!axel3[1] && list2[2][1]) axel3[1] = list2[2][1];
if (!axel1[1] && list2[3][0]) axel1[1] = list2[3][0];
if (!axel1[1] && list2[3][2]) axel1[1] = list2[3][2];
if (!axel3[0] && list2[0][0] && list2[1][0]) axel3[0] = list2[0][0]; // 5
if (!axel3[0] && list2[0][2] && list2[1][2]) axel3[0] = list2[0][2];
if (!axel3[1] && list2[1][0] && list2[2][0]) axel3[0] = list2[2][0]; // 6
if (!axel3[1] && list2[2][1] && list2[2][2]) axel3[0] = list2[2][2];
if (!axel2[0] && list2[0][1] && list2[0][0]) axel2[0] = list2[0][0]; // 3
if (!axel2[0] && list2[2][1] && list2[2][0]) axel2[0] = list2[2][0];
if (!axel2[0] && list2[3][1] && list2[3][0]) axel2[0] = list2[3][0];
if (!axel2[1] && list2[0][1] && list2[0][2]) axel2[1] = list2[0][2]; // 4
if (!axel2[1] && list2[2][1] && list2[2][2]) axel2[1] = list2[2][2];
if (!axel2[1] && list2[3][1] && list2[3][2]) axel2[1] = list2[3][2];
} else {
if (list3[0][0]) {
axel1[0] = list3[0][0];
axel1[1] = list3[2][0];
axel2[0] = list3[4][1];
axel2[1] = list3[2][1];
axel3[0] = list3[3][1];
axel3[1] = list3[1][0];
} else {
axel1[0] = list3[0][1];
axel1[1] = list3[2][1];
axel2[0] = list3[2][0];
axel2[1] = list3[4][0];
axel3[0] = list3[3][0];
axel3[1] = list3[1][1];
}
}
//printf("%d-%d %d-%d %d-%d\n", axel1[0],axel1[1],axel2[0],axel2[1],axel3[0],axel3[1]);
int axels[6] = {axel1[0],axel1[1],axel2[0],axel2[1],axel3[0],axel3[1]};
int face[4] = {0,0,0,0};
int face_ordered[4] = {0,0,0,0};
int min[2] = {7,0};
for (int i = 0; i<6; i++) {
if (axels[i] == 1) {
for (int j=0; j<4; j++) {
//printf("%d-%d-%d-%d\n", i,j,combinations[i][j],axels[combinations[i][j]-1]);
face[j] = axels[combinations[i][j]-1];
}
break;
}
}
for (int i=0; i<4; i++) {
if (face[i]<min[0]) {
min[0] = face[i];
min[1] = i;
}
}
for (int i = min[1]; i<4; i++) face_ordered[i-min[1]] = face[i];
for (int i = 0; i<min[1]; i++) face_ordered[i+(4-min[1])] = face[i];
//for (int i = 0; i<4; i++) printf("%d", face_ordered[i]);
//printf("\n");
/*int range_x = (special) ? 2 : 3;
int range_y = (special) ? 5 : 4;
for (int i=0; i<range_y; i++) {
for (int j=0; j<range_x; j++) {
if (special) {
printf("%d", list3[i][j]);
} else {
printf("%d", list2[i][j]);
}
}
printf("\n");
}*/
struct dice_face result;
result.a = face_ordered[0];
result.b = face_ordered[1];
result.c = face_ordered[2];
result.d = face_ordered[3];
return result;
}
void free_all(char** dices, struct dice_face* results) {
for (int j=0; j<5;j++) {
free(dices[j]);
}
free(dices);
free(results);
//printf("all freed\n");
return;
}
void print_dice(char** dices) {
for (int i = 0; i<5 ; i++) {
for (int j = 0; j<5; j++) {
printf("%c", dices[i][j]);
}
printf("\n");
}
printf("\n\n");
printf("-----\n");
return;
}
int main() {
int num = getc(stdin)-'0';
//printf("num: %d\n", num);
char** dices = malloc(5*sizeof(char*));
for (int i = 0; i<5; i++) {
dices[i] = (char*)malloc(5*sizeof(char));
}
struct dice_face* results = malloc(num*sizeof(struct dice_face));
for (int k=0; k<num ; k++) {
for (int i = 0; i<5 ; i++) {
for (int j = 0; j<5; j++) {
dices[i][j] = getc(stdin);
if (dices[i][j]=='\n') j--;
}
}
results[k] = translate_dice(dices);
//printf("%d done\n", k);
//print_dice(dices);
}
/*for (int i=0; i<num; i++) {
printf("%d - %d - %d - %d\n", results[i].a,results[i].b,results[i].c,results[i].d);
}*/
int count = 0;
for (int i=0; i<num; i++) {
for (int j=0; j<num; j++) {
if (i==j) continue;
if (results[i].a == results[j].a && results[i].b == results[j].b && results[i].c == results[j].c && results[i].d == results[j].d) {
printf("%d ", j+1);
count++;
}
}
if (!count) printf("-");
printf("\n");
count = 0;
}
free_all(dices, results);
return 0;
}