#include <bits/stdc++.h>
using namespace std;
const int AND = 0, OR = 1, NAND = 2, NOR = 3, N = 111;
int n, m, k, a[N][3], b[N][3], ord[N], ordSz, col[N], C;
string s;
vector<int> g[N];
bool st[N], used[N], oldUsed[N];
long long G[N];
int readType() {
  cin >> s;
  if (s == "and") return AND;
  if (s == "or") return OR;
  if (s == "nand") return NAND;
  if (s == "nor") return NOR;
  throw;
}
void read() {
  cin >> n >> m >> k;
  for (int i = 0; i < m; i++) {
    a[i][0] = readType();
    cin >> s;
    int p = 1;
    for (int j = 0; j < n; j++)
      if (s[j] == 'x') a[i][p++] = j;
  }
  for (int i = 0; i < k; i++) {
    b[i][0] = readType();
    cin >> s;
    int p = 1;
    for (int j = 0; j < m; j++)
      if (s[j] == 'x') b[i][p++] = j;
  }
}
void addEdge(int v, int u) {
  g[v ^ 1].push_back(u);
  g[u ^ 1].push_back(v);
}
void addGraph(int v, int tp) {
  tp = a[v][0] ^ (tp << 1);
  if (tp == 0) {
    st[2 * a[v][1] + 1] = 1;
    st[2 * a[v][2] + 1] = 1;
  } else if (tp == 1)
    addEdge(2 * a[v][1] + 1, 2 * a[v][2] + 1);
  else if (tp == 2)
    addEdge(2 * a[v][1], 2 * a[v][2]);
  else if (tp == 3) {
    st[2 * a[v][1]] = 1;
    st[2 * a[v][2]] = 1;
  }
}
void dfsMark(int v) {
  used[v] = 1;
  for (int u : g[v])
    if (!used[u]) dfsMark(u);
}
bool checkUsed() {
  for (int i = 0; i < n; i++)
    if (used[2 * i] && used[2 * i + 1]) return false;
  return true;
}
bool checkSAT(long long MASK) {
  for (int i = 0; i < 2 * n; i++) {
    g[i].clear();
    st[i] = 0;
    used[i] = 0;
  }
  for (int i = 0; i < k; i++) {
    if (((MASK >> i) & 1) == 0) continue;
    for (int j = 1; j < 3; j++) addGraph(b[i][j], (int)(b[i][0] < 2));
  }
  for (int i = 0; i < 2 * n; i++)
    if (st[i]) dfsMark(i);
  if (!checkUsed()) return false;
  for (int i = 0; i < n; i++) {
    if (used[2 * i] || used[2 * i + 1]) continue;
    for (int j = 0; j < 2 * n; j++) oldUsed[j] = used[j];
    dfsMark(2 * i);
    if (checkUsed()) continue;
    for (int j = 0; j < 2 * n; j++) used[j] = oldUsed[j];
    dfsMark(2 * i + 1);
    if (!checkUsed()) return false;
  }
  return checkUsed();
}
int intVar[10], cntVar;
bool oper(int t, bool v1, bool v2) {
  bool res = 0;
  if (t >= 2) {
    t ^= 2;
    res ^= 1;
  }
  if (t == AND)
    return res ^ (v1 && v2);
  else
    return res ^ (v1 || v2);
}
bool getValConst(int v, int MASK) {
  for (int i = 0; i < cntVar; i++)
    if (intVar[i] == v) return (MASK >> i) & 1;
  throw;
}
bool getValA1(int v, int MASK) {
  return oper(a[v][0], getValConst(a[v][1], MASK), getValConst(a[v][2], MASK));
}
bool getValA2(int v, int MASK) {
  return oper(a[v][0] ^ 2, getValConst(a[v][1], MASK),
              getValConst(a[v][2], MASK));
}
bool getValB1(int v, int MASK) {
  return oper(b[v][0], getValA1(b[v][1], MASK), getValA1(b[v][2], MASK));
}
bool getValB2(int v, int MASK) {
  return oper(b[v][0] ^ 2, getValA2(b[v][1], MASK), getValA2(b[v][2], MASK));
}
bool solve(int id1, int id2) {
  cntVar = 0;
  for (int i = 1; i < 3; i++)
    for (int j = 1; j < 3; j++) {
      intVar[cntVar++] = a[b[id1][i]][j];
      intVar[cntVar++] = a[b[id2][i]][j];
    }
  sort(intVar, intVar + cntVar);
  cntVar = unique(intVar, intVar + cntVar) - intVar;
  for (int MASK = 0; MASK < (1 << cntVar); MASK++) {
    if (getValB1(id1, MASK) && getValB2(id2, MASK)) return true;
  }
  return false;
}
bool isGoodMask(long long MASK) { return !checkSAT(MASK); }
void eraseFromG(int v, int u) {
  if ((G[v] >> u) & 1) G[v] ^= 1LL << u;
}
int ANS = 0;
void brute(int curAns, long long curMask, long long cand, long long already) {
  if (cand == 0) {
    if (isGoodMask(curMask)) ANS = max(ANS, curAns);
    return;
  }
  bool ok = true;
  for (int i = 0; ok && i < k; i++) {
    if (((already >> i) & 1) == 0) continue;
    if ((G[i] & cand) == cand) ok = false;
  }
  if (!ok) return;
  for (int v = 0; (1LL << v) <= cand; v++) {
    if (((cand >> v) & 1) == 0) continue;
    brute(curAns + 1, curMask | (1LL << v), (cand & G[v]) ^ (1LL << v),
          already & G[v]);
    already |= 1LL << v;
    cand ^= 1LL << v;
  }
}
int main() {
  read();
  for (int i = 0; i < k; i++) G[i] = (1LL << k) - 1;
  for (int i = 0; i < k; i++)
    for (int j = 0; j < k; j++)
      if (solve(i, j)) {
        eraseFromG(i, j);
        eraseFromG(j, i);
      }
  long long all = 0;
  for (int i = 0; i < k; i++) {
    if (((G[i] >> i) & 1) == 0) continue;
    all |= 1LL << i;
  }
  brute(0, 0, all, 0);
  if (ANS == 0)
    cout << -1 << endl;
  else
    cout << k - ANS << endl;
  return 0;
}

