#include <iostream>
#include <fstream>
#include <map>
#include <cassert>
using namespace std;
ifstream in("bool.in");
ofstream out("bool.out");
struct tree {
char val;
tree *left;
tree *right;
};
int const prmax = 3; //number of priority levels of the operators
int const nmax = 1001;
map<string, char> f;
map<char, int> prio;
map<char, bool> value;
char ex[nmax]; //expression to be evaluated
int n; //number of elements in clean expression
tree *root; //binary tree corresponding to the given expression
int open[nmax], closed[nmax];
//when traversing the expression and reaching index i, open[i] & closed[i] = no. of open & closed brackets encountered so far
int nextop[prmax][nmax], prevop[prmax][nmax];
void read() {
f["NOT"] = '!';
f["AND"] = '&';
f["OR"] = '|';
f["TRUE"] = '1';
f["FALSE"] = '2';
prio['|'] = 0;
prio['&'] = 1;
prio['!'] = 2;
char line[nmax];
in.getline(line, nmax);
char word[nmax];
int wordp = 0, exp = 0; //pointers in word and expression
int i = 0;
while (line[i] != '\0') {
if (line[i] == ' ' || line[i] == '(' || line[i] == ')') {
//add word from stack first
if (0 < wordp) {
if (1 < wordp) { //special word
word[wordp] = '\0'; //end word
ex[exp] = f[word];
} else { //just a letter
ex[exp] = word[0];
value[word[0]] = false;
}
wordp = 0; //clear stack
exp++;
}
//then add the bracket, or just ignore the white space
if (line[i] == '(' || line[i] == ')') {
ex[exp] = line[i];
exp++;
}
} else {
word[wordp] = line[i];
wordp++;
}
i++;
}
if (0 < wordp) {
if (1 < wordp) { //special word
word[wordp] = '\0'; //end word
ex[exp] = f[word];
} else { //just a letter
ex[exp] = word[0];
value[word[0]] = false;
}
wordp = 0; //clear word
exp++;
}
ex[exp] = '\0'; //end expression
value['1'] = true; //everything else is false in the beginning
n = exp;
}
int inc(int x, int from, int to) {
return (from < to) ? (x + 1) : (x - 1);
}
bool inside(int x, int from, int to) {
return (from < to) ? (x <= to) : (to <= x);
}
char openbr(int from, int to) {
return (from < to) ? '(' : ')';
}
char closedbr(int from, int to) {
return (from < to) ? ')' : '(';
}
void analyzeexpression(char *ex, int from, int to, int *open, int *closed, int prevop[prmax][nmax]) {
int lastop[prmax][nmax];
for (int i = 0; i < prmax; i++) {
for (int j = 0; j < n; j++) {
lastop[i][j] = -1;
prevop[i][j] = -1;
open[j] = closed[j] = 0;
}
}
int j = from;
while (inside(j, from, to)) {
if (ex[j] == openbr(from, to)) {
for (int i = 0; i < prmax; i++) {
prevop[i][j] = lastop[i][open[j] - closed[j]];
}
open[j]++;
} else if (ex[j] == closedbr(from, to)) {
closed[j]++;
for (int i = 0; i < prmax; i++) {
prevop[i][j] = lastop[i][open[j] - closed[j]];
}
} else { //operator, character or a number
for (int i = 0; i < prmax; i++) {
prevop[i][j] = lastop[i][open[j] - closed[j]];
}
if (!(prio.find(ex[j]) == prio.end())) { //if an operator
lastop[prio[ex[j]]][open[j] - closed[j]] = j;
}
}
open[inc(j, from, to)] = open[j];
closed[inc(j, from, to)] = closed[j];
j = inc(j, from, to);
}
}
bool hasbigbrackets(int from, int to) {
bool result = false;
if (ex[from] == '(' && ex[to] == ')' && (prevop[0][to] < 0 || prevop[0][to] < from)) {
if (ex[from] != '!' && (nextop[1][from] < 0 || to < nextop[1][from])) {
result = true;
}
}
return result;
}
tree* buildtree(int from, int to) { //1 A B 0
//(1|2)&(3|4)
tree *result = nullptr;;
//1 +2 +(3 +4)+5
if(prevop[0][to] < from && prevop[1][to] < from && prevop[2][to] < from && from != to) {
result = buildtree(from + 1, to - 1);
} else if(from == to){
result = new tree(); // 10001 - 20001; 10001 - 15001; 17345 -> result
result->val = ex[from];
result->left = nullptr;
result->right = nullptr;
//cout<<":";
} else {
if(from <= prevop[0][to]){ ///1+2+(3+4)+5
///il luam
result = new tree(); /// 10001 - 20001; 10001 - 15001; 17345 -> result
result->val = ex[prevop[0][to]];
///il despartim
result->left = buildtree(from, prevop[0][to]-1); //3+5
//cout<<":";
result->right = buildtree(prevop[0][to]+1 ,to);
//cout<<"|";
} else if(from <= prevop[1][to]){
///il luam
result = new tree(); /// 10001 - 20001; 10001 - 15001; 17345 -> result
result->val = ex[prevop[1][to]];
///il despartim
// cout<<"->("<<from<<", "<<to<<")"<<endl;
// cout<<from<<" "<<prevop[1][to]-1<<endl;
result->left = buildtree(from, prevop[1][to]-1); //3+5
//cout<<prevop[1][to]+1<<" "<<to<<endl;
result->right = buildtree(prevop[1][to]+1 ,to);
} else if (from <= prevop[2][to]) { //avem !!!A
// cout<<ex[from]<<" "<<from<<" "<<to<<'\n';
assert(ex[from] == '!');
result = new tree(); // 10001 - 20001; 10001 - 15001; 17345 -> result
result->val = ex[from];
result->left = nullptr;
result->right = buildtree(from + 1 ,to);
} else
while(true);
}
return result;
}
/*
tree *buildtree(int from, int to) {
tree *node;
if (hasbigbrackets(from, to)) {
node = buildtree(from + 1, to - 1);
} else if (from == to) {
node = new tree{
ex[from],
nullptr,
nullptr};
} else { //for sure I have an operator here
if (from < prevop[0][to]) {
node = new tree{
ex[prevop[0][to]],
buildtree(from, prevop[0][to] - 1),
buildtree(prevop[0][to] + 1, to)};
} else if (from < prevop[1][to]) {
node = new tree{
ex[prevop[1][to]],
buildtree(from, prevop[1][to] - 1),
buildtree(prevop[1][to] + 1, to)};
} else if (ex[from] == '!') {
node = new tree{
ex[from],
nullptr,
buildtree(from + 1, to)
};
} else {
while(true);
}
}
return node;
}
*/
bool evaltree(tree *node) {
bool result;
if (node->val == '!') {
result = !evaltree(node->right);
} else if (node->val == '&') {
result = evaltree(node->left) & evaltree(node->right);
} else if (node->val == '|') {
result = evaltree(node->left) | evaltree(node->right);
} else {
result = value[node->val];
}
return result;
}
int main() {
read();
analyzeexpression(ex, 0, n - 1, open, closed, prevop);
analyzeexpression(ex, n - 1, 0, open, closed, nextop);
root = buildtree(0, n - 1);
int nquery;
in >> nquery;
char letter;
for (int i = 0; i < nquery; i++) {
in >> letter;
value[letter] = !value[letter];
out << (int) evaltree(root);
}
out<<endl;
return 0;
}