#include <bits/stdc++.h>
using namespace std;

const int maxnodes = 12012, inf = 1e9;

int nodes, src, dst;
int level[maxnodes], q[maxnodes], work[maxnodes];

struct edge {
	int to, rev, cap, flow;
};

vector <edge> g[maxnodes];

void init(int _nodes) {
	nodes = _nodes;
	for (int i = 0; i < nodes; i ++) g[i].clear();
}

void add(int x, int y, int w) {
	edge a = {y, g[y].size(), w, 0};
	edge b = {x, g[x].size(), 0, 0};
	g[x].push_back(a);
	g[y].push_back(b);
}

bool bfs() {
	fill(level, level + nodes, -1);
	level[src] = 0;
	int h = 0, t = 0;
	q[t++] = src;
	while (h < t) {
		int u = q[h++];
		for (int j = 0; j < g[u].size(); j++) {
			edge &e = g[u][j];
			int v = e.to;
			if (level[v] < 0 && e.flow < e.cap) {
				level[v] = level[u] + 1;
				q[t++] = v;
			}
		}
	}
	return level[dst] >= 0;
}

int dfs(int u, int f) {
	if (u == dst) return f;
	for (int &i = work[u]; i < g[u].size(); i++) {
		edge &e = g[u][i];
		if (e.cap <= e.flow) continue;
		int v = e.to;
		if (level[v] == level[u] + 1) {
			int df = dfs(v, min(f, e.cap - e.flow));
			if (df > 0) {
				e.flow += df;
				g[v][e.rev].flow -= df;
				return df;
			}
		}
	}
	return 0;
}

int dinic(int _src, int _dst) {
	src = _src, dst = _dst;
	int rlt = 0, flow;
	while (bfs()) {
		fill(work, work + nodes, 0);
		while (flow = dfs(src, inf)) rlt += flow;
	}
	return rlt;
}

#define N 12012
#define M 2020

int n, m, k, male[N], v[N], malelover[M], w[M], cnt[M], idx[M][11], gf[M];

bool enemy(int x, int y) {
	for (int i = 1; i <= cnt[x]; i ++) {
		for (int j = 1; j <= cnt[y]; j ++) if (idx[x][i] == idx[y][j]) return 1;
	}
	return 0;
}

int main() {
//	freopen("e.in", "r", stdin);
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= n; i ++) scanf("%d", &male[i]);
	for (int i = 1; i <= n; i ++) scanf("%d", &v[i]);
	int ans = 0;
	for (int i = 1; i <= m; i ++) {
		scanf("%d %d %d", &malelover[i], &w[i], &cnt[i]);
		for (int j = 1; j <= cnt[i]; j ++) scanf("%d", &idx[i][j]);
		scanf("%d", &gf[i]);
		ans += w[i];
		if (gf[i]) w[i] += k;
	}
	init(n + m + 2);
	int src = 0, dst = n + m + 1;
	for (int i = 1; i <= n; i ++) {
		if (!male[i]) add(src, i, v[i]);
		else add(i, dst, v[i]);
	}
	for (int i = 1; i <= m; i ++) {
		if (!malelover[i]) {
			add(src, n + i, w[i]);
			for (int j = 1; j <= cnt[i]; j ++) {
				if (male[idx[i][j]]) add(n + i, idx[i][j], inf);
			}
		}
		else {
			add(n + i, dst, w[i]);
			for (int j = 1; j <= cnt[i]; j ++) {
				if (!male[idx[i][j]]) add(idx[i][j], n + i, inf);
			}
		}
	}
	for (int i = 1; i <= m; i ++) {
		for (int j = i + 1; j <= m; j ++) if (malelover[i] != malelover[j] && enemy(i, j)) {
			int x = n + i, y = n + j;
			if (malelover[i]) swap(x, y);
			add(x, y, inf);
		}
	}
	printf("%d\n", ans - dinic(src, dst));
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxnodes = 12012, inf = 1e9;

int nodes, src, dst;
int level[maxnodes], q[maxnodes], work[maxnodes];

struct edge {
	int to, rev, cap, flow;
};

vector <edge> g[maxnodes];

void init(int _nodes) {
	nodes = _nodes;
	for (int i = 0; i < nodes; i ++) g[i].clear();
}

void add(int x, int y, int w) {
	edge a = {y, g[y].size(), w, 0};
	edge b = {x, g[x].size(), 0, 0};
	g[x].push_back(a);
	g[y].push_back(b);
}

bool bfs() {
	fill(level, level + nodes, -1);
	level[src] = 0;
	int h = 0, t = 0;
	q[t++] = src;
	while (h < t) {
		int u = q[h++];
		for (int j = 0; j < g[u].size(); j++) {
			edge &e = g[u][j];
			int v = e.to;
			if (level[v] < 0 && e.flow < e.cap) {
				level[v] = level[u] + 1;
				q[t++] = v;
			}
		}
	}
	return level[dst] >= 0;
}

int dfs(int u, int f) {
	if (u == dst) return f;
	for (int &i = work[u]; i < g[u].size(); i++) {
		edge &e = g[u][i];
		if (e.cap <= e.flow) continue;
		int v = e.to;
		if (level[v] == level[u] + 1) {
			int df = dfs(v, min(f, e.cap - e.flow));
			if (df > 0) {
				e.flow += df;
				g[v][e.rev].flow -= df;
				return df;
			}
		}
	}
	return 0;
}

int dinic(int _src, int _dst) {
	src = _src, dst = _dst;
	int rlt = 0, flow;
	while (bfs()) {
		fill(work, work + nodes, 0);
		while (flow = dfs(src, inf)) rlt += flow;
	}
	return rlt;
}

#define N 12012
#define M 2020

int n, m, k, male[N], v[N], malelover[M], w[M], cnt[M], idx[M][11], gf[M];

bool enemy(int x, int y) {
	for (int i = 1, j = 1; i <= cnt[x] && j <= cnt[y];) {
		if (idx[x][i] == idx[y][j]) return 1;
		else if (idx[x][i] < idx[y][j]) i ++;
		else j ++;
	}
	return 0;
}

int main() {
//	freopen("e.in", "r", stdin);
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= n; i ++) scanf("%d", &male[i]);
	for (int i = 1; i <= n; i ++) scanf("%d", &v[i]);
	int ans = 0;
	for (int i = 1; i <= m; i ++) {
		scanf("%d %d %d", &malelover[i], &w[i], &cnt[i]);
		for (int j = 1; j <= cnt[i]; j ++) scanf("%d", &idx[i][j]);
		sort(idx[i] + 1, idx[i] + cnt[i] + 1);
		scanf("%d", &gf[i]);
		ans += w[i];
		if (gf[i]) w[i] += k;
	}
	init(n + m + 2);
	int src = 0, dst = n + m + 1;
	for (int i = 1; i <= n; i ++) {
		if (!male[i]) add(src, i, v[i]);
		else add(i, dst, v[i]);
	}
	for (int i = 1; i <= m; i ++) {
		if (!malelover[i]) {
			add(src, n + i, w[i]);
			for (int j = 1; j <= cnt[i]; j ++) {
				if (male[idx[i][j]]) add(n + i, idx[i][j], inf);
			}
		}
		else {
			add(n + i, dst, w[i]);
			for (int j = 1; j <= cnt[i]; j ++) {
				if (!male[idx[i][j]]) add(idx[i][j], n + i, inf);
			}
		}
	}
	for (int i = 1; i <= m; i ++) {
		for (int j = i + 1; j <= m; j ++) if (malelover[i] != malelover[j] && enemy(i, j)) {
			int x = n + i, y = n + j;
			if (malelover[i]) swap(x, y);
			add(x, y, inf);
		}
	}
	printf("%d\n", ans - dinic(src, dst));
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxnodes = 12012, inf = 1e9;

int nodes, src, dst;
int level[maxnodes], q[maxnodes], work[maxnodes];

struct edge {
	int to, rev, cap, flow;
};

vector <edge> g[maxnodes];

void init(int _nodes) {
	nodes = _nodes;
	for (int i = 0; i < nodes; i ++) g[i].clear();
}

void add(int x, int y, int w) {
	edge a = {y, g[y].size(), w, 0};
	edge b = {x, g[x].size(), 0, 0};
	g[x].push_back(a);
	g[y].push_back(b);
}

bool bfs() {
	fill(level, level + nodes, -1);
	level[src] = 0;
	int h = 0, t = 0;
	q[t++] = src;
	while (h < t) {
		int u = q[h++];
		for (int j = 0; j < g[u].size(); j++) {
			edge &e = g[u][j];
			int v = e.to;
			if (level[v] < 0 && e.flow < e.cap) {
				level[v] = level[u] + 1;
				q[t++] = v;
			}
		}
	}
	return level[dst] >= 0;
}

int dfs(int u, int f) {
	if (u == dst) return f;
	for (int &i = work[u]; i < g[u].size(); i++) {
		edge &e = g[u][i];
		if (e.cap <= e.flow) continue;
		int v = e.to;
		if (level[v] == level[u] + 1) {
			int df = dfs(v, min(f, e.cap - e.flow));
			if (df > 0) {
				e.flow += df;
				g[v][e.rev].flow -= df;
				return df;
			}
		}
	}
	return 0;
}

int dinic(int _src, int _dst) {
	src = _src, dst = _dst;
	int rlt = 0, flow;
	while (bfs()) {
		fill(work, work + nodes, 0);
		while (flow = dfs(src, inf)) rlt += flow;
	}
	return rlt;
}

#define N 12012
#define M 2020

int n, m, k, male[N], v[N], malelover[M], w[M], cnt[M], idx[M][11], gf[M];

bool enemy(int x, int y) {
	for (int i = 1; i <= cnt[x]; i ++) {
		for (int j = 1; j <= cnt[y]; j ++) if (idx[x][i] == idx[y][j]) return 1;
	}
	return 0;
}

int main() {
//	freopen("e.in", "r", stdin);
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= n; i ++) scanf("%d", &male[i]);
	for (int i = 1; i <= n; i ++) scanf("%d", &v[i]);
	int ans = 0;
	for (int i = 1; i <= m; i ++) {
		scanf("%d %d %d", &malelover[i], &w[i], &cnt[i]);
		for (int j = 1; j <= cnt[i]; j ++) scanf("%d", &idx[i][j]);
		scanf("%d", &gf[i]);
		ans += w[i];
		if (gf[i]) w[i] += k;
	}
	init(n + m + 2);
	int src = 0, dst = n + m + 1;
	for (int i = 1; i <= n; i ++) {
		if (!male[i]) add(src, i, v[i]);
		else add(i, dst, v[i]);
	}
	for (int i = 1; i <= m; i ++) {
		if (!malelover[i]) {
			add(src, m + i, w[i]);
			for (int j = 1; j <= cnt[i]; j ++) {
				if (male[idx[i][j]]) add(m + i, idx[i][j], inf);
			}
		}
		else {
			add(m + i, dst, w[i]);
			for (int j = 1; j <= cnt[i]; j ++) {
				if (!male[idx[i][j]]) add(idx[i][j], m + i, inf);
			}
		}
	}
	for (int i = 1; i <= m; i ++) {
		for (int j = i + 1; j <= m; j ++) if (malelover[i] != malelover[j] && enemy(i, j)) {
			int x = m + i, y = m + j;
			if (malelover[i]) swap(x, y);
			add(x, y, inf);
		}
	}
	printf("%d\n", ans - dinic(src, dst));
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxnodes = 12012, inf = 1e9;

int nodes, src, dst;
int level[maxnodes], q[maxnodes], work[maxnodes];

struct edge {
	int to, rev, cap, flow;
};

vector <edge> g[maxnodes];

void init(int _nodes) {
	nodes = _nodes;
	for (int i = 0; i < nodes; i ++) g[i].clear();
}

void add(int x, int y, int w) {
	edge a = {y, g[y].size(), w, 0};
	edge b = {x, g[x].size(), 0, 0};
	g[x].push_back(a);
	g[y].push_back(b);
}

bool bfs() {
	fill(level, level + nodes, -1);
	level[src] = 0;
	int h = 0, t = 0;
	q[t++] = src;
	while (h < t) {
		int u = q[h++];
		for (int j = 0; j < g[u].size(); j++) {
			edge &e = g[u][j];
			int v = e.to;
			if (level[v] < 0 && e.flow < e.cap) {
				level[v] = level[u] + 1;
				q[t++] = v;
			}
		}
	}
	return level[dst] >= 0;
}

int dfs(int u, int f) {
	if (u == dst) return f;
	for (int &i = work[u]; i < g[u].size(); i++) {
		edge &e = g[u][i];
		if (e.cap <= e.flow) continue;
		int v = e.to;
		if (level[v] == level[u] + 1) {
			int df = dfs(v, min(f, e.cap - e.flow));
			if (df > 0) {
				e.flow += df;
				g[v][e.rev].flow -= df;
				return df;
			}
		}
	}
	return 0;
}

int dinic(int _src, int _dst) {
	src = _src, dst = _dst;
	int rlt = 0, flow;
	while (bfs()) {
		fill(work, work + nodes, 0);
		while (flow = dfs(src, inf)) rlt += flow;
	}
	return rlt;
}

#define N 12012
#define M 2020

int n, m, k, male[N], v[N], malelover[M], w[M], cnt[M], idx[M][11], gf[M];

bool enemy(int x, int y) {
	for (int i = 1, j = 1; i <= cnt[x] && y <= cnt[y];) {
		if (idx[x][i] == idx[y][j]) return 1;
		else if (idx[x][i] < idx[y][j]) i ++;
		else j ++;
	}
	return 0;
}

int main() {
//	freopen("e.in", "r", stdin);
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= n; i ++) scanf("%d", &male[i]);
	for (int i = 1; i <= n; i ++) scanf("%d", &v[i]);
	int ans = 0;
	for (int i = 1; i <= m; i ++) {
		scanf("%d %d %d", &malelover[i], &w[i], &cnt[i]);
		for (int j = 1; j <= cnt[i]; j ++) scanf("%d", &idx[i][j]);
		sort(idx[i] + 1, idx[i] + cnt[i] + 1);
		scanf("%d", &gf[i]);
		ans += w[i];
		if (gf[i]) w[i] += k;
	}
	init(n + m + 2);
	int src = 0, dst = n + m + 1;
	for (int i = 1; i <= n; i ++) {
		if (!male[i]) add(src, i, v[i]);
		else add(i, dst, v[i]);
	}
	for (int i = 1; i <= m; i ++) {
		if (!malelover[i]) {
			add(src, n + i, w[i]);
			for (int j = 1; j <= cnt[i]; j ++) {
				if (male[idx[i][j]]) add(n + i, idx[i][j], inf);
			}
		}
		else {
			add(n + i, dst, w[i]);
			for (int j = 1; j <= cnt[i]; j ++) {
				if (!male[idx[i][j]]) add(idx[i][j], n + i, inf);
			}
		}
	}
	for (int i = 1; i <= m; i ++) {
		for (int j = i + 1; j <= m; j ++) if (malelover[i] != malelover[j] && enemy(i, j)) {
			int x = n + i, y = n + j;
			if (malelover[i]) swap(x, y);
			add(x, y, inf);
		}
	}
	printf("%d\n", ans - dinic(src, dst));
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

//Start
#define lng long long
#define db double
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define rz resize
#define sz(x) (int)((x).size())
const int inf=0x3f3f3f3f;
const lng INF=0x3f3f3f3f3f3f3f3f;

//Data
const int N=1e4,V=12002;
int n,m,g,o[N+7],sm;

