/*
 *  File:    SODLS9.cpp
 *  Author:  S Harry White
 *  Created: 2017-11-26
 *  Updated: 2022-01-26
 *    Tidy code.
 *  Updated: 2023-01-27
 *   Change outputFile from bufSize to outSize.
 *  Updated: 2023-01-31
 *    Change to compile with g++ for macOS.
 */

/*
 *  Makes order 9 self-orthogonal diagonal Latin squares, (SODLS).
 *
 *  Uses techniques given in the 2017 paper:
 *
 *   ****************************************************************************
 *   *                                                                          *
 *   *   Fast Algorithm for Enumerating Diagonal Latin Squares of Small Order   *
 *   *                                 by                                       *
 *   *            Stepan Kochemazov, Eduard Vatutin, Oleg Zaikin                *
 *   *                                                                          *
 *   ****************************************************************************
 *
 */

//#include <ctype.h>
#include <curses.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
//#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
//#include <sys/types.h>
#include <time.h>
#include <unistd.h>

const bool F=false, T=true;
const int N=9, NN=N*N, Nd2=N/2, M=N-1, L=M-1,
          A=(1<<N)-1, B[]={ 1, 2, 4, 8, 16, 32, 64, 128, 256 }, BM=1<<M, BMp1=BM+1;

int P[BMp1], // Power of 2, the i of B[i]
    Q[N][N], GQ[NN], UQ[NN], rU[N], cU[N], bdU, fdU, qqU[BMp1];

//--------- SODLS fill order ----------
//
//0   0  1  2  3  4  5  6  7  8 
//1  24 10 31 33 35 37 39 18 40
//2  25 32 11 43 45 47 20 49 50
//3  26 34 44 12 53 22 55 57 58
//4  27 36 46 54  9 61 63 65 66
//5  28 38 48 23 62 13 69 71 72
//6  29 41 21 56 64 70 14 75 76
//7  30 19 51 59 67 73 80 15 77
//8  17 42 52 60 68 74 79 78 16

const int row[NN]={
  0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0..8
  4, 1, 2, 3, 5, 6, 7, 8, 8,  // 9..17
  1, 7, 2, 6, 3, 5, 1, 2, 3,  //18..26
  4, 5, 6, 7, 1, 2, 1, 3, 1,  //27..35
  4, 1, 5, 1, 1, 6, 8, 2, 3,  //36..44
  2, 4, 2, 5, 2, 2, 7, 8, 3,  //45..53
  4, 3, 6, 3, 3, 7, 8, 4, 5,  //54..62
  4, 6, 4, 4, 7, 8, 5, 6, 5,  //63..71
  5, 7, 8, 6, 6, 7, 8, 8, 7   //72..80
},

col[NN]={
  0, 1, 2, 3, 4, 5, 6, 7, 8,  // 0..8
  4, 1, 2, 3, 5, 6, 7, 8, 0,  // 9..17
  7, 1, 6, 2, 5, 3, 0, 0, 0,  //18..26
  0, 0, 0, 0, 2, 1, 3, 1, 4,  //27..35
  1, 5, 1, 6, 8, 1, 1, 3, 2,  //36..44
  4, 2, 5, 2, 7, 8, 2, 2, 4,  //45..53
  3, 6, 3, 7, 8, 3, 3, 5, 4,  //54..62
  6, 4, 7, 8, 4, 4, 6, 5, 7,  //63..71
  8, 5, 5, 7, 8, 8, 7, 6, 6   //72..80
};
//=============================================== input ==================================================

void clearLine(int c) { while (c!='\n') c=getchar(); }
//   ---------

int getInt() { int n=0; scanf("%d", &n); clearLine(getchar()); return n; }
//  -------

bool getY() {
//   ----
  int c; do { c=getchar(); } while ((c==' ')|(c=='\t')|(c=='\n'));
  clearLine(c); return (c=='Y')|(c=='y');
} // getY
//=============================================== output =================================================

const int bufSize=1024, outSize=bufSize+50,
          squareBytes=NN+NN+1, numSquares=200000, outputSize=numSquares*squareBytes;
char outputFile[outSize], outputBuffer[outputSize], *outPointer=NULL; int outSquares;

int openOutput() {
//  ----------
  int sub=0; int wfd=-1; const int baseSize=bufSize+25; char baseName[baseSize], buf[outSize];
  snprintf(baseName, baseSize, "./SODLS%d", N); snprintf(buf, outSize, "%s.txt", baseName);
  do {
    if (access(buf, F_OK)!=0) break; snprintf(buf, outSize, "%s_%d.txt", baseName, ++sub);
  } while (T);
  if ((wfd=open(buf, O_CREAT|O_WRONLY, 0644))==-1) {
    char msg[outSize+50]; snprintf(msg, outSize+50, "\a\nCan't open for write %s", buf); perror(msg);
  } else {
    printf("\n... writing SODLS to file %s\n", buf); snprintf(outputFile, outSize, "%s", buf);
  }
  return wfd;
} // openOutput

