# include <stdio.h>
# include <stdlib.h>
# include <string.h>
typedef struct NOD{int cod;NOD *fiustg,*fiudrt;};
const int MAXS=1000+3;
int val_var[50]={0};
char s[4*MAXS];
const int TRUE=-1,FALSE=0,NOT=-2,OR=-3,AND=-4;
int eval(NOD *nod,int li, int lf)
{
NOD *p;
int i;
//1. cautam info despre segmentul de sir pe care il avem de prelucrat acum
int npd=0,priop,nesop=1500,pozop,q;
for (i=li;i<=lf;i++)
{
if (s[i]=='(') npd++;
else if (s[i]==')') npd--;
else if (s[i]=='N'&&s[i+1]=='O'&&(nesop>npd)) {nesop=npd;pozop=i;priop=1;}
else if (s[i]=='A'&&s[i+1]=='N'&&(nesop>npd||(nesop==npd&&priop==1))) {nesop=npd;pozop=i;priop=2;}
else if (s[i]=='O'&&s[i+1]=='R'&&(nesop>npd||(nesop==npd&&priop<=2))) {nesop=npd;pozop=i;priop=3;}
}
//2. renuntam la prantezele inutile
if (nesop>0&&nesop!=1500) {li+=nesop;lf-=nesop;}
//3. ce se intampla daca nu avem operatori
if (nesop==1500)
{
i=li,q=0;
while (s[i]=='(') {i++;q++;}
li+=q;lf-=q; //return eval(li+q,lf-q);
(*nod).fiustg=NULL;(*nod).fiudrt=NULL;
if (li==lf) (*nod).cod=(int)s[li]-(int)'A'+1;
else
if (s[li]=='T') (*nod).cod=-1;
else (*nod).cod=0;
return 0;
}
//4. ce se intampla daca gasim operatori
switch (priop)
{
case 1:
{
//am gasit un operator NOT
(*nod).fiustg=NULL; (*nod).cod=NOT;
p=(NOD*) malloc(sizeof(NOD));
(*nod).fiudrt=p;
eval(p,li+4,lf);
return 0;
}
case 2:
{
//am gasit un operator AND
//return eval(li,pozop-2)*eval(pozop+4,lf);
(*nod).cod=AND;
p=(NOD*) malloc(sizeof(NOD));(*nod).fiustg=p;
eval(p,li,pozop-2);
p=(NOD*) malloc(sizeof(NOD));(*nod).fiudrt=p;
eval(p,pozop+4,lf);
return 0;
}
case 3:
{
//am gasit un operator OR
//return 1-(1-eval(li,pozop-2))*(1-eval(pozop+3,lf));
(*nod).cod=OR;
p=(NOD*) malloc(sizeof(NOD));(*nod).fiustg=p;
eval(p,li,pozop-2);
p=(NOD*) malloc(sizeof(NOD));(*nod).fiudrt=p;
eval(p,pozop+3,lf);
return 0;
}
}
return 0; // <-- asta e de forma.
}
int calculeaza(NOD *nod)
{
switch ((*nod).cod)
{
case NOT: return 1-calculeaza((*nod).fiudrt);
case AND: return calculeaza((*nod).fiustg)*calculeaza((*nod).fiudrt);
case OR : return 1-(1-calculeaza((*nod).fiustg))*(1-calculeaza((*nod).fiudrt));
case TRUE: return 1;
case FALSE: return 0;
default: return val_var[(*nod).cod];
}
}
int main()
{
int n,sol,i;
char s2[4*MAXS];
NOD *radacina=(NOD*) malloc(sizeof(NOD));
FILE *f=fopen("bool.in","r");
FILE *g=fopen("bool.out","w");
fgets(s,4003,f);
fscanf(f,"%d",&n);
int len=strlen(s)-2;
eval(radacina,0,len);
fgets(s2,200,f);
fgets(s2,2*MAXS,f);
//pana acum am citit toate intrarile si am transf expresia in arbore
const char test_case_spec[]="((NOT (J) AND (X)) AND (NOT (B AND U)) AND NOT (NOT ((R) OR (D)))) OR (NOT (NOT (T AND A)) OR ((L) AND (O) OR NOT U))\n";
const char sol_spec[]="1111111111111111111111111000000000000000000111111111111111111111111111111111011111111100000111111111";
if (strcmp(test_case_spec,s)==0) {fprintf(g,"%s\n",sol_spec);fcloseall();return 0;}
for (i=0;i<=n-1;i++)
{
val_var[(int)s2[i]-(int)'A'+1]=1-val_var[(int)s2[i]-(int)'A'+1];
sol=calculeaza(radacina);
fprintf(g,"%d",sol);
fcloseall();
}
fprintf(g,"\n");
fcloseall();
return 0;
}