#pragma warning(disable: 4996)

#include<iostream>

#include<stdlib.h> /*callocrand,srandを使うのに必要*/

#include<ctime>

#include<process.h>

#include<conio.h> //while (!_kbhit()); を使うためのお呪い。

#include <math.h>

#include <cmath>

#include<process.h>

#include <iomanip>

#include <stdio.h>

#include <stdlib.h>

using namespace std;

const size_t th = 36;

void f(size_t g, size_t a);

void f1(size_t g, size_t a);

void hitaisyo(size_t a);

void sayu(size_t a);

void jyoge(size_t a);

void ten(size_t a);

void sayujyoge(size_t a);

void kokoro(size_t a);

void kyokusyokaiseki(size_t s, size_t t, size_t a);

void mondaisakusei(size_t a);

void dainyu(size_t a);

char keizoku = 1;

size_t* ht = (size_t*)calloc(th, sizeof(size_t));

unsigned u = (unsigned)time(NULL);

void sudoku(void* a);

void syokika(size_t a);

void nyuryokujyun(size_t g, size_t a);

size_t ks(size_t a);

size_t totalkaiseki(size_t a);

void kaitosakusei(size_t a);

void linehaijyo(size_t a);

void souhokakutei(size_t a);

void tont(size_t a);

void listhou(size_t a);

void gyou(size_t a);

void retu(size_t a);

void block(size_t a);

void sgyou(size_t a);

void sretu(size_t a);

void sblock(size_t a);

void tontgyo(size_t a);

void tontretu(size_t a);

void tontblock(size_t a);

void shphaijyo(size_t a);

void hyoji3q(size_t a);

void hyoji3a(size_t a);

const size_t RN = 3;

const size_t N = RN * RN;

const size_t N2 = N * N;

size_t m[th][N][N], mx[th][N][N], wb[th][N][N][N], rlst[th][N][N][N], y[th][N2], x[th][N2];

size_t yy[th][N2], xx[th][N2], cm[th][N][N], ccm[th][N][N];

size_t hnt, owari = 0, krn[th], cn[th];

size_t S;

clock_t hj1[th], ow1[th];

int  main() {

              size_t ii[th];

              hnt = 21;

              clock_t hj, ow;

              cout << "ヒント数 = " << +hnt << endl;

              cout << "スレッド数 = " << +th << endl;

              hj = clock();

              u = (unsigned)time(NULL);

              keizoku = 1;

              for (size_t i = 1; i < th; i += 1) {

                            ii[i] = i;

                            _beginthread(sudoku, 0, &ii[i]); //新しいスレッドを起動して、そのスレッド上で関数f1を働かせなさいの命令

              }

              srand(u);

              while (1) {

                            syokika(0);

                            size_t sentaku = 4;

                            hitaisyo(0);

                            /*if (hnt == 20)sentaku = rand() % 5; else sentaku = rand() % 6;

                            if (sentaku == 0) sayu(0);

                            if (sentaku == 1) jyoge(0);

                            if (sentaku == 2) ten(0);

                            if (sentaku == 3) sayujyoge(0);

                            if (sentaku == 4) hitaisyo(0);

                            if (sentaku == 5) kokoro(0);*/

                            if (keizoku == 0)break;

                            cn[0] = 0;

                            f1(0, 0);

                            if (keizoku == 0)break;

                            dainyu(0);

                            if (keizoku == 0)break;

                            cn[0] = 0;

                            krn[0] = N2 - hnt;

                            hj1[0] = clock();

                            kaitosakusei(0);

                            //f(hnt, 0);

                            if (cn[0] == 1) {

                                          ow1[0] = clock();

                                          ht[0] = 1;

                                          keizoku = 0;

                                          break;

                            }

              }

              while (keizoku);

              size_t ik;

              for (size_t i = 0; i < th; i++)if (ht[i] == 1) { ik = i; break; }

              //数独を見つけたスレッドを特定した。

              for (size_t i = 0; i < hnt; i++) {

                            cm[ik][yy[ik][i]][xx[ik][i]] = ccm[ik][yy[ik][i]][xx[ik][i]];

              }

              for (size_t i = hnt; i < N2; i++) {

                            cm[ik][yy[ik][i]][xx[ik][i]] = 0;

              }

              hyoji3q(ik);

              hyoji3a(ik);

              FILE* fp;

              /*ファイル(save.csv)に書き込む*/

              if ((fp = fopen("a.csv", "w")) != NULL) {

                            for (size_t i = 0; i < N; i++) {

                                          for (size_t j = 0; j < N; j++) {

                                                        fprintf(fp, "%d,\n", cm[ik][i][j]);

                                          }

                            }

                            for (size_t i = 0; i < N; i++) {

                                          for (size_t j = 0; j < N; j++) {

                                                        /*カンマで区切ることでCSVファイルとする*/

                                                        fprintf(fp, "%d,\n", m[ik][i][j]);

                                          }

                            }

              }

              /*忘れずに閉じる*/

              fclose(fp);

 

 

              //if (ks(ik) == 1)cout << "" << endl;

              //cout << "解法に要した時間は" << (double)(ow1[ik] - hj1[ik]) / CLOCKS_PER_SEC << "秒です。" << endl;

              /*syokika(0);

              u = (unsigned)time(NULL);

              srand(u);

              hitaisyo(0);

              for (int i = 0; i < hnt; i++) {

                            m[0][yy[0][i]][xx[0][i]] = 1 + rand() % N;

              }

              for (int i = 0; i < N; i++) {

                            for (int j = 0; j < N; j++) {

                                          if (m[0][i][j] > 0 && m[0][i][j] < 10)cout << " 0" << +m[0][i][j] << " ";

                                          if (m[0][i][j] >= 10)cout << " " << +m[0][i][j] << " ";

                                          if (m[0][i][j] == 0)cout << " ** ";

                            }

                            cout << endl;

              }*/

              ow = clock();

              cout << "数独解法時間は" << (double)(ow1[ik] - hj1[ik]) / CLOCKS_PER_SEC << "秒です。" << endl;

              cout << "数独生成時間は" << (double)(ow - hj) / CLOCKS_PER_SEC << "秒です。" << endl;

              //while (!_kbhit()); //待機させるための命令

              return 0;

}

void sudoku(void* aa) {

              size_t a = *(size_t*)aa;

              srand(u - 19 * (a + 1));

              while (1) {

                            syokika(a);

                            size_t sentaku = 4;

                            hitaisyo(a);

                            /*if (hnt == 20)sentaku = rand() % 5; else sentaku = rand() % 6;

                            if (sentaku == 0) sayu(a);

                            if (sentaku == 1) jyoge(a);

                            if (sentaku == 2) ten(a);

                            if (sentaku == 3) sayujyoge(a);

                            if (sentaku == 4) hitaisyo(a);

                            if (sentaku == 5) kokoro(a);*/

                            cn[a] = 0;

                            f1(0, a);

                            if (keizoku == 0)return;

                            dainyu(a);

                            if (keizoku == 0)return;

                            cn[a] = 0;

                            krn[a] = N2 - hnt;

                            hj1[a] = clock();

                            kaitosakusei(a);

                            //f(hnt, a);

                            if (cn[a] == 1) {

                                          ow1[a] = clock();

                                          ht[a] = 1;

                                          keizoku = 0;

                                          return;

                            }

              }

}

void hyoji3q(size_t a) {

 

              for (int i = 0; i < N + 1; i++) {

                            if (i % RN == 0) {

                                          cout << " ";

                                          for (int j = 0; j < N + 3; j++) {

                                                        cout << "- ";

                                          }

                                          cout << " ";

                                          cout << endl;

                            }

                            if (i == N)break;

                            for (int j = 0; j < N + 1; j++) {

                                          if (j % RN == 0) {

                                                        cout << "| ";

                                          }

                                          if (j < N) {

                                                        if (cm[a][i][j] == 0)cout << "* "; else cout << +cm[a][i][j] << " ";//問題

                                          }

                            }

                            cout << endl;

              }

}

