#include <bits/stdc++.h>
const int op_and = 0, op_or = 1, op_nand = 2, op_nor = 3;
int func(int o, int x, int y) {
  switch (o) {
    case op_and:
      return x & y;
    case op_or:
      return x | y;
    case op_nand:
      return !(x & y);
    case op_nor:
      return !(x | y);
  }
}
int get_op() {
  char op[5];
  scanf("%s", op);
  if (*op == 'a') return op_and;
  if (*op == 'o') return op_or;
  if (op[1] == 'a') return op_nand;
  return op_nor;
}
void get_ch(int* c) {
  char s[55];
  scanf("%s", s);
  for (int i = 0, j = 0; s[i]; i++)
    if (s[i] == 'x') c[j++] = i;
}
int n, m, k, op1[55], ch1[55][2], op2[55], ch2[55][2];
long long G[55];
int tmp[55], ans;
struct edge {
  int to;
  edge* next;
} E[210], *ne, *fir[110];
void link(int u, int v) {
  *ne = (edge){v, fir[u]};
  fir[u] = ne++;
}
int dfn[110], low[110], now, stk[110], top, scc[110], scnt;
void cmin(int& a, int b) { b < a ? a = b : 1; }
bool dfs(int i) {
  dfn[i] = low[i] = ++now;
  stk[top++] = i;
  for (edge* e = fir[i]; e; e = e->next) {
    if (!dfn[e->to]) {
      if (dfs(e->to)) return 1;
      cmin(low[i], low[e->to]);
    } else if (!scc[e->to])
      cmin(low[i], dfn[e->to]);
  }
  if (low[i] == dfn[i]) {
    int x;
    scnt++;
    do {
      x = stk[--top];
      scc[x] = scnt;
      if (scc[x] == scc[x < n ? x + n : x - n]) return 1;
    } while (x != i);
  }
  return 0;
}
bool chk(long long T) {
  for (int i = 0; i < n * 2; i++) fir[i] = 0, dfn[i] = scc[i] = 0;
  ne = E, now = top = scnt = 0;
  for (int i = 0; i < k; i++)
    if (T >> i & 1) {
      for (int j = 0; j < 2; j++) {
        int v = ch2[i][j], ty = op2[i] >> 1 ^ op1[v] >> 1;
        if ((op1[v] & 1) == ty) {
          link(ch1[v][0] + n * (1 - ty), ch1[v][1] + n * ty);
          link(ch1[v][1] + n * (1 - ty), ch1[v][0] + n * ty);
        } else {
          link(ch1[v][0] + n * (1 - ty), ch1[v][0] + n * ty);
          link(ch1[v][1] + n * (1 - ty), ch1[v][1] + n * ty);
        }
      }
    }
  for (int i = 0; i < n * 2; i++)
    if (!dfn[i] && dfs(i)) return 1;
  return 0;
}
void dfs(long long S, long long T, long long U) {
  int u = 0, d = n + 1;
  for (int i = 0; i < k; i++)
    if ((S | U) >> i & 1) {
      int c = __builtin_popcountll((G[i] | 1ll << i) & S);
      if (c < d) u = i, d = c;
    }
  long long s = (G[u] | 1ll << u) & S;
  for (int i = 0; i < k; i++)
    if (s >> i & 1) {
      S &= ~(1ll << i);
      dfs(S & ~G[i], T | 1ll << i, U & ~G[i]);
      U |= 1ll << i;
    }
  if (d > n) {
    int c = __builtin_popcountll(T);
    if (c > ans && chk(T)) ans = c;
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    op1[i] = get_op();
    get_ch(ch1[i]);
  }
  for (int i = 0; i < k; i++) {
    op2[i] = get_op();
    get_ch(ch2[i]);
  }
  for (int i = 0; i < k; i++) {
    for (int j = 0; j < k; j++) {
      bool fl = 0;
      for (int st = 0; st < 1 << 8 && !fl; st++) {
        for (int u = 0; u < 4; u++) {
          tmp[ch1[ch2[i][u >> 1]][u & 1]] = st >> u & 1;
          tmp[ch1[ch2[j][u >> 1]][u & 1]] = st >> u + 4 & 1;
        }
        int ci0 = ch2[i][0], ci1 = ch2[i][1], cj0 = ch2[j][0], cj1 = ch2[j][1];
        if (func(op2[i], func(op1[ci0], tmp[ch1[ci0][0]], tmp[ch1[ci0][1]]),
                 func(op1[ci1], tmp[ch1[ci1][0]], tmp[ch1[ci1][1]])) &&
            func(op2[j] ^ 2,
                 func(op1[cj0] ^ 2, tmp[ch1[cj0][0]], tmp[ch1[cj0][1]]),
                 func(op1[cj1] ^ 2, tmp[ch1[cj1][0]], tmp[ch1[cj1][1]])))
          fl = 1;
      }
      if (fl) G[i] |= 1ll << j, G[j] |= 1ll << i;
    }
  }
  long long S = 0;
  for (int i = 0; i < k; i++)
    if (!(G[i] >> i & 1)) S |= 1ll << i;
  ans = -1;
  dfs(S, 0, 0);
  printf("%d\n", ans < 0 ? -1 : k - ans);
}
