#include <cstdio>
#include <vector>
using namespace std;

#define kom "Liczba bezpiecznych ustawień n księżnych na szachownicy n x n"
#define Nmin 1		//minimalny rozmiar szachownicy
#define Nmax 6		//maksymalny rozmiar szachownicy
#define Nfig N	//liczba figur do ustawienia
#define SKOCZEK 1	//0 - goniec, 1 - księżna(gońcoskoczek)
#define POKAZ 0		//0 - tylko liczba, 1 - plansze, 2 - zajęte wiersze na przekątnych

int N,count;

bool D[Nmax*2]; 

struct plansza {bool P[Nmax][Nmax];
  bool operator==(const plansza &P);
  bool equals(plansza P);
  void  symH();
  bool eq_rot180(const plansza &P);
  bool eq_rot90(const plansza &P);
  bool eq_rot270(const plansza &P);
  }P0,P;
vector<plansza> tpl;

struct pozycje {int K[Nmax*2];}K;

//vector<pozycje> tp;

void show(const pozycje &P,int t);
bool ss(int w, int k);

void uws(int p, int n) {
  if (n==0) {
    ++count;  
    bool same=false;
    for (int i=0;!same && i<tpl.size();++i)  same=tpl[i].equals(P);
    if (!same) {
      tpl.push_back(P);
      show(K,POKAZ);
      }
    //tp.push_back(K); 
    return;
    }
  if (p>2*N-1) return;
  if (n<2*N-1-p) {
    K.K[p]=-1;    
    //printf("p[%d]=-1 -> p=%d,n=%d\n",p,p+1,n);
    uws(p+1,n);
    }    
  int wp = p<N ? 0 : p-N+1;
  int wk = p>=N ? N-1 : p;
  for (int w = wp; w<=wk ;++w) {
    int k=  p-w;
    if (D[k-w+N]) continue;
    if (SKOCZEK && !ss(w,p)) continue;
    D[k-w+N]=true;
    K.K[p]=w;
    P.P[w][k]=true;
    //printf("gs[%d,%d] -> p=%d,n=%d\n",w,k,p+1,n-1); show(K,1);
    uws(p+1,n-1);
    D[k-w+N]=false;
    K.K[p]=-1;
    P.P[w][k]=false;
    }
  }

int main() {
puts(kom);
printf("\tall\tdistinct\n");    
for (N=Nmin;N<=Nmax;++N) {
  //tp.clear();
  tpl.clear();
  count=0;
  P=P0;
  for(int i=0;i<2*N-1;++i) K.K[i]=-1;
  uws(0,Nfig);
  printf("n=%d\t%d\t%d\n",N,count,tpl.size());
//  for(int i=0;i<tp.size();++i) {printf("%d\n",i);}
  }
return 0;
}

//-------------------------------------------------------------

void show(const pozycje &P, int t) {
  if (t==1) {
    for (int i=0;i<N;++i) { 
      for (int j=0;j<N;++j)
        printf("%c",P.K[i+j]==i?'X':'o');
      printf("\n");
      }
    printf("\n");
    }
  else if (t==2) {
    for (int i=0;i<2*N-1;++i) 
      printf("%d",P.K[i]);
    printf("\n");
    }
  }

bool ss(int w, int p) {
  if (p<2) return true;
  if (K.K[p-1]>-1) {
    if (w-K.K[p-1]==2) return false;
    if (K.K[p-1]-w==1) return false;
    }
  if (p<3) return true;
  if (K.K[p-3]>-1) {
    if (w-K.K[p-3]==1) return false;
    if (w-K.K[p-3]==2) return false;    
    }
  return true;
  }

bool plansza::operator==(const plansza &Q) {
  bool ok=true;    
  for (int i=0;ok && i<N;++i)
    for (int j=0;ok &&j<N;++j)
      ok=P[i][j]==Q.P[i][j];
  return ok;    
  }

void plansza::symH() {
  for (int i=0;i<N;++i)
    for (int j=0;j<(N+1)/2;++j) {
      bool p=P[i][j];
      P[i][j]=P[i][N-1-j];
      P[i][N-1-j]=p;
      } 
  };

bool plansza::eq_rot90(const plansza &Q) {
  bool ok=true;
  for (int i=0;ok&&i<N;++i)
    for (int j=0;ok&&j<N;++j)
       ok = Q.P[j][N-1-i]==P[i][j];
  return ok;
  }

bool plansza::eq_rot180(const plansza &Q) {
  bool ok=true;
  for (int i=0;ok&&i<N;++i)
    for (int j=0;ok&&j<N;++j)
       ok = Q.P[N-1-i][N-1-j]==P[i][j];
  return ok;
  }

bool plansza::eq_rot270(const plansza &Q) {
  bool ok=true;
  for (int i=0;ok&&i<N;++i)
    for (int j=0;ok&&j<N;++j)
       ok = Q.P[N-1-j][i]==P[i][j];
  return ok;
  }

bool plansza::equals(plansza P) {
  if (eq_rot90(P)) return true;
  if (eq_rot180(P)) return true;
  if (eq_rot270(P)) return true;
  P.symH();
  if (*this==P) return true;
  if (eq_rot90(P)) return true;
  if (eq_rot180(P)) return true;
  if (eq_rot270(P)) return true;
  return false;
  }