//Dinic
int ce=-1,s,t,dn;
vector<int> to,fw,e[V+7];
void add(int x,int y,int f){
	printf("%d-%d:%d\n",x,y,f);
	e[x].pb(++ce),to.pb(y),fw.pb(f);
	e[y].pb(++ce),to.pb(x),fw.pb(0);
}
int dep[V+7],cur[V+7],vis[V+7];
int Bfs(){
	for(int i=1;i<=dn;i++) vis[i]=0,cur[i]=0;
	vector<int> q; q.pb(s),vis[s]=1,dep[s]=0;
	for(int i=0,x=q[i];i<sz(q);x=q[++i])
		for(int j=0,v=e[x][j];j<sz(e[x]);v=e[x][++j])if(!vis[to[v]]&&fw[v])
			q.pb(to[v]),vis[to[v]]=1,dep[to[v]]=dep[x]+1;
	return vis[t];
}
int Dfs(int x,int F){
	if(x==t||!F) return F; int f,flow=0;
	for(int&i=cur[x],v=e[x][i];i<sz(e[x]);v=e[x][++i])
		if(dep[to[v]]==dep[x]+1&&(f=Dfs(to[v],min(F,fw[v])))>0)
			{fw[v]-=f,fw[v^1]+=f,F-=f,flow+=f;if(!F) break;}
	return flow;
}
int Dinic(){
	int f,flow=0;
	while(Bfs()) while((f=Dfs(s,inf))) flow+=f;
	return flow;
}

//Main
int main(){
	scanf("%d%d%d",&n,&m,&g);
	s=(t=dn=n+m+2)-1;
	for(int i=1;i<=n;i++) scanf("%d",&o[i]);
	for(int i=1,v;i<=n;i++) scanf("%d",&v),o[i]?add(i,t,v):add(s,i,v);
	for(int i=1,x,w,k,d;i<=m;i++){
		scanf("%d%d%d",&x,&w,&k),sm+=w;
		for(int j=1,p;j<=k;j++) scanf("%d",&p),x?add(p,n+i,inf):add(n+i,p,inf);
		scanf("%d",&d),x?add(n+i,t,w+d*g):add(s,n+i,w+d*g);
	}
	printf("%d\n",sm-Dinic());
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

//Start
#define lng long long
#define db double
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define rz resize
#define sz(x) (int)((x).size())
const int inf=0x3f3f3f3f;
const lng INF=0x3f3f3f3f3f3f3f3f;

//Data
const int N=1e4,V=12002;
int n,m,g,o[N+7],sm;

//Dinic
int ce=-1,s,t,dn;
vector<int> to,fw,e[V+7];
void add(int x,int y,int f){
	// printf("%d-%d:%d\n",x,y,f);
	e[x].pb(++ce),to.pb(y),fw.pb(f);
	e[y].pb(++ce),to.pb(x),fw.pb(0);
}
int dep[V+7],cur[V+7],vis[V+7];
int Bfs(){
	for(int i=1;i<=dn;i++) vis[i]=0,cur[i]=0;
	vector<int> q; q.pb(s),vis[s]=1,dep[s]=0;
	for(int i=0,x=q[i];i<sz(q);x=q[++i])
		for(int v:e[x])if(!vis[to[v]]&&fw[v])
			q.pb(to[v]),vis[to[v]]=1,dep[to[v]]=dep[x]+1;
	return vis[t];
}
int Dfs(int x,int F){
	if(x==t||!F) return F; int f,flow=0;
	for(int&i=cur[x],v=e[x][i];i<sz(e[x]);v=e[x][++i])
		if(dep[to[v]]==dep[x]+1&&(f=Dfs(to[v],min(F,fw[v])))>0)
			{fw[v]-=f,fw[v^1]+=f,F-=f,flow+=f;if(!F) break;}
	return flow;
}
int Dinic(){
	int f,flow=0;
	while(Bfs()) while((f=Dfs(s,inf))) flow+=f;
	return flow;
}

//Main
int main(){
	scanf("%d%d%d",&n,&m,&g);
	s=(t=dn=n+m+2)-1;
	for(int i=1;i<=n;i++) scanf("%d",&o[i]);
	for(int i=1,v;i<=n;i++) scanf("%d",&v),o[i]?add(i,t,v):add(s,i,v);
	for(int i=1,x,w,k,d;i<=m;i++){
		scanf("%d%d%d",&x,&w,&k),sm+=w;
		for(int j=1,p;j<=k;j++) scanf("%d",&p),x?add(p,n+i,inf):add(n+i,p,inf);
		scanf("%d",&d),x?add(n+i,t,w+d*g):add(s,n+i,w+d*g);
	}
	printf("%d\n",sm-Dinic());
	return 0;
}


#include<bits/stdc++.h>

#define For(i, _l, _r) for (int i = (_l), i##r = (_r); i <= (i##r); ++i)
#define Lop(i, _l, _r) for (int i = (_l), i##r = (_r); i >= (i##r); --i)
#define Rep(i, _l, _r) for (int i = (_l); i; i = (_r))

#define debug(...) fprintf(stderr, __VA_ARGS__)

template <typename tp> inline tp max (tp x, tp y) { return (x > y)? x: y; }
template <typename tp> inline tp min (tp x, tp y) { return (x < y)? x: y; }
template <typename tp>
inline bool chkmax (tp& x, tp y) { return (x >= y)? false: (x = y, true); }
template <typename tp>
inline bool chkmin (tp& x, tp y) { return (x <= y)? false: (x = y, true); }

template <typename tp>
tp read (tp& in) {
	in = 0; char ch = getchar(); tp f = 1;
	for (; ch > '9' || ch < '0'; ch = getchar()) if (ch == '-') f = -1;
	for (; ch >='0' && ch <='9'; ch = getchar()) in = in * 10 + ch - '0';
	return in *= f;
}

static const int max1 = 10000 + 11;
static const int max2 = 2000 + 11;
static const int max3 = 13;
static const int max4 = 12000 + 11;
static const int max5 = 70000 + 11;
static const int inf = ~0U >> 1;

int S, T, cnt, n, m, g;
int vi[max1], sx[max1];

int Ct = 1, Ht[max4], Nt[max5], to[max5], cap[max5];

inline void ins(int x, int y, int z) {
	Nt[++Ct] = Ht[x], Ht[x] = Ct, to[Ct] = y, cap[Ct] = z;
	Nt[++Ct] = Ht[y], Ht[y] = Ct, to[Ct] = x, cap[Ct] = 0;
}

int dep[max4], cur[max4];

bool bfs() {
	static int que[max4];
	int *head = que, *tail = que;

	memset(dep, 0, sizeof(int) * cnt);
	*(++tail) = S; dep[S] = 1;
	while (head != tail) {
		int x = *(++head);
		Rep(i, Ht[x], Nt[i])
			if (!dep[to[i]] && cap[i]) {
				dep[to[i]] = dep[x] + 1;
				if (to[i] == T) return true;
				*(++tail) = to[i];
			}
	}

	return false;
}

int dfs(int x, int maxflow) {
	if (x == T) return maxflow;
	for (int& i = cur[x]; i; i = Nt[i])
		if (dep[to[i]] == dep[x] + 1 && cap[i]) {
			int t = dfs(to[i], min(maxflow, cap[i]));
			if (t)
				return cap[i] -= t, cap[i ^ 1] += t, t;
		}
	return 0;
}

int dinic() {
	int res = 0, t;
	while (bfs()) {
		memcpy(cur, Ht, sizeof(int) * cnt);
		while (t = dfs(S, inf)) res += t;
	}
	return res;
}

int main() {

	read(n), read(m), read(g);
	For(i, 1, n) read(sx[i]);
	For(i, 1, n) read(vi[i]);

	S = n + m + 1, T = n + m + 2, cnt = T + 1;

	For(i, 1, n)
		if (!sx[i]) ins(S, i, vi[i]);
		else ins(i, T, vi[i]);

	int ans = 0;

	For(i, 1, m) {
		int sex, w, k;
		read(sex), read(w), read(k);
		ans += w;
		if (!sex) {
			while (k--) {
				int id; read(id);
				ins(i + n, id, inf);
			}
		} else {
			while (k--) {
				int id; read(id);
				ins(id, i + n, inf);
			}
		}
		int c; read(c);
		if (!sex) ins(S, i + n, w + g * c);
		else ins(i + n, T, w + g * c);
	}

	printf("%d\n", ans - dinic());

	return 0;
}


#include <cstdio>
#include <cstring>

#include <queue>
#include <vector>
#include <algorithm>

using namespace std;

#define NMAX 20000
#define INFTY 1000000000
#define BLACK 0
#define WHITE 1

class NetworkFlow {
 public:
    void initialize(int _s, int _t) {
        s = _s;
        t = _t;
    }

    void link(int u, int v, int capacity) {
        Edge *e = new Edge(v, capacity);
        Edge *re = new Edge(u, 0);
        e->reverse_edge = re;
        re->reverse_edge = e;
        G[u].push_back(e);
        G[v].push_back(re);
    }

    void print() {
        for (int u = 1; u <= NMAX; u++) {
            for (auto e : G[u]) {
                if (e->capacity > 0)
                    printf("%d -> %d : %d\n", u, e->v, e->capacity);
            }
        }
    }

    int solve() {
        int ret = 0;

        while (true) {
            bfs();

            if (!dist[t])
                break;

            memset(pos, 0, sizeof(pos));
            ret += dfs(s, INFTY);
        }

        return ret;
    }

 private:
    struct Edge {
        Edge(int _v, int _capacity)
            : v(_v), capacity(_capacity) {}

        int v;
        int capacity;
        Edge *reverse_edge;
    };

    int s, t;
    vector<Edge *> G[NMAX + 10];
    size_t pos[NMAX + 10];
    int dist[NMAX + 10];

    void bfs() {
        memset(dist, 0, sizeof(dist));
        queue<int> q;
        dist[s] = 1;
        q.push(s);
        while (!q.empty()) {
            int u = q.front();
            q.pop();

            for (auto e : G[u]) {
                int v = e->v;

                if (dist[v] || e->capacity == 0)
                    continue;

                dist[v] = dist[u] + 1;
                q.push(v);
            }
        }
    }

    int dfs(int u, int maxflow) {
        if (u == t)
            return maxflow;

        int ret = 0;
        for (size_t &i = pos[u]; i < G[u].size(); i++) {
            Edge *e = G[u][i];
            int v = e->v;

            if (dist[u] + 1 != dist[v] || e->capacity == 0)
                continue;

            int flow = min(maxflow - ret, e->capacity);
            flow = dfs(v, flow);
            e->capacity -= flow;
            e->reverse_edge->capacity += flow;
            ret += flow;

            if (ret == maxflow)
                break;
        }

        return ret;
    }
};

static int n, m, g, s, t;
static int col[NMAX + 10];
static NetworkFlow net;

void initialize() {
    scanf("%d%d%d", &n, &m, &g);

    s = n + m + 1;
    t = s + 1;
    net.initialize(s, t);
}

int main() {
    initialize();

    int answer = 0;

    for (int i = 1; i <= n; i++) {
        scanf("%d", col + i);
    }

    for (int i = 1; i <= n; i++) {
        int v;
        scanf("%d", &v);

        if (col[i] == BLACK)
            net.link(s, i, v);
        else
            net.link(i, t, v);
    }

    for (int i = 1; i <= m; i++) {
        int c, w, k, f;
        scanf("%d%d%d", &c, &w, &k);
        answer += w;

        if (c == BLACK) {
            for (int j = 0; j < k; j++) {
                int a;
                scanf("%d", &a);
                net.link(n + i, a, INFTY);
            }
        } else {
            for (int j = 0; j < k; j++) {
                int a;
                scanf("%d", &a);
                net.link(a, n + i, INFTY);
            }
        }

        scanf("%d", &f);

        if (c == BLACK)
            net.link(s, n + i, w + f * g);
        else if (c == WHITE)
            net.link(n + i, t, w + f * g);
    }

    // net.print();
    answer -= net.solve();
    printf("%d\n", answer);

    return 0;
}


/* --- author: dxm --- */
#include<bits/stdc++.h>
using namespace std;

#define INF 1e9
#define Inf 1e18
#define rep(i,n) for(int (i)=0;(i)<n;i++)
#define REP(i,n) for(int (i)=1;(i)<=n;i++)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
typedef long long ll;
inline void Fail(){printf("0");exit(0);}

const int maxn=20005;
int n,m,g,ans;
int tp[maxn],pan[maxn];
vector<int>v[maxn];
bool link[maxn][15];

class max_flow{
public:
	int s,t;
	class EDGE{
	public:
		int to,cap,rev;
		EDGE(int _to,int _cap,int _rev){to=_to;cap=_cap;rev=_rev;}
	};
	vector<EDGE>edge[maxn];
	int level[maxn],nxt[maxn],q[maxn];

	void add_edge(int from,int to,int cap){
		edge[from].pb(EDGE(to,cap,edge[to].size()));
		edge[to].pb(EDGE(from,0,edge[from].size()-1));
	}

	void bfs(){
		memset(level,-1,sizeof(level));
		int l=0,r=0;
		q[r++]=s;
		level[s]=0;
		while(l<r){
			int x=q[l++];
			rep(i,edge[x].size()){
				EDGE y=edge[x][i];
				if(y.cap&&level[y.to]<0){
					level[y.to]=level[x]+1;
					q[r++]=y.to;
				}
			}
		}
//		rep(i,t+1)cout<<level[i]<<" ";
//		cout<<endl;
	}

	int dfs(int x,int flow){
		if(x==t)return flow;
		for(int &i=nxt[x];i<edge[x].size();i++){
			EDGE &y=edge[x][i];
			if(y.cap&&level[y.to]==level[x]+1){
				int d=dfs(y.to,min(flow,y.cap));
				if(d>0){
					y.cap-=d;
					edge[y.to][y.rev].cap+=d;
					return d;
				}
			}
		}
		return 0;
	}

	int mf(){
		int flow=0;
		for(;;){
			bfs();
			if(level[t]<0)return flow;
			memset(nxt,0,sizeof(nxt));
			int f;
			while((f=dfs(s,INF))>0)flow+=f;
		}
	}
}M;

bool same(int i,int j){
	rep(ii,v[i].size())if(link[j][v[i][ii]])return true;
	return false;
}

int main(){
	scanf("%d%d%d",&n,&m,&g);
	M.s=n+m;M.t=n+m+1;
	rep(i,n)scanf("%d",&tp[i]);
	rep(i,n)scanf("%d",&pan[i]);
	for(int i=n;i<n+m;i++){
		scanf("%d%d",&tp[i],&pan[i]);
		ans+=pan[i];
		int k;
		scanf("%d",&k);
		while(k--){
			int x;
			scanf("%d",&x);
			v[i].pb(x-1);
			link[i][x-1]=true;
		}
		scanf("%d",&k);
		if(k)pan[i]+=g;
	}
	rep(i,n+m){
		if(!tp[i])M.add_edge(M.s,i,pan[i]);
		else M.add_edge(i,M.t,pan[i]);
	}
	for(int i=n;i<n+m;i++){
		rep(j,v[i].size()){
			if(!tp[i]&&tp[v[i][j]])M.add_edge(i,v[i][j],INF);
			if(tp[i]&&!tp[v[i][j]])M.add_edge(v[i][j],i,INF);
		}
		for(int j=i+1;j<n+m;j++)if(same(i,j)&&tp[i]!=tp[j]){
			if(!tp[i]&&tp[j])M.add_edge(i,j,INF);
			else M.add_edge(j,i,INF);
		}
	}
	printf("%d",ans-M.mf());
	return 0;
}

/*
Input:
-----------------
Output:
*/


/* --- author: dxm --- */
#include<bits/stdc++.h>
using namespace std;

#define INF 1e9
#define Inf 1e18
#define rep(i,n) for(int (i)=0;(i)<n;i++)
#define REP(i,n) for(int (i)=1;(i)<=n;i++)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
typedef long long ll;
inline void Fail(){printf("0");exit(0);}

const int maxn=20005;
int n,m,g,ans;
int tp[maxn],pan[maxn];
vector<int>v[maxn];

class max_flow{
public:
	int s,t;
	class EDGE{
	public:
		int to,cap,rev;
		EDGE(int _to,int _cap,int _rev){to=_to;cap=_cap;rev=_rev;}
	};
	vector<EDGE>edge[maxn];
	int level[maxn],nxt[maxn],q[maxn];

	void add_edge(int from,int to,int cap){
		edge[from].pb(EDGE(to,cap,edge[to].size()));
		edge[to].pb(EDGE(from,0,edge[from].size()-1));
	}

	void bfs(){
		memset(level,-1,sizeof(level));
		int l=0,r=0;
		q[r++]=s;
		level[s]=0;
		while(l<r){
			int x=q[l++];
			rep(i,edge[x].size()){
				EDGE y=edge[x][i];
				if(y.cap&&level[y.to]<0){
					level[y.to]=level[x]+1;
					q[r++]=y.to;
				}
			}
		}
//		rep(i,t+1)cout<<level[i]<<" ";
//		cout<<endl;
	}

	int dfs(int x,int flow){
		if(x==t)return flow;
		for(int &i=nxt[x];i<edge[x].size();i++){
			EDGE &y=edge[x][i];
			if(y.cap&&level[y.to]==level[x]+1){
				int d=dfs(y.to,min(flow,y.cap));
				if(d>0){
					y.cap-=d;
					edge[y.to][y.rev].cap+=d;
					return d;
				}
			}
		}
		return 0;
	}

	int mf(){
		int flow=0;
		for(;;){
			bfs();
			if(level[t]<0)return flow;
			memset(nxt,0,sizeof(nxt));
			int f;
			while((f=dfs(s,INF))>0)flow+=f;
		}
	}
}M;

bool same(int i,int j){
	rep(ii,v[i].size())rep(jj,v[j].size())if(v[i][ii]==v[j][jj])return true;
	return false;
}

int main(){
	scanf("%d%d%d",&n,&m,&g);
	M.s=n+m;M.t=n+m+1;
	rep(i,n)scanf("%d",&tp[i]);
	rep(i,n)scanf("%d",&pan[i]);
	for(int i=n;i<n+m;i++){
		scanf("%d%d",&tp[i],&pan[i]);
		ans+=pan[i];
		int k;
		scanf("%d",&k);
		while(k--){
			int x;
			scanf("%d",&x);
			v[i].pb(x-1);
		}
		scanf("%d",&k);
		if(k)pan[i]+=g;
	}
	rep(i,n+m){
		if(!tp[i])M.add_edge(M.s,i,pan[i]);
		else M.add_edge(i,M.t,pan[i]);
	}
	for(int i=n;i<n+m;i++){
		rep(j,v[i].size()){
			if(!tp[i]&&tp[v[i][j]])M.add_edge(i,v[i][j],INF);
			if(tp[i]&&!tp[v[i][j]])M.add_edge(v[i][j],i,INF);
		}
		for(int j=i+1;j<n+m;j++)if(same(i,j)&&tp[i]!=tp[j]){
			if(!tp[i]&&tp[j])M.add_edge(i,j,INF);
			else M.add_edge(j,i,INF);
		}
	}
	printf("%d",ans-M.mf());
	return 0;
}

/*
Input:
-----------------
Output:
*/


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 30000;
const double INF = 1e18;
const double ep = 1e-8;

struct Edge {
  int from, to;
  double cap, flow;
  Edge(int u, int v, double c, double f) : from(u), to(v), cap(c), flow(f) {}
};

struct Dinic {
  int n, m, s, t;
  vector<Edge> edges;
  vector<int> G[maxn];
  int d[maxn], cur[maxn];
  bool vis[maxn];

  void init(int n) {
    for (int i = 0; i < maxn; i++) G[i].clear();
    edges.clear();
  }

  void add(int from, int to, double cap) {
    edges.push_back(Edge(from, to, cap, 0));
    edges.push_back(Edge(to, from, 0 , 0));
    m = edges.size();
    G[from].push_back(m - 2);
    G[to].push_back(m - 1);
  }

  bool BFS() {
    memset(vis, 0, sizeof(vis));
    queue<int> Q;
    Q.push(s);
    d[s] = 0;
    vis[s] = 1;
    while (!Q.empty()) {
      int x = Q.front();
      Q.pop();
      for (int i = 0; i < G[x].size(); i++) {
        Edge& e = edges[G[x][i]];
        if (!vis[e.to] && e.cap - e.flow > ep) {
          vis[e.to] = 1;
          d[e.to] = d[x] + 1;
          Q.push(e.to);
        }
      }
    }
    return vis[t];
  }

  double DFS(int x, double a) {
    if (x == t || a == 0) return a;
    double flow = 0, f;
    for (int& i = cur[x]; i < G[x].size(); i++) {
      Edge& e = edges[G[x][i]];
      if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
        e.flow += f;
        edges[G[x][i] ^ 1].flow -= f;
        flow += f;
        a -= f;
        if (a == 0) break;
      }
    }
    return flow;
  }

  double maxFlow(int s, int t) {
    this->s = s;
    this->t = t;
    double flow = 0;
    while (BFS()) {
      memset(cur, 0, sizeof(cur));
      flow += DFS(s, INF);
    }
    return flow;
  }

  void show(){
    for(auto& e : edges){
      printf("(%d -> %d) => cap = %f , flow = %f\n" , e.from , e.to , e.cap , e.flow);
    }
  }

  void DFS2(int v){
    vis[v] = true;
    for(int i = 0; i < G[v].size(); ++i){
      Edge e = edges[G[v][i]];
      if(!vis[e.to] && e.cap - e.flow > ep){
        DFS2(e.to);
      }
    }
  }

  void showMinCut(int v){
      DFS2(v);
      for(auto& e : edges){
        if(vis[e.from] && !vis[e.to] && e.cap != 0 && e.flow != 0)
            printf("(%d -> %d) => cap = %f , flow = %f\n" , e.from , e.to , e.cap , e.flow);
      }
  }

};

