#include <bits/stdc++.h>
using namespace std;
const int MAX_N = (int)1e5 + 123;
const int inf = (int)1e9 + 123;
struct edge {
  int from, to, flow, cap;
};
vector<edge> q;
vector<int> g[MAX_N];
int nn;
void add_edge(int u, int v, int cap) {
  g[u].push_back(int((q).size()));
  q.push_back(edge({u, v, 0, cap}));
  g[v].push_back(int((q).size()));
  q.push_back(edge({v, u, 0, 0}));
}
queue<int> Q;
int d[MAX_N];
bool bfs(int second, int t) {
  for (int i = 0; i < nn; i++) d[i] = inf;
  d[second] = 0;
  Q.push(second);
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    for (auto i : g[v])
      if (q[i].flow < q[i].cap && d[q[i].to] > d[v] + 1) {
        d[q[i].to] = d[v] + 1;
        Q.push(q[i].to);
      }
  }
  return (d[t] != inf);
}
int ptr[MAX_N];
int dfs(int v, int target, int cur_min = inf) {
  if (v == target) return cur_min;
  while (ptr[v] < int((g[v]).size())) {
    int id = g[v][ptr[v]];
    if (d[q[id].to] == d[v] + 1 && q[id].flow < q[id].cap) {
      int now = dfs(q[id].to, target, min(cur_min, q[id].cap - q[id].flow));
      if (now) {
        q[id].flow += now;
        q[id ^ 1].flow -= now;
        return now;
      }
    }
    ptr[v]++;
  }
  return 0;
}
int max_flow(int second, int t) {
  int res = 0;
  while (bfs(second, t)) {
    for (int i = 0; i < nn; i++) ptr[i] = 0;
    while (1) {
      int now = dfs(second, t);
      if (!now) break;
      res += now;
    }
  }
  return res;
}
int n, m, G;
int tp[MAX_N], v[MAX_N];
int need[MAX_N], w[MAX_N], good[MAX_N];
int main() {
  scanf("%d%d%d", &n, &m, &G);
  for (int i = 0; i < n; i++) scanf("%d", &tp[i]);
  for (int i = 0; i < n; i++) {
    scanf("%d", &v[i]);
    if (!tp[i])
      add_edge(0, i + 1, v[i]);
    else
      add_edge(i + 1, n + m + 1, v[i]);
  }
  int ans = 0;
  for (int i = 0; i < m; i++) {
    int len;
    scanf("%d%d%d", &need[i], &w[i], &len);
    ans += w[i];
    for (int it = 0, j; it < len; it++) {
      scanf("%d", &j);
      j--;
      if (need[i] == 1)
        add_edge(j + 1, n + i + 1, inf);
      else
        add_edge(n + i + 1, j + 1, inf);
    }
    scanf("%d", &good[i]);
    if (!need[i])
      add_edge(0, n + i + 1, w[i] + (good[i] ? G : 0));
    else
      add_edge(n + i + 1, n + m + 1, w[i] + (good[i] ? G : 0));
  }
  nn = n + m + 2;
  printf("%d", ans - max_flow(0, n + m + 1));
  return 0;
}