bool printDLS(int Q[N][N], const int wfd) {
//   --------
  char *s=outPointer;
  for (int r=0; r<N; ++r) {
    *s++='0'+Q[r][0]; for (int c=1; c<N; ++c) { *s++=' '; *s++='0'+Q[r][c]; } *s++='\n';
  }
  *s++='\n'; outPointer=s; ++outSquares;
  if (outSquares>=numSquares) {
    if (write(wfd, outputBuffer, outputSize)!=outputSize) return F; outPointer=outputBuffer; outSquares=0;
  }
  return T;
} // printDLS

bool outputLast(const int wfd) {
//   ----------
  if (outSquares>0) { const int outBytes=outSquares*squareBytes;
    if (write(wfd, outputBuffer, outBytes)!=outBytes) return F;
  }
  return T;
} // outputLast
//================================================= make ==================================================

void initSODLS(int Q[N][N]) { // natural first row
//   ---------
  for (int i=0; i<N; ++i) { rU[i]=0; qqU[B[i]]=B[i]; } // qqU of \diagonal
  for (int c=0; c<N; c++) { Q[0][c]=c; UQ[c]=B[c]; rU[0]|=B[c]; cU[c]=B[c]; } bdU=1; fdU=BM;
} // initSODLS

bool makeSODLS1(int G[NN], int U[NN], const int wfd) {
//   ----------
  bool ok=F;
  U[76]=rU[row[76]]^A; // rl
  if (!(cU[col[76]]&U[76])) {
    cU[col[75]]|=U[75]; cU[col[76]]|=U[76];

    U[77]=cU[col[77]]^A; // cl
    if (!(rU[row[77]]&U[77])) {
      rU[row[77]]|=U[77];

      U[78]=cU[col[78]]^A; // cl
      if (!((rU[row[78]]&U[78])||(U[78]&qqU[U[77]]))) {
        rU[row[78]]|=U[78]; qqU[U[78]]|=U[77]; qqU[U[77]]|=U[78];

        U[79]=rU[row[79]]^A; // rl
        if (!((cU[col[79]]&U[79])||(U[79]&qqU[U[76]]))) {
          cU[col[79]]|=U[79]; qqU[U[79]]|=U[76]; qqU[U[76]]|=U[79];

          U[80]=rU[row[80]]^A; // rl
          if (!((cU[col[80]]&U[80])||(U[80]&qqU[U[75]]))) {
            for (int j=N; j<NN; ++j) Q[row[j]][col[j]]=P[U[j]]; ok=printDLS(Q, wfd);
          }
          cU[col[79]]^=U[79]; qqU[U[79]]^=U[76]; qqU[U[76]]^=U[79];
        }
        rU[row[78]]^=U[78]; qqU[U[78]]^=U[77]; qqU[U[77]]^=U[78];;
      }
      rU[row[77]]^=U[77];
    }
    cU[col[75]]^=U[75]; cU[col[76]]^=U[76];
  } 
  return ok;
} // makeSODLS1