struct person{
    int dsex; // desired sex
    int w; // payload
    vector<int> req; // which dogs
    int isfriend; // friend of mine?
    person(){}
    person(int d , int w_ , vector<int> r , int i) : dsex(d) , w(w_) , req(r) , isfriend(i) {}
};
int N , M , g;
int v[10005] , w[2005] , sex[10005];
person people[2005];

ll solve(){
    Dinic G;
    int tot = M + N + 3;
    G.init(tot);
    int s = tot - 2 , t = tot - 1;
    for(int i = 1; i <= N; ++i){
        if(sex[i]){
            G.add(s , i , v[i]);
        }
        else{
            G.add(i , t , v[i]);
        }
    }
    for(int i = 1; i <= M; ++i){
        int w = people[i].w + people[i].isfriend * g;
        if(people[i].dsex){
            G.add(s , N + i , w);
        }
        else{
            G.add(N + i , t , w);
        }
        for(int j : people[i].req){
            if(people[i].dsex){
                G.add(N + i , j , INF);
            }
            else{
                G.add(j , N + i , INF);
            }
        }
    }
    ll ret = G.maxFlow(s , t);
    //G.showMinCut(s);
    return ret;
}

int main(){
    ll tot = 0;
    scanf("%d %d %d" , &N , &M , &g);
    for(int i = 1; i <= N; ++i)scanf("%d" , &sex[i]);
    for(int i = 1; i <= N; ++i)scanf("%d" , &v[i]);
    for(int i = 1; i <= M; ++i){
        scanf("%d %d" , &people[i].dsex , &people[i].w);
        tot += people[i].w;
        int sz; scanf("%d" , &sz);
        for(int j = 1; j <= sz; ++j){
            int x; scanf("%d" , &x); people[i].req.push_back(x);
        }
        scanf("%d" , &people[i].isfriend);
    }
    printf("%lld\n" , tot - solve());
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
template<class T>inline void chkmax(T &a,T b){ if(a<b)a=b;}
template<class T>inline void chkmin(T &a,T b){ if(a>b)a=b;}
#define fi first
#define se second
#define mkr(a,b) make_pair(a,b)
inline int read()
{
	int sum=0,p=1;char ch=getchar();
	while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
	if(ch=='-')p=-1,ch=getchar();
	while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
	return sum*p;
}

const int maxn=1e5+20;
const int inf=0x3f3f3f3f;

struct node {
	int v,next,w;
};
node e[maxn<<2];
int cnt=1,start[maxn];
inline void addedge(int u,int v,int w){ e[++cnt]=(node){v,start[u],w};start[u]=cnt;}
inline void Addedge(int u,int v,int w){ addedge(u,v,w);addedge(v,u,0);}

int col[maxn],n,m,g,v[maxn];
int S,T,tot;
int ans;
int rk[maxn];

inline void init()
{
	n=read();m=read();g=read();
	tot=n+m;S=++tot; T=++tot;
	REP(i,1,n)col[i]=read();
	REP(i,1,n)v[i]=read();
	REP(i,1,n)
	{
		if(col[i]==0)Addedge(S,i,v[i]);
		else Addedge(i,T,v[i]);
	}
	REP(i,1,m)
	{
		int sex=read();
		int w=read(),k=read();
		ans+=w;
		REP(j,1,k)rk[j]=read();
		w+=read()*g;
		if(sex==1)
		{
			Addedge(n+i,T,w);
			REP(j,1,k)Addedge(rk[j],i+n,inf);
		}else
		{
			Addedge(S,i+n,w);
			REP(j,1,k)Addedge(i+n,rk[j],inf);
		}
	}
}

int cur[maxn],lev[maxn];

inline bool bfs()
{
	static queue<int>q;
	while(!q.empty())q.pop();
	REP(i,1,tot)lev[i]=0;
	lev[S]=1; q.push(S);
	while(!q.empty())
	{
		int u=q.front();q.pop();
		EREP(i,u)
		{
			int v=e[i].v;
			if(e[i].w && !lev[v])
			{
				lev[v]=lev[u]+1;
				if(v==T)return 1;
				q.push(v);
			}
		}
	}
	return 0;
}

int dfs(int u,int flow)
{
	if(u==T)return flow;
	int tag=0;
	for(int &i=cur[u];i;i=e[i].next)
	{
		int v=e[i].v;
		if(lev[v]==lev[u]+1 && e[i].w)
		{
			int c=dfs(v,min(flow-tag,e[i].w));
			if(c)
			{
				e[i].w-=c;
				e[i^1].w+=c;
				tag+=c;
				if(tag==flow)return tag;
			}
		}
	}
	return tag;
}

inline void doing()
{
	while(bfs())
	{
		REP(i,1,tot)cur[i]=start[i];
		ans-=dfs(S,inf);
	}
	printf("%d\n",ans);
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("biologist.in","r",stdin);
	freopen("biologist.out","w",stdout);
#endif
	init();
	doing();
	return 0;
}


#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
	int x = 0, f = 1, c = getchar();
	for (; !isdigit(c); c = getchar())
		if (c == '-')
			f = -1;
	for (;  isdigit(c); c = getchar())
		x = x * 10 + c - '0';
	return x * f;
}

const int MAXN = 30005;
const int MAXM = 300005;
const int INF = 0x3f3f3f3f;

namespace Flow
{
	struct Edge
	{
		int p, v, w;
	} e[MAXM];

	int e_cnt, S, T, V, ql, qr, q[MAXN], hed[MAXN], dis[MAXN], cur[MAXN];

	inline void Init(int n)
	{
		V = n;
		for (int i = 0; i < V; i ++)
			hed[i] = 0;
		e_cnt = 1;
	}

	inline void Addedge(int x, int y, int w)
	{
		e[++ e_cnt] = {y, hed[x], w}; hed[x] = e_cnt;
		e[++ e_cnt] = {x, hed[y], 0}; hed[y] = e_cnt;
	}

	inline bool Bfs()
	{
		for (int i = 0; i < V; i ++)
			dis[i] = 0;
		dis[q[ql = 0] = S] = qr = 1;
		while (ql ^ qr)
		{
			int x = q[ql ++];
			for (int i = hed[x]; i; i = e[i].v)
				if (e[i].w && !dis[e[i].p])
					dis[q[qr ++] = e[i].p] = dis[x] + 1;
		}
		return dis[T];
	}

	inline int Dfs(int x, int f)
	{
		if (x == T)
			return f;
		int ret = 0, t = 0;
		for (int &i = cur[x]; i; i = e[i].v)
			if (e[i].w && dis[e[i].p] == dis[x] + 1)
			{
				t = Dfs(e[i].p, min(f, e[i].w));
				f -= t; ret += t; e[i].w -= t; e[i ^ 1].w += t;
				if (!f)
					return ret;
			}
		return dis[x] = -1, ret;
	}

	inline int Dinic()
	{
		int ret = 0;
		while (Bfs())
		{
			for (int i = 0; i < V; i ++)
				cur[i] = hed[i];
			ret += Dfs(S, INF);
		}
		return ret;
	}
}

int n, m, g, ans, typ[MAXN];

