program EXPRESSION_CHECK;
uses
  testlib, sysutils;

{ ARGUMENT numbering:
   -2*n + i <-> Ai
   -n   + i <-> Bi
   0...      - dymanic
}

const
  maxn    = 100;
  factor  = 50;
  maxsize = factor*maxn;

  PAR_OPEN  = -9999;
  PAR_CLOSE = -9998;
  STROKE    = -9997;
  EXPR      = -9996;

  tests=1000;

function GetFileSize(name: string): longint;
var
  f: file;
begin
  assign(f, name);
  reset(f, 1);
  GetFileSize:= filesize(f);
  close(f);
end;

var
  n, sp, ep, ofs, i, tst: integer;
  ch: char;
  st: array[1..maxsize] of integer; { Stack for analyzer }
  op1, op2: array[0..maxsize] of integer; { Operands }
  v: array[-2*maxn..maxsize] of boolean; { Calculated value }
  used: array[-2*maxn..-1] of boolean;
  over: boolean;

procedure SPut(i: integer);
begin
  inc(sp);
  st[sp]:= i;
end;

function dval(ch: char): integer;
begin
  dval:= ord(ch) - ord('0');
end;

begin
  n:= inf.readLongint;

  { Read all charactes and process }
  { Single rule: (E|E) -> E        }
  sp:= 0; { Stack pointer - last used place }
  ep:= 0; { Expression pointer - first free place in expr. tables }
  fillchar(used, sizeof(used), false);
  while not ouf.eoln do begin
    ch:= ouf.nextchar;
    case ch of
      '(': SPut(PAR_OPEN);
      ')': SPut(PAR_CLOSE);
      '|': SPut(STROKE);
      'A','B': begin
                 if ch = 'A' then ofs:= -2*n else ofs:= -n;
                 ch:= ouf.nextchar;
                 if not (ch in ['0'..'9']) then
                   Quit(_PE, 'Invalid char after A or B: "' + ch + '"');
                 if ouf.curchar in ['0'..'9'] then begin
                   inc(ofs, dval(ch)*10 + dval(ouf.curchar));
                   ouf.nextchar;
                 end else
                   inc(ofs, dval(ch));
                 SPut(Ofs);
                 used[ofs]:= true;
               end;

    else Quit(_PE, 'Invalid char: "' + ch + '"');
    end;
    { Try to invoke rule }
    if (sp >= 5) and (st[sp] = PAR_CLOSE) and
       (st[sp-1] >= EXPR) and (st[sp-2] = STROKE) and
       (st[sp-3] >= EXPR) and (st[sp-4] = PAR_OPEN) then begin
      op1[ep]:= st[sp-1];
      op2[ep]:= st[sp-3];
      st[sp-4]:= ep;
      sp:= sp-4;
      inc(ep);
    end;
  end;
  if not ouf.seekeof then
    Quit(_PE, 'Extra data in file');
  if (sp <> 1) or (st[1] < EXPR) then
    Quit(_PE, 'Not an expression in file');

  { Expression is Ok. st[1] is the result point (just to be sure)}

  for i:= -2*n to -1 do
    if not used[i] then
      Quit(_WA, 'Obvious error, variable not used');

  randseed:= 12345; { Everyone should be tested equally }

  for tst:= 1 to tests do begin { Perform testing }
    { Generate items }
    for i:= -2*n to -1 do
      v[i]:= random(2) = 0;
    { Evaluate expression }
    for i:= 0 to ep-1 do
      v[i]:= not (v[op1[i]] and v[op2[i]]);
    { Perform addition }
    over:= false;
    for i:= -n to -1 do
      over:= ord(over) + ord(v[i]) + ord(v[i-n]) > 1;
    { Compare }
    if over <> v[st[1]] then
      Quit(_WA, 'Expression is evaluated to wrong value');
  end;

  Quit(_OK, 'Ok');
end.
