#include <perms.h>
int _imp_mainep(int _imp_argc, char **_imp_argv) {
  static int Gra = 1;
  static int Old = 2;
  static int Err = 0;
  static int New = 1;
  static int Glist = 2;
  static int Dlist = 3;
  static int Ssbase = 92;
  static int Eop = 0;
  static int Nmax = -1;
  int Sym;
  int Count;
  int Ordinal;
  int Charmax;
  int Gmin;
  int Gmax;
  int Kmax;
  int Char[600 /*1:600*/];
  int Index[128 /*0:127*/];
  int Item[256 /*0:255*/];
  int Next[256 /*0:255*/];
  int Phrase[111 - Ssbase + 1];
  int Atomic[48 /*64:111*/];
  int Keydict[480 /*32:511*/];
  if (_imp_on_event(9)) goto L__99;
  void Readsym(void) {
  L__1:
    Readsymbol(Sym);
    if (Sym == ' ') goto L__1;
  }
  void Readname(int *N) {
    int I;
    int J;
    int K;
    I = Charmax;
  L__1:
    I++;
    Char[I] = Sym;
    Readsymbol(Sym);
    if ('A' <= Sym && Sym <= 'Z' || '0' <= Sym && Sym <= '9' || Sym == '\'')
      goto L__1;
    I++;
    Char[I] = 0;
    *N = -1;
  L__2:
    if (*N == Nmax) goto L__5;
    *N = *N + 1;
    J = Index[*N];
    K = Charmax + 1;
  L__3:
    if (J == 0 || Char[J] != Char[K]) goto L__2;
    if (!Char[J]) goto L__9;
    J++;
    K++;
    goto L__3;
  L__5:
    *N = *N + 1;
    Nmax = *N;
    Index[*N] = Charmax + 1;
    Charmax = I;
  L__9:
    if (Sym == ' ') Readsym();
  }
  void Printname(int N) {
    N = Index[N & 127];
  L__1:
    Printsymbol(Char[N]);
    N++;
    if (Char[N]) goto L__1;
  }
  void Readgrammar(void) {
    int I;
    int J;
    int P;
    int Min;
    int Max;
    int Exp;
    int End;
    int Terminal;
    int Converted[226 /*-100:125*/];
    int Head[100 /*-100:-1*/];
    int Tail[100 /*-100:-1*/];
    int Token[125 /*1:125*/];
    int Link[125 /*1:125*/];
    int Map[256 /*0:255*/];
    int New(int H, int T) {
      int I;
      I = T;
      if (I > 0) I = 0;
    L__1:
      if (I == Min) goto L__2;
      I--;
      if (Head[I] == H && Tail[I] == T) return (I);
      goto L__1;
    L__2:
      Min--;
      Head[Min] = H;
      Tail[Min] = T;
      Converted[Min] = 0;
      return (Min);
    }
    int Union(int X, int Y) {
      int Hx;
      int Hy;
      if (X == Y) return (X);
      if (X < Y) return (Union(Y, X));
      if (X >= 0) {
        if (Y >= 0) return (New(X, Y));
        Hy = Head[Y];
        if (X > Hy) return (New(X, Y));
        if (X != Hy) return (New(Hy, Union(X, Tail[Y])));
        return (Union(X, Tail[Y]));
      }
      Hx = Head[X];
      Hy = Head[Y];
      if (Hx > Hy) return (New(Hx, Union(Tail[X], Y)));
      if (Hx != Hy) return (New(Hy, Union(X, Tail[Y])));
      return (New(Hx, Union(Tail[X], Tail[Y])));
    }
    void Concatenate(int X, int Y) {
      int I;
      int J;
      I = X;
    L__1:
      J = Link[I];
      Link[I] = Y;
      I = J;
      if (I != X) goto L__1;
    }
    void Acceptexp(int *Exp, int *Expend) {
      int I;
      int String;
      int Stringend;
      int Unit;
      int Unitend;
      *Exp = 0;
    L__1:
      String = 0;
    L__2:
      if (Sym == '(') {
        Readsym();
        Acceptexp(Unit, Unitend);
        if (Unit == 0 || Sym != ')') goto L__9;
        Readsym();
      } else {
        if ('A' > Sym || Sym > 'Z') goto L__9;
        Readname(I);
      L__3:
        if (Sym == '<') {
          I += 128;
          Readsym();
          goto L__3;
        }
        Max++;
        Token[Max] = I;
        Link[Max] = Max;
        Unit = Max;
        Unitend = Max;
      }
      if (Sym == '*' || Sym == '!') {
        Max++;
        Token[Max] = 0;
        Link[Max] = Max;
        Min--;
        Head[Min] = Max;
        Tail[Min] = Unit;
        Concatenate(Unitend, Min);
        Unitend = Max;
        if (Sym == '*') Unit = Min;
        Readsym();
      }
      if (Sym == '?') {
        Max++;
        Token[Max] = 0;
        Link[Max] = Link[Unitend];
        Link[Unitend] = Max;
        Min--;
        Head[Min] = Max;
        Tail[Min] = Unit;
        Unit = Min;
        Readsym();
      }
      if (!String)
        String = Unit;
      else
        Concatenate(Stringend, Unit);
      Stringend = Unitend;
      if (Sym != ',' && Sym != ')' && Sym != Nl) goto L__2;
      if (!*Exp) {
        *Exp = String;
        *Expend = Stringend;
      } else {
        *Exp = Union(String, *Exp);
        I = Link[*Expend];
        Link[*Expend] = Link[Stringend];
        Link[Stringend] = I;
      }
      if (Sym != ',') return;
    L__8:
      Readsym();
      if (Sym == Nl) goto L__8;
      goto L__1;
    L__9:
      *Exp = 0;
    }
    void Convert(void) {
      int I;
      int J;
      int K;
      int L;
      int M;
      int N;
      int Gmax1;
      int Loopstop;
      void Tcount(int X) {
        int T;
      L__1:
        if (!X) return;
        if (X < 0) {
          Tcount(Tail[X]);
          X = Head[X];
        }
        T = Token[X];
        if (T <= 0) {
          if (T == Loopstop) return;
          Token[X] = Loopstop;
          X = Link[X];
          goto L__1;
        }
        K--;
      }
      void Addcomponents(int X) {
        static int I;
        static int J;
        static int K;
        static int T;
      L__1:
        if (X) {
          if (X < 0) {
            Addcomponents(Tail[X]);
            X = Head[X];
          }
          T = Token[X];
          if (T <= 0) {
            if (T == Loopstop) return;
            Token[X] = Loopstop;
            X = Link[X];
            goto L__1;
          }
          I = Gmax1;
          X = Link[X];
        L__2:
          if (I != Gmax) {
            I++;
            K = Item[I];
            if (K != T) {
              K = K & 127;
              if (K < 96 && K != 48 && (K < 64 || Atomic[K] != 48)) goto L__2;
              if ((T & 127) >= K) goto L__2;
              for (I = Gmax; I >= I; I--) {
                Item[I + 1] = Item[I];
                Next[I + 1] = Next[I];
              }
              Gmax++;
              Item[I] = T;
              Next[I] = X;
            } else
              Next[I] = Union(Next[I], X);
          } else {
            Gmax++;
            Item[Gmax] = T;
            Next[Gmax] = X;
          }
        } else
          Terminal = 512;
      }
      Loopstop = 0;
      Gmin = Gmax + 1;
      for (I = Min; I <= Max; I++) Converted[I] = 0;
      N = Next[0];
    L__1:
      Gmax1 = Gmax;
      Loopstop--;
      Terminal = 0;
      Addcomponents(N);
      if (Terminal) {
        Gmax++;
        Item[Gmax] = 0;
        Next[Gmax] = 0;
      }
      Item[Gmax] = Item[Gmax] + 512;
      Converted[N] = Gmax1 + 1;
      M = 0;
      for (I = Gmin; I <= Gmax; I++) {
        J = Next[I];
        if (J) {
          K = Converted[J];
          if (!K) {
            Loopstop--;
            Tcount(J);
            Converted[J] = K;
          }
          if (K < M) {
            M = K;
            N = J;
          }
        }
      }
      if (M) goto L__1;
      for (I = Gmin; I <= Gmax; I++) {
        K = Next[I];
        if (K)
          K = Converted[K];
        else
          K = Eop;
        Next[I] = K;
      }
    }
    void Minimize(void) {
      int I;
      int J;
      int K;
      int M;
      int N;
      int Stack[150 /*1:150*/];
      int Ultmap(int I) {
        int J;
      L__1:
        J = I;
        I = Map[I];
        if (I != J && I != 0) goto L__1;
        return (J);
      }
      int Equivalent(int Nn, int Mm) {
        int I;
        int J;
        int K;
        int Pos1;
        int Pos2;
        Pos1 = 0;
        Pos2 = 0;
      L__1:
        K = Item[Mm];
        if (Item[Nn] != K) goto L__9;
        I = Next[Nn];
        J = Next[Mm];
        if (I != J && (255 == I || I == 0 || 255 == J || J == 0)) goto L__9;
        Pos1++;
        Stack[Pos1] = Nn;
        Map[Nn] = Mm;
        Nn++;
        Mm++;
        if (!(K & 512)) goto L__1;
      L__2:
        if (Pos2 == Pos1) return (1);
        Pos2++;
        I = Stack[Pos2];
        Nn = Ultmap(Next[I]);
        Mm = Ultmap(Next[Map[I]]);
        if (Nn == Mm) goto L__2;
        if (Nn < Mm) {
          I = Nn;
          Nn = Mm;
          Mm = I;
        }
        if (Nn > N) goto L__1;
      L__9:
        if (!Pos1) return (0);
        I = Stack[Pos1];
        Map[I] = I;
        Pos1--;
        goto L__9;
      }
      for (I = 0; I <= 255; I++) Map[I] = I;
      for (N = Gmin; N <= Gmax; N++) {
        if (Map[N] == N) {
          if (N != Gmin && (Item[N - 1] & 512) == 0) goto L__4;
          M = 1;
        L__2:
          if (M != N) {
            if (Map[M] == M && Equivalent(N, M) != 0) goto L__4;
            M++;
            goto L__2;
          }
        } else
          Map[N] = Ultmap(N);
      L__4:;
      }
      J = Gmin - 1;
      for (I = Gmin; I <= Gmax; I++) {
        K = Map[I];
        if (K == I) {
          J++;
          Map[I] = J;
          Item[J] = Item[I];
          Next[J] = Next[I];
        } else
          Map[I] = Map[K];
      }
      Gmax = J;
      for (I = Gmin; I <= Gmax; I++) {
        K = Next[I];
        if (K) Next[I] = Map[K];
      }
    }
    Gmax = 0;
  L__1:
    Readsym();
    if (Sym == Nl) goto L__1;
    if (Sym == '/') return;
    if (Sym == 'S' && Nextsymbol() == 'S') {
      Skipsymbol();
      Read(I);
      P = Ssbase + I;
      Eop = 0;
    } else {
      Readname(P);
      Eop = 0255;
    }
    Min = 0;
    Max = 0;
  L__2:
    Readsym();
    if (Sym == Nl || Sym == '-' || Sym == '>') goto L__2;
    Acceptexp(Exp, End);
    if (Exp == 0 || Sym != Nl) {
      printstring("WRONG FORMAT AT: ");
    L__3:
      Printsymbol(Sym);
      if (Sym == Nl) goto L__1;
      Readsym();
      goto L__3;
    }
    Concatenate(End, 0);
    Item[0] = 1023;
    Next[0] = Exp;
    Convert();
    if (P != 111) Minimize();
    Phrase[P] = Gmin;
    Selectoutput(Glist);
    for (I = Gmin; I <= Gmax; I++) {
      if (I == 1 || (Item[I - 1] & 512) != 0) {
        Newline();
        Write(I, 3);
        J = 0;
      }
      J++;
      if (J > 5) {
        Newline();
        Spaces(4);
        J = 1;
      }
      Spaces(3);
      if (Item[I] & 511) {
        Printname(Item[I] & 127);
        Write(Next[I], 1);
      } else
        printstring("*E*");
    }
    Newline();
    Selectoutput(Err);
    goto L__1;
  }
  void Readatoms(void) {
    int I;
    int J;
    int K;
    int L;
    int P;
    int S;
    int T;
    int Char[451 /*0:450*/];
    int Cont[451 /*0:450*/];
    int Alt[451 /*0:450*/];
    void Reads(void) {
      S = Nextsymbol();
      T = 0;
      if (S != ',' && S != Nl) {
        if ('0' > S || S > '9') {
          Skipsymbol();
          if (S != '(') return;
        }
        Read(T);
        if (Nextsymbol() == ')') Skipsymbol();
      }
      S = K + 128;
    }
    void Insertin(int *X) {
      if (Char[*X] < S) {
        if (!Cont[*X]) Cont[*X] = T;
        Insertin(Alt[*X]);
        return;
      }
      if (Char[*X] != S) {
        J++;
        Char[J] = S;
        Cont[J] = 0;
        Alt[J] = *X;
        *X = J;
      }
      if (!(S & 128)) {
        Reads();
        Insertin(Cont[*X]);
      } else {
        if (T == 0 && Alt[J] != 0) T = Cont[Alt[J]];
        Cont[J] = T;
      }
    }
    void Store(int X) {
      int M;
      int N;
    L__1:
      if (!X) return;
    L__2:
      Kmax++;
      M = Kmax;
      if (P != 0 && Char[X] > M) goto L__2;
      if (Alt[X]) {
        Store(Alt[X]);
        N = ~131071;
      } else
        N = 0;
      if (!(Char[X] & 128)) {
        if (Kmax < 95) Kmax = 95;
        Keydict[M] = N + ((Kmax + 1) << 7) + Char[X];
        X = Cont[X];
        P = 0;
        goto L__1;
      }
      Keydict[M] = N + 65536 + (Cont[X] << 6) + (Char[X] & 63);
    }
    I = 0;
    J = 0;
    Char[0] = 999;
  L__1:
    Sym = Nextsymbol();
    if (Sym == '[' || Sym == Nl) goto L__5;
    if (Sym == '/') goto L__6;
    Read(Ordinal);
    if (Ordinal <= Nmax) exit(0);
    Nmax = Ordinal - 1;
    Readsym();
    Readname(K);
    if (K != Ordinal) exit(0);
    if (K >= 64) {
      if (Sym != '/') goto L__1;
      Readsym();
      Readname(L);
      if (L == Nmax) exit(0);
      Atomic[K] = L;
      goto L__1;
    }
    if (Sym == '[') goto L__5;
  L__3:
    S = Sym;
    Insertin(I);
    if (Nextsymbol() == Nl) goto L__1;
    Skipsymbol();
  L__4:
    Readsymbol(Sym);
    if (Sym == ' ' || Sym == Nl) goto L__4;
    goto L__3;
  L__5:
    Readsymbol(Sym);
    if (Sym != Nl) goto L__5;
    goto L__1;
  L__6:
    for (J = 32; J <= 95; J++) Keydict[J] = 0;
    Kmax = 32;
    P = 1;
    Store(I);
    Keydict[94] = Keydict[92];
    void Display(int I, int S) {
      int J;
    L__1:
      J = Keydict[I];
      if (I == 32) {
        Printsymbol('?');
        Newline();
        return;
      }
      if (!(J & 65536)) {
        Printsymbol(J & 127);
        Space();
        Display((unsigned)J >> 7 & 511, S + 2);
      } else {
        Printsymbol(':');
        Printname(J & 63);
        Write((unsigned)J >> 6 & 1023, 1);
        Newline();
      }
      if (J >= 0) return;
      Spaces(S);
      I++;
      goto L__1;
    }
    Selectoutput(Dlist);
    Newlines(2);
    for (I = 33; I <= 95; I++) {
      J = ((unsigned)Keydict[I] >> 7 & 511) << 2;
      if (!J) J = 32 << 2;
      if ('A' > I || I > 'Z') J += 3;
      if ('0' <= I && I <= '9') J -= 2;
      if (I == ';') J--;
      Keydict[I] = J;
      Printsymbol(I);
      Space();
      Display((unsigned)J >> 2, 2);
    }
    Newlines(2);
    Selectoutput(Err);
  }
  int I;
  int J;
  int K;
  Charmax = 0;
  for (I = 1; I <= 127; I++) Index[I] = 0;
  for (I = 64; I <= 111; I++) Atomic[I] = I;
  for (I = 96; I <= 111; I++) Phrase[I] = 0;
L__1:
  Readsymbol(I);
  if (I != '/') goto L__1;
L__2:
  Readsymbol(I);
  if (I != Nl) goto L__2;
  Readatoms();
L__3:
  Readsymbol(I);
  if (I != Nl) goto L__3;
  Readgrammar();
  Selectoutput(New);
  Write(Gmax, 1);
  Write(Kmax, 1);
L__5:
  Write(Phrase[Ssbase], 1);
  Ssbase++;
  if (Ssbase < 96) goto L__5;
  Newline();
  for (I = 96; I <= 111; I++) {
    if (!(I & 7)) Newline();
    Write(Phrase[I], 3);
  }
  Newline();
  for (I = 64; I <= 111; I++) {
    if (!(I & 7)) Newline();
    Write(Atomic[I], 7);
  }
  Newline();
  for (I = 1; I <= 255; I++) {
    if (!((I - 1) & 7)) Newline();
    K = 0;
    if (I <= Gmax) {
      J = Item[I];
      if (!(J & 512)) K = -131072;
      K += (J & 384) << 8;
      K += Next[I] << 7;
      K += J & 127;
    }
    Write(K, 7);
  }
  Newline();
  for (I = 32; I <= 511; I++) {
    if (!((I - 1) & 7)) Newline();
    Write(Keydict[I], 7);
  }
  Newlines(2);
  Selectinput(Old);
L__10:
  Readsymbol(I);
  if (I != '%' && I != '!') goto L__10;
L__20:
  Printsymbol(I);
  Readsymbol(I);
  goto L__20;
L__99:;
  exit(0);
  return (1);
}
