Const SOUBOR_VSTUP = 'mrizka.txt';
      SOUBOR_VYSTUP = 'vystup.txt';
      MaxN = 16;
Type TMrizka = Array [0 .. MaxN+1, 0 .. MaxN+1] Of Boolean;
     TVelikost = 1 .. MaxN;
Var M : TMrizka;
    N : TVelikost; { velikost mrizky }
    Max : Integer;
    I : Integer;
    S : String;



{ Prevede znak z fiktivniho retezce na pozivi v mrizce,
  Pozice je pozice v retezci, pocitano od nuly.
  (X,Y) jsou souradnice v poli TMrizka }
Procedure Convert(Pozice : Integer; Kvadrant : Char;
          Var X, Y : Integer);
Var kx, ky : Integer; { pozice v kvadrantu }
    M : Integer; {N/2}
Begin
  M := N Div 2;
  kx := Pozice Mod M;
  ky := Pozice Div M;

  Case Kvadrant Of
    'A' : Begin
            X := kx;
            Y := ky;
          End;
    'B' : Begin
            Y := kx;
            X := -ky - 1;
          End;
    'C' : Begin
            X := -kx - 1;
            Y := -ky - 1;
          End;
    'D' : Begin
            X := ky;
            Y := -kx - 1;
          End;
  End;
  X := X + M + 1;
  Y := Y + M + 1;
End;

Function DiraOk(X, Y : Integer) : Boolean;
Begin
  DiraOk := Not (M[X+1, Y] Or M[X-1, Y] Or M[X, Y-1] Or M[X, Y+1])
End;


{ nacte mrizku ze souboru }
Procedure NactiMrizku;
Var I, J, B : Integer;
    F : Text;
Begin
  { otevreni souboru pro cteni }
  Assign(F, SOUBOR_VSTUP);
  Reset(F);

  { nacteni dat }
  Readln(F, N);
  For J := 1 To N Do
    Begin
      For I := 1 To N Do
        Begin
          Read(F, B);
          M[I, J] := B > 0;
        End;
    End;

  {Vynulovani okraju}
  For I := 0 To N+1 Do
    Begin
      M[0, I] := False;
      M[I, 0] := False;
      M[I, N+1] := False;
      M[N+1, I] := False;
    End;

  { uzavreni souboru }
  Close(F);
End;


Procedure NastavRetezec;
Var I, X, Y : Integer;
    C : Char;
Begin
  S := '';
  For I := 1 To N*N Div 4 Do
    Begin
      S := S + 'X';

      { Otestujeme, zda je na teto pozici dira }
      For C := 'A' To 'D' Do
        Begin
          Convert(I-1, C,  X, Y);
          If M[X, Y] Then
            Begin
              S[I] := C;
              Break;
            End;
        End;

    End;
End;


Function R(D : Integer) : Longint;
Var Sum : Longint;
    X, Y : Integer;
    C : Char;
Begin
  If D = Max Then
    R := 1
  Else If S[D+1] <> 'X' Then
    R := R(D+1)
  Else
    Begin
      Sum := 0;

      { Cyklus pres vsechny kamarady }
      For C := 'A' To 'D' Do
        Begin
          Convert(D, C, X, Y);

          { Vyrobime diru, a zavolame R }
          If DiraOk(X, Y) Then
            Begin
              M[X, Y] := True;
              S[D+1] := C;
              Sum := Sum + R(D+1);
              M[X, Y] := False;
            End;

        End;
      S[D+1] := 'X';
      R := Sum;
    End;
End;


Procedure ZapisVysledek(V : Longint);
Var F : Text;
Begin
  { otevreni souboru pro zapis }
  Assign(F, SOUBOR_VYSTUP);
  Rewrite(F);
  Writeln(F, V);
  Close(F);
End;

Begin
  NactiMrizku;
  Max := N*N Div 4;
  NastavRetezec;
  Writeln(R(0));
  ZapisVysledek(R(0));
End.