// This program reads a list of permutations.  These come from
// standard input.  
//
// It checks that each permutation read is ``good'', i.e. satisfies
// Conditions~1 and~2, and moreover that it also satisfies
// Condition~3.
//
// Then it calculates the conjugates of this permutations under the
// 48-element group generated by (a) $j\to j+1$ and (b) $j\to -5j$.
// It then outputs the _smallest_ of these conjugates.  These go to
// file _ofile_ as hardcoded below.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <complex.h>
#include <string.h>

#define FALSE 0
#define TRUE 1

#define NN 24

FILE *ofile;

void DisplayPerm(int Perm[]);
int Check3Perm(int Perm[]);
int Check4Perm(int Perm[]);
int CheckCond3(int Perm[]);

int main() {
  FILE *ifile,*ofile;
  int Perm[NN],Perm4[NN],BestPerm[NN],NewPerm[NN], 
    NewPerm2[NN],TmpPerm[NN],PowerIx,Ix,StabSiz,Diff;

  ofile=fopen("tmp","w");
  assert(ofile != NULL);

  Diff=0;
  while(scanf("%*[ \n\t]") != EOF) {
    for(Ix=0;Ix<NN;Ix++)
      assert(scanf("%i ",&Perm[Ix]) == 1);

    StabSiz=0;
    memcpy(BestPerm,Perm,sizeof(BestPerm));
    memcpy(NewPerm,Perm,sizeof(NewPerm));
    for(PowerIx=0;PowerIx<24;PowerIx++) {
      // Is this permutation equal to the original permutation?
      if(memcmp(Perm,NewPerm,sizeof(Perm)) == 0)StabSiz++;
      // Replace BestPerm, if this one is smaller
      if(memcmp(NewPerm,BestPerm,sizeof(BestPerm))<0)
	memcpy(BestPerm,NewPerm,sizeof(BestPerm));
      // Check Condition 1
      assert(Check3Perm(NewPerm));
      // Check Condition 2
      for(Ix=0;Ix<NN;Ix++) 
	Perm4[Ix] = (NewPerm[Ix] + 4) % 24;
      assert(Check4Perm(Perm4));
      // Check Condition 3
      assert(CheckCond3(NewPerm));

      // Apply conjugation by $j\mapsto 11j$
      for(Ix=0;Ix<NN;Ix++)
	NewPerm2[((24-5)*Ix) % 24]=((24-5)*NewPerm[Ix]) % 24;
      // Is this equal to the original permutation?
      if(memcmp(Perm,NewPerm2,sizeof(Perm)) == 0)StabSiz++;
      // Replace BestPerm, if this new one is smaller
      if(memcmp(NewPerm2,BestPerm,sizeof(BestPerm))<0)
	memcpy(BestPerm,NewPerm2,sizeof(BestPerm));
      // Check Conditions 1, 2, and 3
      assert(Check3Perm(NewPerm2));
      for(Ix=0;Ix<NN;Ix++) 
	Perm4[Ix] = (NewPerm2[Ix] + 4) % 24;
      assert(Check4Perm(Perm4));
      assert(CheckCond3(NewPerm2));

      // Apply conjugation by $j\mapsto j+1$
      for(Ix=0;Ix<NN;Ix++)TmpPerm[(Ix+1) % 24]=(NewPerm[Ix]+1) % 24;
      memcpy(NewPerm,TmpPerm,sizeof(NewPerm));
    }
    assert(StabSiz>=1);
    assert(StabSiz<=48);
    assert(48 % StabSiz == 0);
    if(StabSiz>1 && memcmp(Perm,BestPerm,sizeof(Perm)) == 0) {
      Diff+=48 - 48/StabSiz;
      printf("|Stabilizer|=%2i  ,  |Orbit|=%2i for\n",StabSiz,48/StabSiz);
      //DisplayPerm(Perm);
      for(Ix=0;Ix<NN;Ix++)printf("%3i",Perm[Ix]);
      printf("\n\n");
    }
    for(Ix=0;Ix<NN;Ix++)fprintf(ofile,"%3i",BestPerm[Ix]);
    fprintf(ofile,"\n");
  }
  printf("Diff=%i\n",Diff); // Total size = 48*(# of orbits) - Diff
}