int makeSODLS(int G[NN], int U[NN], const int bv0, const int wfd) {
//  ---------
  initSODLS(Q); int count=0;

  U[9]=bv0; rU[row[9]]=bv0; cU[col[9]]|=bv0; bdU|=bv0; fdU|=bv0; // bf

  for (G[10]=A^(cU[col[10]]|bdU); G[10]!=0; G[10]&=(G[10]-1)) { // bc
  U[10]=(G[10]&-G[10]); rU[row[10]]=U[10]; cU[col[10]]|=U[10]; bdU|=U[10];

  for (G[11]=A^(cU[col[11]]|bdU); G[11]!=0; G[11]&=(G[11]-1)) { // bc
  U[11]=(G[11]&-G[11]); rU[row[11]]=U[11]; cU[col[11]]|=U[11]; bdU|=U[11];

  for (G[12]=A^(cU[col[12]]|bdU); G[12]!=0; G[12]&=(G[12]-1)) { // bc
  U[12]=(G[12]&-G[12]); rU[row[12]]=U[12]; cU[col[12]]|=U[12]; bdU|=U[12];

  for (G[13]=A^(cU[col[13]]|bdU); G[13]!=0; G[13]&=(G[13]-1)) { // bc
  U[13]=(G[13]&-G[13]); rU[row[13]]=U[13]; cU[col[13]]|=U[13]; bdU|=U[13];

  for (G[14]=A^(cU[col[14]]|bdU); G[14]!=0; G[14]&=(G[14]-1)) { // bc
  U[14]=(G[14]&-G[14]); rU[row[14]]=U[14]; cU[col[14]]|=U[14]; bdU|=U[14];

  for (G[15]=A^(cU[col[15]]|bdU); G[15]!=0; G[15]&=(G[15]-1)) { // bc
  U[15]=(G[15]&-G[15]); bdU|=U[15];

      U[16]=bdU^A; if (U[16]==U[8]) { bdU^=U[15]; continue; }
      rU[row[15]]=U[15]; cU[col[15]]|=U[15]; rU[row[16]]=U[16]; cU[col[16]]|=U[16];

  for (G[17]=A^(rU[row[17]]|cU[col[17]]|fdU); G[17]!=0; G[17]&=(G[17]-1)) { // fd
  U[17]=(G[17]&-G[17]); rU[row[17]]|=U[17]; cU[col[17]]|=U[17]; fdU|=U[17];
  qqU[U[17]]|=U[8]; qqU[U[8]]|=U[17];

  for (G[18]=A^(rU[row[18]]|cU[col[18]]|fdU); G[18]!=0; G[18]&=(G[18]-1)) { // fd
  U[18]=(G[18]&-G[18]); rU[row[18]]|=U[18]; cU[col[18]]|=U[18]; fdU|=U[18];

  for (G[19]=A^(rU[row[19]]|cU[col[19]]|fdU); G[19]!=0; G[19]&=(G[19]-1)) { // fd
  U[19]=(G[19]&-G[19]); rU[row[19]]|=U[19]; cU[col[19]]|=U[19]; fdU|=U[19];
  qqU[U[19]]|=U[18]; qqU[U[18]]|=U[19];

  for (G[20]=A^(rU[row[20]]|cU[col[20]]|fdU); G[20]!=0; G[20]&=(G[20]-1)) { // fd
  U[20]=(G[20]&-G[20]); rU[row[20]]|=U[20]; cU[col[20]]|=U[20]; fdU|=U[20];

  for (G[21]=A^(rU[row[21]]|cU[col[21]]|fdU); G[21]!=0; G[21]&=(G[21]-1)) { // fd
  U[21]=(G[21]&-G[21]); rU[row[21]]|=U[21]; cU[col[21]]|=U[21]; fdU|=U[21];
  qqU[U[21]]|=U[20]; qqU[U[20]]|=U[21];

  for (G[22]=A^(rU[row[22]]|cU[col[22]]|fdU); G[22]!=0; G[22]&=(G[22]-1)) { // fd
  U[22]=(G[22]&-G[22]); fdU|=U[22];

       U[23]=fdU^A; if ((U[23]==U[13])||cU[col[23]]&U[23]) { fdU^=U[22]; continue; }
       rU[row[22]]|=U[22]; cU[col[22]]|=U[22]; qqU[U[22]]|=U[23];
       rU[row[23]]|=U[23]; cU[col[23]]|=U[23]; qqU[U[23]]|=U[22];

  for (G[24]=A^(rU[row[24]]|cU[col[24]]|qqU[U[1]]); G[24]!=0; G[24]&=(G[24]-1)) { // cd
  U[24]=(G[24]&-G[24]); rU[row[24]]|=U[24]; cU[col[24]]|=U[24];
  qqU[U[24]]|=U[1]; qqU[U[1]]|=U[24];

  for (G[25]=A^(rU[row[25]]|cU[col[25]]|qqU[U[2]]); G[25]!=0; G[25]&=(G[25]-1)) { // cd
  U[25]=(G[25]&-G[25]); rU[row[25]]|=U[25]; cU[col[25]]|=U[25];
  qqU[U[25]]|=U[2]; qqU[U[2]]|=U[25];

  for (G[26]=A^(rU[row[26]]|cU[col[26]]|qqU[U[3]]); G[26]!=0; G[26]&=(G[26]-1)) { // cd
  U[26]=(G[26]&-G[26]); rU[row[26]]|=U[26]; cU[col[26]]|=U[26];
  qqU[U[26]]|=U[3]; qqU[U[3]]|=U[26];

  for (G[27]=A^(rU[row[27]]|cU[col[27]]|qqU[U[4]]); G[27]!=0; G[27]&=(G[27]-1)) { // cd
  U[27]=(G[27]&-G[27]); rU[row[27]]|=U[27]; cU[col[27]]|=U[27];
  qqU[U[27]]|=U[4]; qqU[U[4]]|=U[27];

  for (G[28]=A^(rU[row[28]]|cU[col[28]]|qqU[U[5]]); G[28]!=0; G[28]&=(G[28]-1)) { // cd
  U[28]=(G[28]&-G[28]); rU[row[28]]|=U[28]; cU[col[28]]|=U[28];
  qqU[U[28]]|=U[5]; qqU[U[5]]|=U[28];

  for (G[29]=A^(rU[row[29]]|cU[col[29]]|qqU[U[6]]); G[29]!=0; G[29]&=(G[29]-1)) { // cd
  U[29]=(G[29]&-G[29]); cU[col[29]]|=U[29];

      U[30]=cU[col[30]]^A;
      if ((rU[row[30]]&U[30])||(U[30]&qqU[U[7]])||((U[7]==U[29])&&(U[6]==U[30])))
        { cU[col[29]]^=U[29]; continue; }
      rU[row[29]]|=U[29]; qqU[U[29]]|=U[6]; qqU[U[6]]|=U[29];
      rU[row[30]]|=U[30]; qqU[U[30]]|=U[7]; qqU[U[7]]|=U[30];

  for (G[31]=A^(rU[row[31]]|cU[col[31]]); G[31]!=0; G[31]&=(G[31]-1)) { // rd
  U[31]=(G[31]&-G[31]); rU[row[31]]|=U[31]; cU[col[31]]|=U[31];

  for (G[32]=A^(rU[row[32]]|cU[col[32]]|qqU[U[31]]); G[32]!=0; G[32]&=(G[32]-1)) { // cd
  U[32]=(G[32]&-G[32]); rU[row[32]]|=U[32]; cU[col[32]]|=U[32];
  qqU[U[32]]|=U[31]; qqU[U[31]]|=U[32];

  for (G[33]=A^(rU[row[33]]|cU[col[33]]); G[33]!=0; G[33]&=(G[33]-1)) { // rd
  U[33]=(G[33]&-G[33]); rU[row[33]]|=U[33]; cU[col[33]]|=U[33];

  for (G[34]=A^(rU[row[34]]|cU[col[34]]|qqU[U[33]]); G[34]!=0; G[34]&=(G[34]-1)) { // cd
  U[34]=(G[34]&-G[34]); rU[row[34]]|=U[34]; cU[col[34]]|=U[34];
  qqU[U[34]]|=U[33]; qqU[U[33]]|=U[34];

  for (G[35]=A^(rU[row[35]]|cU[col[35]]); G[35]!=0; G[35]&=(G[35]-1)) { // rd
  U[35]=(G[35]&-G[35]); rU[row[35]]|=U[35]; cU[col[35]]|=U[35];

  for (G[36]=A^(rU[row[36]]|cU[col[36]]|qqU[U[35]]); G[36]!=0; G[36]&=(G[36]-1)) { // cd
  U[36]=(G[36]&-G[36]); rU[row[36]]|=U[36]; cU[col[36]]|=U[36];
  qqU[U[36]]|=U[35]; qqU[U[35]]|=U[36];

  for (G[37]=A^(rU[row[37]]|cU[col[37]]); G[37]!=0; G[37]&=(G[37]-1)) { // rd
  U[37]=(G[37]&-G[37]); rU[row[37]]|=U[37]; cU[col[37]]|=U[37];

  for (G[38]=A^(rU[row[38]]|cU[col[38]]|qqU[U[37]]); G[38]!=0; G[38]&=(G[38]-1)) { // cd
  U[38]=(G[38]&-G[38]); rU[row[38]]|=U[38]; cU[col[38]]|=U[38];
  qqU[U[38]]|=U[37]; qqU[U[37]]|=U[38];

  for (G[39]=A^(rU[row[39]]|cU[col[39]]); G[39]!=0; G[39]&=(G[39]-1)) { // rd
  U[39]=(G[39]&-G[39]); rU[row[39]]|=U[39];

      U[40]=rU[row[40]]^A; if (cU[col[40]]&U[40]) { rU[row[39]]^=U[39]; continue; }
      cU[col[39]]|=U[39]; cU[col[40]]|=U[40];

  for (G[41]=A^(rU[row[41]]|cU[col[41]]|qqU[U[39]]); G[41]!=0; G[41]&=(G[41]-1)) { // cd
  U[41]=(G[41]&-G[41]); cU[col[41]]|=U[41];

      U[42]=cU[col[42]]^A;
      if ((rU[row[42]]&U[42])||(U[42]&qqU[U[40]])||((U[40]==U[41])&&(U[39]==U[42])))
        { cU[col[41]]^=U[41]; continue; }
      rU[row[41]]|=U[41]; qqU[U[41]]|=U[39]; qqU[U[39]]|=U[41];
      rU[row[42]]|=U[42]; qqU[U[42]]|=U[40]; qqU[U[40]]|=U[42];

  for (G[43]=A^(rU[row[43]]|cU[col[43]]); G[43]!=0; G[43]&=(G[43]-1)) { // rd
  U[43]=(G[43]&-G[43]); rU[row[43]]|=U[43]; cU[col[43]]|=U[43];

  for (G[44]=A^(rU[row[44]]|cU[col[44]]|qqU[U[43]]); G[44]!=0; G[44]&=(G[44]-1)) { // cd
  U[44]=(G[44]&-G[44]); rU[row[44]]|=U[44]; cU[col[44]]|=U[44];
  qqU[U[44]]|=U[43]; qqU[U[43]]|=U[44];

  for (G[45]=A^(rU[row[45]]|cU[col[45]]); G[45]!=0; G[45]&=(G[45]-1)) { // rd
  U[45]=(G[45]&-G[45]); rU[row[45]]|=U[45]; cU[col[45]]|=U[45];

  for (G[46]=A^(rU[row[46]]|cU[col[46]]|qqU[U[45]]); G[46]!=0; G[46]&=(G[46]-1)) { // cd
  U[46]=(G[46]&-G[46]); rU[row[46]]|=U[46]; cU[col[46]]|=U[46];
  qqU[U[46]]|=U[45]; qqU[U[45]]|=U[46];

  for (G[47]=A^(rU[row[47]]|cU[col[47]]); G[47]!=0; G[47]&=(G[47]-1)) { // rd
  U[47]=(G[47]&-G[47]); rU[row[47]]|=U[47]; cU[col[47]]|=U[47];

  for (G[48]=A^(rU[row[48]]|cU[col[48]]|qqU[U[47]]); G[48]!=0; G[48]&=(G[48]-1)) { // cd
  U[48]=(G[48]&-G[48]); rU[row[48]]|=U[48]; cU[col[48]]|=U[48];
  qqU[U[48]]|=U[47]; qqU[U[47]]|=U[48];

  for (G[49]=A^(rU[row[49]]|cU[col[49]]); G[49]!=0; G[49]&=(G[49]-1)) { // rd
  U[49]=(G[49]&-G[49]); rU[row[49]]|=U[49];

        U[50]=rU[row[50]]^A; if (cU[col[50]]&U[50]) { rU[row[49]]^=U[49]; continue; }
        cU[col[49]]|=U[49]; cU[col[50]]|=U[50];

  for (G[51]=A^(rU[row[51]]|cU[col[51]]|qqU[U[49]]); G[51]!=0; G[51]&=(G[51]-1)) { // cd
  U[51]=(G[51]&-G[51]); cU[col[51]]|=U[51];

        U[52]=cU[col[52]]^A;
        if ((rU[row[52]]&U[52])||(U[52]&qqU[U[50]])||((U[50]==U[51])&&(U[49]==U[52])))
          { cU[col[51]]^=U[51]; continue; }
        rU[row[51]]|=U[51]; qqU[U[51]]|=U[49]; qqU[U[49]]|=U[51];
        rU[row[52]]|=U[52]; qqU[U[52]]|=U[50]; qqU[U[50]]|=U[52];

  for (G[53]=A^(rU[row[53]]|cU[col[53]]); G[53]!=0; G[53]&=(G[53]-1)) { // rd
  U[53]=(G[53]&-G[53]); rU[row[53]]|=U[53]; cU[col[53]]|=U[53];

  for (G[54]=A^(rU[row[54]]|cU[col[54]]|qqU[U[53]]); G[54]!=0; G[54]&=(G[54]-1)) { // cd
  U[54]=(G[54]&-G[54]); rU[row[54]]|=U[54]; cU[col[54]]|=U[54]; qqU[U[54]]|=U[53]; qqU[U[53]]|=U[54];

  for (G[55]=A^(rU[row[55]]|cU[col[55]]); G[55]!=0; G[55]&=(G[55]-1)) { // rd
  U[55]=(G[55]&-G[55]); rU[row[55]]|=U[55]; cU[col[55]]|=U[55];

  for (G[56]=A^(rU[row[56]]|cU[col[56]]|qqU[U[55]]); G[56]!=0; G[56]&=(G[56]-1)) { // cd
  U[56]=(G[56]&-G[56]); rU[row[56]]|=U[56]; cU[col[56]]|=U[56]; qqU[U[56]]|=U[55]; qqU[U[55]]|=U[56];

  for (G[57]=A^(rU[row[57]]|cU[col[57]]); G[57]!=0; G[57]&=(G[57]-1)) { // rd
  U[57]=(G[57]&-G[57]); rU[row[57]]|=U[57];

        U[58]=rU[row[58]]^A; if (cU[col[58]]&U[58]) { rU[row[57]]^=U[57]; continue; }
        cU[col[57]]|=U[57]; cU[col[58]]|=U[58];

  for (G[59]=A^(rU[row[59]]|cU[col[59]]|qqU[U[57]]); G[59]!=0; G[59]&=(G[59]-1)) { // cd
  U[59]=(G[59]&-G[59]); cU[col[59]]|=U[59];

        U[60]=cU[col[60]]^A;
        if ((rU[row[60]]&U[60])||(U[60]&qqU[U[58]])||((U[58]==U[59])&&(U[57]==U[60])))
          { cU[col[59]]^=U[59]; continue; }
        rU[row[59]]|=U[59]; qqU[U[59]]|=U[57]; qqU[U[57]]|=U[59];
        rU[row[60]]|=U[60]; qqU[U[60]]|=U[58]; qqU[U[58]]|=U[60]; 

  for (G[61]=A^(rU[row[61]]|cU[col[61]]); G[61]!=0; G[61]&=(G[61]-1)) { // rd
  U[61]=(G[61]&-G[61]); rU[row[61]]|=U[61]; cU[col[61]]|=U[61];

  for (G[62]=A^(rU[row[62]]|cU[col[62]]|qqU[U[61]]); G[62]!=0; G[62]&=(G[62]-1)) { // cd
  U[62]=(G[62]&-G[62]); rU[row[62]]|=U[62]; cU[col[62]]|=U[62]; qqU[U[62]]|=U[61]; qqU[U[61]]|=U[62];

  for (G[63]=A^(rU[row[63]]|cU[col[63]]); G[63]!=0; G[63]&=(G[63]-1)) { // rd
  U[63]=(G[63]&-G[63]); rU[row[63]]|=U[63]; cU[col[63]]|=U[63];

  for (G[64]=A^(rU[row[64]]|cU[col[64]]|qqU[U[63]]); G[64]!=0; G[64]&=(G[64]-1)) { // cd
  U[64]=(G[64]&-G[64]); rU[row[64]]|=U[64]; cU[col[64]]|=U[64]; qqU[U[64]]|=U[63]; qqU[U[63]]|=U[64];

  for (G[65]=A^(rU[row[65]]|cU[col[65]]); G[65]!=0; G[65]&=(G[65]-1)) { // rd
  U[65]=(G[65]&-G[65]); rU[row[65]]|=U[65];

      U[66]=rU[row[66]]^A; if (cU[col[66]]&U[66]) { rU[row[65]]^=U[65]; continue; }
      cU[col[65]]|=U[65]; cU[col[66]]|=U[66];

  for (G[67]=A^(rU[row[67]]|cU[col[67]]|qqU[U[65]]); G[67]!=0; G[67]&=(G[67]-1)) { // cd
  U[67]=(G[67]&-G[67]); cU[col[67]]|=U[67];

      U[68]=cU[col[68]]^A;
      if ((rU[row[68]]&U[68])||(U[68]&qqU[U[66]])||((U[66]==U[67])&&(U[65]==U[68])))
        { cU[col[67]]^=U[67]; continue; }
      rU[row[67]]|=U[67]; qqU[U[67]]|=U[65]; qqU[U[65]]|=U[67];
      rU[row[68]]|=U[68]; qqU[U[68]]|=U[66]; qqU[U[66]]|=U[68];

  for (G[69]=A^(rU[row[69]]|cU[col[69]]); G[69]!=0; G[69]&=(G[69]-1)) { // rd
  U[69]=(G[69]&-G[69]); rU[row[69]]|=U[69]; cU[col[69]]|=U[69];

  for (G[70]=A^(rU[row[70]]|cU[col[70]]|qqU[U[69]]); G[70]!=0; G[70]&=(G[70]-1)) { // cd
  U[70]=(G[70]&-G[70]); rU[row[70]]|=U[70]; cU[col[70]]|=U[70]; qqU[U[70]]|=U[69]; qqU[U[69]]|=U[70];

  for (G[71]=A^(rU[row[71]]|cU[col[71]]); G[71]!=0; G[71]&=(G[71]-1)) { // rd
  U[71]=(G[71]&-G[71]); rU[row[71]]|=U[71];

      U[72]=rU[row[72]]^A; if (cU[col[72]]&U[72]) { rU[row[71]]^=U[71]; continue; }
      cU[col[71]]|=U[71]; cU[col[72]]|=U[72];

  for (G[73]=A^(rU[row[73]]|cU[col[73]]|qqU[U[71]]); G[73]!=0; G[73]&=(G[73]-1)) { // cd
  U[73]=(G[73]&-G[73]); cU[col[73]]|=U[73];

      U[74]=cU[col[74]]^A;
      if ((rU[row[74]]&U[74])||(U[74]&qqU[U[72]])||((U[72]==U[73])&&(U[71]==U[74])))
        { cU[col[73]]^=U[73]; continue; } 
      rU[row[73]]|=U[73]; qqU[U[73]]|=U[71]; qqU[U[71]]|=U[73];
      rU[row[74]]|=U[74]; qqU[U[74]]|=U[72]; qqU[U[72]]|=U[74];

  for (G[75]=A^(rU[row[75]]|cU[col[75]]); G[75]!=0; G[75]&=(G[75]-1)) { // rd 
  U[75]=(G[75]&-G[75]); rU[row[75]]|=U[75];

      if (makeSODLS1(G, U, wfd)) { ++count; if ((count&0xff)==0) printf("%d\n", count); }

  rU[row[75]]^=U[75];
  } // rd, rl
  rU[row[74]]^=U[74];
  qqU[U[74]]^=U[72]; qqU[U[72]]^=U[74]; qqU[U[73]]^=U[71]; qqU[U[71]]^=U[73];
  rU[row[73]]^=U[73]; cU[col[73]]^=U[73];
  } // cd, cl
  cU[col[72]]^=U[72]; rU[row[71]]^=U[71]; cU[col[71]]^=U[71]; 
  } // rd, rl
  rU[row[70]]^=U[70]; cU[col[70]]^=U[70]; qqU[U[70]]^=U[69]; qqU[U[69]]^=U[70];
  } // cd
  rU[row[69]]^=U[69]; cU[col[69]]^=U[69];
  } // rd
  rU[row[68]]^=U[68];
  qqU[U[68]]^=U[66]; qqU[U[66]]^=U[68]; qqU[U[67]]^=U[65]; qqU[U[65]]^=U[67];
  rU[row[67]]^=U[67]; cU[col[67]]^=U[67];
  } // cd, cl
  cU[col[66]]^=U[66]; rU[row[65]]^=U[65]; cU[col[65]]^=U[65];
  } // rd, rl
  rU[row[64]]^=U[64]; cU[col[64]]^=U[64]; qqU[U[64]]^=U[63]; qqU[U[63]]^=U[64];
  } // cd
  rU[row[63]]^=U[63]; cU[col[63]]^=U[63];
  } // rd
  rU[row[62]]^=U[62]; cU[col[62]]^=U[62]; qqU[U[62]]^=U[61]; qqU[U[61]]^=U[62];
  } // cd
  rU[row[61]]^=U[61]; cU[col[61]]^=U[61];
  } // rd
  rU[row[60]]^=U[60];
  qqU[U[60]]^=U[58]; qqU[U[58]]^=U[60]; qqU[U[59]]^=U[57]; qqU[U[57]]^=U[59];
  rU[row[59]]^=U[59]; cU[col[59]]^=U[59];
  } // cd, cl
  cU[col[58]]^=U[58]; rU[row[57]]^=U[57]; cU[col[57]]^=U[57];
  } // rd
  rU[row[56]]^=U[56]; cU[col[56]]^=U[56]; qqU[U[56]]^=U[55]; qqU[U[55]]^=U[56];
  } // cd
  rU[row[55]]^=U[55]; cU[col[55]]^=U[55];
  } // rd
  rU[row[54]]^=U[54]; cU[col[54]]^=U[54]; qqU[U[54]]^=U[53]; qqU[U[53]]^=U[54];
  } // cd
  rU[row[53]]^=U[53]; cU[col[53]]^=U[53];
  } // rd
  rU[row[52]]^=U[52];
  qqU[U[52]]^=U[50]; qqU[U[50]]^=U[52]; qqU[U[49]]^=U[51]; qqU[U[51]]^=U[49];
  rU[row[51]]^=U[51]; cU[col[51]]^=U[51];
  } // cd, cl
  cU[col[50]]^=U[50]; rU[row[49]]^=U[49]; cU[col[49]]^=U[49];
  } // rd, rl
  rU[row[48]]^=U[48]; cU[col[48]]^=U[48]; qqU[U[48]]^=U[47]; qqU[U[47]]^=U[48];
  } // cd
  rU[row[47]]^=U[47]; cU[col[47]]^=U[47];
  } // rd
  rU[row[46]]^=U[46]; cU[col[46]]^=U[46]; qqU[U[46]]^=U[45]; qqU[U[45]]^=U[46];
  } // cd
  rU[row[45]]^=U[45]; cU[col[45]]^=U[45];
  } // rd
  rU[row[44]]^=U[44]; cU[col[44]]^=U[44]; qqU[U[44]]^=U[43]; qqU[U[43]]^=U[44];
  } // cd
  rU[row[43]]^=U[43]; cU[col[43]]^=U[43];
  } // rd
  rU[row[42]]^=U[42];
  qqU[U[42]]^=U[40]; qqU[U[40]]^=U[42]; qqU[U[41]]^=U[39]; qqU[U[39]]^=U[41];
  rU[row[41]]^=U[41]; cU[col[41]]^=U[41];
  } // cd, cl
  cU[col[40]]^=U[40]; rU[row[39]]^=U[39]; cU[col[39]]^=U[39];
  } // rd, rl
  rU[row[38]]^=U[38]; cU[col[38]]^=U[38]; qqU[U[38]]^=U[37]; qqU[U[37]]^=U[38];
  } // cd
  rU[row[37]]^=U[37]; cU[col[37]]^=U[37];
  } // rd
  rU[row[36]]^=U[36]; cU[col[36]]^=U[36]; qqU[U[36]]^=U[35]; qqU[U[35]]^=U[36];
  } // cd
  rU[row[35]]^=U[35]; cU[col[35]]^=U[35];
  } // rd
  rU[row[34]]^=U[34]; cU[col[34]]^=U[34]; qqU[U[34]]^=U[33]; qqU[U[33]]^=U[34];
  } // cd
  rU[row[33]]^=U[33]; cU[col[33]]^=U[33];
  } // rd
  rU[row[32]]^=U[32]; cU[col[32]]^=U[32]; qqU[U[32]]^=U[31]; qqU[U[31]]^=U[32];
  } // cd
  rU[row[31]]^=U[31]; cU[col[31]]^=U[31];
  } // rd
  rU[row[30]]^=U[30];
  qqU[U[30]]^=U[7]; qqU[U[7]]^=U[30]; qqU[U[29]]^=U[6]; qqU[U[6]]^=U[29];
  rU[row[29]]^=U[29]; cU[col[29]]^=U[29];
  } // cd, cl
  rU[row[28]]^=U[28]; cU[col[28]]^=U[28]; qqU[U[28]]^=U[5]; qqU[U[5]]^=U[28];
  } // cd
  rU[row[27]]^=U[27]; cU[col[27]]^=U[27]; qqU[U[27]]^=U[4]; qqU[U[4]]^=U[27];
  } // cd
  rU[row[26]]^=U[26]; cU[col[26]]^=U[26]; qqU[U[26]]^=U[3]; qqU[U[3]]^=U[26];
  } // cd
  rU[row[25]]^=U[25]; cU[col[25]]^=U[25]; qqU[U[25]]^=U[2]; qqU[U[2]]^=U[25];
  } // cd
  rU[row[24]]^=U[24]; cU[col[24]]^=U[24]; qqU[U[24]]^=U[1]; qqU[U[1]]^=U[24];
  } // cd
  rU[row[23]]^=U[23]; cU[col[23]]^=U[23]; qqU[U[23]]^=U[22];
  rU[row[22]]^=U[22]; cU[col[22]]^=U[22]; fdU^=U[22]; qqU[U[22]]^=U[23];
  } // fd, fE
  rU[row[21]]^=U[21]; cU[col[21]]^=U[21]; fdU^=U[21]; qqU[U[21]]^=U[20]; qqU[U[20]]^=U[21];
  } // fd
  rU[row[20]]^=U[20]; cU[col[20]]^=U[20]; fdU^=U[20];
  } // fd
  rU[row[19]]^=U[19]; cU[col[19]]^=U[19]; fdU^=U[19]; qqU[U[19]]^=U[18]; qqU[U[18]]^=U[19];
  } // fd
  rU[row[18]]^=U[18]; cU[col[18]]^=U[18]; fdU^=U[18];
  } // fd
  rU[row[17]]^=U[17]; cU[col[17]]^=U[17]; fdU^=U[17]; qqU[U[17]]^=U[8]; qqU[U[8]]^=U[17];
  } // fd
  cU[col[16]]^=U[16]; cU[col[15]]^=U[15]; bdU^=U[15];
  } // bc, bE
  cU[col[14]]^=U[14]; bdU^=U[14];
  } // bc
  cU[col[13]]^=U[13]; bdU^=U[13];
  } // bc
  cU[col[12]]^=U[12]; bdU^=U[12];
  } // bc
  cU[col[11]]^=U[11]; bdU^=U[11];
  } // bc
  cU[col[10]]^=U[10]; bdU^=U[10];
  } // bc
  if (!outputLast(wfd)) count=0; return count;
} // makeSODLS
//================================================ main ==================================================