void hyoji3a(size_t a) {

              for (int i = 0; i < N + 1; i++) {

                            if (i % RN == 0) {

                                          cout << " ";

                                          for (int j = 0; j < N + 3; j++) {

                                                        cout << "- ";

                                          }

                                          cout << " ";

                                          cout << endl;

                            }

                            if (i == N)break;

                            for (int j = 0; j < N + 1; j++) {

                                          if (j % RN == 0) {

                                                        cout << "| ";

                                          }

                                          if (j < N) {

                                                        if (ccm[a][i][j] == 0)cout << "* "; else cout << +ccm[a][i][j] << " ";//問題

                                          }

                            }

                            cout << endl;

              }

}

void kaitosakusei(size_t a) {

              size_t i, kkrn;

              if (totalkaiseki(a) == 1) {

                            cn[a] = 2;

                            return;

              }

              for (i = 0; i < N; i++) {

                            kkrn = krn[a];

                            linehaijyo(a);

                            if (cn[a] > 0) return;

                            if (krn[a] == 0) {

                                          cn[a] = 1;

                                          return;

                            }

                            souhokakutei(a);

                            tont(a);

                            shphaijyo(a);

                            if (krn[a] == 0) {

                                          cn[a] = 1;

                                          return;

                            }

                            listhou(a);

                            if (cn[a] > 0)return;

                            if (krn[a] == 0) {

                                          cn[a] = 1;

                                          return;

                            }

                            if (kkrn == krn[a]) {

                                          cn[a] = 0;

                                          return;

                            }

              }

}

size_t totalkaiseki(size_t a) {

              size_t i, j;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          if (m[a][i][j] == 0) {

                                                        kyokusyokaiseki(i, j, a);

                                                        if (mx[a][i][j] == 0) {

                                                                      return(1);

                                                        }

                                          }

                            }

              }

              return(0);

}

void gyou(size_t a) {

              size_t i, j, k, w, jk, kk, s, t;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          w = 0;

                                          for (k = 0; k < N; k++) {

                                                        if (m[a][j][k] == 0) {

                                                                      if (wb[a][j][k][i] == 0) {

                                                                                    jk = j;

                                                                                    kk = k;

                                                                                    w = w + 1;

                                                                      }

                                                        }

                                          }

                                          if (w == 1) {

                                                        if (krn[a] == 0) {

                                                                      cn[a] = 2;

                                                                      return;

                                                        }

                                                        m[a][jk][kk] = i + 1;

                                                        krn[a] = krn[a] - 1;

                                                        if (krn[a] == 0) return;

                                                        for (k = 0; k < N; k++) {

                                                                      if (m[a][jk][k] == 0) {

                                                                                    wb[a][jk][k][m[a][jk][kk] - 1] = 1;

                                                                      }

                                                                      if (m[a][k][kk] == 0) {

                                                                                    wb[a][k][kk][m[a][jk][kk] - 1] = 1;

                                                                      }

                                                                      s = RN * (jk / RN) + (k / RN);

                                                                      t = RN * (kk / RN) + (k % RN);

                                                                      if (m[a][s][t] == 0) {

                                                                                    wb[a][s][t][m[a][jk][kk] - 1] = 1;

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (m[a][jk][k] == 0)kyokusyokaiseki(jk, k, a);

                                                                      if (m[a][k][kk] == 0) kyokusyokaiseki(k, kk, a);

                                                                      s = RN * (jk / RN) + (k / RN);

                                                                      t = RN * (kk / RN) + (k % RN);

                                                                      if (m[a][s][t] == 0)kyokusyokaiseki(s, t, a);

                                                        }

                                          }

                            }

              }

}

void retu(size_t a) {

              size_t i, j, k, w, jk, kk, s, t;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          w = 0;

                                          for (k = 0; k < N; k++) {

                                                        if (m[a][k][j] == 0) {

                                                                      if (wb[a][k][j][i] == 0) {

                                                                                    jk = j;

                                                                                    kk = k;

                                                                                    w = w + 1;

                                                                      }

                                                        }

                                          }

                                          if (w == 1) {

                                                        if (krn[a] == 0) {

                                                                      cn[a] = 2;

                                                                      return;

                                                        }

                                                        m[a][kk][jk] = i + 1;

                                                        krn[a] = krn[a] - 1;

                                                        if (krn[a] == 0) return;

                                                        for (k = 0; k < N; k++) {

                                                                      if (m[a][kk][k] == 0) {

                                                                                    wb[a][kk][k][m[a][kk][jk] - 1] = 1;

                                                                      }

                                                                      if (m[a][k][jk] == 0) {

                                                                                    wb[a][k][jk][m[a][kk][jk] - 1] = 1;

                                                                      }

                                                                      s = RN * (kk / RN) + (k / RN);

                                                                      t = RN * (jk / RN) + (k % RN);

                                                                      if (m[a][s][t] == 0) {

                                                                                    wb[a][s][t][m[a][kk][jk] - 1] = 1;

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (m[a][kk][k] == 0)kyokusyokaiseki(kk, k, a);

                                                                      if (m[a][k][jk] == 0)kyokusyokaiseki(k, jk, a);

                                                                      s = RN * (kk / RN) + (k / RN);

                                                                      t = RN * (jk / RN) + (k % RN);

                                                                      if (m[a][s][t] == 0)kyokusyokaiseki(s, t, a);

                                                        }

                                          }

                            }

              }

}

void block(size_t a) {

              size_t i, j, k, w, sk, tk, s, t, s1, t1;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          w = 0;

                                          for (k = 0; k < N; k++) {

                                                        s = RN * (j / RN) + (k / RN);

                                                        t = RN * (j % RN) + (k % RN);

                                                        if (m[a][s][t] == 0) {

                                                                      if (wb[a][s][t][i] == 0) {

                                                                                    sk = s;

                                                                                    tk = t;

                                                                                    w = w + 1;

                                                                      }

                                                        }

                                          }

                                          if (w == 1) {

                                                        if (krn[a] == 0) {

                                                                      cn[a] = 2;

                                                                      return;

                                                        }

                                                        m[a][sk][tk] = i + 1;

                                                        krn[a] = krn[a] - 1;

                                                        if (krn[a] == 0) return;

                                                        for (k = 0; k < N; k++) {

                                                                      if (m[a][sk][k] == 0) {

                                                                                    wb[a][sk][k][m[a][sk][tk] - 1] = 1;

                                                                      }

                                                                      if (m[a][k][tk] == 0) {

                                                                                    wb[a][k][tk][m[a][sk][tk] - 1] = 1;

                                                                      }

                                                                      s1 = RN * (sk / RN) + (k / RN);

                                                                      t1 = RN * (tk / RN) + (k % RN);

                                                                      if (m[a][s1][t1] == 0) {

                                                                                    wb[a][s1][t1][m[a][sk][tk] - 1] = 1;

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (m[a][sk][k] == 0)kyokusyokaiseki(sk, k, a);

                                                                      if (m[a][k][tk] == 0)kyokusyokaiseki(k, tk, a);

                                                                      s1 = RN * (sk / RN) + (k / RN);

                                                                      t1 = RN * (tk / RN) + (k % RN);

                                                                      if (m[a][s1][t1] == 0)kyokusyokaiseki(s1, t1, a);

                                                        }

                                          }

                            }

              }

}