### Prompt

Please provide a CPP coded solution to the problem described below:

Hibiki and Dita are in love with each other, but belong to communities that are in a long lasting conflict. Hibiki is deeply concerned with the state of affairs, and wants to figure out if his relationship with Dita is an act of love or an act of treason.

<image>

Hibiki prepared several binary features his decision will depend on, and built a three layer logical circuit on top of them, each layer consisting of one or more [logic gates](https://en.wikipedia.org/wiki/Logic_gate). Each gate in the circuit is either "or", "and", "nor" (not or) or "nand" (not and). Each gate in the first layer is connected to exactly two features. Each gate in the second layer is connected to exactly two gates in the first layer. The third layer has only one "or" gate, which is connected to all the gates in the second layer (in other words, the entire circuit produces 1 if and only if at least one gate in the second layer produces 1).

The problem is, Hibiki knows very well that when the person is in love, his ability to think logically degrades drastically. In particular, it is well known that when a person in love evaluates a logical circuit in his mind, every gate evaluates to a value that is the opposite of what it was supposed to evaluate to. For example, "or" gates return 1 if and only if both inputs are zero, "t{nand}" gates produce 1 if and only if both inputs are one etc.

In particular, the "or" gate in the last layer also produces opposite results, and as such if Hibiki is in love, the entire circuit produces 1 if and only if all the gates on the second layer produced 0.

Hibiki can’t allow love to affect his decision. He wants to know what is the smallest number of gates that needs to be removed from the second layer so that the output of the circuit for all possible inputs doesn't depend on whether Hibiki is in love or not.

Input

The first line contains three integers n, m, k (2 ≤ n, m ≤ 50; 1 ≤ k ≤ 50) — the number of input features, the number of gates in the first layer, and the number of gates in the second layer correspondingly.

The second line contains m pairs of strings separated by spaces describing the first layer. The first string in each pair describes the gate ("and", "or", "nand" or "nor"), and the second string describes the two input features the gate is connected two as a string consisting of exactly n characters, with exactly two characters (that correspond to the input features the gate is connected to) equal to 'x' and the remaining characters equal to ".'.

The third line contains k pairs of strings separated by spaces describing the second layer in the same format, where the strings that describe the input parameters have length m and correspond to the gates of the first layer.

Output

Print the number of gates that need to be removed from the second layer so that the output of the remaining circuit doesn't depend on whether Hibiki is in love or not.

If no matter how many gates are removed the output of the circuit continues to depend on Hibiki's feelings, print -1.

Examples

Input

2 2 2
and xx nand xx
and xx or xx


Output

1


Input

3 2 2
and xx. nor .xx
and xx nor xx


Output

-1


Input

4 4 5
nor x..x and ..xx and xx.. nand xx..
nand ..xx nor ..xx and xx.. nor ..xx or ..xx


Output

2

Note

In the first example the two gates in the first layer are connected to the same inputs, but first computes "and" while second computes "nand", and as such their output is always different no matter what the input is and whether Hibiki is in love or not. The second layer has "or" and "and" gates both connected to the two gates in the first layer. If Hibiki is not in love, the "and" gate will produce 0 and the "or" gate will produce 1 no matter what input features are equal to, with the final "or" gate in the third layer always producing the final answer of 1. If Hibiki is in love, "and" gate in the second layer will produce 1 and "or" gate will produce 0 no matter what the input is, with the final "or" gate in the third layer producing the final answer of 0. Thus, if both gates in the second layer are kept, the output of the circuit does depend on whether Hibiki is in love. If any of the two gates in the second layer is dropped, the output of the circuit will no longer depend on whether Hibiki is in love or not, and hence the answer is 1.

In the second example no matter what gates are left in the second layer, the output of the circuit will depend on whether Hibiki is in love or not.

In the third example if Hibiki keeps second, third and fourth gates in the second layer, the circuit will not depend on whether Hibiki is in love or not. Alternatively, he can keep the first and the last gates. The former requires removing two gates, the latter requires removing three gates, so the former is better, and the answer is 2.

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
const int AND = 0, OR = 1, NAND = 2, NOR = 3, N = 111;
int n, m, k, a[N][3], b[N][3], ord[N], ordSz, col[N], C;
string s;
vector<int> g[N];
bool st[N], used[N], oldUsed[N];
long long G[N];
int readType() {
  cin >> s;
  if (s == "and") return AND;
  if (s == "or") return OR;
  if (s == "nand") return NAND;
  if (s == "nor") return NOR;
  throw;
}
void read() {
  cin >> n >> m >> k;
  for (int i = 0; i < m; i++) {
    a[i][0] = readType();
    cin >> s;
    int p = 1;
    for (int j = 0; j < n; j++)
      if (s[j] == 'x') a[i][p++] = j;
  }
  for (int i = 0; i < k; i++) {
    b[i][0] = readType();
    cin >> s;
    int p = 1;
    for (int j = 0; j < m; j++)
      if (s[j] == 'x') b[i][p++] = j;
  }
}
void addEdge(int v, int u) {
  g[v ^ 1].push_back(u);
  g[u ^ 1].push_back(v);
}
void addGraph(int v, int tp) {
  tp = a[v][0] ^ (tp << 1);
  if (tp == 0) {
    st[2 * a[v][1] + 1] = 1;
    st[2 * a[v][2] + 1] = 1;
  } else if (tp == 1)
    addEdge(2 * a[v][1] + 1, 2 * a[v][2] + 1);
  else if (tp == 2)
    addEdge(2 * a[v][1], 2 * a[v][2]);
  else if (tp == 3) {
    st[2 * a[v][1]] = 1;
    st[2 * a[v][2]] = 1;
  }
}
void dfsMark(int v) {
  used[v] = 1;
  for (int u : g[v])
    if (!used[u]) dfsMark(u);
}
bool checkUsed() {
  for (int i = 0; i < n; i++)
    if (used[2 * i] && used[2 * i + 1]) return false;
  return true;
}
bool checkSAT(long long MASK) {
  for (int i = 0; i < 2 * n; i++) {
    g[i].clear();
    st[i] = 0;
    used[i] = 0;
  }
  for (int i = 0; i < k; i++) {
    if (((MASK >> i) & 1) == 0) continue;
    for (int j = 1; j < 3; j++) addGraph(b[i][j], (int)(b[i][0] < 2));
  }
  for (int i = 0; i < 2 * n; i++)
    if (st[i]) dfsMark(i);
  if (!checkUsed()) return false;
  for (int i = 0; i < n; i++) {
    if (used[2 * i] || used[2 * i + 1]) continue;
    for (int j = 0; j < 2 * n; j++) oldUsed[j] = used[j];
    dfsMark(2 * i);
    if (checkUsed()) continue;
    for (int j = 0; j < 2 * n; j++) used[j] = oldUsed[j];
    dfsMark(2 * i + 1);
    if (!checkUsed()) return false;
  }
  return checkUsed();
}
int intVar[10], cntVar;
bool oper(int t, bool v1, bool v2) {
  bool res = 0;
  if (t >= 2) {
    t ^= 2;
    res ^= 1;
  }
  if (t == AND)
    return res ^ (v1 && v2);
  else
    return res ^ (v1 || v2);
}
bool getValConst(int v, int MASK) {
  for (int i = 0; i < cntVar; i++)
    if (intVar[i] == v) return (MASK >> i) & 1;
  throw;
}
bool getValA1(int v, int MASK) {
  return oper(a[v][0], getValConst(a[v][1], MASK), getValConst(a[v][2], MASK));
}
bool getValA2(int v, int MASK) {
  return oper(a[v][0] ^ 2, getValConst(a[v][1], MASK),
              getValConst(a[v][2], MASK));
}
bool getValB1(int v, int MASK) {
  return oper(b[v][0], getValA1(b[v][1], MASK), getValA1(b[v][2], MASK));
}
bool getValB2(int v, int MASK) {
  return oper(b[v][0] ^ 2, getValA2(b[v][1], MASK), getValA2(b[v][2], MASK));
}
bool solve(int id1, int id2) {
  cntVar = 0;
  for (int i = 1; i < 3; i++)
    for (int j = 1; j < 3; j++) {
      intVar[cntVar++] = a[b[id1][i]][j];
      intVar[cntVar++] = a[b[id2][i]][j];
    }
  sort(intVar, intVar + cntVar);
  cntVar = unique(intVar, intVar + cntVar) - intVar;
  for (int MASK = 0; MASK < (1 << cntVar); MASK++) {
    if (getValB1(id1, MASK) && getValB2(id2, MASK)) return true;
  }
  return false;
}
bool isGoodMask(long long MASK) { return !checkSAT(MASK); }
void eraseFromG(int v, int u) {
  if ((G[v] >> u) & 1) G[v] ^= 1LL << u;
}
int ANS = 0;
void brute(int curAns, long long curMask, long long cand, long long already) {
  if (cand == 0) {
    if (isGoodMask(curMask)) ANS = max(ANS, curAns);
    return;
  }
  bool ok = true;
  for (int i = 0; ok && i < k; i++) {
    if (((already >> i) & 1) == 0) continue;
    if ((G[i] & cand) == cand) ok = false;
  }
  if (!ok) return;
  for (int v = 0; (1LL << v) <= cand; v++) {
    if (((cand >> v) & 1) == 0) continue;
    brute(curAns + 1, curMask | (1LL << v), (cand & G[v]) ^ (1LL << v),
          already & G[v]);
    already |= 1LL << v;
    cand ^= 1LL << v;
  }
}
int main() {
  read();
  for (int i = 0; i < k; i++) G[i] = (1LL << k) - 1;
  for (int i = 0; i < k; i++)
    for (int j = 0; j < k; j++)
      if (solve(i, j)) {
        eraseFromG(i, j);
        eraseFromG(j, i);
      }
  long long all = 0;
  for (int i = 0; i < k; i++) {
    if (((G[i] >> i) & 1) == 0) continue;
    all |= 1LL << i;
  }
  brute(0, 0, all, 0);
  if (ANS == 0)
    cout << -1 << endl;
  else
    cout << k - ANS << endl;
  return 0;
}

```