void outputLocalTime() {
//   ---------------
  time_t startTime=time(NULL); struct tm *local=localtime(&startTime);
  if (local!=NULL) {
    char dateTime[100];
    size_t slen=strftime(dateTime, 100, "%A %Y-%m-%d %X %Z\n\0", local); printf("\n%s", dateTime);
  }
} // outputLocalTime

void printElapsedTime(time_t startTime, const char *c) {
//   ---------------- 
  const int et=(int)difftime(time(NULL), startTime);
  if (et>0) printf("%selapsed time %d:%02d:%02d\n", c, et/3600, et%3600/60, et%60);
} // printElapsedTime

int main() {
//  ----
  bool ok=F; outputLocalTime(); for (int i=0; i<N; ++i) P[B[i]]=i;
  while (T) {
    printf("Center value, (1, 2, 3, 5, 6, 7)? "); const int v0=getInt();
    if ((v0>0)&(v0<M)&(v0!=Nd2)) {
      const int wfd=openOutput();
      if (wfd!=-1) {
        int count=0; ok=F; time_t startTime=time(NULL);
        outPointer=outputBuffer; outSquares=0;
        count=makeSODLS(GQ, UQ, B[v0], wfd);
        printf("\nNumber of SODLS %d\n", count); printElapsedTime(startTime, " ");
        close(wfd); if (count==0) remove(outputFile);
      }
    } else printf("\aError: Bad value %d.\n", v0);
    printf("Continue? y (yes) or n (no)? "); if (!getY()) break;
  }
  printf("\nHit return to close the console.");
  while (T) if (getchar()=='\n') break; return ok ? EXIT_SUCCESS : EXIT_FAILURE;
} // main