int main()
{
#ifdef wxh010910
	freopen("data.in", "r", stdin);
#endif
	n = Read(), m = Read(), g = Read(), Flow::Init(n + m + 2), Flow::T = n + m + 1;
	for (int i = 1; i <= n; i ++)
		typ[i] = Read();
	for (int i = 1; i <= n; i ++)
		if (typ[i])
			Flow::Addedge(i, n + m + 1, Read());
		else
			Flow::Addedge(0, i, Read());
	for (int i = 1; i <= m; i ++)
	{
		int typ = Read(), val = Read(), cnt = Read();
		ans += val;
		for (int j = 1; j <= cnt; j ++)
			if (typ)
				Flow::Addedge(Read(), i + n, INF);
			else
				Flow::Addedge(i + n, Read(), INF);
		if (Read())
			val += g;
		if (typ)
			Flow::Addedge(i + n, n + m + 1, val);
		else
			Flow::Addedge(0, i + n, val);
	}
	return printf("%d\n", ans - Flow::Dinic()), 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
const int N = 15000;
const int inf = 1e9;
struct edge{int to,nxt,w;}a[N*10];
int n,m,g,sex[N],S,T,head[N],cnt=1,dep[N],cur[N],ans;
queue<int>Q;
void link(int u,int v,int w)
{
    a[++cnt]=(edge){v,head[u],w};
    head[u]=cnt;
    a[++cnt]=(edge){u,head[v],0};
    head[v]=cnt;
}
bool bfs()
{
    memset(dep,0,sizeof(dep));
    dep[S]=1;Q.push(S);
    while (!Q.empty())
    {
        int u=Q.front();Q.pop();
        for (int e=head[u];e;e=a[e].nxt)
            if (a[e].w&&!dep[a[e].to])
                dep[a[e].to]=dep[u]+1,Q.push(a[e].to);
    }
    return dep[T];
}
int dfs(int u,int f)
{
    if (u==T) return f;
    for (int &e=cur[u];e;e=a[e].nxt)
        if (a[e].w&&dep[a[e].to]==dep[u]+1)
        {
            int tmp=dfs(a[e].to,min(a[e].w,f));
            if (tmp) {a[e].w-=tmp;a[e^1].w+=tmp;return tmp;}
        }
    return 0;
}
int Dinic()
{
    int res=0;
    while (bfs())
    {
        for (int i=1;i<=T;++i) cur[i]=head[i];
        while (int tmp=dfs(S,inf)) res+=tmp;
    }
    return res;
}
int main()
{
    n=gi();m=gi();g=gi();S=n+m+1;T=S+1;
    for (int i=1;i<=n;++i) sex[i]=gi();
    for (int i=1;i<=n;++i)
    {
        int x=gi();
        sex[i]?link(i,T,x):link(S,i,x);
    }
    for (int i=1;i<=m;++i)
    {
        int v=gi(),w=gi(),k=gi();ans+=w;
        while (k--)
        {
            int x=gi();
            v?link(x,i+n,inf):link(i+n,x,inf);
        }
        int gg=gi();w+=g*gg;
        v?link(i+n,T,w):link(S,i+n,w);
    }
    printf("%d\n",ans-Dinic());
    return 0;
}


#include <algorithm>
// #include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <cmath>
#include <set>
#include <map>
// #include <bitset>
using namespace std;
typedef long long LL;
typedef double db;
const int oo=2139063143;
const int N=1010000;
const int P=1000000007;
const db eps=1e-7;
#define pritnf printf
//char buf[1<<22],*p1=buf,*p2=buf,obuf[1<<22],*O=obuf;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
template <typename T>
inline void sc (T &x)
{
    x=0; static int p; p=1; static char c; c=getchar();
    while (!isdigit(c)) { if (c=='-') p=-1; c=getchar(); }
    while ( isdigit(c)) { x=(x<<1)+(x<<3)+(c-48); c=getchar(); }
    x*=p;
}
template <typename T>
inline void print (T x)
{
    if (x< 0) putchar('-'),x=-x;
    if (x>=10) print(x/10);
    putchar(x%10+'0');
}
template <typename T>
inline void pr (T x) { print(x),putchar('\n'); }
template <typename T1,typename T2>
void chkmax (T1 &A,T2 B) { A=A>=B?A:B; }
template <typename T1,typename T2>
void chkmin (T1 &A,T2 B) { A=A<=B?A:B; }

int n,m,k;
struct EDGE { int v,w,nx; }lb[N]; int top[N],cur[N],tot=1;
void add (int u,int v,int w)
{
	lb[++tot]=(EDGE){v,w,top[u]},top[u]=tot;
	lb[++tot]=(EDGE){u,0,top[v]},top[v]=tot;
}
int s,t,dep[N];
bool bfs ()
{
	memcpy (cur,top,sizeof (int)*(t+1));
	memset (dep,0,sizeof (int)*(t+1));
	queue <int> q; dep[s]=1,q.push (s);
	while (q.size ())
	{
		int u=q.front (); q.pop ();
		for (int kb=top[u]; kb; kb=lb[kb].nx)
		{
			int v=lb[kb].v,w=lb[kb].w;
			if (w> eps&&!dep[v]) dep[v]=dep[u]+1,q.push (v);
		}
	}
	return dep[t];
}
int dinic (int u,int flow)
{
	if (u==t) return flow;
	int rest=flow;
	for (int &kb=cur[u]; kb; kb=lb[kb].nx)
	{
		int v=lb[kb].v,w=lb[kb].w;
		if (w> eps&&dep[v]==dep[u]+1)
		{
			int k=dinic (v,min (rest,w));
			if (k< eps) dep[v]=0;
			rest-=k;
			lb[kb].w-=k,lb[kb^1].w+=k;
			if (rest< eps) break;
		}
	}
	return flow-rest;
}
int a[N];
int main ()
{
    // freopen (".in","r",stdin);
    // freopen (".out","w",stdout);
	sc(n),sc(m),sc(k);
	for (int i=1; i<=n; i++)
		sc(a[i]);
	s=n+m+1,t=s+1;
	for (int i=1; i<=n; i++)
	{
		int x; sc(x);
		a[i]?add (s,i,x):add (i,t,x);
	}
	int ans=0;
	for (int i=1; i<=m; i++)
	{
		int x,w,h,y; sc(x),sc(w),sc(h);
		while (h--)
			sc(y),x?add (i+n,y,oo):add (y,i+n,oo);
		sc(y); x?add (s,i+n,(y?k:0)+w):add (i+n,t,(y?k:0)+w);
		ans+=w;
	}
	int flow=0;
	while (bfs ())
		while ((flow=dinic (s,oo))) ans-=flow;
	pr(ans);

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'

void io(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(15);
}
const int MAX = 12005;
const int INF = 1e9 + 1 ;
//Complexity O(V^2E)
class Dinic {
public:
    struct edge {
        int a, b, cap, flow;
    };
    int n, source, sink;
    int dis[MAX];
    int ptr[MAX];
    vector<edge> e;
    vector<int> adj[MAX];
    Dinic(int a, int b, int c) {
        n = a;
        source = b;
        sink = c;
    }
    void init(int a,int b,int c){
        e.clear() ;
        n = a ;
        source = b ;
        sink = c ;
        for(int i = 0; i <= n; i++){
            adj[i].clear() ;
        }
    }
    void set_dis() {
        for(int i=0; i<=n; ++i) {
            dis[i] = -1;
        }
    }
    void set_ptr() {
        for(int i=0; i<=n; ++i) {
            ptr[i] = 0;
        }
    }
    void add_edge(int a, int b, int cap) {
        edge e1 = {a, b, cap, 0};
        edge e2 = {b, a, 0, 0};
        adj[a].push_back((int)e.size());
        e.push_back(e1);
        adj[b].push_back((int)e.size());
        e.push_back(e2);
    }
    bool bfs() {
        queue<int> q;
        q.push(source);
        set_dis();
        dis[source] = 0;
        while(!q.empty() && dis[sink] == -1) {
            int v = q.front();
            q.pop();
            for(size_t i=0; i<adj[v].size(); ++i) {
                int id = adj[v][i];
                int to = e[id].b;
                if (dis[to] == -1 && e[id].flow < e[id].cap) {
                    dis[to] = dis[v] + 1;
                    q.push(to);
                }
            }
        }
        while(!q.empty()) {
            q.pop();
        }
        return dis[sink] != -1;
    }
    int dfs(int v, int flow) {
        if (!flow) {
            return 0;
        }
        if (v == sink) {
            return flow;
        }
        for(; ptr[v]<(int)adj[v].size(); ++ptr[v]) {
            int id = adj[v][ptr[v]];
            int to = e[id].b;
            if (dis[to] != dis[v] + 1) {
                continue;
            }
            int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
            if (pushed) {
                e[id].flow += pushed;
                e[id^1].flow -= pushed;
                return pushed;
            }
        }
        return 0;
    }
    int max_flow() {
        int flow = 0;
        while(bfs()) {
            set_ptr();
            int pushed;
            while(pushed = dfs(source, INT_MAX)) {
                flow += pushed;
            }
        }
        return flow;
    }
    void print_graph() {
        for(size_t i=0; i<(int)e.size(); ++i) {
            printf("from: %d to : %d flow : %d cap : %d\n", e[i].a, e[i].b, e[i].flow, e[i].cap);
        }
    }
};
Dinic min_cut(0,0,0);
bool isMale[10004] ;
int cost[10004] ;
int main(int argc,char* argv[]) {
    io() ;
    int n, m, g ;
    cin >> n >> m >> g ;
    int src = n + m + 1 ;
    int snk = n + m + 2 ;
    min_cut.init(n + m + 2, src, snk) ;
    for(int i = 1; i <= n; i++){
        cin >> isMale[i] ;
    }
    for(int i = 1; i <= n; i++){
        cin >> cost[i] ;
    }
    for(int i = 1; i <= n; i++){
        if(!isMale[i]){
            min_cut.add_edge(src, i, cost[i]) ;
        }
        else{
            min_cut.add_edge(i,snk,cost[i]) ;
        }
    }
    int fans = 0 ;
    for(int i = 1; i <= m; i++){
        int s, w, k, sp ;
        cin >> s >> w >> k  ;
        fans += w ;
        int d ;
        for(int j = 1; j <= k; j++){
            cin >> d ;
            if(s)
                min_cut.add_edge(d, n + i, INF) ;
            else
                min_cut.add_edge(n + i,d, INF) ;
        }
        cin >> sp ;
        if(sp == 1){
            w += g ;
        }
        if(s == 0){
            min_cut.add_edge(src,n + i,w) ;
        }
        else{
            min_cut.add_edge(n + i,snk,w) ;
        }
    }
    int mn_cut = min_cut.max_flow() ;
    fans -= mn_cut ;
    cout  << fans << endl ;
    return 0 ;
}


#include<bits/stdc++.h>
using namespace std;

int V, E, src, snk;
vector<int> la, nxt, oppo, capa;
void init() {
    E = 0;
    la.clear(); nxt.clear(); oppo.clear(); capa.clear();
    la = vector<int>(V, -1);
}
void add(int u, int v, int c) {
    nxt.push_back(la[u]);
    la[u] = E++;
    oppo.push_back(v);
    capa.push_back(c);
}
vector<int> dist;
queue<int> q;
bool bfs() {
    dist = vector<int>(V, -1);
    q.push(src);
    dist[src] = 0;
    while(!q.empty()) {
        int u = q.front(); q.pop();

        for(int i = la[u]; i != -1; i = nxt[i]) {
            int v = oppo[i];
            if(capa[i] && dist[v] == -1) {
                dist[v] = dist[u] + 1;
                q.push(v);
            }
        }
    }
    return dist[snk] != -1;
}
vector<int> laa;
int dfs(int u, int f) {
    if(u == snk) return f;

    for(int i = laa[u]; i != -1; i = nxt[i]) {
        laa[u] = i;
        int v = oppo[i];
        if(capa[i] && dist[v] == dist[u] + 1) {
            if(int tmp = dfs(v, min(capa[i], f))) {
                capa[i] -= tmp;
                capa[i^1] += tmp;
                return tmp;
            }
        }
    }
    return 0;
}
int dinic() {
    int tf = 0;
    while(bfs()) {
        laa = la;
        while(int tmp = dfs(src, 1e9)) tf += tmp;
    }
    return tf;
}

int N, M, G;
vector<int> sex;

int main() {
    scanf("%d %d %d", &N, &M, &G);

    V = N + M + 2, src = V - 2, snk = V - 1;
    init();

    sex.resize(N);
    for(int i = 0; i < N; i++) {
        scanf("%d", &sex[i]);
    }
    for(int i = 0; i < N; i++) {
        int t; scanf("%d", &t);

        if(sex[i] == 0) {
            add(src, i, t);
            add(i, src, 0);
        }
        if(sex[i] == 1) {
            add(i, snk, t);
            add(snk, i, 0);
        }
    }

    int sum = 0;
    for(int i = 0; i < M; i++) {
        int s, w, k; scanf("%d %d %d", &s, &w, &k);
        sum += w;

        if(s == 0) {
            add(src, N + i, w);
            add(N + i, src, 0);
        }
        if(s == 1) {
            add(N + i, snk, w);
            add(snk, N + i, 0);
        }

        for(int j = 0; j < k; j++) {
            int x; scanf("%d", &x);
            x--;

            if(s == 0) {
                add(N + i, x, 1e9);
                add(x, N + i, 0);
            }
            if(s == 1) {
                add(x, N + i, 1e9);
                add(N + i, x, 0);
            }
        }

        int f; scanf("%d", &f);
        if(f) {
            if(s == 0) {
                add(src, N + i, G);
                add(N + i, src, 0);
            }
            if(s == 1) {
                add(N + i, snk, G);
                add(snk, N + i, 0);
            }
        }
    }

    printf("%d", sum - dinic());
}


#pragma warning(disable:4996)

#include <stdio.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <cmath>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <complex>
#include <iterator>
#include <random>
#include <time.h>
#include <tuple>
#include <functional>
#include <list>
#include <limits.h>
using namespace std;

int V, E, src, snk;
vector<int> la, nxt, oppo, capa;
void init() {
	E = 0;
	la.clear(); nxt.clear(); oppo.clear(); capa.clear();
	la = vector<int>(V, -1);
}
void add(int u, int v, int c) {
	nxt.push_back(la[u]);
	la[u] = E++;
	oppo.push_back(v);
	capa.push_back(c);
}
vector<int> dist;
queue<int> q;
bool bfs() {
	dist = vector<int>(V, -1);
	q.push(src);
	dist[src] = 0;
	while(!q.empty()) {
		int u = q.front(); q.pop();

		for(int i = la[u]; i != -1; i = nxt[i]) {
			int v = oppo[i];
			if(capa[i] && dist[v] == -1) {
				dist[v] = dist[u] + 1;
				q.push(v);
			}
		}
	}
	return dist[snk] != -1;
}
vector<int> laa;
int dfs(int u, int f) {
	if(u == snk) return f;
	for(int i = laa[u]; i != -1; i = nxt[i]) {
		laa[u] = i;
		int v = oppo[i];
		if(capa[i] && dist[v] == dist[u] + 1) {
			if(int tmp = dfs(v, min(capa[i], f))) {
				capa[i] -= tmp;
				capa[i^1] += tmp;
				return tmp;
			}
		}
	}
	return 0;
}
int dinic() {
	int tf = 0;
	while(bfs()) {
		laa = la;
		while(int tmp = dfs(src, 1e9)) tf += tmp;
	}
	return tf;
}

int N, M, G;
vector<int> sex;

int main() {
	scanf("%d %d %d", &N, &M, &G);
	V = N + M + 2, src = V - 2, snk = V - 1;
	init();
	sex.resize(N);
	for(int i = 0; i < N; i++) {
		scanf("%d", &sex[i]);
	}
	for(int i = 0; i < N; i++) {
		int t; scanf("%d", &t);
		if(sex[i]) {
			add(src, i, t);
			add(i, src, 0);
		}
		else {
			add(i, snk, t);
			add(snk, i, 0);
		}
	}
	int sum = 0;
	for(int i = 0; i < M; i++) {
		int s, w, k; scanf("%d %d %d", &s, &w, &k);
		sum += w;
		if(s) {
			add(src, N + i, w);
			add(N + i, src, 0);
		}
		else {
			add(N + i, snk, w);
			add(snk, N + i, 0);
		}
		for(int j = 0; j < k; j++) {
			int t; scanf("%d", &t);
			t--;
			if(s) {
				add(N + i, t, 1e9);
				add(t, N + i, 0);
			}
			else {
				add(t, N + i, 1e9);
				add(N + i, t, 0);
			}
		}
		int t; scanf("%d", &t);
		if(t) {
			if(s) {
				add(src, N + i, G);
				add(N + i, src, 0);
			}
			else {
				add(N + i, snk, G);
				add(snk, N + i, 0);
			}
		}
	}
	cout << sum - dinic();
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define loop(k,a) for (int k=(a); ~k; k=link[k])
using namespace std;

const int maxn = 100009, maxm = 1000009, INF = 1e9;
struct edge { int u, v, f, c; };
struct ISAP {
	int n, m, s, t, head[maxn], link[maxm];
	int d[maxn], p[maxn], cur[maxn], num[maxn];
	edge e[maxm];
	void init(int _n) {
		n = _n; m = 0;
		memset(head, -1, sizeof head);
		memset(cur, -1, sizeof cur);
	}
	void addEdge(int u, int v, int w) {
		e[m].u = u; e[m].v = v; e[m].f = 0; e[m].c = w;
		link[m] = head[u]; cur[u] = head[u] = m++;
		e[m].u = v; e[m].v = u; e[m].f = 0; e[m].c = 0;
		link[m] = head[v]; cur[v] = head[v] = m++;
	}
	int augment() {
		int mn = INF, u = t;
		while (u != s) {
			mn = min(mn, e[p[u]].c - e[p[u]].f);
			u = e[p[u]].u;
		}
		u = t;
		while (u != s) {
			e[p[u]].f += mn; e[p[u]^1].f -= mn;
			u = e[p[u]].u;
		}
		return mn;
	}
	int Maxflow(int _s, int _t) {
		int res = 0, u = _s, flag;
		memset(d, 0, sizeof d);
		memset(num, 0, sizeof num);
		s = _s; t = _t; num[0] = 0;
		while (d[s] < n) {
			if (u == t) { res += augment(); u = s; }
			flag = 0;
			loop (k, cur[u])
				if (e[k].f < e[k].c && d[u] == d[e[k].v] + 1) {
					p[e[k].v] = cur[u] = k;
					u = e[k].v; flag = 1;
					break;
				}
			if (flag) continue;
			int mn = n;
			loop (k, head[u])
				if (e[k].f < e[k].c)
					mn = min(mn, d[e[k].v] + 1);
			if (--num[d[u]] == 0) return res;
			num[d[u] = mn]++; cur[u] = head[u];
			if (u != s) u = e[p[u]].u;
		}
		return res;
	}
} G;
int n, m, g, v, S, T, need, w, k, t, flag, ans;
int dog[maxn];

int main() {
	scanf("%d%d%d", &n, &m, &g);
	rep (i, 1, n) scanf("%d", &dog[i]);
	S = n + m + 1; T = S + 1;
	G.init(T + 1);
	rep (i, 1, n) {
		scanf("%d", &v);
		if (dog[i]) G.addEdge(S, i, v);
		else G.addEdge(i, T, v);
	}
	rep (i, 1, m) {
		scanf("%d%d%d", &need, &w, &k);
		rep (j, 1, k) {
			scanf("%d", &t);
			if (need) G.addEdge(n+i, t, INF);
			else G.addEdge(t, n+i, INF);
		}
		scanf("%d", &flag);
		if (need) G.addEdge(S, n+i, w + flag * g);
		else G.addEdge(n+i, T, w + flag * g);
		ans += w;
	}
	printf("%d\n", ans - G.Maxflow(S, T));
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int nex[64005], d[64005], las[12005], g[64005];
int top = 1, S, T;
void Add(int x, int y, int z) {
  nex[++top] = las[x];
  d[las[x] = top] = y;
  g[top] = z;
  nex[++top] = las[y];
  d[las[y] = top] = x;
  g[top] = 0;
}
int dis[12005], sum[12005];
int Sap(int x, int flow) {
  if (x == T) return flow;
  int ret = 0, tmp;
  for (int i = las[x]; i; i = nex[i])
    if (g[i] && dis[d[i]] == dis[x] - 1) {
      tmp = Sap(d[i], min(flow - ret, g[i]));
      g[i] -= tmp;
      g[i ^ 1] += tmp;
      ret += tmp;
      if (ret == flow) return ret;
      if (dis[S] > T) return ret;
    }
  if (!--sum[dis[x]]) dis[S] = T + 1;
  ++sum[++dis[x]];
  return ret;
}
int a[10005], n, m, q, ans = 0, G;
int main() {
  scanf("%d%d%d", &n, &m, &G);
  S = 1;
  T = 2 + n + m;
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for (int i = 1, x; i <= n; i++) {
    scanf("%d", &x);
    if (a[i])
      Add(S, i + 1, x);
    else
      Add(i + 1, T, x);
  }
  for (int i = 1, t, x, f, k; i <= m; i++) {
    scanf("%d%d%d", &f, &x, &t);
    for (int j = 1; j <= t; j++) scanf("%d", &a[j]);
    scanf("%d", &k);
    ans += x;
    if (f) {
      Add(S, i + n + 1, x + k * G);
      for (int j = 1; j <= t; j++) Add(i + n + 1, a[j] + 1, 0x7fffffff);
    } else {
      Add(i + n + 1, T, x + k * G);
      for (int j = 1; j <= t; j++) Add(a[j] + 1, i + n + 1, 0x7fffffff);
    }
  }
  sum[0] = T;
  while (dis[S] <= T) ans -= Sap(S, 0x7fffffff);
  printf("%d\n", ans);
}


#include <bits/stdc++.h>

#define F first
#define S second
#define pii pair<int, int>
#define pb push_back

using namespace std;

const int N = 2e4, E = 7e4 + 10, INF = 1e9;

int ed = 0, to[E], cap[E], nex[E], head[N];
int que[N], dis[N], vv[N], state[N];

void add_edge(int u, int v, int c)
{
	to[ed] = v, cap[ed] = c, nex[ed] = head[u], head[u] = ed ++;
	to[ed] = u, cap[ed] = 0, nex[ed] = head[v], head[v] = ed ++;
}

void bfs(int source)
{
	memset(dis, -1, sizeof dis);
	dis[source] = 0;
	int st = 0, en = 0;
	que[en ++] = source;
	while(en - st)
	{
		int v = que[st ++];
		for(int e = head[v]; e != -1; e = nex[e])
			if(cap[e] && dis[to[e]] == -1)
			{
				dis[to[e]] = dis[v] + 1;
				que[en ++] = to[e];
			}
	}
	return ;
}

int dfs(int v, int sink, int flow)
{
	if(flow == 0)return flow;
	if(v == sink)return flow;

	int res = 0;
	for(int e = head[v]; e != -1; e = nex[e])
	{
		if(cap[e] && res < flow && dis[to[e]] == dis[v] + 1)
		{
			int curr = dfs(to[e], sink, min(flow - res, cap[e]));
			if(curr > 0)
			{
				res += curr;
				cap[e] -= curr;
				cap[e ^ 1] += curr;
			}
		}
	}
	return res;
}

int MaxFlow(int source, int sink)
{
	int flow = 0, f = INF;
	while(f)
	{
		bfs(source);
		f = dfs(source, sink, INF);
		flow += f;
	}
	return flow;
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);

	memset(head, -1, sizeof head);
	int ans = 0, n, m, g; cin >> n >> m >> g;
	int source = 0, sink = n + m + 1;
	for(int i=1; i<=n; i++)
		cin >> state[i];

	for(int i=1; i<=n; i++)
	{
		cin >> vv[i];
		if(state[i] == 0)add_edge(source, i, vv[i]);
		else add_edge(i, sink, vv[i]);
	}

	for(int i=1; i<=m; i++)
	{
		int tp, w, k; cin >> tp >> w >> k;
		while(k--)
		{
			int v; cin >> v;
			if(tp == 0)add_edge(i + n, v, INF);
			else add_edge(v, i + n, INF);
		}
		int fr; cin >> fr;
		if(tp == 0)add_edge(source, i + n, w + g * fr);
		else add_edge(i + n, sink, w + fr * g);
		ans += w;
	}
	cout << ans - MaxFlow(source, sink) << endl;

}


#include <bits/stdc++.h>

#define F first
#define S second
#define pii pair<int, int>
#define pb push_back

using namespace std;

const int N = 2e4, E = 4e4 + 10, INF = 1e9;

int ed = 0, to[E], cap[E], nex[E], head[N];
int que[N], dis[N], vv[N], state[N];

bool mark[N];

void add_edge(int u, int v, int c)
{
	to[ed] = v, cap[ed] = c, nex[ed] = head[u], head[u] = ed ++;
	to[ed] = u, cap[ed] = 0, nex[ed] = head[v], head[v] = ed ++;
}

void bfs(int source)
{
	memset(dis, -1, sizeof dis);
	dis[source] = 0;
	int st = 0, en = 0;
	que[en ++] = source;
	while(en - st)
	{
		int v = que[st ++];
		for(int e = head[v]; e != -1; e = nex[e])
			if(cap[e] && dis[to[e]] == -1)
			{
				dis[to[e]] = dis[v] + 1;
				que[en ++] = to[e];
			}
	}
	return ;
}

int dfs(int v, int sink, int flow)
{
	mark[v] = true;
	if(flow == 0)return flow;
	if(v == sink)return flow;

	int res = 0;
	for(int e = head[v]; e != -1; e = nex[e])
	{
		if(cap[e] && !mark[to[e]] && dis[to[e]] == dis[v] + 1)
		{
			int curr = dfs(to[e], sink, min(flow, cap[e]));
			if(curr > 0)
			{
				res += curr;
				cap[e] -= curr;
				cap[e ^ 1] += curr;
			}
		}
	}
	return res;
}

int MaxFlow(int source, int sink)
{
	int flow = 0, f = INF;
	while(f)
	{
		bfs(source);
		memset(mark, 0, sizeof mark);
		f = dfs(source, sink, INF);
		flow += f;
	}
	return flow;
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);

	memset(head, -1, sizeof head);
	int ans = 0, n, m, g; cin >> n >> m >> g;
	int source = 0, sink = n + m + 1;
	for(int i=1; i<=n; i++)
		cin >> state[i];

	for(int i=1; i<=n; i++)
	{
		cin >> vv[i];
		if(state[i] == 0)add_edge(source, i, vv[i]);
		else add_edge(i, sink, vv[i]);
	}

	for(int i=1; i<=m; i++)
	{
		int tp, w, k; cin >> tp >> w >> k;
		while(k--)
		{
			int v; cin >> v;
			if(tp == 0)add_edge(i + n, v, INF);
			else add_edge(v, i + n, INF);
		}
		int fr; cin >> fr;
		if(tp == 0)add_edge(source, i + n, w + g * fr);
		else add_edge(i + n, sink, w + fr * g);
		ans += w;
	}
	cout << ans - MaxFlow(source, sink) << endl;

}


#include <bits/stdc++.h>

#define F first
#define S second
#define pii pair<int, int>
#define pb push_back

using namespace std;

const int N = 2e4, E = 7e4 + 10, INF = 1e9;

int ed = 0, to[E], cap[E], nex[E], head[N];
int que[N], dis[N], vv[N], state[N];

bool mark[N];

void add_edge(int u, int v, int c)
{
	to[ed] = v, cap[ed] = c, nex[ed] = head[u], head[u] = ed ++;
	to[ed] = u, cap[ed] = 0, nex[ed] = head[v], head[v] = ed ++;
}

void bfs(int source)
{
	memset(dis, -1, sizeof dis);
	dis[source] = 0;
	int st = 0, en = 0;
	que[en ++] = source;
	while(en - st)
	{
		int v = que[st ++];
		for(int e = head[v]; e != -1; e = nex[e])
			if(cap[e] && dis[to[e]] == -1)
			{
				dis[to[e]] = dis[v] + 1;
				que[en ++] = to[e];
			}
	}
	return ;
}

int dfs(int v, int sink, int flow)
{
	if(flow == 0)return flow;
	if(v == sink)return flow;

	int res = 0;
	for(int e = head[v]; e != -1; e = nex[e])
	{
		if(cap[e] && res < flow && dis[to[e]] == dis[v] + 1)
		{
			int curr = dfs(to[e], sink, min(flow - res, cap[e]));
			if(curr > 0)
			{
				res += curr;
				cap[e] -= curr;
				cap[e ^ 1] += curr;
			}
		}
	}
	if(res == 0)dis[v] = -1;
	return res;
}

int MaxFlow(int source, int sink)
{
	int flow = 0, f = INF;
	while(f)
	{
		bfs(source);
		memset(mark, 0, sizeof mark);
		f = dfs(source, sink, INF);
		flow += f;
	}
	return flow;
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);

	memset(head, -1, sizeof head);
	int ans = 0, n, m, g; cin >> n >> m >> g;
	int source = 0, sink = n + m + 1;
	for(int i=1; i<=n; i++)
		cin >> state[i];

	for(int i=1; i<=n; i++)
	{
		cin >> vv[i];
		if(state[i] == 0)add_edge(source, i, vv[i]);
		else add_edge(i, sink, vv[i]);
	}

	for(int i=1; i<=m; i++)
	{
		int tp, w, k; cin >> tp >> w >> k;
		while(k--)
		{
			int v; cin >> v;
			if(tp == 0)add_edge(i + n, v, INF);
			else add_edge(v, i + n, INF);
		}
		int fr; cin >> fr;
		if(tp == 0)add_edge(source, i + n, w + g * fr);
		else add_edge(i + n, sink, w + fr * g);
		ans += w;
	}
	cout << ans - MaxFlow(source, sink) << endl;

}


#include <bits/stdc++.h>

#define F first
#define S second
#define pii pair<int, int>
#define pb push_back

using namespace std;

const int N = 2e4, E = 3e4 + 10, INF = 1e9;

int ed = 0, to[E], cap[E], nex[E], head[N];
int que[N], dis[N], vv[N], state[N];

bool mark[N];

void add_edge(int u, int v, int c)
{
	to[ed] = v, cap[ed] = c, nex[ed] = head[u], head[u] = ed ++;
	to[ed] = u, cap[ed] = 0, nex[ed] = head[v], head[v] = ed ++;
}

void bfs(int source)
{
	memset(dis, -1, sizeof dis);
	dis[source] = 0;
	int st = 0, en = 0;
	que[en ++] = source;
	while(en - st)
	{
		int v = que[st ++];
		for(int e = head[v]; e != -1; e = nex[e])
			if(cap[e] && dis[to[e]] == -1)
			{
				dis[to[e]] = dis[v] + 1;
				que[en ++] = to[e];
			}
	}
	return ;
}

int dfs(int v, int sink, int flow)
{
	mark[v] = true;
	if(flow == 0)return flow;
	if(v == sink)return flow;

	int res = 0;
	for(int e = head[v]; e != -1; e = nex[e])
	{
		if(cap[e] && !mark[to[e]] && dis[to[e]] == dis[v] + 1)
		{
			int curr = dfs(to[e], sink, min(flow, cap[e]));
			if(curr > 0)
			{
				res += curr;
				cap[e] -= curr;
				cap[e ^ 1] += curr;
			}
		}
	}
	return res;
}

int MaxFlow(int source, int sink)
{
	int flow = 0, f = INF;
	while(f)
	{
		bfs(source);
		memset(mark, 0, sizeof mark);
		f = dfs(source, sink, INF);
		flow += f;
	}
	return flow;
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);

	memset(head, -1, sizeof head);
	int ans = 0, n, m, g; cin >> n >> m >> g;
	int source = 0, sink = n + m + 1;
	for(int i=1; i<=n; i++)
		cin >> state[i];

	for(int i=1; i<=n; i++)
	{
		cin >> vv[i];
		if(state[i] == 0)add_edge(source, i, vv[i]);
		else add_edge(i, sink, vv[i]);
	}

	for(int i=1; i<=m; i++)
	{
		int tp, w, k; cin >> tp >> w >> k;
		while(k--)
		{
			int v; cin >> v;
			if(tp == 0)add_edge(i + n, v, INF);
			else add_edge(v, i + n, INF);
		}
		int fr; cin >> fr;
		if(tp == 0)add_edge(source, i + n, w + g * fr);
		else add_edge(i + n, sink, w + fr * g);
		ans += w;
	}
	cout << ans - MaxFlow(source, sink) << endl;

}