// Displays the cycle representation of a permutation 
void DisplayPerm(int Perm[]) {
  int StartIx,Ix,Displayed[NN];

  memset(Displayed,0,sizeof(Displayed));

  StartIx=0;
  while(StartIx<NN) {
    printf("(");
    Ix=StartIx;
    while(TRUE) {
      printf("%3i",Ix);
      Displayed[Ix]=TRUE;
      Ix=Perm[Ix];
      if(Ix == StartIx)break;
    }
    printf(") ");
    for(StartIx++;StartIx<NN && Displayed[StartIx];StartIx++);
  }
  printf("\n");

  return;
}

// Checks ``Condition 3'' for a permutation.  This condition is that
// if
//
//   \gamma_A(j)=11+Perm[j]
//   \gamma_B(j)=17+Perm[j]
//
// then for every $j$ there exist indices $p$, $q$, and $r$ so that
//
//   \gamma_p(\gamma_p(\gamma_r(j)))=j
//
int CheckCond3(int Perm[]) {
  int Choice[3],Summand[3],Chain[4],StepIx,Ix,OK;
  int Options[2]={11,-7};

  for(Ix=0;Ix<NN;Ix++) {
    OK=FALSE;
    for(Choice[0]=0;Choice[0]<2;Choice[0]++) {
      for(Choice[1]=0;Choice[1]<2;Choice[1]++) {
	for(Choice[2]=0;Choice[2]<2;Choice[2]++) {
	  Chain[0]=Ix;
	  for(StepIx=0;StepIx<3;StepIx++) {
	    Summand[StepIx]=Options[Choice[StepIx]];
	    Chain[StepIx+1]=(Perm[Chain[StepIx]]+Summand[StepIx]+24) % 24;
	  }
	  if(Chain[3] == Chain[0]) {
	    OK=TRUE;
	    break;
	  }
	}
	if(OK)break;
      }
      if(OK)break;
    }
    if(!OK)return FALSE;
  }
  return TRUE;
}

// Check whether a permutations is all 3-cycles (1-cycles NOT allowed)
int Check3Perm(int Perm[]) {
  int Ix,C0,C1,C2,Checked[NN];

  memset(Checked,FALSE,sizeof(Checked));

  //printf("Check3Perm A: Perm=");
  //for(Ix=0;Ix<NN;Ix++)printf("%3i",Ix);
  //printf("\n                   ");
  //for(Ix=0;Ix<NN;Ix++)printf("%3i",Perm[Ix]);
  //printf("\n");

  for(Ix=0;Ix<NN;Ix++)assert(Perm[Ix]>=0 && Perm[Ix]<NN);

  for(Ix=0;Ix<NN;Ix++) {
    if(Checked[Ix])continue;
    C0=Ix;
    C1=Perm[C0];
    if(C0 == C1)return FALSE;
    C2=Perm[C1];
    if(C0 != Perm[C2])return FALSE;
    Checked[C0]=Checked[C1]=Checked[C2]=TRUE;
  }

  return TRUE;
}

// Check whether a permutations is all 4-cycles (1-cycles NOT allowed)
int Check4Perm(int Perm[]) {
  int Ix,C0,C1,C2,C3,Checked[NN];

  memset(Checked,FALSE,sizeof(Checked));

  for(Ix=0;Ix<NN;Ix++) {
    if(Checked[Ix])continue;
    C0=Ix;
    C1=Perm[C0];
    if(C0 == C1)return FALSE;
    C2=Perm[C1];
    if(C0 == C2)return FALSE;
    C3=Perm[C2];
    if(C0 != Perm[C3])return FALSE;
    Checked[C0]=Checked[C1]=Checked[C2]=Checked[C3]=TRUE;
  }

  return TRUE;
}
