#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define LOGIX	3

#define FALSCH	0
#define UNDEF	1
#define WAHR	2

char *names[3] = {
  "FALSCH",
  "UNDEF",
  "WAHR"
};

typedef struct {
	int x, y;
	int values[LOGIX];
	} table;

static table und_t[3*3] = {
	{ UNDEF,  UNDEF,  { UNDEF,  UNDEF,  UNDEF  }},
	{ UNDEF,  FALSCH, { UNDEF,  UNDEF,  FALSCH }},
	{ UNDEF,  WAHR,   { UNDEF,  UNDEF,  UNDEF  }},
	{ FALSCH, UNDEF,  { UNDEF,  FALSCH, FALSCH }},
	{ FALSCH, FALSCH, { FALSCH, FALSCH, FALSCH }},
	{ FALSCH, WAHR,   { FALSCH, FALSCH, FALSCH }},
	{ WAHR,   UNDEF,  { UNDEF,  UNDEF,  UNDEF  }},
	{ WAHR,   FALSCH, { FALSCH, FALSCH, FALSCH }},
	{ WAHR,   WAHR,   { WAHR,   WAHR,   WAHR   }}
	};

static table oder_t[3*3] = {
	{ UNDEF,  UNDEF,  { UNDEF,  UNDEF,  UNDEF  }},
	{ UNDEF,  FALSCH, { UNDEF,  UNDEF,  UNDEF  }},
	{ UNDEF,  WAHR,   { UNDEF,  UNDEF,  WAHR   }},
	{ FALSCH, UNDEF,  { UNDEF,  UNDEF,  UNDEF  }},
	{ FALSCH, FALSCH, { FALSCH, FALSCH, FALSCH }},
	{ FALSCH, WAHR,   { WAHR,   WAHR,   WAHR   }},
	{ WAHR,   UNDEF,  { UNDEF,  WAHR,   WAHR   }},
	{ WAHR,   FALSCH, { WAHR,   WAHR,   WAHR   }},
	{ WAHR,   WAHR,   { WAHR,   WAHR,   WAHR   }}
	};

static table imp_t[3*3] = {
	{ UNDEF,  UNDEF,  { UNDEF,  UNDEF,  UNDEF  }},
	{ UNDEF,  FALSCH, { UNDEF,  UNDEF,  UNDEF  }},
	{ UNDEF,  WAHR,   { UNDEF,  UNDEF,  WAHR   }},
	{ FALSCH, UNDEF,  { UNDEF,  WAHR,   WAHR   }},
	{ FALSCH, FALSCH, { WAHR,   WAHR,   WAHR   }},
	{ FALSCH, WAHR,   { WAHR,   WAHR,   WAHR   }},
	{ WAHR,   UNDEF,  { UNDEF,  UNDEF,  UNDEF  }},
	{ WAHR,   FALSCH, { FALSCH, FALSCH, FALSCH }},
	{ WAHR,   WAHR,   { WAHR,   WAHR,   WAHR   }}
	};

static table not_t[3*3] = {
	{ UNDEF,  UNDEF,  { UNDEF,  UNDEF,  UNDEF  }},
	{ UNDEF,  FALSCH, { UNDEF,  UNDEF,  UNDEF  }},
	{ UNDEF,  WAHR,   { UNDEF,  UNDEF,  UNDEF  }},
	{ FALSCH, UNDEF,  { WAHR,   WAHR,   WAHR   }},
	{ FALSCH, FALSCH, { WAHR,   WAHR,   WAHR   }},
	{ FALSCH, WAHR,   { WAHR,   WAHR,   WAHR   }},
	{ WAHR,   UNDEF,  { FALSCH, FALSCH, FALSCH }},
	{ WAHR,   FALSCH, { FALSCH, FALSCH, FALSCH }},
	{ WAHR,   WAHR,   { FALSCH, FALSCH, FALSCH }}
	};

