#include <perms.h>
int Cputime(void);
_imp_string Cliparam(void);
typedef struct Paminfo {
  unsigned char Groupsep;
  unsigned char Keyflag;
  short Allflags;
  *Params;
} Paminfo;
Paminfo *Pam(void);
static const int Pamnewgroup = 1;
static const int Pamnodefault = 2;
static const int Pammajor = 4;
static const int Pamkeepcase = 8;
static const int Paminfile = 16;
static const int Pamoutfile = 32;
void Defineparam(_imp_string Text, _imp_string *Variable, int Flags);
void Defineintparam(_imp_string Text, int *Variable, int Flags);
void Defineenumparam(_imp_string Text, unsigned char *Variable, int Flags);
void Definebooleanparams(_imp_string Text, int *Variable, int Flags);
void Processparameters(_imp_string Parm);
int _imp_mainep(int _imp_argc, char **_imp_argv) {
  static const int Outstream = 1;
  static const int Not = -1;
  static const int Or = -2;
  static const int And = -3;
  static const int Sign = 0x80000000;
  static const int Forced = 0x40000000;
  static int Min = 4096;
  static int Inc = 4096;
  static int Echo = 0;
  static int Squash = 0;
  static int Nin = 0;
  static int Nout = 0;
  static int Check = 0;
  static int Mon = 0;
  static int Single = 0;
  static int Tabin = 0;
  static int Instream = 3;
  int Negin;
  int Ignorin;
  int Negout;
  int Ignorout;
  int Count;
  int Aim;
  int Minsep;
  int Sym;
  int Start;
  static const int Storebound = 2000;
  int Dclim;
  int Esslim;
  int Sp1;
  int Sp;
  int Np;
  int Np1;
  int Needsp;
  typedef struct Cell {
    int T;
    int F;
    int Outs;
    int Flags;
  } Cell;
  Cell W[2000 /*1:2000*/];
  static const int Namebound = 256;
  int Inmax;
  int Outmin;
  int Namemax;
  _imp_string Name[256 /*1:256*/];
  int Exp[256 /*1:256*/];
  static const int Defbound = 8192;
  int Dp;
  int Def[8192 /*1:8192*/];
  int Bits(int V) {
    int K;
    K = 0;
    if (V < 0) {
      K = 1;
      V = (unsigned)V << 1 >> 1;
    }
    while (V) {
      K++;
      V = V & (V - 1);
    }
    return (K);
  }
  void Out(int V) {
    if (V >= 10) {
      Out(V / 10);
      V -= V / 10 * 10;
    }
    Printsymbol(V + '0');
  }
  void Croak(_imp_string S) {
    Selectoutput(0);
    Newline();
    Printstring(_imp_join(_imp_str_literal("*"), _imp_join(S, _imp_str_literal("  Abandoned"))));
    if (Sym != Nl) {
      Printstring(_imp_str_literal(" at: "));
      do {
        Readsymbol(Sym);
        Printsymbol(Sym);
      } while (Sym != Nl);
    }
    exit(0);
  }
  void Printtime(void) {
    int T;
    T = Cputime();
    Print((T - Start) / 1000, 5, 3);
    Start = T;
  }
  void Push(Cell V) {
    Np--;
    W[Np] = V;
    if (Np - Sp >= Minsep) return;
    Minsep = Np - Sp;
    if (Minsep > 2) return;
    Croak(_imp_str_literal("No space."));
  }
  void Stack(Cell V) {
    W[Sp] = V;
    Sp++;
    if (Np - Sp > Minsep) return;
    Minsep = Np - Sp;
    if (Minsep > 2) return;
    Croak(_imp_str_literal("No space."));
  }
  void Readin(void) {
    int Bit;
    int Pos;
    int Pos1;
    int Found;
    int First;
    int Dp1;
    int Outmax;
    int Pend;
    _imp_string Curname;
    void Put(int V) {
      if (Dp > Defbound) Croak(_imp_str_literal(" Definitions too long"));
      Def[Dp] = V;
      Dp++;
    }
    void Readsym(void) {
      if (_imp_on_event(9)) {
        Sym = '*';
        Instream--;
        if (!Instream) return;
        if (Instream < 0) {
          Sym = Nl;
          Croak(_imp_str_literal("Premature end of input."));
        }
        Selectinput(Instream);
      }
      Sym = Pend;
      Pend = 0;
      if (Sym) return;
      for (;;) {
        Readsymbol(Sym);
        if (Echo) Printsymbol(Sym);
        if (Sym != '{') return;
        do {
          Readsymbol(Sym);
          if (Echo) Printsymbol(Sym);
        } while (Sym != '}');
      }
    }
    void Readname(void) {
      int K;
      int L;
      do
        Readsym();
      while (Sym <= ' ');
      L = 0;
      K = Sym;
      if (K >= 'a') K = K - 'a' + 'A';
      if ('A' <= K && K <= 'Z') {
        for (;;) {
          if (L < 6) {
            L++;
            *Charno(Curname, L) = K;
          }
          Readsym();
          K = Sym;
          if (K >= 'a') K = K - 'a' + 'A';
          if (('0' > K || K > '9') && (*Charno(Curname, L) < 'A' || 'A' > K || K > 'Z')) break;
        }
        if (Sym == '?') {
          L++;
          *Charno(Curname, L) = Sym;
          Readsym();
        }
      }
      *Length(Curname) = L;
      if (Sym == ' ') {
        do
          Readsym();
        while (Sym == ' ');
        if ('A' <= (Sym & 95) && (Sym & 95) <= 'Z') {
          Pend = Sym;
          Sym = ' ';
        }
      }
    }
    void Init(int *V) {
      Found = 1;
      *V = 1;
      if (Sym == '=') {
        Read(*V);
        Out(*V);
      }
    }
    void Lookup(void) {
      Pos = Namemax + 1;
      do
        Pos--;
      while (Pos != 0 && Name[Pos] != Curname);
    }
    void Queryname(void) {
      if (Echo) Newline();
      Printstring(_imp_join(Curname, _imp_str_literal(" not known")));
      Newline();
    }
    void Addname(void) {
      Namemax++;
      Name[Namemax] = Curname;
    }
    void Newname(void) {
      if (Pos) Croak(_imp_join(_imp_str_literal("Duplicate: "), _imp_join(Curname, _imp_str_literal(". "))));
      Addname();
    }
    void Readexp(void) {
      void Readterm(void) {
        Readname();
        if (_imp_strcmp(Curname, _imp_str_literal("")) != 0) {
          if (Sym >= 'A' || Sym == '(') Pend = Sym;
          Lookup();
          if (!Pos) {
            Queryname();
            Pos = 1;
          }
          Put(Pos);
        } else if (Sym == '\\') {
          Put(Not);
          Readterm();
          Put(Not);
        } else {
          if (Sym != '(') Croak(_imp_str_literal("Faulty format. "));
          Readexp();
          if (Sym != ')') Croak(_imp_str_literal("Missing ')'. "));
          Readsym();
        }
      }
      void Readexp1(void) {
        Readterm();
        while (Sym == '&' || Sym == '.' || Sym >= 'A' || Sym == '(') {
          Readterm();
          Put(And);
        }
      }
      Readexp1();
      while (Sym == '!' || Sym == '+') {
        Readexp1();
        Put(Or);
      }
    }
    Namemax = 0;
    Dp = 1;
    Pend = 0;
    for (;;) {
      Readname();
      if (Sym == '*') exit(0);
      if (_imp_strcmp(Curname, _imp_str_literal("MODE")) != 0) break;
      if (!Echo) {
        Printstring(_imp_str_literal("MODE "));
        Printsymbol(Pend);
      }
      Echo -= 2;
      do {
        Readname();
        Found = 0;
        if (_imp_strcmp(Curname, _imp_str_literal("NIN")) == 0) Init(Nin);
        if (_imp_strcmp(Curname, _imp_str_literal("NOUT")) == 0) Init(Nout);
        if (_imp_strcmp(Curname, _imp_str_literal("MIN")) == 0) Init(Min);
        if (_imp_strcmp(Curname, _imp_str_literal("INC")) == 0) Init(Inc);
        if (_imp_strcmp(Curname, _imp_str_literal("ECHO")) == 0) Init(Echo);
        if (_imp_strcmp(Curname, _imp_str_literal("SQUASH")) == 0) Init(Squash);
        if (_imp_strcmp(Curname, _imp_str_literal("CHECK")) == 0) Init(Check);
        if (_imp_strcmp(Curname, _imp_str_literal("MON")) == 0) Init(Mon);
        if (_imp_strcmp(Curname, _imp_str_literal("SINGLE")) == 0) Init(Single);
        if (_imp_strcmp(Curname, _imp_str_literal("TABIN")) == 0) Init(Tabin);
        if (_imp_strcmp(Curname, _imp_str_literal("EQUIN")) == 0) {
          Init(Tabin);
          Tabin--;
        }
        if (!Found) Printsymbol('?');
      } while (Sym == ',');
      if (Echo < 0) {
        Echo += 2;
        if (!Echo) Newline();
      }
    }
    if (_imp_strcmp(Curname, _imp_str_literal("IN")) != 0)
      Croak(_imp_join(_imp_str_literal("Keyword "), _imp_join(Curname, _imp_str_literal("? "))));
    if (!Pend) Pend = Sym;
    Bit = 1;
    Negin = 0;
    Ignorin = 0;
    do {
      if (!Bit) Croak(_imp_str_literal("Too many inputs."));
      do
        Readsym();
      while (Sym <= ' ' || Sym == ',');
      if (Sym == '-') {
        Ignorin += Bit;
        Curname = _imp_str_literal("-");
        Readsym();
      } else {
        if (Sym == '\\')
          Negin += Bit;
        else
          Pend = Sym;
        Readname();
        Lookup();
      }
      Newname();
      Exp[Namemax] = Bit;
      Bit = Bit << 1;
    } while (Sym == ',');
    Inmax = Namemax;
    if (Nin) Negin = ~Negin;
    if (!Tabin)
      for (;;) {
        Readname();
        if (Sym != '=') break;
        Lookup();
        if (Pos <= Inmax) Pos = 0;
        Newname();
        Exp[Namemax] = Dp;
        Namemax--;
        Readexp();
        Namemax++;
        Put(0);
        if (Sym != Nl) Croak(_imp_str_literal("Faulty format. "));
      }
    else {
      Pos1 = Namebound + 1;
      Outmax = 0;
      for (;;) {
        do
          Readsym();
        while (Sym <= ' ');
        if ((Sym & 95) == 'O') {
          Pend = Sym;
          break;
        }
        Pos1--;
        if (Pos1 == Namemax) Croak(_imp_str_literal("Too many table entries"));
        Exp[Pos1] = 0;
        First = 1;
        for (Pos = 1; Pos <= Inmax; Pos++) {
          if (((unsigned)Ignorin >> (Pos - 1) & 1) == 0 && (Sym == '0' || Sym == '1')) {
            if (Sym == '1')
              Put(Pos);
            else {
              Put(Not);
              Put(Pos);
              Put(Not);
            }
            if (!First) Put(And);
            First = 0;
          }
          do
            Readsym();
          while (Sym == ' ');
        }
        Put(0);
        Bit = 1;
        Namemax = Inmax;
        while (Sym != Nl) {
          if ((Sym != '0' && Sym != '1') || Namemax == Outmax) Croak(_imp_str_literal("Faulty entry. "));
          if (Sym == '1') Exp[Pos1] = Exp[Pos1] | Bit;
          Bit = Bit << 1;
          Namemax++;
          do
            Readsym();
          while (Sym == ' ');
        }
        if (!Outmax) Outmax = Namemax;
        if (Outmax != Namemax) Croak(_imp_str_literal("Faulty entry. "));
      }
      Bit = 1;
      if (Check) {
        Bit = ~0;
        Namemax = Inmax + 1;
      }
      for (Pos = Inmax + 1; Pos <= Namemax; Pos++) {
        Exp[Pos] = Dp;
        First = 1;
        int Firstpos1a = Pos1;
        for (Pos1 = Namebound; Pos1 >= Firstpos1a; Pos1--)
          if (Exp[Pos1] & Bit) {
            Put(Pos1);
            if (!First) Put(Or);
            First = 0;
          }
        Put(0);
        Bit = Bit << 1;
      }
      Dp1 = 1;
      int Firstpos1b = Pos1;
      for (Pos1 = Namebound; Pos1 >= Firstpos1b; Pos1--) {
        Exp[Pos1] = Dp1;
        do
          Dp1++;
        while (Def[Dp1 - 1]);
      }
      Readname();
    }
    if (_imp_strcmp(Curname, _imp_str_literal("OUT")) != 0)
      Croak(_imp_join(_imp_str_literal("Keyword "), _imp_join(Curname, _imp_str_literal("? "))));
    if (!Pend) Pend = Sym;
    Outmin = Namemax + 1;
    Pos = Inmax;
    Negout = 0;
    Ignorout = 0;
    Bit = 1;
    do {
      if (Namemax - Outmin + 2 > 32) Croak(_imp_str_literal("Too many outputs. "));
      do
        Readsym();
      while (Sym <= ' ' || Sym == ',');
      if (Sym == '-') {
        Ignorout += Bit;
        Curname = _imp_str_literal("-");
        Readsym();
      } else {
        if (Sym == '\\')
          Negout += Bit;
        else
          Pend = Sym;
        Readname();
      }
      if (!Tabin)
        Lookup();
      else
        Pos++;
      if (Pos) {
        Addname();
        Exp[Namemax] = Dp;
        Put(Pos);
        if (!Tabin) {
          Curname = _imp_join(Curname, _imp_str_literal("?"));
          Lookup();
          if (Pos) {
            Put(Pos);
            Put(Or);
          }
        }
        Put(0);
      } else
        Queryname();
      Bit = Bit << 1;
    } while (Sym == ',');
    if (Outmin > Namemax) exit(0);
    if (Sym != Nl) Croak(_imp_str_literal("Faulty format. "));
    if (Nout) Negout = ~Negout;
  }
  void Printterm(Cell V, int X) {
    int I;
    int L;
    for (I = 1; I <= Inmax; I++) {
      if (!Squash) Space();
      if ((V.T | V.F) & 1) {
        L = ' ';
        if (V.F & 1) L = '\\';
        Printsymbol(L);
        Printstring(Name[I]);
      } else {
        L = *Length(Name[I]);
        Spaces((L + 1) / 2);
        Printsymbol('.');
        Spaces(L / 2);
      }
      V.T = (unsigned)V.T >> 1;
      V.F = (unsigned)V.F >> 1;
    }
    if (!Squash) Space();
    Printsymbol(':');
    for (I = Outmin; I <= Namemax; I++) {
      Space();
      if (V.Outs & 1)
        Printstring(Name[I]);
      else {
        L = *Length(Name[I]);
        Spaces((L - 1) / 2);
        if (!(X & 1))
          Printsymbol('.');
        else
          Printsymbol('?');
        Spaces(L / 2);
      }
      V.Outs = (unsigned)V.Outs >> 1;
      X = (unsigned)X >> 1;
    }
    Newline();
  }
  void Monitor(int Lim) {
    int Q;
    Newline();
    Q = 1;
    while (Q != Lim) {
      if (Mon & 4) Write(Q, 2);
      Printterm(W[Q], 0);
      Q++;
    }
    Newline();
  }
  void Copydown(void) {
    Np1 = Np;
    while (Sp != Sp1) {
      Sp--;
      Np--;
      W[Np] = W[Sp];
    }
  }
  void Erase(int P) {
    Sp--;
    while (P != Sp) {
      W[P] = W[P + 1];
      P++;
    }
  }
  void Merge(void) {
    int P;
    int K;
    int Same;
    static Cell V;
    static Cell N = 0;
    while (Np != Np1) {
      V = W[Np];
      Np++;
      P = Sp1;
      Same = 0;
      while (P != Sp) {
        if ((W[P].T | V.T) == V.T && (W[P].F | V.F) == V.F) {
          V.Outs = V.Outs & (~W[P].Outs);
          if (!V.Outs) break;
          if (W[P].T == V.T && W[P].F == V.F) Same = P;
        }
        P++;
      }
      if (V.Outs) {
        while (P != Sp1) {
          P--;
          N.Outs = W[P].Outs & V.Outs;
          if (N.Outs) {
            N.T = W[P].T | V.T;
            N.F = W[P].F | V.F;
            K = (N.T) & N.F;
            if (K != 0 && ((K - 1) & K) == 0) {
              N.T = N.T ^ K;
              N.F = N.F ^ K;
              Push(N);
              if ((N.T | V.T) == V.T && (N.F | V.F) == V.F) V.Outs = V.Outs ^ N.Outs;
              N.T = N.T | W[P].T;
              N.F = N.F | W[P].F;
            }
            if (N.T == W[P].T && N.F == W[P].F) {
              W[P].Outs = W[P].Outs ^ N.Outs;
              if (!W[P].Outs) {
                Erase(P);
                if (Same > P) Same--;
              }
            }
            if (!V.Outs) break;
          }
        }
        if (V.Outs)
          if (!Same) {
            W[Sp] = V;
            Sp++;
          } else
            W[Same].Outs = W[Same].Outs + V.Outs;
      }
    }
  }
  void Convert(void) {
    int Outbit;
    int Oldsp;
    int I;
    int J;
    int K;
    int P;
    int Q;
    int Hp;
    int Inv;
    static Cell V = 0;
    int Hold[20 /*1:20*/];
    void Convert(int J) {
      int Defp;
      Defp = Exp[J];
      for (;;) {
        J = Def[Defp];
        Defp++;
        if (!J) return;
        if (J > 0)
          if (J > Inmax)
            Convert(J);
          else {
            Hp++;
            Hold[Hp] = Sp1;
            Sp1 = Sp;
            V.T = Exp[J];
            V.F = 0;
            if (Inv ^ ((unsigned)Negin >> (J - 1) & 1)) {
              V.F = V.T;
              V.T = 0;
            }
            Stack(V);
          }
        else if (J == Not)
          Inv = Inv ^ 1;
        else if (J - Inv == And) {
          Np1 = Np;
          while (Sp != Sp1) {
            Sp--;
            P = Sp1;
            while (P != Hold[Hp]) {
              P--;
              V.T = W[Sp].T | W[P].T;
              V.F = W[Sp].F | W[P].F;
              if (!(V.T & V.F)) Push(V);
            }
          }
          Sp1 = Hold[Hp];
          Hp--;
          Sp = Sp1;
          Merge();
        } else {
          Copydown();
          Sp1 = Hold[Hp];
          Hp--;
          Merge();
        }
      }
    }
    Sp = 1;
    Np = Storebound;
    Minsep = Np - Sp;
    V.Flags = 0;
    Outbit = 1;
    for (I = Outmin; I <= Namemax; I++) {
      if (!(Ignorout & Outbit)) {
        K = Def[Exp[I] + 1];
        if (K) {
          Sp1 = 1;
          Hp = 0;
          Inv = 0;
          V.Outs = Outbit;
          Convert(K);
          Copydown();
          Sp1 = 1;
          Merge();
        }
      }
      Outbit = Outbit << 1;
    }
    Dclim = Sp;
    Outbit = 1;
    for (I = Outmin; I <= Namemax; I++) {
      if (!(Ignorout & Outbit)) {
        Sp1 = 1;
        Hp = 0;
        Inv = (unsigned)Negout >> (I - Outmin) & 1;
        V.Outs = Outbit;
        Convert(I);
        Copydown();
        Sp1 = Dclim;
        if (Single)
          Merge();
        else {
          Oldsp = Sp;
          while (Np != Np1) {
            Q = Sp1 - 1;
            V = 0;
            for (;;) {
              V.T = V.T | W[Np].T;
              V.F = V.F | W[Np].F;
              if (!(V.T & V.F)) {
                V.Outs = V.Outs | Outbit;
                P = Sp;
                while (P != Sp1) {
                  P--;
                  if (W[P].T == V.T && W[P].F == V.F) V.Outs = V.Outs | W[P].Outs;
                  J = W[P].T | V.T;
                  K = W[P].F | V.F;
                  if (J == V.T && K == V.F && (W[P].Outs & V.Outs) == V.Outs) break;
                  if (J == W[P].T && K == W[P].F && (W[P].Outs & V.Outs) == W[P].Outs) {
                    if (P < Oldsp) Oldsp--;
                    if (P <= Q) Q--;
                    Erase(P);
                  }
                }
                if (P == Sp1) Stack(V);
              }
              Q++;
              if (Q == Oldsp) break;
              V = W[Q];
            }
            Np++;
          }
        }
      }
      Outbit = Outbit << 1;
    }
  }
  int Needed(int Q, int Testlim) {
    int P;
    static Cell V;
    static Cell N = 0;
    Sp1 = Sp;
    Np1 = Np;
    V = W[Q];
    W[Sp1].T = V.T;
    W[Sp1].F = V.F;
    W[Sp1].Outs = 0;
    Sp++;
    P = 1;
    while (P != Testlim) {
      if (W[P].Flags >= 0) {
        N.Outs = W[P].Outs & V.Outs;
        if (N.Outs != 0 && P != Q) {
          N.T = W[P].T | V.T;
          N.F = W[P].F | V.F;
          if (!(N.T & N.F)) {
            Np--;
            W[Np] = N;
            Merge();
            if (W[Sp1].Outs == V.Outs) break;
          }
        }
      }
      P++;
    }
    Needsp = Sp;
    Sp = Sp1;
    return (P);
  }
  void Printall(void) {
    int P;
    int Q;
    Newlines(2);
    Q = Dclim;
    if (Mon & 2) Q = Esslim;
    while (Q != Sp) {
      if (W[Q].Flags >= 0) {
        P = Needed(Q, Sp);
        if (Mon & 4) Write(Q, 2);
        W[Sp1].Outs = W[Q].Outs - W[Sp1].Outs;
        Printterm(W[Sp1], W[Q].Outs);
      }
      Q++;
    }
    Newline();
  }
  void Pcount(void) {
    Write((unsigned)Count >> 12, 1);
    Printsymbol('/');
    Out(Count & 4095);
  }
  void Promote(int Q, int Past) {
    Cell V;
    V = W[Q];
    if (!Past) {
      Count = Count + Bits(V.T | V.F) + 4096;
      Past = Esslim;
      Esslim++;
    }
    while (Past != Esslim && Past != Dclim) {
      if (W[Past - 1].Flags <= V.Flags) break;
      Past--;
    }
    while (Q != Past) {
      Q--;
      W[Q + 1] = W[Q];
    }
    W[Q] = V;
  }
  void Reduce1(void) {
    int P;
    int Q;
    Q = Dclim;
    Esslim = Q;
    while (Q != Sp) {
      W[Q].Flags = (Bits(W[Q].T | W[Q].F) << 5) + 31 - Bits(W[Q].Outs);
      P = Needed(Q, Sp);
      if (P == Sp)
        Promote(Q, 0);
      else if (P >= Esslim)
        Promote(Q, Q);
      else {
        Erase(Q);
        Q--;
      }
      Q++;
    }
  }
  void Reduce2(void) {
    int P;
    int Q;
    int Bq;
    int Sphold;
    int Done;
    Cell V;
    do {
      Done = 1;
      Q = Sp;
      while (Q != Esslim) {
        Q--;
        P = Needed(Q, Esslim);
        if (P == Esslim) {
          W[Q].Outs = W[Q].Outs - W[Sp1].Outs;
          W[Sp1].Outs = 0;
          Bq = (unsigned)W[Q].Flags >> 5;
          Sphold = Sp;
          while (P != Sp) {
            if (((unsigned)W[P].Flags >> 5) - Min < Bq && P != Q) {
              V.Outs = W[P].Outs & W[Q].Outs;
              if (V.Outs) {
                V.T = W[P].T | W[Q].T;
                V.F = W[P].F | W[Q].F;
                if (!(V.T & V.F)) {
                  Sp1 = Sp;
                  Sp = Needsp;
                  while (Sp1 != Needsp) {
                    W[Sp] = W[Sp1];
                    Sp++;
                    Sp1++;
                  }
                  Push(V);
                  Merge();
                  Sp = Sphold;
                  if (W[Sp1].Outs == W[Q].Outs) break;
                }
              }
            }
            P++;
          }
        }
        if (P != Sp) {
          Erase(Q);
          if (P > Q) P--;
          if (P >= Esslim)
            if (Needed(P, Sp) == Sp) {
              if (P >= Q) Q++;
              Promote(P, 0);
              Done = 0;
            }
        }
      }
    } while (!Done);
  }
  void Order(void) {
    int J;
    int K;
    int P;
    int Q;
    int R;
    int Poss;
    int Last;
    int Link[Sp];
    Cell V;
    Q = Sp;
    Poss = 0;
    Last = Sp;
    while (Q != Esslim) {
      Q--;
      P = Needed(Q, Sp);
      Link[Q] = P;
      if (P > Q && Link[P] > P) {
        Poss++;
        if (Q != Last) Poss += 99;
        V = W[P];
        R = Sp;
        do {
          R--;
          J = Link[R];
          if (J == P)
            J = Q;
          else if (Q <= J && J < P)
            J++;
          if (R >= P)
            Link[R] = J;
          else {
            Link[R + 1] = J;
            W[R + 1] = W[R];
          }
        } while (R != Q);
        W[R] = V;
        Q += 2;
        Last = Q - 1;
      }
    }
    Write(Poss, 1);
    do {
      V = W[Q];
      V.Flags = (unsigned)V.Flags >> 5;
      P = Needed(Q, Sp);
      if (P > Q) {
        Count = Count + V.Flags + 4096;
        W[Q].Flags = V.Flags + (Count << 5);
      } else {
        do
          P++;
        while (W[P].Flags < 0);
        R = Q;
        while (R != P) {
          R--;
          W[R + 1] = W[R];
        }
        V.Flags = (W[R - 1].Flags & 0x0FFFFFE0) + V.Flags + Sign;
        W[R] = V;
      }
      Q++;
    } while (Q != Sp);
  }
  void Minimise(void) {
    int K;
    int P;
    int Q;
    int M;
    Q = Sp;
    for (;;) {
      while (Q != Sp) {
        M = W[Q].Flags;
        P = Needed(Q, Sp);
        if (P == Sp)
          M += Forced;
        else {
          if (P < Q) M += Sign + Forced;
        }
        if (M >= 0) {
          K = (M & 31) + Count + 4096;
          if (K + Inc > Aim) break;
          if (K + Inc > ((unsigned)M >> 5 & 0x7FFFFF)) break;
          Count = K;
        }
        W[Q].Flags = M;
        Q++;
      }
      if (Q == Sp) {
        Pcount();
        if (Inc == 0 || (Mon & 1) != 0) Printall();
        Aim = Count;
        Q = Esslim;
        while (Q != Sp) {
          K = W[Q].Flags & 0xCFFFFFFF;
          W[Q].Flags = ((unsigned)(K & 0xC0000000) >> 2) + K;
          Q++;
        }
      }
      for (;;) {
        if (Q == Esslim) {
          while (Q != Sp) {
            K = W[Q].Flags & 0x3FFFFFFF;
            W[Q].Flags = ((K & 0x30000000) << 2) + K;
            Q++;
          }
          if (Inc <= Min) return;
          Count = Aim;
          Inc = (unsigned)Inc >> 1;
          if (!Inc) Printall();
        }
        Q--;
        M = W[Q].Flags;
        W[Q].Flags = M & 0x3FFFFFFF;
        if (M >= 0) {
          K = (M & 31) + 4096;
          Count -= K;
          if (!(M & Forced)) break;
        }
      }
      W[Q].Flags = W[Q].Flags + Sign;
      Q++;
    }
  }

  {
    _imp_string In1 = _imp_str_literal(":N");
    _imp_string In2 = _imp_str_literal(":N");
    _imp_string In3;
    _imp_string Out = _imp_str_literal(":T");
    int Bools = 0x05000000;
    void Init(int *N) {
      if (Bools < 0) *N = 1;
      Bools = Bools << 1;
    }
    Defineparam(_imp_str_literal("Input file"), In3, Pamnodefault);
    Defineparam(_imp_str_literal("Input 2"), In2, 0);
    Defineparam(_imp_str_literal("Input 3"), In1, 0);
    Defineparam(_imp_str_literal("Output file"), Out, Pamnewgroup);
    Defineintparam(_imp_str_literal("MIN"), Min, 0);
    Defineintparam(_imp_str_literal("INC"), Inc, 0);
    Defineintparam(_imp_str_literal("MON"), Mon, 0);
    Definebooleanparams(_imp_str_literal("ECho,SQuash,NIn,NOut,Check,SIngle,Tabin,EQuin"), Bools, 0);
    Processparameters(Cliparam());
    Init(Echo);
    Init(Squash);
    Init(Nin);
    Init(Nout);
    Init(Check);
    Init(Single);
    Init(Tabin);
    if (Bools < 0) Tabin = 0;
    Openinput(Instream - 2, In3);
    Openinput(Instream - 1, In2);
    Openinput(Instream, In1);
    Openoutput(Outstream, Out);
  }
  Selectoutput(Outstream);
  Selectinput(Instream);
  for (;;) {
    Start = Cputime();
    Readin();
    Printstring(_imp_str_literal("Read in:"));
    Printtime();
    Newline();
    Convert();
    Aim = 999999;
    Count = 0;
    Printstring(_imp_str_literal("Implicants:"));
    Write(Sp - Dclim, 3);
    Printtime();
    Newline();
    if (Inc != 0 && (Mon & 16) != 0) Printall();
    Reduce1();
    Printstring(_imp_str_literal("Reduced(1):"));
    Write(Sp - Dclim, 3);
    Printstring(_imp_str_literal(" (nucleus"));
    Pcount();
    Printsymbol(')');
    Printtime();
    Newline();
    if (Inc != 0 && (Mon & 16) != 0) Printall();
    if (Sp != Esslim) {
      Reduce2();
      Printstring(_imp_str_literal("Reduced(2):"));
      Write(Sp - Dclim, 3);
      Printstring(_imp_str_literal(" (nucleus"));
      Pcount();
      Printsymbol(')');
      if (Sp != Esslim) Order();
      Printtime();
      Newline();
      if (Inc != 0 && (Mon & 16) != 0) Printall();
    }
    if (Mon & 2) Monitor(Esslim);
    if (Sp != Esslim) {
      if (Mon & 8) Monitor(Sp);
      Printstring(_imp_str_literal("Minimised:"));
      Minimise();
    }
    if (Inc != 0 && (Mon & 1) == 0) Printall();
    Printstring(_imp_str_literal("  Cells used:"));
    Write(Storebound - 1 - Minsep, 1);
    Printtime();
    Newline();
  }
  exit(0);
  return (1);
}