#include <bits/stdc++.h>

#define F first
#define S second
#define pii pair<int, int>
#define pb push_back

using namespace std;

const int N = 2e4, E = 2e5 + 10, INF = 1e9;

int ed = 0, to[E], cap[E], nex[E], head[N];
int que[N], dis[N], vv[N], state[N];

bool mark[N];

void add_edge(int u, int v, int c)
{
	to[ed] = v, cap[ed] = c, nex[ed] = head[u], head[u] = ed ++;
	to[ed] = u, cap[ed] = 0, nex[ed] = head[v], head[v] = ed ++;
}

void bfs(int source)
{
	memset(dis, -1, sizeof dis);
	dis[source] = 0;
	int st = 0, en = 0;
	que[en ++] = source;
	while(en - st)
	{
		int v = que[st ++];
		for(int e = head[v]; e != -1; e = nex[e])
			if(cap[e] && dis[to[e]] == -1)
			{
				dis[to[e]] = dis[v] + 1;
				que[en ++] = to[e];
			}
	}
	return ;
}

int dfs(int v, int sink, int flow)
{
	mark[v] = true;
	if(flow == 0)return flow;
	if(v == sink)return flow;

	int res = 0;
	for(int e = head[v]; e != -1; e = nex[e])
	{
		if(cap[e] && !mark[to[e]] && dis[to[e]] == dis[v] + 1)
		{
			int curr = dfs(to[e], sink, min(flow, cap[e]));
			if(curr > 0)
			{
				res += curr;
				cap[e] -= curr;
				cap[e ^ 1] += curr;
			}
		}
	}
	return res;
}