int calc (table *tptr, int x, int y, int logix)
{
  int i;
  
  for (i=0; i<3*3; i++)
    if (tptr->x == x && tptr->y == y)
      return (tptr->values)[logix];
    else
      tptr++;

  printf ("Error! Value not defined for %d %d\n", x, y);
  return UNDEF;
}

#define ERROR(t) {printf("Error at %s\n",t);while(*t)t++;return UNDEF;}

int eval (char *string, char **rpr, int x, int y, int z, int logix)
{
  int left, right, op, res, nflag=0;
  char *ptr;

  while (*string == ' ')
    string++;

  if (*string == 'n') {
    nflag = 1;
    while (isalpha(*string)) string++;
    while (*string == ' ')   string++;
  }
  else
    nflag = 0;

  if (*string == '(') {
    left   = eval (string+1, &ptr, x, y, z, logix);
    string = ptr;
  }
  else {
    if      (*string == 'x') left = x;
    else if (*string == 'y') left = y;
    else if (*string == 'z') left = z;
    else if (*string == 't') left = WAHR;
    else if (*string == 'w') left = WAHR;
    else if (*string == 'f') left = FALSCH;
    else                     ERROR(string);
    while (isalpha (*string)) string++;
  }
  while (*string == ' ')    string++;

  if (nflag) {
    left = calc (not_t, left, left, logix);
    nflag = 0;
  }

  if (*string == ')') {
    string++;
    while (*string == ' ')
      string++;
    *rpr = string;
    return left;
  }
  else if (*string == '\0') {
    *rpr = string;
    return left;
  }

  op = *string++;

  while (isalpha(*string)) string++;
  while (*string == ' ')   string++;

  if (*string == 'n') {
    nflag = 1;
    while (isalpha(*string)) string++;
    while (*string == ' ')   string++;
  }
  else
    nflag = 0;

  if (*string == '(') {
    right  = eval (string+1, &ptr, x, y, z, logix);
    string = ptr;
  }
  else {
    if      (*string == 'x') right = x;
    else if (*string == 'y') right = y;
    else if (*string == 'z') right = z;
    else if (*string == 't') right = WAHR;
    else if (*string == 'w') right = WAHR;
    else if (*string == 'f') right = FALSCH;
    else                     ERROR(string);
    while (isalpha (*string)) string++;
  }
  while (*string == ' ')    string++;

  if (nflag) {
    right = calc (not_t, right, right, logix);
    nflag = 0;
  }

  switch (op) {
  case 'u': res = calc (und_t,  left, right, logix); break;
  case 'o': res = calc (oder_t, left, right, logix); break;
  case '>': res = calc (imp_t,  left, right, logix); break;
  default:  printf ("ERROR: Unknown operator %c\n", op); res=UNDEF; break;
  }

  if (*string == ')') {
    string++;
    while (*string == ' ')
      string++;
  }
  *rpr = string;
  return res;
}

void checkx (char *form1, char *form2)
{
  int left, right, vals[LOGIX], x, i;
  char *dummy;

  printf ("\tL: %s\n\tR: %s\n", form1, form2);

  for (i=0; i<LOGIX; i++)
    vals[i] = 1;

  printf ("X      ");
  for (i=0; i<LOGIX; i++)
    printf ("| L%-2d      R%-2d    ", i+1, i+1);
  printf ("\n-------");
  for (i=0; i<LOGIX; i++)
    printf ("+-----------------");
  printf ("\n");

  for (x=0; x<3; x++) {
    printf ("%-6s ", names[x]);

    for (i=0; i<LOGIX; i++) {
      left  = eval (form1, &dummy, x, 0, 0, i);
      right = eval (form2, &dummy, x, 0, 0, i);

      printf ("| %-6s %c %-6s ", names[left], (left==right)?' ':'!', names[right]);

      if (left != right)
	vals[i] = 0;
    }
    printf ("\n");
  }
  printf ("-------");
  for (i=0; i<LOGIX; i++)
    printf ("+-----------------");
  printf ("\n");

  printf ("TOTAL  ");
  for (i=0; i<LOGIX; i++)
    printf ("| %-6s          ", (vals[i]) ? "OK" : "FALSCH");

  printf ("\n\n");
}

