#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Node{
	int num,left_child,right_child,code_id,order;
};

Node nodes[200];
int nodes_index,setsu_num,codes[200][16];

char buf[200];
int length,POW[4] = {1,2,4,8};

void recursive(int left,int right,int parent_index){
	int depth = 0;
	int count = 0;

	for(int i = left; i <= right;){

		if(depth == 0 && buf[i] == '('){
			depth = 1;

			for(int k = i+1; k <= right; k++){
				if(buf[k] == '('){
					depth++;
				}else if(buf[k] == ')'){
					depth--;
					if(depth == 0){
						if(count == 0){
							nodes[parent_index].left_child = nodes_index;
							nodes_index++;
							recursive(i+1,k-1,nodes_index-1);
							count++;
							i = k+2;
						}else{
							nodes[parent_index].right_child = nodes_index;
							nodes_index++;
							recursive(i+1,k-1,nodes_index-1);
							i = k+1;
						}
						break;
					}
				}
			}

		}else if(buf[i] >= '1' && buf[i] <= '9'){

			int code_id = buf[i]-'0';

			if(count == 0){
				nodes[parent_index].left_child = nodes_index;
				i += 2;
			}else{
				nodes[parent_index].right_child = nodes_index;
				i += 1;
			}

			nodes[nodes_index].code_id = code_id;
			nodes_index++;
			count++;
		}
	}
}

void calc(int node_id){

	if(nodes[node_id].left_child == -1){

		codes[node_id][nodes[node_id].num]++;

	}else{

		//????????????????¨????
		calc(nodes[node_id].left_child);
		calc(nodes[node_id].right_child);

		int left_table[16],right_table[16];
		for(int i = 0; i < 16; i++){
			left_table[i] = codes[nodes[node_id].left_child][i];
			right_table[i] = codes[nodes[node_id].right_child][i];
		}

		int num_A,num_O,num_X;

		for(int left = 0; left < 16; left++){
			if(left_table[left] == 0)continue;
			for(int right = 0; right < 16; right++){
				if(right_table[right] == 0)continue;

				num_A = num_O = num_X = 0;
				for(int i = 0; i < 4; i++){
					if((left & (1 << i)) != 0 && (right & (1 << i)) != 0){
						num_A += POW[i];
						num_O += POW[i];
					}else if((left & (1 << i)) == 0 && (right & (1 << i)) != 0){
						num_O += POW[i];
						num_X += POW[i];
					}else if((left & (1 << i)) != 0 && (right & (1 << i)) == 0){
						num_O += POW[i];
						num_X += POW[i];
					}
				}

				codes[node_id][num_O] += left_table[left]*right_table[right];

				codes[node_id][num_A] += left_table[left]*right_table[right];

				codes[node_id][num_X] += left_table[left]*right_table[right];
			}
		}
	}
}

void func(){

	for(int i = 0; i < 200; i++){
		nodes[i].left_child = -1;
		nodes[i].right_child = -1;
		nodes[i].num = -1;
		nodes[i].code_id = -1;
	}

	for(length = 0; buf[length] != '\0' && buf[length] != '\n'; length++);

	nodes_index = 1;
	recursive(1,length-2,0);

	int N;
	scanf("%d",&N);

	int tmp[4],table[N+1];

	for(int i = 1; i <= N; i++){
		scanf("%d %d %d %d",&tmp[0],&tmp[1],&tmp[2],&tmp[3]);

		table[i] = POW[3]*tmp[0] + POW[2]*tmp[1] + POW[1]*tmp[2] + POW[0]*tmp[3];
	}

	setsu_num = 0;
	for(int i = 0; i < nodes_index;i++){
		if(nodes[i].code_id != -1){
			nodes[i].num = table[nodes[i].code_id];
		}else{
			setsu_num++;
		}
	}

	for(int i = 0; i < nodes_index; i++){
		for(int k = 0; k < 16; k++)codes[i][k] = 0;
	}

	calc(0);

	printf("%d\n",codes[0][15]);

	getchar();

}

int main(){

	while(true){
		fgets(buf,200,stdin);
		if(buf[0] == 'E')break;

		func();
	}
	return 0;
}

Measured memory_bytes: 3148