int MaxFlow(int source, int sink)
{
	int flow = 0, f = INF;
	while(f)
	{
		bfs(source);
		memset(mark, 0, sizeof mark);
		f = dfs(source, sink, INF);
		flow += f;
	}
	return flow;
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);

	memset(head, -1, sizeof head);
	int ans = 0, n, m, g; cin >> n >> m >> g;
	int source = 0, sink = n + m + 1;
	for(int i=1; i<=n; i++)
		cin >> state[i];

	for(int i=1; i<=n; i++)
	{
		cin >> vv[i];
		if(state[i] == 0)add_edge(source, i, vv[i]);
		else add_edge(i, sink, vv[i]);
	}

	for(int i=1; i<=m; i++)
	{
		int tp, w, k; cin >> tp >> w >> k;
		while(k--)
		{
			int v; cin >> v;
			if(tp == 0)add_edge(i + n, v, INF);
			else add_edge(v, i + n, INF);
		}
		int fr; cin >> fr;
		if(tp == 0)add_edge(source, i + n, w + g * fr);
		else add_edge(i + n, sink, w + fr * g);
		ans += w;
	}
	cout << ans - MaxFlow(source, sink) << endl;

}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define N 20010
using namespace std;
const int inf = 0x3f3f3f3f;
struct flows {
	struct node {
		int to, next, flow;
	} e[N * 40];
	int tot, st[N], dis[N], cur[N];
	void init() {
		tot = -1, memset(e, -1, sizeof e),
		memset(st, -1, sizeof st);
	}
	void add(int x, int y, int z) {
		e[++tot].to = y;
		e[tot].flow = z;
		e[tot].next = st[x];
		st[x] = tot;
	}
	void add_edge(int x, int y, int z) {
//		printf("%d %d %d\n", x, y, z);
		add(x, y, z), add(y, x, 0);
	}
	queue <int> que;
	int bfs(int S, int T) {
		memcpy(cur, st, sizeof st);
		memset(dis, 0, sizeof dis);
		while (!que.empty()) que.pop();
		que.push(S);
		dis[S] = 1;
		while(!que.empty()) {
			int now = que.front();
			que.pop();
			for (int i = st[now]; ~i; i = e[i].next)
				if (e[i].flow && !dis[e[i].to]) {
					dis[e[i].to] = dis[now] + 1;
					if (e[i].to == T) return 1;
					que.push(e[i].to);
				}
		}
		return 0;
	}
	int finds(int now, int T, int flow) {
		if (now == T)
			return flow;
		int f;
		for (int i = cur[now]; ~i; i = e[i].next) {
			cur[now] = i;
			if (e[i].flow && dis[e[i].to] == dis[now] + 1 &&
				(f = finds(e[i].to, T, min(flow, e[i].flow)))) {
				e[i].flow -= f;
				e[i^1].flow += f;
				return f;
			}
		}
		return 0;
	}
	int dinic(int S, int T) {
		int flow = 0, x;
		while(bfs(S, T)) {
			while(x = finds(S, T, inf)) {
				flow += x;
			}
		}
		return flow;
	}
}flow;
int n, m, g, v, w, t, id, ans, x, sex[N], want[N];
vector <int> ins[N];
main() {
	scanf("%d%d%d", &n, &m, &g);
	int S = 0, T = n + m + 1;
	flow.init();
	for (int i = 1; i <= n; ++i)
		scanf("%d", &sex[i]);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &v);
		if (sex[i])
			flow.add_edge(i, T, v);
		else
			flow.add_edge(S, i, v);
	}
	for (int i = 1; i <= m; ++i) {
		scanf("%d%d%d", &want[i], &w, &t);
		for (int j = 1; j <= t; ++j) {
			scanf("%d", &id);
			if (sex[id] ^ want[i])
				if (want[i])
					flow.add_edge(id, n + i, inf);
				else
					flow.add_edge(n + i, id, inf);
			ins[id].push_back(i);
		}
		ans += w;
		scanf("%d", &x);
		if (x) w += g;
		if (want[i])
			flow.add_edge(n + i, T, w);
		else
			flow.add_edge(S, n + i, w);
	}
	for (int i = 1; i <= n; ++i)
		for (int j = 0; j < ins[i].size(); ++j)
			for (int k = j + 1; k < ins[i].size(); ++k)
				if (want[ins[i][j]] ^ want[ins[i][k]])
					if (want[ins[i][j]])
						flow.add_edge(n + ins[i][k], n + ins[i][j], inf);
					else
						flow.add_edge(n + ins[i][j], n + ins[i][k], inf);
	printf("%d", ans - flow.dinic(S, T));
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define M 20100
#define N 10100
using namespace std;
const int inf = 0x3f3f3f3f;
struct flows {
	struct node {
		int to, next, flow;
	} e[M];
	int tot, st[N], dis[N], cur[N];
	void init() {
		tot = -1, memset(e, -1, sizeof e),
		memset(st, -1, sizeof st);
	}
	void add(int x, int y, int z) {
		e[++tot].to = y;
		e[tot].flow = z;
		e[tot].next = st[x];
		st[x] = tot;
	}
	void add_edge(int x, int y, int z) {
//		printf("%d %d %d\n", x, y, z);
		add(x, y, z), add(y, x, 0);
		add(x, y, 0), add(y, x, z);
	}
	queue <int> que;
	int bfs(int S, int T) {
		memcpy(cur, st, sizeof st);
		memset(dis, 0, sizeof dis);
		while (!que.empty()) que.pop();
		que.push(S);
		dis[S] = 1;
		while(!que.empty()) {
			int now = que.front();
			que.pop();
			for (int i = st[now]; ~i; i = e[i].next)
				if (e[i].flow && !dis[e[i].to]) {
					dis[e[i].to] = dis[now] + 1;
					if (e[i].to == T) return 1;
					que.push(e[i].to);
				}
		}
		return 0;
	}
	int finds(int now, int T, int flow) {
		if (now == T)
			return flow;
		int f;
		for (int i = cur[now]; ~i; i = e[i].next) {
			cur[now] = i;
			if (e[i].flow && dis[e[i].to] == dis[now] + 1 &&
				(f = finds(e[i].to, T, min(flow, e[i].flow)))) {
				e[i].flow -= f;
				e[i^1].flow += f;
				return f;
			}
		}
		return 0;
	}
	int dinic(int S, int T) {
		int flow = 0, x;
		while(bfs(S, T)) {
			while(x = finds(S, T, inf)) {
				flow += x;
			}
		}
		return flow;
	}
}flow;
int n, m, g, v, w, t, id, ans, x, sex[N], want[N], ins[N][N];
main() {
	scanf("%d%d%d", &n, &m, &g);
	int S = 0, T = n + m + 1;
	flow.init();
	for (int i = 1; i <= n; ++i)
		scanf("%d", &sex[i]);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &v);
		if (sex[i])
			flow.add_edge(i, T, v);
		else
			flow.add_edge(S, i, v);
	}
	for (int i = 1; i <= m; ++i) {
		scanf("%d%d%d", &want[i], &w, &t);
		for (int j = 1; j <= t; ++j) {
			scanf("%d", &id);
			if (sex[id] ^ want[i])
				if (want[i])
					flow.add_edge(id, n + i, inf);
				else
					flow.add_edge(n + i, id, inf);
			ins[id][++ins[id][0]] = i;
		}
		ans += w;
		scanf("%d", &x);
		if (x) w += g;
		if (want[i])
			flow.add_edge(n + i, T, w);
		else
			flow.add_edge(S, n + 1, w);
	}
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= ins[i][0]; ++j)
			for (int k = j + 1; k <= ins[i][0]; ++k)
				if (want[ins[i][j]] ^ want[ins[i][k]])
					if (want[ins[i][j]])
						flow.add_edge(n + ins[i][k], n + ins[i][j], inf);
					else
						flow.add_edge(n + ins[i][j], n + ins[i][k], inf);
	printf("%d", ans - flow.dinic(S, T));
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define N 20010
using namespace std;
const int inf = 0x3f3f3f3f;
struct flows {
	struct node {
		int to, next, flow;
	}e[N * 41];
	int tot, st[N], dis[N], cur[N];
	void init() {
		tot = -1, memset(e, -1, sizeof e),
		memset(st, -1, sizeof st);
	}
	void add(int x, int y, int z) {
		e[++tot].to = y;
		e[tot].flow = z;
		e[tot].next = st[x];
		st[x] = tot;
	}
	void add_edge(int x, int y, int z) {
//		printf("%d %d %d\n", x, y, z);
		add(x, y, z), add(y, x, 0);
		add(x, y, 0), add(y, x, z);
	}
	queue <int> que;
	int bfs(int S, int T) {
		memcpy(cur, st, sizeof st);
		memset(dis, 0, sizeof dis);
		while (!que.empty()) que.pop();
		que.push(S);
		dis[S] = 1;
		while(!que.empty()) {
			int now = que.front();
			que.pop();
			for (int i = st[now]; ~i; i = e[i].next)
				if (e[i].flow && !dis[e[i].to]) {
					dis[e[i].to] = dis[now] + 1;
					if (e[i].to == T) return 1;
					que.push(e[i].to);
				}
		}
		return 0;
	}
	int finds(int now, int T, int flow) {
		if (now == T)
			return flow;
		int f;
		for (int i = cur[now]; ~i; i = e[i].next) {
			cur[now] = i;
			if (e[i].flow && dis[e[i].to] == dis[now] + 1 &&
				(f = finds(e[i].to, T, min(flow, e[i].flow)))) {
				e[i].flow -= f;
				e[i^1].flow += f;
				return f;
			}
		}
		return 0;
	}
	int dinic(int S, int T) {
		int flow = 0, x;
		while(bfs(S, T)) {
			while(x = finds(S, T, inf)) {
				flow += x;
			}
		}
		return flow;
	}
}flow;
int n, m, g, v, w, t, id, ans, x, sex[N], want[N];
vector <int> ins[N];
main() {
	scanf("%d%d%d", &n, &m, &g);
	int S = 0, T = n + m + 1;
	flow.init();
	for (int i = 1; i <= n; ++i)
		scanf("%d", &sex[i]);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &v);
		if (sex[i])
			flow.add_edge(i, T, v);
		else
			flow.add_edge(S, i, v);
	}
	for (int i = 1; i <= m; ++i) {
		scanf("%d%d%d", &want[i], &w, &t);
		for (int j = 1; j <= t; ++j) {
			scanf("%d", &id);
			if (sex[id] ^ want[i])
				if (want[i])
					flow.add_edge(id, n + i, inf);
				else
					flow.add_edge(n + i, id, inf);
			ins[id].push_back(i);
		}
		ans += w;
		scanf("%d", &x);
		if (x) w += g;
		if (want[i])
			flow.add_edge(n + i, T, w);
		else
			flow.add_edge(S, n + 1, w);
	}
	for (int i = 1; i <= n; ++i)
		for (int j = 0; j < ins[i].size(); ++j)
			for (int k = j + 1; k < ins[i].size(); ++k)
				if (want[ins[i][j]] ^ want[ins[i][k]])
					if (want[ins[i][j]])
						flow.add_edge(n + ins[i][k], n + ins[i][j], inf);
					else
						flow.add_edge(n + ins[i][j], n + ins[i][k], inf);
	printf("%d", ans - flow.dinic(S, T));
}


#include<iostream>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 200005;
const int INF = 0x3f3f3f3f;
//vector<int> G[N];
int level[N], iter[N], head[N], tot = 1, n, m, s, t;
struct node{
	int to, w, rev, nxt;
}e[N << 1];
void add(int u, int v, int w)
{
	e[tot].to = v, e[tot].w = w, e[tot].rev = tot + 1, e[tot].nxt = head[u], head[u] = tot++;
	e[tot].to = u, e[tot].w = 0, e[tot].rev = tot - 1, e[tot].nxt = head[v], head[v] = tot++;
}
void bfs(int s)
{
	memset(level, -1, sizeof(level));
	queue<int> que;
	que.push(s);
	level[s] = 0;
	while (!que.empty())
	{
		int x = que.front();
		que.pop();
		for (int i = head[x]; i; i = e[i].nxt)
		{
			int v = e[i].to;
			if (e[i].w > 0 && level[v] == -1)
			{
				level[v] = level[x] + 1;
				que.push(v);
			}
		}
	}
}
int dfs(int v, int t, int f)
{
	if (v == t)
		return f;
	for (int &i = iter[v]; i; i = e[i].nxt)
	{
		node & eg = e[i];
		if (eg.w > 0 && level[v] < level[eg.to])
		{
			int d = dfs(eg.to, t, min(f, eg.w));
			if (d > 0)
			{
				eg.w -= d;
				e[eg.rev].w += d;
				return d;
			}
		}
	}
	return 0;
}
ll dinic(int s, int t)
{
	ll flow = 0;
	for (; ;)
	{
		bfs(s);
		if (level[t] < 0)	return flow;
		for (int i = 0; i <= t; i++)
			iter[i] = head[i];
		int f;
		while ((f = dfs(s, t, INF)) > 0)
			flow += f;
	}
}

int sum, g, a, w, num, x;
char ch[10005];
int main()
{
	scanf("%d%d%d", &n, &m, &g);
	s = n + m, t = s + 1;
	for (int i = 0; i < n; i++)
		scanf(" %c", &ch[i]);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &x);
		if (ch[i] == '0')
		{
			add(s, i, x);
		}
		else
		{
			add(i, t, x);
		}
	}
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &w, &num);
		sum += w;
		for (int j = 0; j < num; j++)
		{
			scanf("%d", &x);
			if (a == 0)
				add(i + n, x - 1, INF);
			else
				add(x - 1, i + n, INF);
		}
		scanf("%d", &num);
		if (num)
			w += g;
		if (a)
			add(i + n, t, w);
		else
			add(s, i + n, w);
	}
	printf("%d", sum - dinic(s, t));
}


/*Lucky_Glass*/
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=1e4,inf=(1<<29),M=2000;

