#include <perms.h>
int _imp_mainep(int _imp_argc, char **_imp_argv) {
  const int Bit = 0x80000000;
  const int Maxscore = +50000;
  extern void PROMPT(_imp_string S);
  const int Plywidth = 5;
  typedef struct Sqf {
    int P;
    int Att;
    int Def;
    int Attp;
  } Sqf;
  typedef struct Rowf {
    Sqf R[1+8 /*1:8*/];
#define R(i) R[i]
  } Rowf;
  static Rowf Brd[1+8 /*1:8*/];
#define Brd(i) Brd[i]
  static Rowf Brdold[1+8 /*1:8*/];
#define Brdold(i) Brdold[i]
  int Val[13 /*-6:6*/];
#define Val(n) Val[(n)+6]
  typedef struct Listf Listf;
  typedef struct Listf {
    Listf *L;
    int Score;
    unsigned char Fr;
    unsigned char To;
    int Spec;
    int Chk;
  } Listf;
  typedef struct Qhf {
    Listf *L;
    int Hold;
  } Qhf;
  typedef struct Ptf {
    int *P;
  } Ptf;
  Ptf Pt[1+64 /*1:64*/];
#define Pt(i) Pt[i]
  const int King = 6;
  const int Queen = 5;
  const int Rook = 4;
  const int Pawn = 1;
  Listf *Freelist;
  Qhf Move;
  Listf Lista[4001 /*0:4000*/];
#define Lista(i) Lista[i]
  ;
  Sqf *Sq;
  static int Pinx[1+32 /*1:32*/] = {[0 ... 32] = 0};
#define Pinx(i) Pinx[i]
  static int Piny[1+32 /*1:32*/] = {[0 ... 32] = 0};
#define Piny(i) Piny[i]
  int Pindx[1+32 /*1:32*/];
#define Pindx(i) Pindx[i]
  int Pinpy[1+32 /*1:32*/];
#define Pinpy(i) Pinpy[i]
  static int Pinpt;
  static int Px;
  static int Py;
  typedef struct Sqif {
    Sqf *Sq;
  } Sqif;
  Sqif Sqi[64 /*1:64*/];
#define Sqi(i) Sqi[i]
  const int Bitval[1+6 /*1:6*/] = {0, 256, 64, 32, 8, 2, 1};
#define Bitval(i) Bitval[i]
  const int Pawn2d[9+64 /*9:72*/] = {0,0,0, 0,0,0, 0,0,0,
#define Pawn2d(i) Pawn2d[i]
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
                                   5,
                                   0,
                                   0,
                                   3,
                                   3,
                                   3,
                                   20,
                                   20,
                                   3,
                                   3,
                                   3,
                                   4,
                                   6,
                                   6,
                                   50,
                                   50,
                                   6,
                                   6,
                                   4,
                                   8,
                                   9,
                                   30,
                                   55,
                                   55,
                                   30,
                                   9,
                                   8,
                                   10,
                                   10,
                                   35,
                                   60,
                                   60,
                                   35,
                                   10,
                                   10,
                                   [57 ... 64] = 100,
                                   [65 ... 72] = 500};
  const unsigned char Posx[1+12 /*1:12*/] = {0, 2,  3,  6, 7, 58, 59,
                                           62, 63, 1, 8, 57, 64};
#define Posx(i) Posx[i]
  const int Posp[1+12 /*1:12*/] = {0, -2, -3, -3, -2, 2, 3, 3, 2, -4, -4, 4, 4};
#define Posp(i) Posp[i]
  const int Pospp[1+12 /*1:12*/] = {0, [1 ... 4] = -7, [5 ... 8] = 7, [9 ... 10] = -10,
                                  [11 ... 12] = 10};
#define Pospp(i) Pospp[i]
  const int Nolegmove[3 /*-1:1*/] = {-24000, 0, 24000};
#define Nolegmove(i) Nolegmove[(i)+1]
  static unsigned char Kmove[3 /*-1:1*/] = {[0 ... 2] = 0};
#define Kmove(i) Kmove[(i)+1]
  static int Kcas[3 /*-1:1*/] = {[0 ... 2] = 0};
#define Kcas(i) Kcas[(i)+1]
  Listf Lm;
  Qhf Mmove;
  int I;
  int X;
  int Y;
  int Play;
  static double Time;
  static double Time2;
  static double Timtt = 15;
  static int No = 1;
  static int Scorea;
  static int Xdepth;
  static int Pdepth;
  static int Mon;
  static int Justoneply;
  static int Chk;
  static int Lastchk;
  static int Pinremove;
  auto Listf *Nply(int Which, int Depth, Listf *Chain);
  auto Listf *Sortandprune(Listf *List, int Width, int Which);
  auto int Score(int Which, Listf *L);
  auto Listf *Moves(int Which, int Scrq);
  auto Listf *Oneply(int Which, int Width);
  auto int Changeboard(Qhf *B);
  auto void Restoreboard(Qhf *B);
  auto void Burp(Qhf *X, int W);
  auto void Tell(Listf *Move, int Which);
  auto void Printboard(void);
  auto void Printmove(Listf *List);
  auto int Checkyourmove(Listf *List);
  auto void Yourmove(void);
  for (I = 0; I <= 4000 - 1; I++) Lista(I).L = &Lista(I + 1);
  Freelist = &Lista(0);
  SELECTINPUT(1);
  for (I = -6; I <= 6; I++) READ(Val(I));
  READ(Pdepth);
  READ(Mon);
  READ(Play);
  I = 1;
  for (Y = 1; Y <= 8; Y++)
    for (X = 1; X <= 8; X++) {
      Sq = &Brd(Y).R(X);
      READ(Sq->P);
      Sqi(I).Sq = Sq;
      Pt(I).P = &Sq->P;
      I = I + 1;
    }
  SELECTINPUT(0);
  Mmove.Hold = 0;
  Move.Hold = 0;
  Lm.Score = 0;
  Lm.Chk = 0;
  Mmove.L = &Lm;
  PRINTSTRING(
      _imp_str_literal("Version 2.5\nHOW DIFFICULT A GAME DO YOU WANT?\n      "
                       "2 = NORMAL STRENGTH, 3 = MORE DIFFICULT\n"));
  PROMPT(_imp_str_literal("2-4?"));
  READ(Pdepth);
  SKIPSYMBOL();
  PROMPT(_imp_str_literal("Move?"));
  Printboard();
  Time2 = CPUTIME();
  for (;;) {
    if (Play == 1) {
      Move.L = Nply(-1, 0, Move.L);
      Tell(Move.L, -1);
      I = Changeboard(&Move);
    } else {
      Yourmove();
      Burp(&Mmove, -1);
    }
    Time = CPUTIME();
    Move.L = Nply(+1, 0, Mmove.L);
    Burp(&Move, +1);
    Printboard();
    SELECTOUTPUT(2);
    Printboard();
    SELECTOUTPUT(0);
    No = No + 1;
  }
  void Releasechain(Listf *L) {
    Listf *L2;
    L2 = L;
    while (L->L != NULL) {
      L = L->L;
    }
    L->L = Freelist;
    Freelist = L2;
  }
  Listf *Nply(int Which, int Depth, Listf *Chain) {
    int I;
    int Xwhich;
    int J;
    int Swidth;
    int Ci;
    int Flag;
    Qhf *Bpt;
    Qhf B[1+40 /*1:40*/];
#define B(i) B[i]
    Listf *List;
    Listf *Listx;
    const int Xwidth[11 /*0:10*/] = {8, 8, [2 ... 10] = 3};
#define Xwidth(i) Xwidth[i]
    Xdepth = Depth;
    Depth = Depth + 1;
    Swidth = Xwidth(Depth);
    if (Depth == Pdepth) Swidth = 1;
    Lastchk = Chain->Chk;
    List = Oneply(Which, Swidth);
    I = 1;
    B(1).L = RECORD(0);
    Flag = 0;
    while (List != NULL) {
      Bpt = &B(I);
      Bpt->L = List;
      List = List->L;
      if (Mon != 0) {
        SELECTOUTPUT(2);
        SPACES(Depth * 3);
        WRITE(Depth, 1);
        SPACES(2);
        Printmove(Bpt->L);
        if (Lastchk != 0) PRINTSTRING(_imp_str_literal(" FORCED"));
        NEWLINE();
        SELECTOUTPUT(0);
      }
      I = I + 1;
      Xwhich = Which ^ 0xFFFFFFFE;
      if (Depth < Pdepth) {
        Ci = Changeboard(Bpt);
        Listx = Nply(Xwhich, Depth, Bpt->L);
        Lastchk = Chain->Chk;
        Restoreboard(Bpt);
        if (Listx != NULL) {
          Bpt->L->Score = Listx->Score;
          Releasechain(Listx);
          Flag = Flag + 1;
        } else {
          Bpt->L->Score = Nolegmove(Which);
        }
      }
      if (I > Swidth) {
        if (Flag != 0 || I == 2) break;
        if (Mon != 0) {
          SELECTOUTPUT(2);
          PRINTSTRING(_imp_str_literal("FORCED TO INCREASE PLYWIDTH\n"));
          SELECTOUTPUT(0);
        }
      }
    }
    if (List != NULL) Releasechain(List);
    List = RECORD(0);
    if (I == 1) return NULL;
    if (I == 2) return B(1).L;
    for (J = 1; J <= I - 1; J++) {
      B(J).L->L = List;
      List = B(J).L;
    }
    return (Sortandprune(List, 1, Which));
  }
  Listf *Oneply(int Which, int Width) {
    Listf *List;
    List = Moves(Which, 0);
    List = Sortandprune(List, Width, Which);
    return List;
  }
  int Exval(int Occ, int Side1, int Side2) {
    int Gain;
    int Loss;
    int New;
    const int Pce[1+31 /*1:31*/] = {0, 3, [2 ... 7] = 2, [8 ... 31] = 1};
#define Pce(i) Pce[i]
    const int Bit[1+6 /*1:6*/] = {0, 256, 64, 32, 8, 2, 1};
#define Bit(i) Bit[i]
    Gain = Val(Occ);
    if (Side1 < 0) {
      PRINTSTRING(
          _imp_str_literal("PROGRAM ERROR, NEXT MOVE MAY BE STUPID!\n"));
      return (0);
    }
    if (Side2 == 0) return (Gain);
    New = Side1 >> 5;
    if (New != 0)
      New = Pce(New);
    else
      New = Pce(Side1) + 3;
    Loss = Exval(New, Side2, Side1 - Bit(New));
    if (Loss < 0)
      return (Gain);
    else
      return (Gain - Loss);
  }
  void Checkpins(int Which) {
    int I;
    //int K;
    int Bv;
    Sqf *Sq;
    if (Pinpt == 0) return;
    for (I = 1; I <= Pinpt; I++) {
      Px = Pinx(I);
      Py = Piny(I);
      Sq = Sqi(Pindx(I)).Sq;
      Bv = Bitval(Pinpy(I));
      if ((Sq->Att & Bv) != 0)
        ;
      else {
        Pinremove = Pinpy(I);
        (void) Moves(Which, 3);
        Scorea = Scorea + Sq->P * 5;
      }
    }
  }
  int Tryanotherply(int Which) {
    Listf *List2;
    int X;
    int Ww;
    int Xmon;
    const int Www[3 /*-1:1*/] = {25, 0, -25};
#define Www(i) Www[(i)+1]
    if (Justoneply == 1) return (0);
    Justoneply = 1;
    Xmon = Mon;
    Mon = 1;
    Ww = Which ^ 0xFFFFFFFE;
    List2 = Moves(Ww, 0);
    Justoneply = 0;
    Mon = Xmon;
    if (List2 == NULL)
      return (-Nolegmove(Ww) / 2);
    else {
      List2 = Sortandprune(List2, 1, Ww);
      X = List2->Score;
    }
    if (List2 != NULL) Releasechain(List2);
    return (X + Www(Ww));
  }
  int Score(int Which, Listf *L) {
    int Scoreb;
    int X;
    int Y;
    int I;
    int P;
    int Q;
    int Qq;
    int Pawnb;
    int Whx;
    int W2;
    int Gain;
    int Squ;
    int Loss;
    int Nph;
    int Nph2;
    int Bad;
    int Scorec;
    Qhf Hold;
    Listf *List2;
    Sqf *Sq;
    Pinpt = 0;
    for (I = 1; I <= 64; I++) {
      Sqi(I).Sq->Att = 0;
      Sqi(I).Sq->Def = 0;
    }
    Whx = Which & Bit;
    L->Chk = 0;
    Hold.L = L;
    (void)Changeboard(&Hold);
    Scoreb = 0;
    Scorea = 0;
    Scorec = 0;
    (void)Moves(Which, 1);
    Squ = 0;
    Bad = 0;
    Nph = 0;
    Nph2 = 0;
    for (Y = 1; Y <= 8; Y++)
      for (X = 1; X <= 8; X++) {
        Squ = Squ + 1;
        Sq = Sqi(Squ).Sq;
        Q = Sq->P;
        if (Q != 0) {
          if (Q < 0) {
            Qq = -Q;
            W2 = -1;
          } else {
            Qq = Q;
            W2 = 1;
          }
          P = 0;
          if (Qq == 1) {
            if (Q > 0)
              Pawnb = 9 - Y;
            else
              Pawnb = Y;
            P = Pawn2d(Pawnb * 8 + X) * Q;
          }
          if ((Q & Bit) == Whx) {
            if (Qq == 6) {
              if (Sq->Att != 0) {
                Restoreboard(&Hold);
                return (Maxscore);
              }
            }
            if (Sq->Att > 0) {
              Gain = Exval(Qq, Sq->Att, Sq->Def);
              if (Gain > 0) {
                Gain = Gain + P;
                Scorea = Scorea - (Gain * W2) / 10;
                if (Gain > Bad) Bad = Gain;
              }
            }
          } else if (Sq->Att != 0) {
            Gain = Exval(Qq, Sq->Att, Sq->Def);
            if (Gain > 0)
              if (Gain > Nph) {
                Nph2 = Nph;
                Nph = Gain;
              } else if (Gain > Nph2)
                Nph2 = Gain;
            if (Qq == 6) L->Chk = Q;
          }
          Scoreb = Scoreb + P + Val(Q);
        }
      }
    Loss = 0;
    if (Bad > 0) {
      if (((Bad > 300 && Nph > 400) || Nph > 400) && Bad < 500)
        Scorec = Tryanotherply(Which);
      Nph = Nph / 3;
      Loss = Bad;
      if (Nph > Bad)
        Loss = Nph2 / 3;
      else
        Loss = Loss - Nph;
    } else {
      if (Nph2 != 0) Loss = -Nph2;
      Loss = Loss - Nph / 6;
    }
    Scoreb = Scoreb + Kcas(-1) + Kcas(1);
    for (I = 1; I <= 12; I++)
      if (Posp(I) != *Pt(Posx(I)).P) Scoreb = Scoreb + Pospp(I);
    if (L->Chk != 0)
      if (Scorec == 0) Scorec = Tryanotherply(Which);
    Restoreboard(&Hold);
    if ((Mon & 64) != 0) {
      SELECTOUTPUT(2);
      PRINTSTRING(_imp_str_literal("SCORE:"));
      WRITE(Scorea, 1);
      WRITE(Scoreb, 1);
      WRITE(Scorec, 1);
      WRITE(Bad, 1);
      WRITE(Nph, 1);
      WRITE(Nph2, 1);
      WRITE(Loss, 1);
      NEWLINE();
      SELECTOUTPUT(0);
    }
    if (Scorec != 0) return (Scorec);
    return (Scoreb + Scorea - Loss * Which);
  }
  Listf *Moves(int Which, int Scrq) {
    int X;
    int Y;
    int Q;
    int Qq;
    int Whichx;
    int A;
    int B;
    int K;
    int I;
    int Type;
    int W2;
    int Diag;
    int Spec;
    int Pinflag;
    int Pinpiece;
    int Pox;
    int Poy;
    int Squ;
    int Imodk;
    Rowf *Row;
    Listf *List;
    static int Kcasch[3 /*-1:1*/] = {1, 0, 8};
#define Kcasch(i) Kcasch[(i)+1]
    static int Move_sw;
    static void *Move[1+6 /*1:6*/] = { NULL,
#define Move(i) Move[i]
        &&Move_1, &&Move_2, &&Move_3, &&Move_4, &&Move_5, &&Move_6,
    };
    int Dom(int X0, int Y0) {
      Sqf *Sq;
      int I;
      int J;
      int K;
      Listf *List2;
      Listf *N;
      if (1 > X0 || X0 > 8 || 1 > Y0 || Y0 > 8) return (0);
      Sq = &Brd(Y0).R(X0);
      K = Sq->P;
      if (Scrq <= 0) {
        if (K != 0 && (K & Bit) == (Q & Bit)) return (0);
        if (Qq == Pawn) {
          if ((Type == 0 && K != 0) || (Type == 1 && K == 0)) return (0);
          if (Y0 == 1 || Y0 == 8) Spec = 5 * Q;
        }
        Spec = 0;
        N = Freelist;
        Freelist = N->L;
        if (Freelist == NULL) {
          PRINTSTRING(_imp_str_literal("OUT OF FREE CELLS!!!\n"));
          exit(0);
        }
        N->Fr = (X << 4) + Y;
        N->To = (X0 << 4) + Y0;
        N->Spec = Spec;
        if (6 <= Type && Type <= 7) {
          N->Spec = Type;
          N->To = N->Fr;
        }
        N->Score = Score(Which, N);
        if (Type == 6)
          if (Row->R(6).Att != 0) N->Score = Maxscore;
        if (Type == 7)
          if (Row->R(4).Att != 0) N->Score = Maxscore;
        if (N->Score == Maxscore) {
          N->L = Freelist;
          Freelist = N;
          if (K != 0) return (0);
          return (1);
        }
        if ((Mon & 2) == 2) {
          SELECTOUTPUT(2);
          SPACES(20);
          WRITE(Xdepth, 5);
          PRINTSTRING(_imp_str_literal("---"));
          Printmove(N);
          NEWLINE();
          SELECTOUTPUT(0);
        }
        N->L = List;
        List = N;
        if (K == 0)
          J = 1;
        else
          J = 0;
      } else {
        J = 2;
        if (K != 0) {
          if (Qq == Pawn && Type == 0) return (0);
          J = 0;
          Imodk = IMOD(K);
          if ((K & Bit) == (Q & Bit)) {
            if (Qq == 5)
              if ((Diag == 1 && Imodk == 3) || (Diag == 0 && Imodk == 4))
                J = 1;
              else if (Imodk == 5)
                if (3 <= Qq && Qq <= 4) J = 1;
            if (Scrq != 3)
              if (Pinflag == 0)
                Sq->Def = Sq->Def + Bitval(Qq);
              else
                Sq->Def = Sq->Def - Bitval(Qq);
          } else if (Scrq == 3)
            if (Pinremove >= Imodk)
              Sq->Att = Sq->Att - Bitval(Qq);
            else if (Pinflag == 0) {
              Sq->Att = Sq->Att + Bitval(Qq);
              Pinflag = 1;
              J = 3;
              Pinpiece = Imodk;
              Pox = X0;
              Poy = Y0;
            } else if (Imodk > 3 && Imodk > Pinpiece) {
              if (Pinpt != 0)
                for (I = 1; I <= Pinpt; I++)
                  if (Pinx(I) == Pox && Piny(I) == Poy) goto Nopin;
              Pinpt = Pinpt + 1;
              Pinx(Pinpt) = Pox;
              Piny(Pinpt) = Poy;
              Pindx(Pinpt) = Squ;
              Pinpy(Pinpt) = Pinpiece;
            Nopin:;
            }
        }
        Scorea = Scorea + W2;
      }
      return (J);
    }
    Diag = 0;
    List = RECORD(0);
    Whichx = Which & Bit;
    if (Scrq == 3) {
      X = Px;
      Y = Py;
      Squ = (Y - 1) * 8 + X;
      goto Pinentry;
    }
    Squ = 0;
    for (Y = 1; Y <= 8; Y++)
      for (X = 1; X <= 8; X++) {
        Type = -1;
        Squ = Squ + 1;
      Pinentry:;
        Q = *Pt(Squ).P;
        if (Q != 0 && ((Q & Bit) == Whichx || Scrq > 0)) {
          if (Q < 0) {
            Qq = -Q;
            W2 = -1;
          } else {
            Qq = Q;
            W2 = +1;
          }
          goto *Move[Move_sw = (Qq)-1];
        Move_1:;
          Type = 0;
          Pinflag = 0;
          K = Dom(X, Y - W2);
          Pinflag = 0;
          if ((Y == 2 || Y == 7) && K != 0) K = Dom(X, Y - W2 - W2);
          Type = 1;
          Pinflag = 0;
          K = Dom(X - 1, Y - W2);
          Pinflag = 0;
          K = Dom(X + 1, Y - W2);
          goto Out;
        Move_2:;
          for (A = -2; A <= 2; A += 4)
            for (B = -1; B <= 1; B += 2) {
              Pinflag = 0;
              K = Dom(X + A, Y + B);
              Pinflag = 0;
              K = Dom(X + B, Y + A);
            }
          goto Out;
        Move_3:;
        Move_5:;
          Diag = 1;
          I = 0;
          Pinflag = 0;
          do {
            I = I - 1;
            K = Dom(X + I, Y + I);
          } while (K != 0);
          I = 0;
          Pinflag = 0;
          do {
            I = I - 1;
            K = Dom(X - I, Y + I);
          } while (K != 0);
          I = 0;
          Pinflag = 0;
          do {
            I = I - 1;
            K = Dom(X + I, Y - I);
          } while (K != 0);
          I = 0;
          Pinflag = 0;
          do {
            I = I - 1;
            K = Dom(X - I, Y - I);
          } while (K != 0);
          if (Qq != Queen) goto Out;
        Move_4:;
          Diag = 0;
          K = 1;
          I = 0;
          Pinflag = 0;
          do {
            I = I - 1;
            K = Dom(X, Y + I);
          } while (K != 0);
          I = 0;
          Pinflag = 0;
          do {
            I = I + 1;
            K = Dom(X + I, Y);
          } while (K != 0);
          I = 0;
          Pinflag = 0;
          do {
            I = I + 1;
            K = Dom(X, Y + I);
          } while (K != 0);
          I = 0;
          Pinflag = 0;
          do {
            I = I - 1;
            K = Dom(X + I, Y);
          } while (K != 0);
          goto Out;
        Move_6:;
          Row = &Brd(Y);
          for (A = -1; A <= 1; A++)
            for (B = -1; B <= 1; B++)
              if (A != 0 || B != 0) {
                Pinflag = 0;
                K = Dom(X + A, Y + B);
              }
          if (Lastchk != Q && Kcasch(W2) == Y && Kmove(W2) == 0) {
            if (Row->R(6).P == 0 && 0 == Row->R(7).P &&
                Row->R(8).P == Rook * W2) {
              Type = 6;
              K = Dom(7, Y);
            }
            if (Row->R(4).P == 0 && 0 == Row->R(3).P && Row->R(2).P == 0 &&
                Row->R(1).P == Rook * W2) {
              Type = 7;
              K = Dom(3, Y);
            }
          }
        Out:;
        }
        if (Scrq == 3) return (0);
      }
    if (Scrq > 0) Checkpins(Which);
    return List;
  }
  Listf *Sortandprune(Listf *List, int Width, int Which) {
    int I;
    int Max;
    Listf *M1;
    Listf *M2;
    Listf *L;
    Listf *Ln;
    Listf *Res;
    const int Maxa[3 /*-1:1*/] = {25000, 0, -25000};
#define Maxa(i) Maxa[(i)+1]
    if (List == NULL) return (NULL);
    Res = NULL;
    for (I = 1; I <= Width; I++) {
      M1 = NULL;
      M2 = M1;
      Ln = M1;
      Max = Maxa(Which);
      L = List;
      if (L == NULL) break;
      while (L != NULL) {
        if ((Which < 0 && L->Score < Max) || (Which > 0 && L->Score > Max)) {
          M2 = L;
          M1 = Ln;
          Max = L->Score;
        }
        Ln = L;
        L = L->L;
      }
      L = M2->L;
      M2->L = Res;
      Res = M2;
      if (M1 == NULL)
        List = L;
      else
        M1->L = L;
    }
    if (List != NULL) Releasechain(List);
    L = NULL;
    while (Res != NULL) {
      M1 = Res->L;
      Res->L = L;
      L = Res;
      Res = M1;
    }
    return L;
  }
  int Changeboard(Qhf *B) {
    Sqf *Sq;
    Rowf *Row;
    Listf *List;
    int From;
    int To;
    int X;
    int Y;
    int X0;
    int Y0;
    int King;
    int Cas;
    int Rook;
    List = B->L;
    From = List->Fr;
    To = List->To;
    X = From >> 4;
    X0 = To >> 4;
    Y = From & 15;
    Y0 = To & 15;
    Sq = &Brd(Y0).R(X0);
    B->Hold = Sq->P;
    if (List->Spec != 0) {
      if (List->Spec >= 6) {
        if (Sq->P < 0) {
          Cas = 1;
          King = -6;
          Rook = -4;
          Kcas(-1) = -30;
        } else {
          Cas = 8;
          King = 6;
          Rook = 4;
          Kcas(1) = 30;
        }
        Row = &Brd(Cas);
        if (List->Spec == 6) {
          Row->R(7).P = King;
          Row->R(6).P = Rook;
          Row->R(8).P = 0;
        } else {
          Row->R(3).P = King;
          Row->R(4).P = Rook;
          Row->R(1).P = 0;
        }
        Sq->P = 0;
        return (King);
      }
      Sq->P = List->Spec;
    } else
      Sq->P = Brd(Y).R(X).P;
    Brd(Y).R(X).P = 0;
    return (Sq->P);
  }
  void Restoreboard(Qhf *B) {
    Sqf *Sq;
    Rowf *Row;
    Listf *List;
    int From;
    int To;
    int X;
    int Y;
    int X0;
    int Y0;
    int King;
    int Cas;
    int Rook;
    List = B->L;
    From = List->Fr;
    To = List->To;
    X = From >> 4;
    X0 = To >> 4;
    Y = From & 15;
    Y0 = To & 15;
    Sq = &Brd(Y0).R(X0);
    if (List->Spec != 0) {
      if (List->Spec >= 6) {
        if (Y0 == 1) {
          Cas = 1;
          King = -6;
          Rook = -4;
          Kcas(-1) = 0;
        } else {
          Cas = 8;
          King = 6;
          Rook = 4;
          Kcas(1) = 0;
        }
        Row = &Brd(Cas);
        if (List->Spec == 6) {
          Row->R(8).P = Rook;
          Row->R(7).P = 0;
          Row->R(6).P = 0;
        } else {
          Row->R(1).P = Rook;
          Row->R(3).P = 0;
          Row->R(4).P = 0;
        }
        Sq->P = King;
        return;
      }
      if (Y0 == 8)
        Sq->P = -1;
      else
        Sq->P = 1;
    }
    Brd(Y).R(X).P = Sq->P;
    Sq->P = B->Hold;
  }
  void Burp(Qhf *X, int W) {
    int I;
    Tell(X->L, W);
    SELECTOUTPUT(2);
    PRINTSYMBOL('*');
    Tell(X->L, W);
    SELECTOUTPUT(0);
    I = Changeboard(X);
    if (I == King * W) Kmove(W) = 1;
  }
  void Tell(Listf *Move, int Which) {
    if (Move == NULL) {
      if (Which < 0)
        PRINTSTRING(_imp_str_literal("I Win\n"));
      else
        PRINTSTRING(_imp_str_literal("YOU WIN\n"));
      exit(0);
    }
    WRITE(No, 1);
    if (Which > 0)
      SPACES(25);
    else
      SPACES(4);
    Printmove(Move);
    PRINTSTRING(_imp_str_literal("("));
    if (Which > 0) {
      Timtt = CPUTIME() - Time;
      PRINT(Timtt, 1, 2);
    } else
      PRINT(CPUTIME() - Time2, 1, 2);
    PRINTSTRING(_imp_str_literal(" Secs)\n"));
  }
  void Printboard(void) {
    const unsigned char Black[1+64 /*1:64*/] = {0,
        0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1,
        0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0,
        1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0};
#define Black(i) Black[i]
    void Line(void) {
      PRINTSTRING(_imp_str_literal("  !---!---!---!---!---!---!---!---!\n"));
    }
    const unsigned char Px[13 /*-6:6*/] = {'k', 'q', 'r', 'b', 'n', 'p', ' ',
                                           'P', 'N', 'B', 'R', 'Q', 'K'};
    #define Px(i) Px[(i)+6]
    int X;
    int Y;
    int I;
    int P;
    int Q;
    Rowf *Row;
    Q = 1;
    for (Y = 8; Y >= 1; Y--) {
      Row = &Brd(Y);
      Line();
      WRITE(Y, 1);
      for (X = 1; X <= 8; X++) {
        PRINTSTRING(_imp_str_literal("! "));
        P = Row->R(X).P;
        if (P != 0)
          PRINTSYMBOL(Px(P));
        else if (Black(Q) == 1)
          PRINTSYMBOL('*');
        else
          PRINTSYMBOL(' ');
        if (P > 0)
          PRINTSYMBOL('+');
        else
          PRINTSYMBOL(' ');
        Q = Q + 1;
      }
      PRINTSTRING(_imp_str_literal("!\n"));
    }
    Line();
    PRINTSTRING(_imp_str_literal("    A   B   C   D   E   F   G   H\n"));
  }
  void Printmove(Listf *List) {
    int I;
    int J;
    int K;
    void Burp(int X) {
      PRINTSYMBOL((X >> 4) + 'A' - 1);
      PRINTSYMBOL((X & 15) + '0');
      SPACE();
    }
    Burp(List->Fr);
    Burp(List->To);
    if (List->Chk != 0) PRINTSYMBOL('+');
    WRITE(List->Score, 5);
  }
  int Checkyourmove(Listf *List) {
    Listf *L2;
    Listf *Mm;
    int I;
    Mm = Mmove.L;
    L2 = List;
    while (List != NULL) {
      if (List->Fr == Mm->Fr && List->To == Mm->To) {
        Mm->Score = List->Score;
        Mm->Chk = List->Chk;
        return (1);
      }
      List = List->L;
    }
    return (0);
  }
  Listf *Printmoves(Listf *List) {
    Listf *L;
    SELECTOUTPUT(2);
    List = Sortandprune(List, 100, -1);
    L = List;
    for (;;) {
      Printmove(L);
      NEWLINE();
      L = L->L;
      if (L == NULL) break;
    }
    SELECTOUTPUT(0);
    return List;
  }
  void Yourmove(void) {
    int Readm(int X, int Y) {
      int I;
      int J;
      while (NEXTSYMBOL() == NL) SKIPSYMBOL();
      READSYMBOL(&I);
      while (NEXTSYMBOL() == NL) SKIPSYMBOL();
      READSYMBOL(&J);
      X = I - 'A' + 1;
      Y = J - '0';
      return (0);
    }
    int I;
    int X;
    int Y;
    int X0;
    int Y0;
    int K;
    Listf *List;
    Justoneply = 1;
    List = Moves(-1, 0);
    Justoneply = 0;
    if (List == 0) Tell(List, -1);
    if ((Mon & 1) != 0) List = Printmoves(List);
  Again:;
    Lm.Spec = 0;
    if (NEXTSYMBOL() == 'M') {
      SKIPSYMBOL();
      PROMPT(_imp_str_literal("MON?"));
      READ(Mon);
      SKIPSYMBOL();
      PROMPT(_imp_str_literal("Move?"));
      goto Again;
    }
    if (NEXTSYMBOL() == 'X') {
      SKIPSYMBOL();
      SKIPSYMBOL();
      //Pprofile();
    }
    if (NEXTSYMBOL() == 'P') {
      PROMPT(_imp_str_literal("NEW PLY?"));
      SKIPSYMBOL();
      READ(Pdepth);
      SKIPSYMBOL();
      PROMPT(_imp_str_literal("Move?"));
      goto Again;
    }
    if (NEXTSYMBOL() == 'O') {
      X = 0;
      SKIPSYMBOL();
      READSYMBOL(&I);
      if (I != '-') goto No;
      READSYMBOL(&I);
      if (I != 'O') goto No;
      if (NEXTSYMBOL() == '-') {
        X = 1;
        SKIPSYMBOL();
        SKIPSYMBOL();
      }
      Lm.Spec = 6 + X;
      Lm.Fr = (5 << 4) + 1;
      Lm.To = (5 << 4) + 1;
    } else {
      I = Readm(X, Y);
      I = Readm(X0, Y0);
      if (NEXTSYMBOL() == '(') {
        SKIPSYMBOL();
        READSYMBOL(&K);
        SKIPSYMBOL();
        Lm.Spec = (K - '0') * (-1);
      }
      if (0 >= X || X >= 9 || 0 >= X0 || X0 >= 9 || 0 >= Y || Y >= 9 ||
          0 >= Y0 || Y0 >= 9) {
      No:
        PRINTSTRING(_imp_str_literal("INVALID MOVE - MY FORMAT IS D2D4\n"));
        for (;;) {
          READSYMBOL(&I);
          if (I == NL) break;
        }
        goto Again;
      }
      Lm.Fr = (X << 4) + Y;
      Lm.To = (X0 << 4) + Y0;
    }
    Mmove.L = &Lm;
    if (Checkyourmove(List) == 0) goto No;
    SKIPSYMBOL();
    Releasechain(List);
  }
  exit(0);
  return (1);
}