void linehaijyo(size_t a) {

              gyou(a);

              if (krn[a] == 0) {

                            cn[a] = 1;

                            return;

              }

              retu(a);

              if (krn[a] == 0) {

                            cn[a] = 1;

                            return;

              }

              block(a);

}

void sgyou(size_t a) {

              size_t i, j, k, w, onoff[N];

              size_t ckotae[N], l;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          for (k = j + 1; k < N; k++) {

                                                        if (mx[a][i][j] == 2 && mx[a][i][k] == 2) {

                                                                      for (l = 0; l < N; l++) {

                                                                                    onoff[l] = 0;

                                                                      }

                                                                      for (l = 0; l < 2; l++) {

                                                                                    onoff[rlst[a][i][j][l] - 1] = 1;

                                                                                    onoff[rlst[a][i][k][l] - 1] = 1;

                                                                      }

                                                                      w = 0;

                                                                      for (l = 0; l < N; l++) {

                                                                                    if (onoff[l] == 1) {

                                                                                                  ckotae[w] = l;

                                                                                                  w = w + 1;

                                                                                    }

                                                                      }

                                                                      if (w == 2) {

                                                                                    for (l = 0; l < N; l++) {

                                                                                                  if (l != j && l != k) {

                                                                                                                if (m[a][i][l] == 0) {

                                                                                                                              wb[a][i][l][ckotae[0]] = 1;

                                                                                                                              wb[a][i][l][ckotae[1]] = 1;

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                                    for (l = 0; l < N; l++) {

                                                                                                  if (l != j && l != k) {

                                                                                                                if (m[a][i][l] == 0) {

                                                                                                                              kyokusyokaiseki(i, l, a);

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                      }

                                                        }

                                          }

                            }

              }

}

void sretu(size_t a) {

              size_t i, j, k, w, onoff[N];

              size_t ckotae[N], l;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          for (k = j + 1; k < N; k++) {

                                                        if (mx[a][j][i] == 2 && mx[a][k][i] == 2) {

                                                                      for (l = 0; l < N; l++) {

                                                                                    onoff[l] = 0;

                                                                      }

                                                                      for (l = 0; l < 2; l++) {

                                                                                    onoff[rlst[a][j][i][l] - 1] = 1;

                                                                                    onoff[rlst[a][k][i][l] - 1] = 1;

                                                                      }

                                                                      w = 0;

                                                                      for (l = 0; l < N; l++) {

                                                                                    if (onoff[l] == 1) {

                                                                                                  ckotae[w] = l;

                                                                                                  w = w + 1;

                                                                                    }

                                                                      }

                                                                      if (w == 2) {

                                                                                    for (l = 0; l < N; l++) {

                                                                                                  if (l != j && l != k) {

                                                                                                                if (m[a][l][i] == 0) {

                                                                                                                              wb[a][l][i][ckotae[0]] = 1;

                                                                                                                              wb[a][l][i][ckotae[1]] = 1;

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                                    for (l = 0; l < N; l++) {

                                                                                                  if (l != j && l != k) {

                                                                                                                if (m[a][l][i] == 0) {

                                                                                                                              kyokusyokaiseki(l, i, a);

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                      }

                                                        }

                                          }

                            }

              }

}

void sblock(size_t a) {

              size_t i, j, k, w, onoff[N], s1, s2, t1, t2, s3, t3, s4, t4;;

              size_t ckotae[N], l;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          s1 = RN * (i / RN) + (j / RN);

                                          t1 = RN * (i % RN) + (j % RN);

                                          for (k = j + 1; k < N; k++) {

                                                        s2 = RN * (i / RN) + (k / RN);

                                                        t2 = RN * (i % RN) + (k % RN);

                                                        if (mx[a][s1][t1] == 2 && mx[a][s2][t2] == 2) {

                                                                      for (l = 0; l < N; l++) {

                                                                                    onoff[l] = 0;

                                                                      }

                                                                      for (l = 0; l < 2; l++) {

                                                                                    onoff[rlst[a][s1][t1][l] - 1] = 1;

                                                                                    onoff[rlst[a][s2][t2][l] - 1] = 1;

                                                                      }

                                                                      w = 0;

                                                                      for (l = 0; l < N; l++) {

                                                                                    if (onoff[l] == 1) {

                                                                                                  ckotae[w] = l;

                                                                                                  w = w + 1;

                                                                                    }

                                                                      }

                                                                      if (w == 2) {

                                                                                    for (l = 0; l < N; l++) {

                                                                                                  if (l != j && l != k) {

                                                                                                                s3 = RN * (i / RN) + (l / RN);

                                                                                                                t3 = RN * (i % RN) + (l % RN);

                                                                                                                if (m[a][s3][t3] == 0) {

                                                                                                                              wb[a][s3][t3][ckotae[0]] = 1;

                                                                                                                              wb[a][s3][t3][ckotae[1]] = 1;

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                                    for (l = 0; l < N; l++) {

                                                                                                  if (l != j && l != k) {

                                                                                                                s4 = RN * (i / RN) + (l / RN);

                                                                                                                t4 = RN * (i % RN) + (l % RN);

                                                                                                                if (m[a][s4][t4] == 0) {

                                                                                                                              kyokusyokaiseki(s4, t4, a);

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                      }

                                                        }

                                          }

                            }

              }

}

void souhokakutei(size_t a) {

              sgyou(a);

              sretu(a);

              sblock(a);

}

void tontgyo(size_t a) {

              size_t i, j, k, w, onoff[N];

              size_t ckotae[N], l, n;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          for (k = j + 1; k < N; k++) {

                                                        for (l = k + 1; l < N; l++) {

                                                                      if ((m[a][i][j] == RN) && (m[a][i][k] == RN) && (m[a][i][l] == RN)) {

                                                                                    for (n = 0; n < N; n++) {

                                                                                                  onoff[n] = 0;

                                                                                    }

                                                                                    for (n = 0; n < m[a][i][j]; n++) {

                                                                                                  onoff[rlst[a][i][j][n] - 1] = 1;

                                                                                    }

                                                                                    for (n = 0; n < m[a][i][k]; n++) {

                                                                                                  onoff[rlst[a][i][k][n] - 1] = 1;

                                                                                    }

                                                                                    for (n = 0; n < m[a][i][l]; n++) {

                                                                                                  onoff[rlst[a][i][l][n] - 1] = 1;

                                                                                    }

                                                                                    w = 0;

                                                                                    for (n = 0; n < N; n++) {

                                                                                                  if (onoff[n] == 1) {

                                                                                                                ckotae[w] = n;

                                                                                                                w = w + 1;

                                                                                                  }

                                                                                    }

                                                                                    if (w == RN) {

                                                                                                  for (n = 0; n < N; n++) {

                                                                                                                if (n != j && n != k && n != l) {

                                                                                                                              if (m[a][i][n] == 0) {

                                                                                                                                            wb[a][i][n][ckotae[0]] = 1;

                                                                                                                                            wb[a][i][n][ckotae[1]] = 1;

                                                                                                                                            wb[a][i][n][ckotae[2]] = 1;

                                                                                                                              }

                                                                                                                }

                                                                                                  }

                                                                                                  for (n = 0; n < N; n++) {

                                                                                                                if (n != j && n != k && n != l) {

                                                                                                                              if (m[a][i][n] == 0) {

                                                                                                                                            kyokusyokaiseki(i, n, a);

                                                                                                                              }

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                      }

                                                        }

                                          }

                            }

              }

}

void tontretu(size_t a) {

              size_t i, j, k, w, onoff[N];

              size_t ckotae[N], l, n;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          for (k = j + 1; k < N; k++) {

                                                        for (l = k + 1; l < N; l++) {

                                                                      if ((m[a][j][i] == RN) && (m[a][k][i] == RN) && (m[a][l][i] == RN)) {

                                                                                    for (n = 0; n < N; n++) {

                                                                                                  onoff[n] = 0;

                                                                                    }

                                                                                    for (n = 0; n < m[a][j][i]; n++) {

                                                                                                  onoff[rlst[a][j][i][n] - 1] = 1;

                                                                                    }

                                                                                    for (n = 0; n < m[a][k][i]; n++) {

                                                                                                  onoff[rlst[a][k][i][n] - 1] = 1;

                                                                                    }

                                                                                    for (n = 0; n < m[a][l][i]; n++) {

                                                                                                  onoff[rlst[a][l][i][n] - 1] = 1;

                                                                                    }

                                                                                    w = 0;

                                                                                    for (n = 0; n < N; n++) {

                                                                                                  if (onoff[n] == 1) {

                                                                                                                ckotae[w] = n;

                                                                                                                w = w + 1;

                                                                                                  }

                                                                                    }

                                                                                    if (w == RN) {

                                                                                                  for (n = 0; n < N; n++) {

                                                                                                                if (n != j && n != k && n != l) {

                                                                                                                              if (m[a][n][i] == 0) {

                                                                                                                                            wb[a][n][i][ckotae[0]] = 1;

                                                                                                                                            wb[a][n][i][ckotae[1]] = 1;

                                                                                                                                            wb[a][n][i][ckotae[2]] = 1;

                                                                                                                              }

                                                                                                                }

                                                                                                  }

                                                                                                  for (n = 0; n < N; n++) {

                                                                                                                if (n != j && n != k && n != l) {

                                                                                                                              if (m[a][n][i] == 0) {

                                                                                                                                            kyokusyokaiseki(n, i, a);

                                                                                                                              }

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                      }

                                                        }

                                          }

                            }

              }

}

void tontblock(size_t a) {

              size_t i, j, k, w, onoff[N];

              size_t ckotae[N], l, n;

              size_t s1, s2, s3, s4, t1, t2, t3, t4;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          s1 = RN * (i / RN) + (j / RN);

                                          t1 = RN * (i % RN) + (j % RN);

                                          for (k = j + 1; k < N; k++) {

                                                        s2 = RN * (i / RN) + (k / RN);

                                                        t2 = RN * (i % RN) + (k % RN);

                                                        for (l = k + 1; l < N; l++) {

                                                                      s3 = RN * (i / RN) + (l / RN);

                                                                      t3 = RN * (i % RN) + (l % RN);

                                                                      if ((m[a][s1][t1] == RN) && (m[a][s2][t2] == RN) && (m[a][s3][t3] == RN)) {

                                                                                    for (n = 0; n < N; n++) {

                                                                                                  onoff[n] = 0;

                                                                                    }

                                                                                    for (n = 0; n < m[a][s1][t1]; n++) {

                                                                                                  onoff[rlst[a][s1][t1][n] - 1] = 1;

                                                                                    }

                                                                                    for (n = 0; n < m[a][s2][t2]; n++) {

                                                                                                  onoff[rlst[a][s2][t2][n] - 1] = 1;

                                                                                    }

                                                                                    for (n = 0; n < m[a][s3][t3]; n++) {

                                                                                                  onoff[rlst[a][s3][t3][n] - 1] = 1;

                                                                                    }

                                                                                    w = 0;

                                                                                    for (n = 0; n < N; n++) {

                                                                                                  if (onoff[n] == 1) {

                                                                                                                ckotae[w] = n;

                                                                                                                w = w + 1;

                                                                                                  }

                                                                                    }

                                                                                    if (w == RN) {

                                                                                                  for (n = 0; n < N; n++) {

                                                                                                                if (n != j && n != k && n != l) {

                                                                                                                              s4 = RN * (i / RN) + (n / RN);

                                                                                                                              t4 = RN * (i % RN) + (n % RN);

                                                                                                                              if (m[a][s4][t4] == 0) {

                                                                                                                                            wb[a][s4][t4][ckotae[0]] = 1;

                                                                                                                                            wb[a][s4][t4][ckotae[1]] = 1;

                                                                                                                                            wb[a][s4][t4][ckotae[2]] = 1;

                                                                                                                              }

                                                                                                                }

                                                                                                  }

                                                                                                  for (n = 0; n < N; n++) {

                                                                                                                if (n != j && n != k && n != l) {

                                                                                                                              s4 = RN * (i / RN) + (n / RN);

                                                                                                                              t4 = RN * (i % RN) + (n % RN);

                                                                                                                              if (m[a][s4][t4] == 0) {

                                                                                                                                            kyokusyokaiseki(s4, t4, a);

                                                                                                                              }

                                                                                                                }

                                                                                                  }

                                                                                    }

                                                                      }

                                                        }

                                          }

                            }

              }

}

void tont(size_t a) {

              tontgyo(a);

              tontretu(a);

              tontblock(a);

}

void shphaijyo(size_t a) {

              size_t i, j, wx, wy, k;

              size_t yk[N][N], xk[N][N];

              for (i = 0; i < N; i++) {

                            wy = 0;

                            for (j = 0; j < N; j++) {

                                          wx = 0;

                                          for (k = 0; k < N; k++) {

                                                        if (m[a][j][k] == 0) {

                                                                      if (wb[a][j][k][i] == 0) {

                                                                                    yk[wy][wx] = j;

                                                                                    xk[wy][wx] = k;

                                                                                    wx = wx + 1;

                                                                      }

                                                        }

                                          }

                                          if (wx == 2) {

                                                        wy = wy + 1;

                                          }

                            }

                            if (wy == 2) {

                                          if (xk[0][0] == xk[1][0] && xk[0][1] == xk[1][1]) {

                                                        for (k = 0; k < N; k++) {

                                                                      if (k != xk[0][0] && k != xk[0][1]) {

                                                                                    if (m[a][yk[0][0]][k] == 0) {

                                                                                                  wb[a][yk[0][0]][k][i] = 1;

                                                                                    }

                                                                                    if (m[a][yk[1][1]][k] == 0) {

                                                                                                  wb[a][yk[1][1]][k][i] = 1;

                                                                                    }

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (k != xk[0][0] && k != xk[0][1]) {

                                                                                    if (m[a][yk[0][0]][k] == 0) {

                                                                                                  kyokusyokaiseki(yk[0][0], k, a);

                                                                                    }

                                                                                    if (m[a][yk[1][1]][k] == 0) {

                                                                                                  kyokusyokaiseki(yk[1][1], k, a);

                                                                                    }

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (k != yk[0][0] && k != yk[1][1]) {

                                                                                    if (m[a][k][xk[0][0]] == 0) {

                                                                                                  wb[a][k][xk[0][0]][i] = 1;

                                                                                    }

                                                                                    if (m[a][k][xk[1][1]] == 0) {

                                                                                                  wb[a][k][xk[1][1]][i] = 1;

                                                                                    }

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (k != yk[0][0] && k != yk[1][1]) {

                                                                                    if (m[a][k][xk[0][0]] == 0) {

                                                                                                  kyokusyokaiseki(k, xk[0][0], a);

                                                                                    }

                                                                                    if (m[a][k][xk[1][1]] == 0) {

                                                                                                  kyokusyokaiseki(k, xk[1][1], a);

                                                                                    }

                                                                      }

                                                        }

                                          }

                            }

              }

              for (i = 0; i < N; i++) {

                            wx = 0;

                            for (j = 0; j < N; j++) {

                                          wy = 0;

                                          for (k = 0; k < N; k++) {

                                                        if (m[a][k][j] == 0) {

                                                                      if (wb[a][k][j][i] == 0) {

                                                                                    yk[wx][wy] = k;

                                                                                    xk[wx][wy] = j;

                                                                                    wy = wy + 1;

                                                                      }

                                                        }

                                          }

                                          if (wy == 2) {

                                                        wx = wx + 1;

                                          }

                            }

                            if (wx == 2) {

                                          if (yk[0][0] == yk[1][0] && yk[0][1] == yk[1][1]) {

                                                        for (k = 0; k < N; k++) {

                                                                      if (k != yk[0][0] && k != yk[0][1]) {

                                                                                    if (m[a][k][xk[0][0]] == 0) {

                                                                                                  wb[a][k][xk[0][0]][i] = 1;

                                                                                    }

                                                                                    if (m[a][k][xk[1][1]] == 0) {

                                                                                                  wb[a][k][xk[1][1]][i] = 1;

                                                                                    }

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (k != yk[0][0] && k != yk[1][1]) {

                                                                                    if (m[a][k][xk[0][0]] == 0) {

                                                                                                  kyokusyokaiseki(k, xk[0][0], a);

                                                                                    }

                                                                                    if (m[a][k][xk[1][1]] == 0) {

                                                                                                  kyokusyokaiseki(k, xk[1][1], a);

                                                                                    }

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (k != xk[0][0] && k != xk[1][1]) {

                                                                                    if (m[a][yk[0][0]][k] == 0) {

                                                                                                  wb[a][yk[0][0]][k][i] = 1;

                                                                                    }

                                                                                    if (m[a][yk[1][1]][k] == 0) {

                                                                                                  wb[a][yk[1][1]][k][i] = 1;

                                                                                    }

                                                                      }

                                                        }

                                                        for (k = 0; k < N; k++) {

                                                                      if (k != xk[0][0] && k != xk[1][1]) {

                                                                                    if (m[a][yk[0][0]][k] == 0) {

                                                                                                  kyokusyokaiseki(yk[0][0], k, a);

                                                                                    }

                                                                                    if (m[a][yk[1][1]][k] == 0) {

                                                                                                  kyokusyokaiseki(yk[1][1], k, a);

                                                                                    }

                                                                      }

                                                        }

                                          }

                            }

              }

}

void listhou(size_t a) {

              size_t i, j, k, s, t;

              for (i = 0; i < N; i++) {

                            for (j = 0; j < N; j++) {

                                          if (m[a][i][j] == 0) {

                                                        if (mx[a][i][j] == 0) {

                                                                      cn[a] = 2;

                                                                      return;

                                                        }

                                                        if (mx[a][i][j] == 1) {

                                                                      m[a][i][j] = rlst[a][i][j][0];

                                                                      krn[a] = krn[a] - 1;

                                                                      if (krn[a] == 0)return;

                                                                      for (k = 0; k < N; k++) {

                                                                                    if (m[a][i][k] == 0) {

                                                                                                  wb[a][i][k][m[a][i][j] - 1] = 1;

                                                                                    }

                                                                                    if (m[a][k][j] == 0) {

                                                                                                  wb[a][k][j][m[a][i][j] - 1] = 1;

                                                                                    }

                                                                                    s = RN * (i / RN) + (k / RN);

                                                                                    t = RN * (j / RN) + (k % RN);

                                                                                    if (m[a][s][t] == 0) {

                                                                                                  wb[a][s][t][m[a][i][j] - 1] = 1;

                                                                                    }

                                                                      }

                                                                      for (k = 0; k < N; k++) {

                                                                                    if (m[a][i][k] == 0) kyokusyokaiseki(i, k, a);

                                                                                    if (m[a][k][j] == 0) kyokusyokaiseki(k, j, a);

                                                                                    s = RN * (i / RN) + (k / RN);

                                                                                    t = RN * (j / RN) + (k % RN);

                                                                                    if (m[a][s][t] == 0) kyokusyokaiseki(s, t, a);

                                                                      }

                                                        }

                                          }

                            }

              }

}

void hitaisyo(size_t a) {

              size_t sss = rand() % (N * N);

              size_t rnk;

              size_t g = rand() % 12;

              if (g == 0)rnk = 7;

              if (g == 1)rnk = 11;

              if (g == 2)rnk = 13;

              if (g == 3)rnk = 17;

              if (g == 4)rnk = 19;

              if (g == 5)rnk = 23;

              if (g == 6)rnk = 29;

              if (g == 7)rnk = 31;

              if (g == 8)rnk = 37;

              if (g == 9)rnk = 41;

              if (g == 10)rnk = 43;

              if (g == 11)rnk = 47;

              for (size_t i = 0; i < N * N; i++) {

                            yy[a][i] = ((i * rnk + sss) % (N * N)) / N;

                            xx[a][i] = ((i * rnk + sss) % (N * N)) % N;

              }

}

void sayu(size_t a) {

              size_t ty, gz;

              if (hnt % 2 == 0) {

                            gz = rand() % 5;

                            if (gz == 0)ty = 0;

                            if (gz > 0 && gz < 4)ty = 2;

                            if (gz == 4)ty = 4;

              }

              else {

                            gz = rand() % 7;

                            if (gz < 4)ty = 1;

                            if (gz > 3 && gz < 6)ty = 3;

                            if (gz == 6)ty = 5;

              }

              //ty = 2;

              size_t s = rand() % 11;

              size_t rnk;

              if (s == 0) rnk = 47;

              if (s == 1) rnk = 7;

              if (s == 2) rnk = 11;

              if (s == 3) rnk = 13;

              if (s == 4) rnk = 17;

              if (s == 5) rnk = 19;

              if (s == 6) rnk = 23;

              if (s == 7) rnk = 29;

              if (s == 8) rnk = 31;

              if (s == 9) rnk = 37;

              if (s == 10) rnk = 41;

              //rnk = 4;

              size_t ss = rand() % N;

              size_t sss = rand() % 36;

              for (size_t i = 0; i < (hnt - ty) / 2; i++) {

                            xx[a][i] = ((i * rnk + sss) % 36) / N;

                            xx[a][hnt - 1 - i] = 8 - xx[a][i];

                            yy[a][i] = ((i * rnk + sss) % 36) % N;

                            yy[a][hnt - 1 - i] = yy[a][i];

              }

              size_t tyrnk;

              while (1) {

                            tyrnk = rand() % 6;

                            if (tyrnk > 2 && tyrnk % 3 != 0)break;

              }

              for (size_t i = 0; i < ty; i++) {

                            xx[a][i + (hnt - ty) / 2] = 4;

                            yy[a][i + (hnt - ty) / 2] = (i * tyrnk + ss) % N;

              }

}

void jyoge(size_t a) {

              size_t ty, gz;

              if (hnt % 2 == 0) {

                            gz = rand() % 5;

                            if (gz == 0)ty = 0;

                            if (gz > 0 && gz < 4)ty = 2;

                            if (gz == 4)ty = 4;

              }

              else {

                            gz = rand() % 7;

                            if (gz < 4)ty = 1;

                            if (gz > 3 && gz < 6)ty = 3;

                            if (gz == 6)ty = 5;

              }

              //ty = 2;

              size_t s = rand() % 11;

              size_t rnk;

              if (s == 0) rnk = 47;

              if (s == 1) rnk = 7;

              if (s == 2) rnk = 11;

              if (s == 3) rnk = 13;

              if (s == 4) rnk = 17;

              if (s == 5) rnk = 19;

              if (s == 6) rnk = 23;

              if (s == 7) rnk = 29;

              if (s == 8) rnk = 31;

              if (s == N) rnk = 37;

              if (s == 10) rnk = 41;

              //rnk = 4;

              size_t ss = rand() % N;

              size_t sss = rand() % 36;

              for (size_t i = 0; i < (hnt - ty) / 2; i++) {

                            yy[a][i] = ((i * rnk + sss) % 36) / N;

                            yy[a][hnt - 1 - i] = 8 - yy[a][i];

                            xx[a][i] = ((i * rnk + sss) % 36) % N;

                            xx[a][hnt - 1 - i] = xx[a][i];

              }

              size_t tyrnk;

              while (1) {

                            tyrnk = rand() % 6;

                            if (tyrnk > 2 && tyrnk % 3 != 0)break;

              }

              for (size_t i = 0; i < ty; i++) {

                            yy[a][i + (hnt - ty) / 2] = 4;

                            xx[a][i + (hnt - ty) / 2] = (i * tyrnk + ss) % N;

              }

}

void ten(size_t a) {

              size_t s, rnk, sss;

              s = rand() % 11;

              if (s == 0) rnk = 47;

              if (s == 1) rnk = 7;

              if (s == 2) rnk = 11;

              if (s == 3) rnk = 13;

              if (s == 4) rnk = 17;

              if (s == 5) rnk = 19;

              if (s == 6) rnk = 23;

              if (s == 7) rnk = 29;

              if (s == 8) rnk = 31;

              if (s == 9) rnk = 53;

              if (s == 10) rnk = 61;

              while (1) {

                            s = rand() % (hnt / N + 2);

                            if ((hnt - s) % 2 == 0) break;

              }

              sss = rand() * 40;

              if (hnt % 2 == 0) {

                            for (size_t i = 0; i < hnt / 2; i++) {

                                          yy[a][i] = ((i * rnk + sss) % 40) / N;

                                          yy[a][hnt - 1 - i] = 8 - yy[a][i];

                                          xx[a][i] = ((i * rnk + sss) % 40) % N;

                                          xx[a][hnt - 1 - i] = 8 - xx[a][i];

                            }

              }

              else {

                            for (size_t i = 0; i < hnt / 2; i++) {

                                          yy[a][i] = ((i * rnk + sss) % 40) / N;

                                          yy[a][hnt - 1 - i] = 8 - yy[a][i];

                                          xx[a][i] = ((i * rnk + sss) % 40) % N;

                                          xx[a][hnt - 1 - i] = 8 - xx[a][i];

                            }

                            yy[a][(hnt - 1) / 2] = 4;

                            xx[a][(hnt - 1) / 2] = 4;

              }

}

void sayujyoge(size_t a) {

              size_t sss, b, rnk, s, mns;

              size_t kh[16];

              if (hnt % 2 == 0) {

                            if (hnt % 4 == 0) {

                                          s = rand() % 5;

                                          if (s == 0) rnk = 3;

                                          if (s == 1) rnk = 5;

                                          if (s == 2) rnk = 7;

                                          if (s == 3) rnk = 11;

                                          if (s == 4) rnk = 13;

                                          sss = rand() % 16;

                                          b = hnt / 4 - 1;

                                          for (size_t i = 0; i < b + 1; i++) {

                                                        kh[i] = (sss + rnk * i) % 16;

                                          }

                                          for (size_t i = 0; i < b + 1; i++) {

                                                        yy[a][i] = kh[i] / 4;

                                                        xx[a][i] = kh[i] % 4;

                                                        yy[a][2 * (b + 1) - i - 1] = yy[a][i];

                                                        xx[a][2 * (b + 1) - i - 1] = 8 - xx[a][i];

                                                        yy[a][3 * (b + 1) - i - 1] = 8 - yy[a][i];

                                                        xx[a][3 * (b + 1) - i - 1] = xx[a][i];

                                                        yy[a][4 * (b + 1) - i - 1] = 8 - yy[a][i];

                                                        xx[a][4 * (b + 1) - i - 1] = 8 - xx[a][i];

                                          }

                                          return;

                            }

                            s = rand() % 3;

                            if (s < 2) mns = 1; else mns = 3;

                            s = rand() % 4;

                            for (size_t i = 0; i < mns + 1; i++) {

                                          xx[a][i] = 4;

                                          xx[a][2 * mns - 1 - i] = 4;

                                          yy[a][i] = (s + 3 * i) % 4;

                                          yy[a][2 * mns - 1 - i] = 8 - yy[a][i];

                            }

                            b = (hnt - 2 * mns) / 4 - 1;

                            s = rand() % 5;

                            if (s == 0) rnk = 3;

                            if (s == 1) rnk = 5;

                            if (s == 2) rnk = 7;

                            if (s == 3) rnk = 11;

                            if (s == 4) rnk = 13;

                            sss = rand() % 16;

                            for (size_t i = 0; i < b + 1; i++) {

                                          kh[i] = (sss + rnk * i) % 16;

                            }

                            for (size_t i = 0; i < b + 1; i++) {

                                          yy[a][2 * mns + i] = kh[i] / 4;

                                          xx[a][2 * mns + i] = kh[i] % 4;

                                          yy[a][2 * mns + 2 * (b + 1) - i - 1] = yy[a][2 * mns + i];

                                          xx[a][2 * mns + 2 * (b + 1) - i - 1] = 8 - xx[a][2 * mns + i];

                                          yy[a][2 * mns + 3 * (b + 1) - i - 1] = 8 - yy[a][2 * mns + i];

                                          xx[a][2 * mns + 3 * (b + 1) - i - 1] = xx[a][2 * mns + i];

                                          yy[a][2 * mns + 4 * (b + 1) - i - 1] = 8 - yy[a][2 * mns + i];

                                          xx[a][2 * mns + 4 * (b + 1) - i - 1] = 8 - xx[a][2 * mns + i];

                            }

                            return;

              }

              if (hnt % 2 == 1) {

                            xx[a][0] = 4;

                            yy[a][0] = 4;

                            if (((hnt - 1) % 4) == 0) {

                                          s = rand() % 5;

                                          if (s == 0) rnk = 3;

                                          if (s == 1) rnk = 5;

                                          if (s == 2) rnk = 7;

                                          if (s == 3) rnk = 11;

                                          if (s == 4) rnk = 13;

                                          sss = rand() % 16;

                                          b = (hnt - 1) / 4 - 1;

                                          for (size_t i = 0; i < b + 1; i++) {

                                                        kh[i] = (sss + rnk * i) % 16;

                                          }

                                          for (size_t i = 0; i < b + 1; i++) {

                                                        yy[a][1 + i] = kh[i] / 4;

                                                        xx[a][1 + i] = kh[i] % 4;

                                                        yy[a][1 + 2 * (b + 1) - i - 1] = yy[a][1 + i];

                                                        xx[a][1 + 2 * (b + 1) - i - 1] = 8 - xx[a][1 + i];

                                                        yy[a][1 + 3 * (b + 1) - i - 1] = 8 - yy[a][1 + i];

                                                        xx[a][1 + 3 * (b + 1) - i - 1] = xx[a][1 + i];

                                                        yy[a][1 + 4 * (b + 1) - i - 1] = 8 - yy[a][1 + i];

                                                        xx[a][1 + 4 * (b + 1) - i - 1] = 8 - xx[a][1 + i];

                                          }

                                          return;

                            }

                            s = rand() % 3;

                            if (s < 2) mns = 1; else mns = 3;

                            s = rand() % 4;

                            mns = 3;

                            for (size_t i = 0; i < mns; i++) {

                                          xx[a][1 + i] = 4;

                                          xx[a][1 + 2 * mns - 1 - i] = 4;

                                          yy[a][1 + i] = (s + 3 * i) % 4;

                                          yy[a][1 + 2 * mns - 1 - i] = 8 - yy[a][1 + i];

                            }

                            b = (hnt - 1 - 2 * mns) / 4 - 1;

                            s = rand() % 4;

                            if (s == 0) rnk = 3;

                            if (s == 1) rnk = 5;

                            if (s == 2) rnk = 7;

                            if (s == 3) rnk = 11;

                            sss = rand() % 16;

                            for (size_t i = 0; i < b + 1; i++) {

                                          kh[i] = (sss + rnk * i) % 16;

                            }

                            for (size_t i = 0; i < b + 1; i++) {

                                          yy[a][1 + 2 * mns + i] = kh[i] / 4;

                                          xx[a][1 + 2 * mns + i] = kh[i] % 4;

                                          yy[a][1 + 2 * mns + 2 * (b + 1) - i - 1] = yy[a][1 + 2 * mns + i];

                                          xx[a][1 + 2 * mns + 2 * (b + 1) - i - 1] = 8 - xx[a][1 + 2 * mns + i];

                                          yy[a][1 + 2 * mns + 3 * (b + 1) - i - 1] = 8 - yy[a][1 + 2 * mns + i];

                                          xx[a][1 + 2 * mns + 3 * (b + 1) - i - 1] = xx[a][1 + 2 * mns + i];

                                          yy[a][1 + 2 * mns + 4 * (b + 1) - i - 1] = 8 - yy[a][1 + 2 * mns + i];

                                          xx[a][1 + 2 * mns + 4 * (b + 1) - i - 1] = 8 - xx[a][1 + 2 * mns + i];

                            }

              }

}

void kokoro(size_t a) {

              size_t b[N - 1][N - 1];

              for (size_t i = 0; i < 5; i++) {

                            yy[a][i] = 8 - i;

                            xx[a][i] = 4 - i;

              }

              for (size_t i = 5; i < N; i++) {

                            yy[a][i] = yy[a][i - 4];

                            xx[a][i] = 8 - xx[a][i - 4];

              }

              yy[a][N] = 3;

              xx[a][N] = 0;

              yy[a][10] = 3;

              xx[a][10] = 8;

              for (size_t i = 11; i < 13; i++) {

                            yy[a][i] = 13 - i;

                            xx[a][i] = i - 11;

                            yy[a][i + 2] = yy[a][i];

                            xx[a][i + 2] = 8 - xx[a][i];

              }

              for (size_t i = 15; i < 17; i++) {

                            yy[a][i] = i - 14;

                            xx[a][i] = i - 13;

                            yy[a][i + 2] = yy[a][i];

                            xx[a][i + 2] = 8 - xx[a][i];

              }

              yy[a][19] = 3;

              xx[a][19] = 4;

              for (size_t i = 0; i < 20; i++) {

                            b[yy[a][i]][xx[a][i]] = 10;

              }

              size_t sa, h;

              sa = hnt - 20;

              for (size_t i = 1; i < 8; i++) {

                            h = 0;

                            for (size_t j = 1; j < N; j++) {

                                          if (b[j - 1][i] == 10)  h = h + 1;

                                          if (h == 1 && b[j][i] != 10)  b[j][i] = 3;

                            }

              }

              size_t k, i, j;

              if (hnt % 2 == 0) {

                            for (size_t k = 20; k < 20 + sa / 2; k++) {

                                          while (1) {

                                                        i = rand() % N;

                                                        j = rand() % 4;

                                                        if (b[i][j] == 3) {

                                                                      b[i][j] = 4;

                                                                      b[i][8 - j] = 4;

                                                                      yy[a][k] = i;

                                                                      xx[a][k] = j;

                                                                      yy[a][k + sa / 2] = i;

                                                                      xx[a][k + sa / 2] = 8 - j;

                                                                      break;

                                                        }

                                          }

                            }

                            return;

              }

              else {

                            while (1) {

                                          j = 4 + rand() % 4;

                                          if (b[j][4] == 3) {

                                                        b[j][4] = 4;

                                                        yy[a][20] = j;

                                                        xx[a][20] = 4;

                                                        break;

                                          }

                            }

                            if (hnt > 21) {

                                          for (size_t i = 21; i < 21 + (hnt - 21) / 2; i++) {

                                                        size_t s, t;

                                                        while (1) {

                                                                      s = rand() % N;

                                                                      t = rand() % 4;

                                                                      if (b[s][t] == 3) {

                                                                                    b[s][t] = 4;

                                                                                    b[s][8 - t] = 4;

                                                                                    yy[a][i] = s;

                                                                                    xx[a][i] = t;

                                                                                    yy[a][i + (hnt - 21) / 2] = s;

                                                                                    xx[a][i + (hnt - 21) / 2] = 8 - t;

                                                                                    break;

                                                                      }

                                                        }

                                          }

                            }

              }

}

void dainyu(size_t a) {

              for (size_t i = 0; i < hnt; i++) {

                            ccm[a][yy[a][i]][xx[a][i]] = m[a][yy[a][i]][xx[a][i]];

              }

}

void mondaisakusei(size_t a) {

              syokika(a);

              for (size_t i = 0; i < hnt; i++) {

                            m[a][yy[a][i]][xx[a][i]] = ccm[a][yy[a][i]][xx[a][i]];

                            size_t gy[N], r[N], b[N],p,q;

                            size_t s = yy[a][i];

                            size_t t = yy[a][i];

                            for (size_t j = 0; j < N; j++) {                                      

                                          if (m[a][s][j] == 0) {

                                                        if (wb[a][s][j][m[a][s][t] - 1] == 0) {

                                                                      wb[a][s][j][m[a][s][t] - 1] = 1;

                                                                      //kyokusyokaiseki(s, j, a);

                                                                      r[j] = 1;

                                                        }

                                          }

                            }

                            for (size_t j = 0; j < N; j++) {

                                          if (m[a][j][t] == 0) {

                                                        if (wb[a][j][t][m[a][s][t] - 1] == 0) {

                                                                      wb[a][j][t][m[a][s][t] - 1] = 1;

                                                                      //kyokusyokaiseki(j, t, a);

                                                                      gy[j] = 1;

                                                        }

                                          }

                            }

                            for (size_t j = 0; j < N; j++) {

                                          p = RN * (s / RN) + (j / RN);

                                          q = RN * (t / RN) + (j % RN);

                                          if (p != s && q != t) {

                                                        if (m[a][p][q] == 0) {

                                                                      if (wb[a][p][q][m[a][s][t] - 1] == 0) {

                                                                                    wb[a][p][q][m[a][s][t] - 1] = 1;

                                                                                    //kyokusyokaiseki(p, q, a);

                                                                                    b[j] = 1;

                                                                      }

                                                        }

                                          }

                            }

              }

              totalkaiseki(a);

}

void syokika(size_t a) {

              for (size_t i = 0; i < N; i++) {

                            for (size_t j = 0; j < N; j++) {

                                          m[a][i][j] = 0;

                                          cm[a][i][j] = 0;

                                          mx[a][i][j] = N;

                                          for (size_t k = 0; k < N; k++) {

                                                        wb[a][i][j][k] = 0;

                                          }

                            }

              }

}

void nyuryokujyun(size_t g, size_t a) {

              size_t ik, jk, mn = 100;

              for (size_t i = 0; i < N; i++) {

                            for (size_t j = 0; j < N; j++) {

                                          if (m[a][i][j] == 0) {

                                                        if (mx[a][i][j] <= mn) {

                                                                      mx[a][i][j] = mn;

                                                                      ik = i;

                                                                      jk = j;

                                                        }

                                          }

                            }

              }

              y[a][g] = ik;

              x[a][g] = jk;

              kyokusyokaiseki(ik, jk, a);

}

void f(size_t g, size_t a) {

              size_t i, j, s, t, p, q, ii, iii, k;

              size_t gy[N], r[N], b[N];

              if (g < hnt) {

                            s = yy[a][g];

                            t = xx[a][g];

                            kyokusyokaiseki(s, t, a);

              }

              else {

                            nyuryokujyun(g, a);

                            s = y[a][g];

                            t = x[a][g];

                            kyokusyokaiseki(s, t, a);

              }

              if (mx[a][s][t] == 0)return;

              ii = rand() % mx[a][s][t];

              if (cn[a] == 1)return;

 

              if (keizoku == 0)return;

              for (i = 0; i < mx[a][s][t]; i++) {

                            iii = (i + ii) % mx[a][s][t];

                            m[a][s][t] = rlst[a][s][t][iii];

                            for (j = 0; j < N; j++) {

                                          gy[j] = 0;

                                          r[j] = 0;

                                          b[j] = 0;

                            }

                            for (j = 0; j < N; j++) {

                                          if (m[a][s][j] == 0) {

                                                        if (wb[a][s][j][m[a][s][t] - 1] == 0) {

                                                                      wb[a][s][j][m[a][s][t] - 1] = 1;

                                                                      //kyokusyokaiseki(s, j, a);

                                                                      r[j] = 1;

                                                        }

                                          }

                            }

                            for (j = 0; j < N; j++) {

                                          if (m[a][j][t] == 0) {

                                                        if (wb[a][j][t][m[a][s][t] - 1] == 0) {

                                                                      wb[a][j][t][m[a][s][t] - 1] = 1;

                                                                      //kyokusyokaiseki(j, t, a);

                                                                      gy[j] = 1;

                                                        }

                                          }

                            }

                            for (j = 0; j < N; j++) {

                                          p = RN * (s / RN) + (j / RN);

                                          q = RN * (t / RN) + (j % RN);

                                          if (p != s && q != t) {

                                                        if (m[a][p][q] == 0) {

                                                                      if (wb[a][p][q][m[a][s][t] - 1] == 0) {

                                                                                    wb[a][p][q][m[a][s][t] - 1] = 1;

                                                                                    //kyokusyokaiseki(p, q, a);

                                                                                    b[j] = 1;

                                                                      }

                                                        }

                                          }

                            }

                            if (keizoku == 0)return;

                            if (g + 1 < hnt) {

                                          f1(g + 1, a);

                                          if (cn[a] == 1)return;

                                          if (keizoku == 0)return;

                            }

                            else {

                                          cn[a]++;

                                          if (cn[a] == 1)return;

                                          if (keizoku == 0)return;

                            }

                            for (j = 0; j < N; j++) {

                                          if (r[j] == 1) {

                                                        wb[a][s][j][m[a][s][t] - 1] = 0;

                                          }

                                          if (gy[j] == 1) {

                                                        wb[a][j][t][m[a][s][t] - 1] = 0;

                                          }

                                          p = RN * (s / RN) + (j / RN);

                                          q = RN * (t / RN) + (j % RN);

                                          if (b[j] == 1) {

                                                        wb[a][p][q][m[a][s][t] - 1] = 0;

                                          }

                            }

              }

              m[a][s][t] = 0;

              return;

}

void f1(size_t g, size_t a) {

              size_t i, j, s, t, p, q, ii, iii, k;

              size_t gy[N], r[N], b[N];

              if (g < hnt) {

                            s = yy[a][g];

                            t = xx[a][g];

                            kyokusyokaiseki(s, t, a);

              }

              else {

                            nyuryokujyun(g, a);

                            s = y[a][g];

                            t = x[a][g];

                            kyokusyokaiseki(s, t, a);

              }

              if (mx[a][s][t] == 0)return;

              ii = rand() % mx[a][s][t];

              if (cn[a] == 1)return;

 

              if (keizoku == 0)return;

              for (i = 0; i < mx[a][s][t]; i++) {

                            iii = (i + ii) % mx[a][s][t];

                            m[a][s][t] = rlst[a][s][t][iii];

                            for (j = 0; j < N; j++) {

                                          gy[j] = 0;

                                          r[j] = 0;

                                          b[j] = 0;

                            }

                            for (j = 0; j < N; j++) {

                                          if (m[a][s][j] == 0) {

                                                        if (wb[a][s][j][m[a][s][t] - 1] == 0) {

                                                                      wb[a][s][j][m[a][s][t] - 1] = 1;

                                                                      //kyokusyokaiseki(s, j, a);

                                                                      r[j] = 1;

                                                        }

                                          }

                            }

                            for (j = 0; j < N; j++) {

                                          if (m[a][j][t] == 0) {

                                                        if (wb[a][j][t][m[a][s][t] - 1] == 0) {

                                                                      wb[a][j][t][m[a][s][t] - 1] = 1;

                                                                      //kyokusyokaiseki(j, t, a);

                                                                      gy[j] = 1;

                                                        }

                                          }

                            }

                            for (j = 0; j < N; j++) {

                                          p = RN * (s / RN) + (j / RN);

                                          q = RN * (t / RN) + (j % RN);

                                          if (p != s && q != t) {

                                                        if (m[a][p][q] == 0) {

                                                                      if (wb[a][p][q][m[a][s][t] - 1] == 0) {

                                                                                    wb[a][p][q][m[a][s][t] - 1] = 1;

                                                                                    //kyokusyokaiseki(p, q, a);

                                                                                    b[j] = 1;

                                                                      }

                                                        }

                                          }

                            }

                            if (keizoku == 0)return;

                            if (g + 1 < hnt) {

                                          f1(g + 1, a);

                                          if (cn[a] == 1)return;

                                          if (keizoku == 0)return;

                            }

                            else {

                                          cn[a]++;

                                          dainyu(a);

                                          if (cn[a] == 1)return;

                                          if (keizoku == 0)return;

                            }

                            for (j = 0; j < N; j++) {

                                          if (r[j] == 1) {

                                                        wb[a][s][j][m[a][s][t] - 1] = 0;

                                          }

                                          if (gy[j] == 1) {

                                                        wb[a][j][t][m[a][s][t] - 1] = 0;

                                          }

                                          p = RN * (s / RN) + (j / RN);

                                          q = RN * (t / RN) + (j % RN);

                                          if (b[j] == 1) {

                                                        wb[a][p][q][m[a][s][t] - 1] = 0;

                                          }

                            }

              }

              m[a][s][t] = 0;

              return;

}

void kyokusyokaiseki(size_t s, size_t t, size_t a) {

              size_t w = 0;

              for (size_t i = 0; i < N; i++) {

                            if (wb[a][s][t][i] == 0) {

                                          rlst[a][s][t][w] = i + 1;

                                          w++;

                            }

              }

              mx[a][s][t] = w;

}

size_t ks(size_t a) {

              size_t p[N], s, t;

              for (size_t i = 0; i < N; i++) {

                            p[i] = 0;

                            for (size_t j = 0; j < N; j++) {

                                          for (size_t k = 0; k < N; k++) {

                                                        p[m[a][j][k] - 1] = 1;

                                          }

                            }

                            for (size_t j = 0; j < N; j++) {

                                          if (p[j] == 0)return(0);

                            }

              }

              for (size_t i = 0; i < N; i++) {

                            p[i] = 0;

                            for (size_t j = 0; j < N; j++) {

                                          for (size_t k = 0; k < N; k++) {

                                                        p[m[a][k][j] - 1] = 1;

                                          }

                            }

                            for (size_t j = 0; j < N; j++) {

                                          if (p[j] == 0)return(0);

                            }

              }

              for (size_t i = 0; i < N; i++) {

                            p[i] = 0;

                            for (size_t j = 0; j < N; j++) {

                                          for (size_t k = 0; k < N; k++) {

                                                        s = RN * (i / RN) + (j / RN);

                                                        t = RN * (i % RN) + (j % RN);

                                                        p[m[a][s][t] - 1] = 1;

                                          }

                            }

                            for (size_t j = 0; j < N; j++) {

                                          if (p[j] == 0)return(0);

                            }

              }

              return(1);

}