#include <bits/stdc++.h>
using namespace std;
bool debug = 0;
int n, m, k;
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
long long ln, lk, lm;
void add(int &x, long long y) {
  while (y >= 1000000007) y -= 1000000007;
  x += y;
  while (x >= 1000000007) x -= 1000000007;
}
inline void FWT(int *A, const int fla, int lenth) {
  for (int i = 1; i < lenth; i <<= 1)
    for (int j = 0; j < lenth; j += (i << 1))
      for (int k = 0; k < i; k++) {
        if (fla == 1)
          add(A[j + k + i], A[j + k]);
        else
          add(A[j + k + i], 1000000007 - A[j + k]);
      }
}
inline void FWT_and(int *A, const int fla, int lenth) {
  for (int i = 1; i < lenth; i <<= 1)
    for (int j = 0; j < lenth; j += (i << 1))
      for (int k = 0; k < i; k++) {
        if (fla == 1)
          add(A[j + k], A[j + k + i]);
        else
          add(A[j + k], 1000000007 - A[j + k + i]);
      }
}
char s[505];
const int MN = 1 << 16;
int pos, dp[200][MN], cnt;
string vars = "ABCDabcd", opes = "&|";
int buildMask(int i) {
  int r = 0;
  for (int(j) = 0; (j) < (int)(16); (j)++)
    if ((j >> i) & 1) r |= 1 << j;
  return r;
}
int tr[MN], tl[MN], tmp[2][MN];
void sumSub(const int *ori, int *ret, bool fg) {
  for (int(i) = 0; (i) < (int)(MN); (i)++) ret[i] = ori[i];
  for (int(i) = 0; (i) < (int)(16); (i)++) {
    for (int mask = 0; mask < (1 << 16); mask++) {
      if (~mask & (1 << i)) {
        if (fg)
          add(ret[mask ^ (1 << i)], (long long)ret[mask]);
        else
          add(ret[mask ^ (1 << i)], 1000000007 - ret[mask]);
      }
    }
  }
}
void cal(const int *dl, const int *dr, int *x) {
  sumSub(dl, tl, 1);
  sumSub(dr, tr, 1);
  for (int(i) = 0; (i) < (int)(MN); (i)++)
    tl[i] = (long long)tl[i] * tr[i] % 1000000007;
  sumSub(tl, x, 0);
}
void neg(int *x) { reverse(x, x + MN); }
int build() {
  if (s[pos] != '(') {
    int v = vars.find(s[pos]);
    if (v == -1) {
      for (int(j) = 0; (j) < (int)(4); (j)++) {
        dp[cnt][buildMask(j)] = 1;
        dp[cnt][buildMask(j) ^ ((1 << 16) - 1)] = 1;
      }
    } else {
      if (v < 4)
        dp[cnt][buildMask(v)] = 1;
      else
        dp[cnt][buildMask(v - 4) ^ ((1 << 16) - 1)] = 1;
    }
    pos++;
    return cnt++;
  }
  pos++;
  int node = cnt++;
  int l = build();
  assert(s[pos] == ')');
  pos++;
  int o = opes.find(s[pos++]);
  assert(s[pos++] == '(');
  int r = build();
  assert(s[pos++] == ')');
  for (int(i) = 0; (i) < (int)(MN); (i)++) tl[i] = dp[l][i];
  FWT(tl, 1, MN);
  for (int(i) = 0; (i) < (int)(MN); (i)++) tr[i] = dp[r][i];
  FWT(tr, 1, MN);
  for (int(i) = 0; (i) < (int)(MN); (i)++)
    tmp[1][i] = (long long)tl[i] * tr[i] % 1000000007;
  FWT(tmp[1], -1, MN);
  for (int(i) = 0; (i) < (int)(MN); (i)++) tl[i] = dp[l][i];
  FWT_and(tl, 1, MN);
  for (int(i) = 0; (i) < (int)(MN); (i)++) tr[i] = dp[r][i];
  FWT_and(tr, 1, MN);
  for (int(i) = 0; (i) < (int)(MN); (i)++)
    tmp[0][i] = (long long)tl[i] * tr[i] % 1000000007;
  FWT_and(tmp[0], -1, MN);
  if (o == string::npos) {
    for (int(i) = 0; (i) < (int)(MN); (i)++)
      add(dp[node][i], (long long)tmp[0][i] + tmp[1][i]);
  } else {
    for (int(i) = 0; (i) < (int)(MN); (i)++) add(dp[node][i], tmp[o][i]);
  }
  return node;
}
int req[22];
void fmain() {
  scanf("%s", s);
  int rt = build();
  scanf("%d", &n);
  memset(req, -1, sizeof req);
  for (int a, i = 0; i < n; i++) {
    int id = 0;
    for (int(j) = 0; (j) < (int)(4); (j)++) {
      scanf("%d", &a);
      if (a == 1) id |= 1 << j;
    }
    scanf("%d", &req[id]);
  }
  int ans = 0;
  for (int(i) = 0; (i) < (int)(MN); (i)++) {
    bool fg = 1;
    for (int(j) = 0; (j) < (int)(16); (j)++) {
      fg &= (req[j] == -1 || req[j] == ((i >> j) & 1));
    }
    if (fg) add(ans, dp[rt][i]);
  }
  printf("%d\n", ans);
}
int main() {
  fmain();
  return 0;
}