struct EDGE{int to,lim;EDGE *nxt,*rev;}*cpy[N+M+10];
struct FLOWGRAPH{
	EDGE edg[3*(N+M*10+M)],*ncnt,*top[N+M+10];
	FLOWGRAPH(){ncnt=edg;}
	void AddEdge(int u,int v,int lim){
		EDGE *p=++ncnt,*q=++ncnt;
		*p=(EDGE){v,lim,top[u],q};top[u]=p;
		*q=(EDGE){u,0  ,top[v],p};top[v]=q;
	}
}Gflw;

int n,m,Vg,Ps,Pt,Vtot;
int Cs[N+3],Cv[N+3],Cp[N+3],rnk[N+M+10];

bool BFS(){
	for(int i=1;i<=Pt;i++) rnk[i]=0;
	queue<int> que;
	que.push(Ps);rnk[Ps]=1;
	while(!que.empty()){
		int u=que.front();que.pop();
		for(EDGE *it=Gflw.top[u];it;it=it->nxt){
			int v=it->to;
			if(!it->lim || rnk[v]) continue;
			rnk[v]=rnk[u]+1;
			if(v==Pt) return true;
			que.push(v);
		}
	}
	return rnk[Pt]!=0;
}
int GetFlow(int u,int flwin){
	if(u==Pt) return flwin;
	int flwout=0;
	for(EDGE *it=cpy[u];it;it=it->nxt){
		cpy[u]=it;
		int v=it->to;
		if(!it->lim || rnk[v]!=rnk[u]+1) continue;
		int flwv=GetFlow(v,min(flwin-flwout,it->lim));
		it->lim-=flwv;it->rev->lim+=flwv;
		flwout+=flwv;
		if(flwout==flwin) break;
	}
	return flwout;
}
int Dinic(){
	int ret=0;
	while(BFS()){
		memcpy(cpy,Gflw.top,sizeof Gflw.top);
		ret+=GetFlow(Ps,inf);
	}
	return ret;
}
int main(){
	scanf("%d%d%d",&n,&m,&Vg);
	Ps=n+m+1;Pt=n+m+2;
	for(int i=1;i<=n;i++) scanf("%d\n",&Cs[i]);
	for(int i=1;i<=n;i++) scanf("%d\n",&Cv[i]);
	for(int i=1;i<=n;i++){
		if(Cs[i]) Gflw.AddEdge(Ps,i,Cv[i]);
		else Gflw.AddEdge(i,Pt,Cv[i]);
	}
	for(int i=1;i<=m;i++){
		int Vs,Vw,Vn,Vt;
		scanf("%d%d%d",&Vs,&Vw,&Vn);Vtot+=Vw;
		for(int j=1;j<=Vn;j++) scanf("%d",&Cp[j]);
		scanf("%d",&Vt);
		if(Vs){
			if(Vt) Gflw.AddEdge(Ps,n+i,Vw+Vg);
			else Gflw.AddEdge(Ps,n+i,Vw);
			for(int j=1;j<=Vn;j++)
				Gflw.AddEdge(n+i,Cp[j],inf);
		}
		else{
			if(Vt) Gflw.AddEdge(n+i,Pt,Vw+Vg);
			else Gflw.AddEdge(n+i,Pt,Vw);
			for(int j=1;j<=Vn;j++)
				Gflw.AddEdge(Cp[j],n+i,inf);
		}
	}
	printf("%d\n",Vtot-Dinic());
	return 0;
}


#include<bits/stdc++.h>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define LL long long
#define inf (0x3f3f3f3f)
#define NN 20010
using namespace std;
template<typename T>void read(T &x){
    x=0;int f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-48;
    x*=f;
}
vector<int>e[NN];
vector<int>c[NN];
vector<int>fan[NN];
inline void jb(int u,int v,int cc){
    e[u].push_back(v);
    e[v].push_back(u);
    c[u].push_back(cc);
    c[v].push_back(0);
    fan[u].push_back(e[v].size()-1);
    fan[v].push_back(e[u].size()-1);
}
inline void jbb(int u,int v,int cc){
    e[u].push_back(v);
    e[v].push_back(u);
    c[u].push_back(cc);
    c[v].push_back(cc);
    fan[u].push_back(e[v].size()-1);
    fan[v].push_back(e[u].size()-1);
}
int s,t,ans,n,m,g;
int dis[NN];
int bfs(){
	static int dl[NN],l,r;
    for(int i=1;i<=r;++i) dis[dl[i]]=-1;
    l=1,r=1;
    dl[1]=s;
    dis[s]=1;
    while(l<=r){
        int x=dl[l];
        int si=e[x].size();
  		if (si>0) for(int i=0;i<=si-1;++i){
            int u=e[x][i];
            if (c[x][i]&&dis[u]==-1){
                dis[u]=dis[x]+1;++r;dl[r]=u;
            }
        }
        ++l;
    }
    if (dis[t]==-1) return 0;
    else return 1;
}
int cur[NN];
int dfs(int x,int flow){
    if (x==t) return flow;
    else {
    	int used=0;
        int si=e[x].size();
        for(int i=cur[x];i<=si-1;++i){
            int u=e[x][i];
            if(dis[u]==dis[x]+1&&c[x][i]) {
                int ha=dfs(u,min(flow-used,c[x][i]));
                if (ha){
                    c[x][i]-=ha;
                    c[u][fan[x][i]]+=ha;
                    used+=ha;
                    if(used==flow)return used;
                }
            }
            cur[x]=i;
        }
        return used;
    }
}
int sx[10010];
int main(){
    read(n);read(m);read(g);
    s=0,t=n+m+1;
    for(int i=1;i<=n;++i) read(sx[i]);
    for(int i=1;i<=n;++i){
    	int x;read(x);
		if(!sx[i]) jb(s,i,x);
			else jb(i,t,x);
	}
	for(int i=1;i<=m;++i){
		int op,ww,kk,py;
		read(op);
		read(ww);read(kk); ans+=ww;
		for(int j=1;j<=kk;++j){
			int x;
			read(x);
			if(!op) jb(n+i,x,inf);
			else jb(x,n+i,inf);
		}
		read(py);
		if(py) ww+=g;
//		jb(n+i,n+m+i,ww);
		if(!op) jb(s,n+i,ww);
			else jb(n+i,t,ww);
	}
    memset(dis,-1,sizeof(dis));
    while(bfs()){
    	memset(cur,0,sizeof(cur));
    	ans-=dfs(s,inf);
	}
    cout<<ans<<endl;
    return 0;
}


import	java.io.*;
import	java.util.*;
public	class	Main{
	public	static	void	main(String[]args)throws	Exception{
		ScanReader	in=new	ScanReader(System.in);
		int	s=0,d=in.nextInt(),n=d+in.nextInt(),q=in.nextInt(),w,x=0,y;
		boolean	f,F[]=new	boolean[n];
		Net	G=new	Net(2+n,n+10*(n-d)<<1);
		for(G.InClr(2+n,n,1+n);d>x;F[x++]=0<in.nextInt());
		for(x=0;d>x;++x)
			if(F[x])	G.DaddE(x,G.t,in.nextInt());
			else	G.DaddE(G.s,x,in.nextInt());
		for(x=n;d<x--;){
			f=0<in.nextInt();s+=w=in.nextInt();y=in.nextInt();
			if(f)	for(;0<y--;G.DaddE(in.nextInt()-1,x,G.INF));
			else	for(;0<y--;G.DaddE(x,in.nextInt()-1,G.INF));
			w+=0<in.nextInt()?q:0;
			if(f)	G.DaddE(x,G.t,w);else	G.DaddE(G.s,x,w);
		}
		System.out.print(s-G.maxFlow());
	}
}
class	Net{
	public	final	int	N,M,INF;
	int	n,m,s,t;
	private	int[]H,D,P;
	private	class	Edge{int	y,w,p;}
	private	Edge[]G;
	public	Net(int	_N,int	_M,int	_INF){
		H=new	int[N=_N];D=new	int[N];P=new	int[1+N];
		for(INF=_INF,G=new	Edge[m=M=_M];0<m;G[--m]=new	Edge());
	}
	public	Net(int	_N,int	_M){this(_N,_M,Integer.MAX_VALUE>>1);}
	public	void	InClr(int	_n,int	_s,int	_t){
		Arrays.fill(H,m=0,n=_n,-1);s=_s;t=_t;
	}
	void	addE(int	x,int	y,int	w){
		G[m].y=y;G[m].w=w;G[m].p=H[x];H[x]=m++;
	}
	public	void	DaddE(int	x,int	y,int	w){
		addE(x,y,w);addE(y,x,0);
	}
	private	int	ExPh(int	x,int	w){
		if(t==x)	return	w;
		int	d=n,a=0,c,p=H[x];
		for(Edge	E;-1<p&&w>a;p=E.p)	if(0<(E=G[p]).w){
			if(1+D[E.y]==D[x]){
				a+=c=ExPh(E.y,Math.min(E.w,w-a));
				E.w-=c;G[1^p].w+=c;
				if(n==D[s])	return	a;
			}d=Math.min(d,1+D[E.y]);
		}
		if(1>a){if(1>--P[D[x]])	D[s]=n;++P[D[x]=d];}
		return	a;
	}
	private	int	ISAP(){
		int	a=0;
		Arrays.fill(D,0,n,0);Arrays.fill(P,1,n,0);
		for(P[0]=n;n>D[s];a+=ExPh(s,INF));
		return	a;
	}
	public	int	maxFlow(){return	ISAP();}
}
class	ScanReader{
	private	final	StreamTokenizer	st;
	public	ScanReader(Reader	in){
		if(null==in)	throw	new	NullPointerException();
		st=new	StreamTokenizer(new	BufferedReader(in));
	}
	public	ScanReader(InputStream	in){
		this(null!=in?new	InputStreamReader(in):null);
	}
	private	boolean	eof(){
		int	ttype=0;
		try{ttype=st.nextToken();}
		catch(IOException	e){throw	new	RuntimeException(e);}
		return	StreamTokenizer.TT_EOF==ttype;
	}
	public	int	nextInt(){
		if(eof())	throw	new	NoSuchElementException();
		return	(int)st.nval;
	}
}


import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author sheep
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		Task solver = new Task();
		solver.solve(1, in, out);
		out.close();
	}
}

class Task {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int m = in.nextInt();
        int g = in.nextInt();

        int[] gender = new int[n];
        int[] cost = new int[n];

        for (int i = 0; i < n; ++i) {
            gender[i] = in.nextInt();
        }

        for (int i = 0; i < n; ++i) {
            cost[i] = in.nextInt();
        }

        int source = n + m, target = source + 1;
        MaxFlow maxFlow = new MaxFlow(n + m + 2, source, target);

        for (int i = 0; i < n; ++i) {
            if (gender[i] == 0) {
                maxFlow.insert(source, i, cost[i]);
            } else {
                maxFlow.insert(i, target, cost[i]);
            }
        }

        int[][] dogs = new int[m][];
        int[] appGender = new int[m];

        int costSum = 0;
        for (int i = 0; i < m; ++i) {
            int appointedGender = in.nextInt();
            int w = in.nextInt();
            int k = in.nextInt();

            dogs[i] = new int[k];

            appGender[i] = appointedGender;

            for (int j = 0; j < k; ++j) {
                int chosen = in.nextInt() - 1;
                dogs[i][j] = chosen;
                if (appointedGender == 0) {
                    maxFlow.insert(i + n, chosen, 0x3f3f3f3f);
                } else {
                    maxFlow.insert(chosen, i + n, 0x3f3f3f3f);
                }

            }

            Arrays.sort(dogs[i]);

            int isFriend = in.nextInt();

            costSum += w;
            int weight = (isFriend == 1 ? g + w : w);
            if (appointedGender == 0) {
                maxFlow.insert(source, i + n, weight);
            } else {
                maxFlow.insert(i + n, target, weight);
            }
        }

//        for (int i = 0; i < m; ++i) {
//            for (int j = 0; j < m; ++j) {
//                if (appGender[i] == 0 && appGender[j] == 1) {
//                    if (intersect(dogs[i], dogs[j])) {
//                        maxFlow.insert(i + n, j + n, 0x3f3f3f3f);
//                    }
//                }
//            }
//        }

        out.println(costSum - maxFlow.maxFlow());
    }

    }

class MaxFlow
{
    public class Edge
    {
        public int u,v,c;
        public Edge next,r;

        public Edge(int u,int v,int c)
        {
            this.u = u;
            this.v = v;
            this.c = c;
            next = r = null;
        }
    }

    public Edge vertex[];
    public int height[], nheight[];
    public int s, t, n;

    public void init(int n,int s,int t)
    {
        height = new int[n+1];
        nheight = new int[n+1];
        vertex = new Edge[n+1];
        this.s = s;
        this.t = t;
        this.n = n;
    }

    public MaxFlow(int n,int s,int t)
    {
        init(n,s,t);
    }

    public void insert(int u,int v,int c)
    {
        Edge e = new Edge(u,v,c);
        Edge r = new Edge(v,u,0);
        e.r = r;
        r.r = e;
        e.next = vertex[u];
        vertex[u] = e;
        r.next = vertex[v];
        vertex[v] = r;
    }

    public int augPath(int u,int push)
    {
        if (u == t) return push;
        int flow = push, minheight = n-1;
        for (Edge e = vertex[u]; e != null; e = e.next)
            if (e.c != 0)
            {
                if (height[e.v] + 1 == height[e.u])
                {
                    int delta = flow < e.c ? flow : e.c;
                    if (delta > 0)
                        delta = augPath(e.v,delta);
                    e.c -= delta;
                    e.r.c += delta;
                    flow -= delta;
                    if (0 == flow || height[s] >= n) return push - flow;
                }
                minheight = Math.min(minheight, height[e.v]);
            }
        if (push == flow)
        {
            --nheight[height[u]];
            if (0 == nheight[height[u]]) height[s] = n;
            height[u] = ++minheight;
            ++nheight[height[u]];
        }
        return push - flow;
    }

    public int maxFlow()
    {
        Arrays.fill(height, 0);
        Arrays.fill(nheight, 0);
        nheight[0] = n;
        int flow = 0;
        while (height[s] < n)
            flow += augPath(s,Integer.MAX_VALUE);
        return flow;
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (Exception e) {
                throw new UnknownError();
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    }


import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author sheep
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		Task solver = new Task();
		solver.solve(1, in, out);
		out.close();
	}
}

class Task {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int m = in.nextInt();
        int g = in.nextInt();

        int[] gender = new int[n];
        int[] cost = new int[n];

        for (int i = 0; i < n; ++i) {
            gender[i] = in.nextInt();
        }

        for (int i = 0; i < n; ++i) {
            cost[i] = in.nextInt();
        }

        int source = n + m, target = source + 1;
        MaxFlow maxFlow = new MaxFlow(n + m + 2, source, target);

        for (int i = 0; i < n; ++i) {
            if (gender[i] == 0) {
                maxFlow.insert(source, i, cost[i]);
            } else {
                maxFlow.insert(i, target, cost[i]);
            }
        }

        int[][] dogs = new int[m][];
        int[] appGender = new int[m];