void checkxy (char *form1, char *form2)
{
  int left, right, vals[LOGIX], x, y, i;
  char *dummy;

  printf ("\tL: %s\n\tR: %s\n", form1, form2);

  for (i=0; i<LOGIX; i++)
    vals[i] = 1;

  printf ("X      Y      ");
  for (i=0; i<LOGIX; i++)
    printf ("| L%-2d      R%-2d    ", i+1, i+1);
  printf ("\n--------------");
  for (i=0; i<LOGIX; i++)
    printf ("+-----------------");
  printf ("\n");

  for (x=0; x<3; x++) {
    for (y=0; y<3; y++) {
      printf ("%-6s %-6s ", names[x], names[y]);

      for (i=0; i<LOGIX; i++) {
	left  = eval (form1, &dummy, x, y, 0, i);
	right = eval (form2, &dummy, x, y, 0, i);

	printf ("| %-6s %c %-6s ", names[left], (left==right)?' ':'!', names[right]);

	if (left != right)
	  vals[i] = 0;
      }
      printf ("\n");
    }
  }
  printf ("--------------");
  for (i=0; i<LOGIX; i++)
    printf ("+-----------------");
  printf ("\n");
  printf ("TOTAL         ");
  for (i=0; i<LOGIX; i++)
    printf ("| %-6s          ", (vals[i]) ? "OK" : "FALSCH");
  
  printf ("\n\n");
}

void checkxyz (char *form1, char *form2)
{
  int left, right, vals[LOGIX], x, y, z, i;
  char *dummy;

  printf ("\tL: %s\n\tR: %s\n", form1, form2);

  for (i=0; i<LOGIX; i++)
    vals[i] = 1;

  printf ("X      Y      Z      ");
  for (i=0; i<LOGIX; i++)
    printf ("| L%-2d      R%-2d    ", i+1, i+1);
  printf ("\n---------------------");
  for (i=0; i<LOGIX; i++)
    printf ("+-----------------");
  printf ("\n");

  for (x=0; x<3; x++) {
    for (y=0; y<3; y++) {
      for (z=0; z<3; z++) {
	printf ("%-6s %-6s %-6s ", names[x], names[y], names[z]);

	for (i=0; i<LOGIX; i++) {
	  left  = eval (form1, &dummy, x, y, z, i);
	  right = eval (form2, &dummy, x, y, z, i);
	  
	  printf ("| %-6s %c %-6s ", names[left], (left==right)?' ':'!', names[right]);
	  
	  if (left != right)
	    vals[i] = 0;
	}
	printf ("\n");
      }
    }
  }
  printf ("---------------------");
  for (i=0; i<LOGIX; i++)
    printf ("+-----------------");
  printf ("\n");
  printf ("TOTAL                ");
  for (i=0; i<LOGIX; i++)
    printf ("| %-6s          ", (vals[i]) ? "OK" : "FALSCH");
  
  printf ("\n\n");
}

void main (void)
{
  char str1[256], str2[256], str3[256], *ptr;

  while (!feof (stdin)) {
    if (fgets (str1, 255, stdin) == NULL)
      break;

    if (ptr = strchr (str1, '\n'))
      *ptr = '\0';
    if ((ptr = strchr (str1, '=')) == NULL) {
      ptr = str1;
      while (*ptr == ' ') ptr++;
      if (*ptr != '\0')
	printf ("Ungueltige Zeile: %s\n", str1);
      continue;
    }
    *ptr++ = '\0';
    while (*ptr == ' ')
      ptr++;

    strcpy (str2, str1);
    strcpy (str3, ptr);

    if (strchr (str1, 'z'))
      checkxyz (str2, str3);
    else if (strchr (str1, 'y'))
      checkxy (str2, str3);
    else
      checkx (str2, str3);

    printf ("\n");
    fflush (stdout);
  }
}