        int costSum = 0;
        for (int i = 0; i < m; ++i) {
            int appointedGender = in.nextInt();
            int w = in.nextInt();
            int k = in.nextInt();

            dogs[i] = new int[k];

            appGender[i] = appointedGender;

            for (int j = 0; j < k; ++j) {
                int chosen = in.nextInt() - 1;
                dogs[i][j] = chosen;
                if (appointedGender == 0) {
                    maxFlow.insert(i + n, chosen, 0x3f3f3f3f);
                } else {
                    maxFlow.insert(chosen, i + n, 0x3f3f3f3f);
                }

            }

            Arrays.sort(dogs[i]);

            int isFriend = in.nextInt();

            costSum += w;
            int weight = (isFriend == 1 ? g + w : w);
            if (appointedGender == 0) {
                maxFlow.insert(source, i + n, weight);
            } else {
                maxFlow.insert(i + n, target, weight);
            }
        }

        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < m; ++j) {
                if (appGender[i] == 0 && appGender[j] == 1) {
                    if (intersect(dogs[i], dogs[j])) {
                        maxFlow.insert(i + n, j + n, 0x3f3f3f3f);
                    }
                }
            }
        }

        out.println(costSum - maxFlow.maxFlow());
    }

    private boolean intersect(int[] x, int[] y) {
        for (int i : x) {
            for (int j : y) {
                if (i == j) {
                    return true;
                }
            }
        }

        return false;
    }
}

class MaxFlow
{
    public class Edge
    {
        public int u,v,c;
        public Edge next,r;

        public Edge(int u,int v,int c)
        {
            this.u = u;
            this.v = v;
            this.c = c;
            next = r = null;
        }
    }

    public Edge vertex[];
    public int height[], nheight[];
    public int s, t, n;

    public void init(int n,int s,int t)
    {
        height = new int[n+1];
        nheight = new int[n+1];
        vertex = new Edge[n+1];
        this.s = s;
        this.t = t;
        this.n = n;
    }

    public MaxFlow(int n,int s,int t)
    {
        init(n,s,t);
    }

    public void insert(int u,int v,int c)
    {
        Edge e = new Edge(u,v,c);
        Edge r = new Edge(v,u,0);
        e.r = r;
        r.r = e;
        e.next = vertex[u];
        vertex[u] = e;
        r.next = vertex[v];
        vertex[v] = r;
    }

    public int augPath(int u,int push)
    {
        if (u == t) return push;
        int flow = push, minheight = n-1;
        for (Edge e = vertex[u]; e != null; e = e.next)
            if (e.c != 0)
            {
                if (height[e.v] + 1 == height[e.u])
                {
                    int delta = flow < e.c ? flow : e.c;
                    if (delta > 0)
                        delta = augPath(e.v,delta);
                    e.c -= delta;
                    e.r.c += delta;
                    flow -= delta;
                    if (0 == flow || height[s] >= n) return push - flow;
                }
                minheight = Math.min(minheight, height[e.v]);
            }
        if (push == flow)
        {
            --nheight[height[u]];
            if (0 == nheight[height[u]]) height[s] = n;
            height[u] = ++minheight;
            ++nheight[height[u]];
        }
        return push - flow;
    }

    public int maxFlow()
    {
        Arrays.fill(height, 0);
        Arrays.fill(nheight, 0);
        nheight[0] = n;
        int flow = 0;
        while (height[s] < n)
            flow += augPath(s,Integer.MAX_VALUE);
        return flow;
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (Exception e) {
                throw new UnknownError();
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    }


import java.util.*;
import java.io.*;
public class CodeforcesE311 {
	public static void main(String[] args){
		Scanner br = new Scanner(System.in);
		int n = br.nextInt();
		int m = br.nextInt();
		int g = br.nextInt();
		int[] gen = new int[n];
		for(int i = 0;i<n;i++){
			gen[i] = br.nextInt();
		}
		int[] vs = new int[n];
		for(int i = 0;i<n;i++){
			vs[i] = br.nextInt();
		}

		person[] ps = new person[m];
		int total = 0;
		for(int i = 0;i<m;i++){
			int a = br.nextInt();
			int b = br.nextInt();
			total+=b;
			int c = br.nextInt();
			int[] ds = new int[c];
			for(int j = 0;j<c;j++){
				ds[j] = br.nextInt()-1;
			}

			int d = br.nextInt();
			if(d == 1){
				b+=g;
			}
			ps[i] = new person(a, b, c, d, ds);
		}

		Dinic d = new Dinic(n+m+2, n+m, n+m+1);
		for(int i = 0;i<n;i++){
			if(gen[i] == 0){
				d.add(n+m, i, vs[i]);
			}
			else{
				d.add(i, n+m+1, vs[i]);
			}
		}

		for(int i = 0;i<m;i++){
			if(ps[i].gen == 0){
				d.add(n+m, i+n, ps[i].w);
				for(int k : ps[i].dogs){

					d.add(i+n, k, 100000000);
				}
			}
			else{
				d.add(i+n, n+m+1, ps[i].w);
				for(int k : ps[i].dogs){

					d.add(k, i+n, 100000000);
				}
			}
		}
		System.out.println(total-d.maxFlow());

	}
	public static class person{
		int gen, w, k, f;
		int[] dogs;
		public person(int a, int b, int c, int d, int[] ds){
			gen = a;
			w = b;
			k = c;
			f = d;
			dogs = ds;
		}
	}
	public static class Dinic {
		ArrayList<Edge>[] gg;
		ArrayDeque<Integer> qu;
		Edge[][] g;
		int src, sink, n;
		int[] dist;
		boolean[] blocked;
		public Dinic(int N, int s, int t) {
			n = N; src = s; sink = t; //src = N++; sink = N++; n = N;
			g = new Edge[n][0];
			gg = new ArrayList[n];
			qu = new ArrayDeque<Integer>();
			for (int i = 0; i < n; gg[i] = new ArrayList<Edge>(),i++);
		}
		public void add(int s, int e, int cap) {
			gg[s].add(new Edge(e, cap, gg[e].size() + (s == e ? 1 : 0)));
			gg[e].add(new Edge(s, 0, gg[s].size() - 1));
		}
		public int maxFlow() {
			for(int i=0;i<n; i++)
				g[i] = gg[i].toArray(g[i]);
			int ans = 0;
			blocked = new boolean[n];
			while (bfs()){
				Arrays.fill(blocked, false);
				ans+=dfs(src, (int)2e9);
			}
			return ans;
		}
		public boolean bfs() {
			dist = new int[n];
			qu.add(sink);
			while(!qu.isEmpty() ){
				int cur = qu.poll();
				if(dist[src] != 0 && dist[cur] >= dist[src]) break;
				for(Edge e : g[cur])
					if(g[e.e][e.rev].flow < g[e.e][e.rev].cap && e.e != sink &&  dist[e.e] == 0){
						qu.add(e.e);
						dist[e.e] = dist[cur]+1;
					}
			}
			qu.clear();
			return (dist[src] != 0);
		}
		public int dfs(int pos, int min) {
			if (pos == sink) return min;
			int flow = 0;
			for (Edge e : g[pos])
				if (!blocked[e.e] && dist[e.e]+1 == dist[pos] && e.flow < e.cap) {
					int cur = dfs(e.e, Math.min(min-flow, e.cap-e.flow));
					g[e.e][e.rev].flow = -(e.flow += cur);
					flow+=cur;
					if(flow == min)
						return flow;
				}
			blocked[pos] |= (flow != min);
			return flow;
		}
		public class Edge {
			int e, flow, rev, cap;
			public Edge(int b, int c, int f) {
				cap = c; e = b; rev = f;
			}
		}
	}
}


import java.util.*;
import java.io.*;
public class CodeforcesE311 {
	public static void main(String[] args){
		Scanner br = new Scanner(System.in);
		int n = br.nextInt();
		int m = br.nextInt();
		int g = br.nextInt();
		int[] gen = new int[n];
		for(int i = 0;i<n;i++){
			gen[i] = br.nextInt();
		}
		int[] vs = new int[n];
		for(int i = 0;i<n;i++){
			vs[i] = br.nextInt();
		}

		person[] ps = new person[m];
		int total = 0;
		for(int i = 0;i<m;i++){
			int a = br.nextInt();
			int b = br.nextInt();
			total+=b;
			int c = br.nextInt();
			int[] ds = new int[c];
			for(int j = 0;j<c;j++){
				ds[j] = br.nextInt()-1;
			}

			int d = br.nextInt();
			if(d == 1){
				b+=g;
			}
			ps[i] = new person(a, b, c, d, ds);
		}

		Dinic d = new Dinic(n+m+2, n+m, n+m+1);
		for(int i = 0;i<n;i++){
			if(gen[i] == 0){
				d.add(n+m, i, vs[i]);
			}
			else{
				d.add(i, n+m+1, vs[i]);
			}
		}

		for(int i = 0;i<m;i++){
			if(ps[i].gen == 0){
				d.add(n+m, i+n, ps[i].w);
				for(int k : ps[i].dogs){
					d.add(k, i+n, 100000000);

					d.add(i+n, k, 100000000);
					if(gen[k] == 1){
					}
				}
			}
			else{
				d.add(i+n, n+m+1, ps[i].w);
				for(int k : ps[i].dogs){
					d.add(k, i+n, 100000000);

					d.add(i+n, k, 100000000);
				}
			}
		}

		System.out.println(total-d.maxFlow());

	}
	public static class person{
		int gen, w, k, f;
		int[] dogs;
		public person(int a, int b, int c, int d, int[] ds){
			gen = a;
			w = b;
			k = c;
			f = d;
			dogs = ds;
		}
	}
	public static class Dinic {
		ArrayList<Edge>[] gg;
		ArrayDeque<Integer> qu;
		Edge[][] g;
		int src, sink, n;
		int[] dist;
		boolean[] blocked;
		public Dinic(int N, int s, int t) {
			n = N; src = s; sink = t; //src = N++; sink = N++; n = N;
			g = new Edge[n][0];
			gg = new ArrayList[n];
			qu = new ArrayDeque<Integer>();
			for (int i = 0; i < n; gg[i] = new ArrayList<Edge>(),i++);
		}
		public void add(int s, int e, int cap) {
			gg[s].add(new Edge(e, cap, gg[e].size() + (s == e ? 1 : 0)));
			gg[e].add(new Edge(s, 0, gg[s].size() - 1));
		}
		public int maxFlow() {
			for(int i=0;i<n; i++)
				g[i] = gg[i].toArray(g[i]);
			int ans = 0;
			blocked = new boolean[n];
			while (bfs()){
				Arrays.fill(blocked, false);
				ans+=dfs(src, (int)2e9);
			}
			return ans;
		}
		public boolean bfs() {
			dist = new int[n];
			qu.add(sink);
			while(!qu.isEmpty() ){
				int cur = qu.poll();
				if(dist[src] != 0 && dist[cur] >= dist[src]) break;
				for(Edge e : g[cur])
					if(g[e.e][e.rev].flow < g[e.e][e.rev].cap && e.e != sink &&  dist[e.e] == 0){
						qu.add(e.e);
						dist[e.e] = dist[cur]+1;
					}
			}
			qu.clear();
			return (dist[src] != 0);
		}
		public int dfs(int pos, int min) {
			if (pos == sink) return min;
			int flow = 0;
			for (Edge e : g[pos])
				if (!blocked[e.e] && dist[e.e]+1 == dist[pos] && e.flow < e.cap) {
					int cur = dfs(e.e, Math.min(min-flow, e.cap-e.flow));
					g[e.e][e.rev].flow = -(e.flow += cur);
					flow+=cur;
					if(flow == min)
						return flow;
				}
			blocked[pos] |= (flow != min);
			return flow;
		}
		public class Edge {
			int e, flow, rev, cap;
			public Edge(int b, int c, int f) {
				cap = c; e = b; rev = f;
			}
		}
	}
}


#include<bits/stdc++.h>
using namespace std;
namespace my_std{
	#define ll long long
	#define bl bool
	bl ccc(int a,int b){
		return a>b;
	}
	ll my_pow(ll a,ll b,ll mod){
		ll res=1;
		if(!b) return 1;
		while(b){
			if(b&1) res=(res*a)%mod;
			a=(a*a)%mod;
			b>>=1;
		}
		return res;
	}
	ll qpow(ll a,ll b){
		ll res=1;
		if(!b) return 1;
		while(b){
			if(b&1) res*=a;
			a*=a;
			b>>=1;
		}
		return res;
	}
	#define db double
	#define pf printf
	#define pc putchar
	#define fr(i,x,y) for(register ll i=(x);i<=(y);i++)
	#define pfr(i,x,y) for(register ll i=(x);i>=(y);i--)
	#define go(u) for(ll i=head[u];i;i=e[i].nxt)
	#define enter pc('\n')
	#define space pc(' ')
	#define fir first
	#define sec second
	#define MP make_pair
	#define il inline
	#define sr(a,b,n) sort((a)+(b),(a)+(n)+(b))
	#define psr(a,b,n) sort((a)+(b),(a)+(n)+(b),ccc)
	#define maxinf 0xffffffff
	#define mininf -0xffffffff
	#define chs(a,b,c) (a)?(b):(c)
	#define random(x) rand()*rand()%(x)
	#define inv(a,mod) my_pow((a),(mod-2),(mod))
	il ll read(){
		ll sum=0,f=1;
		char ch=0;
		while(!isdigit(ch)){
			if(ch=='-') f=-1;
			ch=getchar();
		}
		while(isdigit(ch)){
			sum=sum*10+(ch^48);
			ch=getchar();
		}
		return sum*f;
	}
	il void write(ll x){
		if(x<0){
			x=-x;
			pc('-');
		}
		if(x>9) write(x/10);
		pc(x%10+'0');
	}
	il void writeln(ll x){
		write(x);
		enter;
	}
	il void writesp(ll x){
		write(x);
		space;
	}
}
using namespace my_std;
ll n,m,g,s,t,a[1000001],head[4000004],dep[4000004],cnt=1,ans=0;
queue<ll> q;
struct node{
	ll to,nxt,w;
}e[4000004];
void add1(ll x,ll y,ll z){
	e[++cnt].nxt=head[x];
	e[cnt].to=y;
	e[cnt].w=z;
	head[x]=cnt;
}
void add(ll x,ll y,ll z){
	add1(x,y,z);
	add1(y,x,0);
}
bl bfs(){
	memset(dep,0,sizeof(dep));
    q.push(s);
	dep[s]=1;
    while(!q.empty()){
    	ll u=q.front();
    	q.pop();
    	go(u){
    		ll v=e[i].to;
    		if(e[i].w&&!dep[v]){
    			dep[v]=dep[u]+1;
    			q.push(v);
    		}
    	}
    }
    return dep[t];
}
ll dfs(ll x,ll sum){
	if(x==t) return sum;
	ll k,res=0;
	go(x){
		ll v=e[i].to;
		if(e[i].w>0&&(dep[v]==dep[x]+1)){
			k=dfs(v,min(sum,e[i].w));
			if(!k) dep[v]=maxinf;
			e[i].w-=k;
			e[i^1].w+=k;
			res+=k;
			sum-=k;
		}
	}
	return res;
}
int main(){
	n=read();
	m=read();
	g=read();
	s=0;
	t=n+m+1;
	fr(i,1,n) a[i]=read();
	fr(i,1,n){
		ll v=read();
		if(!a[i]) add(s,i,v);
		else add(i,t,v);
	}
	fr(i,1,m){
		ll p=read(),w=read(),k=read();
		fr(j,1,k){
			ll x=read();
			if(!p) add(n+i,x,maxinf);
			else add(x,n+i,maxinf);
		}
		ll pp=read();
		if(!p) add(s,n+i,w+pp*g);
		else add(n+i,t,w+pp*g);
		ans+=w;
	}
//	write(ans);
//	puts(" ");
	while(bfs()) ans-=dfs(s,maxinf);
	write(ans);
}