jiahuimbzuai/CoQuIR huggingface dataset:
//  [java]
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.stream.IntStream;


public class Main {

	class Container {
		String cityName;
		int score;
		int i;

		Container(String cityName, int score, int i) {
			this.cityName = cityName;
			this.score = score;
			this.i = i;
		}
	}

	// invoked from main
	private void solve() throws Exception {
		int N = in.i(), M = in.i();
		int[] pow2 = new int[N+1];
		pow2[0] = 1;
		for (int i = 1; i <= N; i++)
			pow2[i] = 2*pow2[i-1];

		// 電球M個のon条件をbitで表す
		int[] s = new int[M];
		for (int i = 0; i < M; i++) {
			s[i] = 0;
			int k_i = in.i();
			for (int j = 0; j < k_i; j++)
				s[i] += pow2[in.i()-1];
		}

		int[] p = new int[M];
		for (int i = 0; i < M; i++)
			p[i] = in.i();

		int count = 0;
		label: for (int i = 0; i < pow2[N]; i++) {
			for (int j = 0; j < M ; j++)
				if (Integer.bitCount(i & s[j]) % 2 != p[j])
					continue label;
			count++;
		}

		out.println(count);
	}


	public static void main(String[] args) throws Exception {
		instance.solve();
	}

	static PrintStream out = System.out;
	static FastReader in = new FastReader();
	static Main instance = new Main();
}

class FastReader {
	final private int BUF_SIZE = 1 << 16;
	private DataInputStream din = new DataInputStream(System.in);
	private byte[] buffer = new byte[BUF_SIZE];
	private int bufferPointer, bytesRead;

	String s() throws IOException {
		return s(64);
	}

	// make for line
	String s(int capacity) throws IOException {
		byte[] buf = new byte[capacity];
		int cnt = 0, c;
		while ((c = c()) != -1) {
			if (Character.isSpaceChar(c)) break;
			buf[cnt++] = (byte) c;
		}
		return new String(buf, 0, cnt);
	}

	int i() throws IOException {
		int ret = 0;
		byte c = c();
		while (c <= ' ') c = c();
		boolean neg = (c == '-');
		if (neg) c = c();
		do {
			ret = ret * 10 + c - '0';
		} while ((c = c()) >= '0' && c <= '9');
		return neg ? -ret : ret;
	}

	long l() throws IOException {
		long ret = 0;
		byte c = c();
		while (c <= ' ') c = c();
		boolean neg = (c == '-');
		if (neg) c = c();
		do {
			ret = ret * 10 + c - '0';
		} while ((c = c()) >= '0' && c <= '9');
		return neg ? -ret : ret;
	}

	double d() throws IOException {
		double ret = 0, div = 1;
		byte c = c();
		while (c <= ' ') c = c();
		boolean neg = (c == '-');
		if (neg) c = c();
		do {
			ret = ret * 10 + c - '0';
		} while ((c = c()) >= '0' && c <= '9');
		if (c == '.')
			while ((c = c()) >= '0' && c <= '9')
				ret += (c - '0') / (div *= 10);
		return neg ? -ret : ret;
	}

	private void fillBuffer() throws IOException {
		bytesRead = din.read(buffer, bufferPointer = 0, BUF_SIZE);
		if (bytesRead == -1) buffer[0] = -1;
	}

	byte c() throws IOException {
		if (bufferPointer == bytesRead) fillBuffer();
		return buffer[bufferPointer++];
	}
}
//  [java]
import java.util.Arrays;
import java.util.Scanner;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {

	public static void main(String[] args) {
		try (Scanner scanner = new Scanner(System.in)) {
			int n = scanner.nextInt(), m = scanner.nextInt();
			@SuppressWarnings("unchecked")
			Set<Integer>[] sets = new Set[m];
			IntStream.range(0, m).forEach(i -> {
				int k = scanner.nextInt();
				sets[i] = IntStream.range(0, k).map(j -> scanner.nextInt()).boxed().collect(Collectors.toSet());
			});
			int[] p = IntStream.range(0, m).map(i -> scanner.nextInt()).toArray();
			int[] counts = new int[m];
			System.out.println(IntStream.range(1, 1 << n).filter(i -> {
				Arrays.fill(counts, 0);
				IntStream.range(0, n).filter(j -> (i & (1 << j)) > 0).forEach(j -> {
					IntStream.range(0, m).forEach(k -> counts[k] += sets[k].contains(j + 1) ? 1 : 0);
				});
				return m == IntStream.range(0, m).filter(j -> p[j] == (1 & counts[j])).count();
			}).count());
		}
	}
}
//  [java]
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) throws FileNotFoundException {

		//    	File file = new File("src/in.txt");
		//    	Scanner sc = new Scanner(file);

		Scanner sc = new Scanner(System.in);

		int N = sc.nextInt();
		int M = sc.nextInt();

		int[][] s = new int[M][N];

		for (int i = 0; i < M; i++) {
			int k = sc.nextInt();
			for (int j = 0; j < k; j++) {
				int num = sc.nextInt()-1;
				s[i][num] = 1;
			}
		}

		int[] p = new int[M];
		for (int i = 0; i < M; i++) {
			p[i] = sc.nextInt();
		}

		int ans = 0;
		for (int i = 0; i < 1 << N; i++) {
			boolean flg = true;
			// bit全探索の全通りのloop
			int[] A = new int[N];
			for (int j = 0; j < N; j++) {
				if ((1 & i >> j) == 1) {
					A[j] = 1;
				}
			}

			for (int k = 0; k < M; k++) {
				int sum = 0;
				for (int l = 0; l < N; l++) {
					sum = sum + s[k][l] * A[l];
				}
				if (sum%2 == p[k]) {
					flg = false;
				}
			}
			if (flg == true) {
				ans++;
			}
		}
		System.out.println(ans);

	}
}
//  [java]
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int switchCount = sc.nextInt();
		int lampCount = sc.nextInt();
		List<int[]> switchInfo = new ArrayList<int[]>();
		for(int i =0;i < lampCount;i++) {
			int connectSwitch = sc.nextInt();
			int[] connectSwitchInfo = new int[connectSwitch];
			for(int j =0; j < connectSwitch; j++) {
				connectSwitchInfo[j] = sc.nextInt();
			}
			switchInfo.add(connectSwitchInfo);
		}
		int[] onOffInfo = new int[lampCount];
		for(int i =0;i < lampCount; i++) {
			onOffInfo[i] = sc.nextInt();
		}
		int answer = 0;
		for(int i =0;i < 1 <<switchCount;i++) {
			for(int j =0; j < lampCount;j++) {
				int switchOnCount = 0;
				for(int k =0; k < switchInfo.get(j).length;k++) {
					if((1 & (i >> k)) == 1 ) {
						switchOnCount++;
					}
				}
				if(switchOnCount % 2 != onOffInfo[j]) {
					break;
				}
				if(j ==lampCount-1) {
					answer++;
				}
			}
		}
		System.out.println(answer);
	}
}
//  [cpp]
#include <bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define EPS (1e-10)
using namespace std;
typedef long long ll;
typedef pair<int,int>P;

vector<int>v[20];
int p[20];

int main(){
	int n,m;cin>>n>>m;
	rep(i,m){
		int a;scanf("%d",&a);
		rep(j,a){
			int b;scanf("%d",&b);b--;
			v[i].push_back(b);
		}
	}
	rep(i,m){
		scanf("%d",&p[i]);
	}
	int ans=0;
	rep(i,1<<n){
		bool ok=true;
		rep(j,m){
			int cnt=0;
			for(int k:v[j]){
				if(i>>k&1)cnt^=1;
			}
			if(cnt!=p[j])ok=false;
		}
		ans+=ok;
	}
	cout<<ans<<endl;
}
//  [cpp]
#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define repp(i, l, r) for(int i = (l); i < (r); i++)
#define per(i, n) for(int i = ((n)-1); i >= 0; i--)
#define perr(i, l, r) for(int i = ((r)-1); i >= (l); i--)
#define all(x) (x).begin(),(x).end()
#define MOD 1000000007
#define IINF 1000000000
#define LINF 1000000000000000000
#define SP <<" "<<
#define CYES cout<<"Yes"<<endl
#define CNO cout<<"No"<<endl
#define CFS cin.tie(0);ios::sync_with_stdio(false)

typedef long long LL;
typedef long double LD;

int main(){
  int n,m;
  cin >> n >> m;
  vector<vector<int>> w(m,vector<int>(n,0));
  vector<int> p(m);
  rep(i,m){
    int k;
    cin >> k;
    int s;
    rep(j,k){
      cin >> s;
      w[i][s-1]=1;
    }
  }
  rep(i,m) cin >> p[i];
  int ans=0;
  rep(i,(1<<n)){
    int tmp=0;
    rep(j,m){
      int x=0;
      rep(k,n){
        if((i&(1<<k))&&w[j][k]) x++;
      }
      if(x%2==p[j]) tmp++;
    }
    if(tmp==m) ans++;
  }
  cout << ans << endl;
  return 0;
}
//  [cpp]
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
using pii=pair<int,int>;
using vi = vector<int>;
using vvi = vector<vi>;
#define all(c) begin(c),end(c)
#define rall(c) rbegin(c),rend(c)
#define fore(x,c) for(auto &&x:c)
#define rep(i,a,n) for(int i=a,i##len=(int)(n);i<i##len;++i)
#define rrep(i, a, n) for(int i=(int)(n-1);i>=a;--i)
#define sz(c) ((int)c.size())
#define contains(c,x) (c.find(x)!=end(c))
#define inseg(l,x,r) ((l)<=(x)&&(x)<(r))
#define dump(...)
#define pb push_back
#define _ 0
const signed INF_=1001001001; const long long INF=1001001001001001001LL;
const int DX[9]={0,1,0,-1,1,1,-1,-1,0},DY[9]={-1,0,1,0,-1,1,1,-1,0};
template<class T> ostream& operator<<(ostream &os,const vector<T> &v) {
    for (auto i = begin(v); i != end(v); i++) os<<*i<<(i==end(v)-1?"":" ");return os;}
template<class T> istream& operator>>(istream &is,vector<T> &v) {
    for (auto i = begin(v); i != end(v); i++) is>>*i;return is;}
template<class T,class U> istream& operator>>(istream &is, pair<T,U> &p) {
    is>>p.first>>p.second;return is;}
template<class T, class U> bool chmax(T &a,const U &b){return a<b?a=b,1:0;}
template<class T, class U> bool chmin(T &a,const U &b){return a>b?a=b,1:0;}
template <class T> void psum(T& c) {partial_sum(begin(c), end(c), begin(c));}
template<class T> using heap=priority_queue<T,vector<T>,greater<T>>;
struct before_main_function {
    before_main_function() {
        cin.tie(nullptr); ios::sync_with_stdio(0);
        cout << setprecision(15) << fixed;
        // #define endl "\n"
    }
} before_main_function;
//------------------8<------------------------------------8<--------------------

signed main() {
    int N, M;
    cin >> N >> M;
    vector<vector<int>> s(M);
    rep(i, 0, M) {
        int k;
        cin >> k;
        s[i].resize(k);
        cin >> s[i];
        for (int &x : s[i]) x--;
    }
    vector<int> p(M);
    cin >> p;
    int ans = 0;
    rep(i, 0, 1 << N) {
        bool ok = true;
        rep(j, 0, M) {
            int cnt = 0;
            for (int k : s[j]) {
                if (i >> k & 1) {
                    cnt++;
                }
            }
            if (cnt % 2 != p[j]) {
                ok = false;
            }
        }
        if (ok) ans++;
    }
    cout << ans << endl;
    return (0^_^0);
}
//  [cpp]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
#define rep(i,n) for (int i = 0; i < (n); i++)

int main() {
    int N, M; cin >> N >> M;
    vector<vector<int> > s(M);
    for (int i = 0; i < M; ++i) {
        int k; cin >> k;
        for (int j = 0; j < k; ++j) {
            int a; cin >> a; --a;
            s[i].push_back(a);
        }
    }
    vector<int> p(M);
    for (int i = 0; i < M; ++i) cin >> p[i];

    long long res = 0;
    for (int bit = 0; bit < (1<<N); ++bit) {
      cout << bit << endl;
        bool ok = true;
        for (int i = 0; i < M; ++i) {
            int con = 0;
            for (auto v : s[i]) {
                // onになっているスイッチの数を数える
                if (bit & (1<<v)) ++con;
            }
            // スイッチの数を2で割った個数が不一致の場合
            if (con % 2 != p[i]) ok = false;
        }
        // 不一致が一つもなかった場合にのみ　カウントする
        if (ok) ++res;
    }
    cout << res << endl;
}
//  [cpp]
#include <iostream>
#include <vector>
using namespace std;

int main() {
    int N, M; cin >> N >> M;
    vector<int> s[M];
    for (int i = 0; i < M; i++) {
        int k; cin >> k;
        s[i].resize(k);
        for (int j = 0; j < k; j++) cin >> s[i][j];
    }
    vector<int> p(M);
    for (int i = 0; i < M; i++) cin >> p[i];

    int ans = 0;
    for (int bit = 0; bit < (1<<N); bit++) {
        int sum = 0;
        for (int i = 0; i < M; i++) {
            int cnt = 0;
            for (int j = 0; j < s[i].size(); j++) {
                if ((bit >> s[i][j]) & 1) cnt++;
            }
            if (cnt % 2 == p[i]) sum++;
        }
        if (sum == M) ans++;
    }
    cout << ans << endl;
    return 0;
}
//  [cpp]
#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int,int>;
#define chmax(x,y) x = max(x,y);
#define chmin(x,y) x = min(x,y);
const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, -1, 0, 1};
const int INF = 1001001001;



int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> s(m);
    rep(i,m) {
        int k;
        cin >> k;
        rep(j,k) {
            int a;
            cin >> a;
            s[i].push_back(a);
        }
    }
    vector<int> p(m);
    rep(i,m) cin >> p[i];
    int ans = 0;
    rep(is,1<<n) {
        bool ok = true;
        rep(i,m) {
            int cnt = 0;
            for (int x : s[i]) {
                if (is>>x&1) cnt++;
            }
            cnt %= 2;
            if (cnt != p[i]) ok = false;
        }
        if (ok) ans++;
    }
    cout << ans << endl;
    return 0;
}
//  [c]
#include <stdio.h>
int main(void){
    int n,m,i,j,k,s,ans=0;
    scanf("%d%d",&n,&m);
    int a[10]={0},p=0;
    for(i=0;i<m;i++){
        scanf("%d",&k);
        for(j=0;j<k;j++){
            scanf("%d",&s);
            s--;
            a[s] |= 1<<i;
        }
    }
    for(i=0;i<m;i++){
        scanf("%d",&s);
        p |= s<<i;
    }
    for(i=0;i<(1<<n);i++){
        int t=0;
        for(j=0;j<n;j++){
            if(i>>j&1) t^=a[j];
        }
        if(t==p) ans++;
    }
    printf("%d",ans);
}
//  [c]
#include <stdio.h>
 
int main()
{
	int i, j, N, M, k[11], s[11][11], p[11];
	scanf("%d %d", &N, &M);
	for (i = 1; i <= M; i++) {
		scanf("%d", &(k[i]));
		for (j = 1; j <= k[i]; j++) scanf("%d", &(s[i][j]));
	}
	for (i = 1; i <= M; i++) scanf("%d", &(p[i]));
	
	int count = 0, flag[11] = {}, tmp;
	while (1) {
		for (i = 1; i <= M; i++) {
			tmp = 0;
			for (j = 1; j <= k[i]; j++) {
              if (flag[s[i][j]] == 1) tmp ^= 1;
            }
			if (tmp != p[i]) break;
		}
		
		if (i > M) count++;
		for (i = 1; i <= N; i++) if (flag[i] == 0) break;
		if (i > N) break;
		flag[i] = 1;
		for (i--; i >= 1; i--) flag[i] = 0;
	}
	
	printf("%d\n", count);
	fflush(stdout);
	return 0;
}
//  [c]
#include<stdio.h>

#define N 10
#define M 10

int n, m, k[M], s[M][N], p[M];

int search(int a, int *cnt, int *isSwitch){
  if(a==n){
    int isAllLight=1;
    for(int i=0; i<m; i++){
      int sumSwitchOn=0;
      for(int j=0; j<k[i]; j++){
        if(isSwitch[s[i][j]-1]==1){
          sumSwitchOn++;
        }
      }
      if((sumSwitchOn&1)!=p[i]){
        isAllLight=0;
        break;
      }
    }
    if(isAllLight==1){
      *cnt=*cnt+1;
    }
  }
  else{
    for(int b=0; b<=1; b++){
      isSwitch[a] = b;
      search(a+1, cnt, isSwitch);
    }
  }
  return 0;
}

int main(){
  int isSwitch[N], cnt=0;
  scanf("%d %d", &n, &m);
  for(int i=0; i<m; i++){
    scanf("%d", &k[i]);
    for(int j=0; j<k[i]; j++){
      scanf("%d", &s[i][j]);
    } 
  }
  for(int i=0; i<m; i++){
    scanf("%d", &p[i]);
  }
  
  search(0, &cnt, isSwitch);
  printf("%d",cnt);
  
  return 0;
}
//  [c]
#include <stdio.h>
#include <stdlib.h>

int N, M;   //N個のスイッチとM個の電球
int k[11];  //k個のスイッチにつながってる
int s[11][11];  //k個のスイッチ=s1~sk
int p[11];  //s個のスイッチのうち、オンになっている数を2で割った余りがpの時、点灯

/* ビットの立っているフラグをついてる電球する。s個ずらす方法で比べて、つながってる電球のうちついているものがいくつかを調べる。その調べた個数を2で割ってpと比べる */
int judge(int bit)
{
    int cnt;
    for(int i=1; i<=N; i++) {
        cnt=0;
        for(int j=1; j<=k[i]; j++) {
            if(bit & (1<<(s[i][j]-1))) cnt++;
            // printf("%dの%d回目:%d\n", i, j, cnt);
        }
        if((cnt%2) != p[i]) return 0;
    }
    return 1;
}

int main()
{
    int total=0;
    scanf("%d %d", &N, &M);
    for(int i=1; i<=M; i++) {
        scanf("%d", &k[i]);
        for(int j=1; j<=k[i]; j++) {
            scanf("%d", &s[i][j]);
        }
    }
    for(int i=1; i<=M; i++) scanf("%d", &p[i]);

    for(int bit=0; bit<(1<<N); bit++) {
        if(judge(bit)) total++;
    }

    printf("%d", total);
}
//  [c]
#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
const int INF = 1e9;

int main() {
  int n, m; cin >> n >> m;
  vector<int> k(m);
  vector<vector<int>> s(m);
  vector<int> p(m);

  for (int i = 0; i < m; ++i) {
    cin >> k[i];
    s[i].resize(k[i]);
    for (int j = 0; j < k[i]; ++j) {
      cin >> s[i][j];
      --s[i][j];
    }
  }
  for (int k = 0; k < m; ++k) {
    cin >> p[k];
  }

  int ans = 0;
  for (int bits = 0; bits < (1 << n); ++bits) {
    bool all_ok = true;
    for (int i = 0; i < m; ++i) {
      int cnt = 0;
      for (int j = 0; j < k[i]; ++j) {
        if ( (bits >> j) & 1 ) cnt++;
      }
      if (p[i] != (cnt % 2)) all_ok = false;
    }
    if (all_ok) ++ans;
  }
  cout << ans << endl;
}
//  [c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef long long ll;
#define rep(i,l,r) for(int i=l; i<(int)(r); i++)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
int upcmpll(const void *a, const void *b){
    return (*(ll*)a == *(ll*)b ? 0 : (*(ll*)a > *(ll*)b ? 1 : -1));
}
void sort_u(ll *a, int n){ qsort(a, n, sizeof(ll), upcmpll); }

int k[12], s[12][12], p[12];

int main(){
    int n,m; scanf("%d%d", &n, &m);
    rep(i,0,m){
        scanf("%d", k+i);
        rep(j,0,k[i]){
            scanf("%d", &s[i][j]);
        }
    }
    rep(i,0,m) scanf("%d", p+i);

    int ans = 0;
    //ビット全探索　初期値は0 (ans=0あり)
    rep(bit, 0, (1 << n)) {
        int t_lmp = 0;
        rep(i, 0, m) {
            int tmp_sum = 0;
            rep(j, 0, k[i]){
                if(bit&(1<<s[i][j])) tmp_sum++;
            }
            if(tmp_sum%2 == p[i]) t_lmp++;
            else break;
        }
        if(t_lmp == m) ans++;
    }

    printf("%d\n", ans);
    return 0;
}
//  [javascript]
'use strict';
console.log(function(args){
  const tmp = args.trim().split('\n').map(a=>a.split(' ').map(v=>v|0));
  const N = tmp[0][0], M = tmp[0][1];
  const p = tmp[M+1];
  const k = Array(M),s = Array(M);
  let count = 0;
  for ( let i = 1; i <= M; i++ ) {
    k[i-1] = tmp[i][0];
    s[i-1] = tmp[i].slice(1).map(v=>v-1);
  }
  TEST: for ( let state = 0; state < 1<<N; state++ ) {
    for ( let i = 0; i < M; i++ ) {
      let bulb = !p[i];
      for ( let j = 0; j < k[i]; j++ ) {
        if ( state & (1 << s[i][j] ) ) {
          bulb^=1;
        }
      }
      if ( !bulb ) continue TEST;
    }
    count++;
  }
  return count.toString();
}(require('fs').readFileSync('/dev/stdin', 'utf8')));
//  [javascript]
'use strict'

const INF = 900719925474099;

function numofbits5(bits)
{
    bits = bits & 0xffffffff
    bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
    bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
    bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
    bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
    bits = (bits & 0x0000ffff) + (bits >>16 & 0x0000ffff);

    //console.log('bits:',bits);
    return bits;
}

function Main(input){
    let temp = input.trim().split('\n');
    let temp2 = temp[0].split(' ').map((v)=>parseInt(v));
    let n = temp2.shift();
    let m = temp2.shift();
    
    let k;
    let sum;
    let ksw = [];
    for(let i=1;i<=m;i++){
        temp2 = temp[i].split(' ').map((v)=>parseInt(v));
        k = temp2[0];
        sum = 0;
        for(let j=1;j<=k;j++){
            sum += 1 << (temp2[j]-1);
        }
        ksw.push(sum);
    }
    let p = temp[m+1].split(' ').map((v)=>parseInt(v));

    //console.log('-------------------------');
    //console.log(ksw,p);
    let ans = 0;
    let f;
    let maxi = Math.pow(2,n)
    for(let i=0;i<maxi;i++){
        f = true;
        for(let j=0;j<m;j++){
            //console.log('ksw:',ksw[j],'i:',i,'ksw&i:',ksw[j]&i,'bits:',numofbits5(ksw[j]&i),'p:',p[j],'if:',numofbits5(ksw[j]&i)%2 != p[j]);
            if(numofbits5(ksw[j]&i)%2 != p[j]){
                f = false;
                //console.log('break;');
                break;
            }
        }
        if(f == true) ans++;
        //console.log('cnt:',ans);
    }
    console.log(ans);
}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [javascript]
'use strict';(function(input){
  function count(pi,A,B){
    var C=A&B;
    var counter=pi;
    while(C>0){
      counter+=(C%2);
      C=(C>>1);
    }
    return ((counter%2)===0);
  }
  
  input=input.trim().split(/\n+/);
  input=input.map(str=>str.split(/\s+/).map(x=>x-0));
  const N=input[0][0];
  const M=input[0][1];
  const p=input.pop();
  for(let i=1;i<=M;i++)
    input[i].shift();
  const arr=new Array(1<<N).fill('filler').map((x,i)=>i);
  const mask=[];
  for(let i=1;i<=M;i++)
    mask.push(input[i].reduce((acc,cur)=>acc+(1<<(cur-1)),0));
  mask.forEach(function(A,i){
    let j=0;
    while(j<arr.length){
      if(!count(p[i],A,arr[j])){
        arr.splice(j,1);
      }else{
        j++;
      }
    }
  });
  console.log(arr.length);
})(require('fs').readFileSync('/dev/stdin','utf8'));
//  [javascript]
function Main(input) {
    input = input.trim().split("\n").map(function(x) { return x.split(" ")});
    var NM = [ ];
    var vec_p = [ ];
    var vec_s = [ ];
    var ary_ks = [];
    var ans = 0;
    var tmpAry, j, tmpNum, tmpSum;
    NM = input[0].map(e => parseInt(e, 10)); 
    vec_p = input[NM[1]+1].map(e => parseInt(e, 10)); 
    for (var ki = 1; ki <= NM[1]; ki++){
    	ary_ks.push(input[ki].map(e => parseInt(e, 10))); 
    }
  var x=0; 
    for (var i = Math.pow(2, NM[0]); i <  Math.pow(2, NM[0]) * 2; i++){
      x++;
    	tmpAry = i.toString(2).substr(1);
    	tmpSum = 0;
    	tmpAry_loop:
    	for (var ki = 1; ki <= NM[1]; ki++){
			for (var sij = 1; sij <=  ary_ks[ki-1][0]; sij++){
				tmpNum = parseInt(tmpAry[ary_ks[ki-1][sij]-1], 10);
 				tmpSum +=  tmpNum;
			}
			if (ki == NM[1])  {
              //console.log("tmpNum %d", tmpNum);
            }
		
			if (tmpSum % 2 != vec_p [ki-1]) break tmpAry_loop;
			if (ki == NM[1]) {
                           //console.log(tmpAry); 
              	//			console.log(tmpSum);
				//console.log(tmpSum % 2);
              
              ans ++;
            }
		}
    }
    console.log(ans);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [javascript]
function Main(input) {
    input = input.trim().split("\n").map(function(x) { return x.split(" ")});
    var NM = [ ];
    var vec_p = [ ];
    var vec_s = [ ];
    var ary_ks = [];
    var ans = 0;
    var tmpAry, j, tmpNum, tmpSum;
    NM = input[0].map(e => parseInt(e, 10)); 
    vec_p = input[NM[1]+1].map(e => parseInt(e, 10)); 
    for (var ki = 1; ki <= NM[1]; ki++){
    	ary_ks.push(input[ki].map(e => parseInt(e, 10))); 
    }
    for (var i = Math.pow(2, NM[0]); i <  Math.pow(2, NM[0]) * 2; i++){
    	tmpAry = i.toString(2).substr(1);
    	tmpSum = 0;
    	tmpAry_loop:
    	for (var ki = 1; ki <= NM[1]; ki++){
			for (var sij = 1; sij <=  ary_ks[ki-1][0]; sij++){
				tmpNum = parseInt(tmpAry[ary_ks[ki-1][sij]-1], 10);
				tmpSum +=  tmpNum;
			}
			if (tmpSum % 2 != vec_p [ki-1]) break tmpAry_loop;
			if (ki == NM[1]) ans ++;
		}
    }
    console.log(ans);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [javascript]
function main(input) {
  const inputs = input.split('\n');
  var n = inputs[0].split(' ')[0] - 0;
  var m = inputs[0].split(' ')[1] - 0;

  var ds = [];
  for (var i = 0; i < n; i++) {
    ds.push(inputs[i + 1].split(' ').filter((n, i) => i > 0).map((n) => n - 1));
  }
  var p = inputs[1 + m].split(' ').map((n) => parseInt(n, 10));

  var counter = 0;
  // bit all search
  for (var bit = 0; bit < (1 << n); bit++) {
    var allOn = true;
    // all search for switches
    for (var swi = 0; swi < n; swi++) {
      var sum = 0;
      // a bit pattern
      for (var biti = 0; biti < n; biti++) {
        if ((bit & (1 << biti)) != 0) continue;
        if (ds[swi].find((v) => v == biti) >= 0) sum++;
      }
      allOn = allOn && (sum % 2 == p[swi]);
    }
    if (allOn) counter += 1;
  }
  console.log(counter);
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)
var ans int = 0

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func scanInts(n int) []int {
	sl := make([]int, n)
	for i := range sl {
		sl[i] = scanInt()
	}
	return sl
}

func scanStrings(n int) []string {
	sl := make([]string, n)
	for i := range sl {
		sl[i] = scanString()
	}
	return sl
}

func init() {
	sc.Split(bufio.ScanWords)
}

func check(now []bool, next_idx int, N int, data map[int][]int, correct []bool) {
	// if index N is on
	now_on := make([]bool, len(now))
	now_off := make([]bool, len(now))
	copy(now_on, now)
	copy(now_off, now)

	if _, ok := data[next_idx]; ok {
		for _, i := range data[next_idx] {
			now_on[i-1] = !now_on[i-1]
		}
	}
	ok := true
	for i := range now_on {
		if correct[i] != now_on[i] {
			ok = false
			break
		}
	}
	if ok == true {
		ans++
	}

	if next_idx == 1 {
		ok := true
		for i := range now_off {
			if correct[i] != now_off[i] {
				ok = false
				break
			}
		}
		if ok == true {
			ans++
		}
	}

	//fmt.Printf("%v => %v %v\n", now, now_on, now_off)
	if next_idx != N {
		// if index N is off
		check(now_off, next_idx+1, N, data, correct)
		check(now_on, next_idx+1, N, data, correct)
	}
}

func main() {
	N, M := scanInt(), scanInt()
	data := map[int][]int{}
	for i := 0; i < M; i++ {
		k := scanInt()
		for j := 0; j < k; j++ {
			s := scanInt()
			if _, ok := data[s]; ok {
				data[s] = append(data[s], i+1)
			} else {
				data[s] = []int{i + 1}
			}
		}
	}
	//fmt.Printf("%v\n", data)
	correct := make([]bool, M)
	for i := 0; i < M; i++ {
		if scanInt() == 0 {
			correct[i] = false
		} else {
			correct[i] = true
		}
	}
	state := make([]bool, M)
	//fmt.Printf("init: %v\n", state)
	check(state, 1, N, data, correct)
	fmt.Println(ans)
}
//  [go]
package main

import (
	"fmt"
)

func main() {
	var n, m int
	fmt.Scan(&n, &m)
	k := make([]int, m)
	s := make([][]int, m)
	for i := range k {
		fmt.Scan(&k[i])
		s[i] = make([]int, k[i])
		for j := range s[i] {
			fmt.Scan(&s[i][j])
		}
	}
	p := make([]int, m)
	for i := range p {
		fmt.Scan(&p[i])
	}

	ans := 0
	for i := 0; i < (1 << uint(n)); i++ {
		ok := true
		for j := 0; j < m; j++ {
			sum := 0
			for _, v := range s[j] {
				sum += i >> uint(v-1) & 1
			}
			if sum%2 != p[j] {
				ok = false
				break
			}
		}
		if ok {
			ans++
		}
	}
	fmt.Println(ans)
}
//  [go]
package main

import (
        "fmt"
)

func solution(n, m int, k, p []int, s [][]int) int {

        out := 0

        for a := 0; a < 1<<uint(n); a++ {
                var ok bool = true
                for i := 0; i < m; i++ {
                        c := 0
                        for j := range s[i] {
                                if (a>>uint(j))&1 == 1 {
                                        c++
                                }
                        }
                        c %= 2
                        if c != p[i] {
                                ok = false
                        }
                }
                if ok {
                        out++
                }
        }
        return out
}

func main() {
        var n, m int
        fmt.Scan(&n, &m)
        k := make([]int, m)
        s := make([][]int, m)
        for i := range k {
                fmt.Scan(&k[i])
                s[i] = make([]int, k[i])
                for j := range s[i] {
                        fmt.Scan(&s[i][j])
                }
        }
        p := make([]int, m)
        for i := range p {
                fmt.Scan(&p[i])
        }
        fmt.Println(solution(n, m, k, p, s))
}
//  [go]
package main

import (
        "fmt"
)

func solution(n, m int, k, p []int, s [][]int) int {

        out := 0

        for a := 0; a < 1<<uint(n); a++ {
                var ok bool = true
                for i := 0; i < m; i++ {
                        c := 0
                        for j := range s[i] {
                                if a>>uint(j)&1 == 1 {
                                        c++
                                }
                        }
                        c %= 2
                        if c != p[i] {
                                ok = false
                        }
                }
                if ok {
                        out++
                }
        }
        return out
}

func main() {
        var n, m int
        fmt.Scan(&n, &m)
        k := make([]int, m)
        s := make([][]int, m)
        for i := range k {
                fmt.Scan(&k[i])
                s[i] = make([]int, k[i])
                for j := range s[i] {
                        fmt.Scan(&s[i][j])
                }
        }
        p := make([]int, m)
        for i := range p {
                fmt.Scan(&p[i])
        }
        fmt.Println(solution(n, m, k, p, s))
}
//  [go]
package main

import (
        "fmt"
)

func solution(n, m int, k, p []int, s [][]int) int {

        out := 0

        for a := 0; a < 1<<uint(n); a++ {
                var ok bool = true
                for i := 0; i < m; i++ {
                        c := 0
                        for j := range s[i] {
                                if a>>uint(j)&1 == 0 {
                                        c++
                                }
                        }
                        c %= 2
                        if c != p[i] {
                                ok = false
                        }
                }
                if ok {
                        out++
                }
        }
        return out
}

func main() {
        var n, m int
        fmt.Scan(&n, &m)
        k := make([]int, m)
        s := make([][]int, m)
        for i := range k {
                fmt.Scan(&k[i])
                s[i] = make([]int, k[i])
                for j := range s[i] {
                        fmt.Scan(&s[i][j])
                }
        }
        p := make([]int, m)
        for i := range p {
                fmt.Scan(&p[i])
        }
        fmt.Println(solution(n, m, k, p, s))
}
//  [ruby]
=begin
－－－－－－－－－－－－－－
n = スイッチの数
m = 電球の数
k = 電球[i]に繋がっているスイッチ
a = スイッチを表す配列 (N個分)
pi = スイッチの最終状態
t = スイッチの押しパターンごとの電球の状態を記録
ans = 答えの数
－－－－－－－－－－－－－－
1: 各スイッチにどの電球が繋がっているのかを記録する
  1.1: i 番目の電球に繋がっている スイッチ k を受け取り、k をループする
    1.1.1: k 番目のスイッチ(a[k]) が繋がっている 電球[i]を 2進数で記録する (スイッチ k[j] には複数の 電球m[i] が繋がっている可能性のあるため ビットOR で受け取る)
2: スイッチの最終状態 pi を 2 進数で 受け取る
3: スイッチの押しパターンを全て試す
  3.1: パターンごとに 電球の状態 t を記録し、スイッチの最終状態 pi と一致すれば ans += 1
4: ans を出力
=end

n, m = gets.split.map(&:to_i)
a = Array.new(n,0)
pi = 0
ans = 0

for i in 0..(m-1) do
  k = gets.split.map{|v| v.to_i - 1}
  k.shift()
  k.each do |j|
    a[j] |=  1<<i
  end
end

a_pi = gets.split.map(&:to_i)
a_pi.each_with_index do |x, i|
  pi |= x << i
end

s = 0;
while(s < (1<<n)) do
  t = 0;
  for i in 0..(n-1) do
    if s[i] != 0
      t ^= a[i];
    end
  end
  ans += 1 if t == pi
  s += 1
end

puts ans
//  [ruby]
N,M = gets.split.map &:to_i
switches = Array.new(N,0)
M.times{ |j|
  k,*s = gets.split.map &:to_i
  s.each{ |i| switches[i-1] += (1 << j) }
}
P = gets.split.reverse.join.to_i(2)
p (0...(1<<N)).count{ |s|
  t = 0
  (0...N).each{ |i|
    t ^= switches[i] if (s & (1 << i)) > 0
  }
  t == P 
}
//  [ruby]
N, M = gets.split.map(&:to_i)
sw = [0] * -~N
M.times do |i|
	gets.split.map(&:to_i)[1..-1].each do |s|
		sw[s-1] |= 1 << i
	end
end
#p sw
#p b

pp =  gets.tr(" ",?_).reverse.to_i(2)
res = -(pp-1 >> 20)
1.upto(N) do |n|
	N.times.to_a.combination(n) do |x|
#		p [x, sw.values_at(*x),sw.values_at(*x).inject(:^)]
		res += 1 if sw.values_at(*x).inject(:^) == pp
	end
end
p res
//  [ruby]
n,m=gets.split.map(&:to_i)
k=[]
m.times do
  k<<gets.split.map(&:to_i)
end
p=gets.split.map(&:to_i)
switch=0
ans=0
can=0
s=[0,1].repeated_permutation(n).to_a
s.each do |s|
  can=0
  m.times do |i|
    1.upto(k[i][0]) do |j|
      switch+=s[k[i][j]-1]
    end
    if switch%2==p[i]
      can+=1
    end
  end
  if can==m
    ans+=1
  end
end
puts ans
//  [ruby]
n,m=gets.split.map(&:to_i)
k=[]
m.times do
  k<<gets.split.map(&:to_i)
end
p=gets.split.map(&:to_i)
switch=0
ans=0
can=0
s=[0,1].repeated_permutation(n).to_a
s.each do |s|
  can=0
  m.times do |i|
    1.upto(k[i][0]) do |j|
      switch+=s[k[i][j]-1]
    end
    if switch%2==p[i]
      can+=1
    else
      break
    end
  end
  if can==m
    ans+=1
  end
end
puts ans
//  [ruby]
n,m=gets.split.map(&:to_i)
k=[]
m.times do
  k<<gets.split.map(&:to_i)
end
switch=0
ans=0
can=false
p=gets.split.map(&:to_i)
s=[0,1].repeated_permutation(n).to_a
s.each do |s|
  m.times do |i|
    can=false
    1.upto(k[i][0]) do |j|
      switch+=s[k[i][j]-1]
    end
    if switch%2==p[i]
      can=true
    else
      break
    end
  end
  if can
    ans+=1
  end
end
puts ans
//  [rust]
use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("filed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let n: usize = read();
    let m: usize = read();
    let mut s = vec![vec![]; m];
    for i in 0..m {
        let k: usize = read();
        for _ in 0..k {
            // sにはk個の各スイッチの1～Nの番号
            let a = read::<usize>() - 1;
            s[i].push(a);
        }
    }
    let p: Vec<usize> = (0..m).map(|_| read()).collect();

    let mut res = 0;
    for bit in 0..1 << n {
        let mut ok = true;
        for (i, switch) in s.iter().enumerate() {
            let mut con = 0;
            for &j in switch.iter() {
                if bit & 1 << j == 1 << j {
                    con += 1;
                }
            }
            if con % 2 != p[i] {
                ok = false;
                break;
            }
        }
        if ok {
            res += 1;
        }
    }
    println!("{}", res);
}
//  [rust]
use std::io::*;
use std::str::FromStr;

//https://qiita.com/tubo28/items/e6076e9040da57368845
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn rec(
    n: usize,
    m: usize,
    status: &mut Vec<usize>,
    mut ans: u32,
    switch: &Vec<Vec<usize>>,
    p: &Vec<u32>,
) -> u32 {
    //最深まで探索し、状態を判定する
    if status.len() == n {
        let mut light = vec![false; m];
        for i in 0..m {
            let mut on = 0;
            for j in switch[i].iter() {
                if (status[*j - 1]) == 1 {
                    on += 1;
                }
            }
            //点灯の確認
            //println!("on{}",on);
            if on % 2 == p[i]{
                light[i] = true;
            }
        }
        //全点灯の確認
        if light.iter().all(|c| *c == true) {
            ans += 1;
        }
        //println!("ans{} status{:?}",ans,status);
    } else {
        //再帰全探索
        for c in 0..2 {
            status.push(c);
            ans = rec(n, m, status, ans, switch, p);
            status.pop();
        }
    }

    return ans;
}
fn main() {
    let n: usize = read();
    let m: usize = read();
    let mut switch: Vec<Vec<usize>> = vec![vec![0; 0]; m]; //m個の空のvecを用意

    for i in 0..m {
        let k: usize = read();
        for _ in 0..k {
            let s: usize = read();
            switch[i].push(s);
        }
    }
    let p: Vec<u32> = (0..m).map(|_| read()).collect();

    let mut status = Vec::new();
    let ans = rec(n, m, &mut status, 0, &switch, &p);
    print!("{}", ans);
}
//  [rust]
use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("filed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let n: usize = read();
    let m: usize = read();
    let mut s = vec![vec![]; m];
    for i in 0..m {
        let k: usize = read();
        for _ in 0..k {
            // sにはk個の各スイッチの1～Nの番号
            let a = read::<usize>() - 1;
            s[i].push(a);
        }
    }
    let p: Vec<usize> = (0..m).map(|_| read()).collect();

    let mut res = 0;
    for bit in 0..1 << n {
        let mut ok = true;
        for (i, switch) in s.iter().enumerate() {
            let mut con = 0;
            for &i in switch.iter() {
                if bit & 1 << i == 1 << i {
                    con += 1;
                }
            }
            if con % 2 != p[i] {
                ok = false;
                break;
            }
        }
        if ok {
            res += 1;
        }
    }
    println!("{}", res);
}
//  [rust]
// -*- coding:utf-8-unix -*-

use proconio::input;
use std::collections::HashSet;

fn main() {
    input! {
        n: usize,
        m: usize,
    }
    let mut k = vec![];
    let mut s = vec![];
    for _ in 0..m {
        input! {
            a: usize,
            b: [u16; a],
        }
        k.push(a);
        s.push(b);
    }
    input! {
        p: [u16; m],
    }
    // println!("k: {:?}", k);
    // println!("s: {:?}", s);
    // println!("p: {:?}", p);

    let mut ans = 0;
    for bit_row in 0..2u32.pow(n as u32) {
        // println!("{:b}", bit_row);
        let mut selected = HashSet::new();
        for i in 0..n {
            if (bit_row & (1 << i)) > 0 {
                selected.insert(i as u16);
            }
        }
        // println!("on: {:?}", selected);

        if selected.len() == 0 {
            if p.iter().all(|&a| a == 0) {
                ans += 1;
            }
        }

        for i in 0..m {
            let mut swsum = 0;
            for j in 0..k[i] {
                // println!("sij: {}", s[i][j]);
                if selected.contains(&(s[i][j] - 1)) {
                    swsum += 1;
                }
            }
            // println!("{}: {}", i, swsum);
            if swsum % 2 != p[i] {
                break;
            }

            if i == m - 1 {
                ans += 1;
            }
        }
    }
    println!("{}", ans);
}
//  [rust]
fn solve(ksss: Vec<Vec<u64>>, ps: Vec<u64>, n: usize) -> usize {
    let mut result = 0;
    let sss: Vec<Vec<u64>> = ksss.iter()
        .map(|kss| kss.iter().skip(1).map(|s| s - 1).collect::<Vec<_>>())
        .collect();

    for bins in binary_combinations(n) {
        if (0..ps.len()).all(|i| sss[i].iter().zip(&bins).filter(|(_, &bin)| bin).count() % 2 == ps[i] as usize) {
            result += 1
        }
    }

    result
}

fn binary_combinations(n: usize) -> Vec<Vec<bool>> {
    fn rec(n: usize, mut acc: Vec<Vec<bool>>) -> Vec<Vec<bool>> {
        if n == 0 {
            acc
        } else {
            let mut tmp = acc.clone();
            acc.iter_mut().for_each(|v| v.push(false));
            tmp.iter_mut().for_each(|v| v.push(true));
            acc.extend(tmp);

            rec(n - 1, acc)
        }
    }

    rec(n, vec![vec![]])
}

fn main() {
    let (n, m) = read_tup2();
    let ksss = read_vec_n(m);
    let ps = read_vec();

    println!("{}", solve(ksss, ps, n));
}

fn read_tup2<T: std::str::FromStr + Copy>() -> (T, T) {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    let v = s.trim().split_whitespace()
        .map(|c| c.parse().ok().unwrap())
        .collect::<Vec<T>>();
    (v[0], v[1])
}

fn read_vec_n<T: std::str::FromStr>(n: usize) -> Vec<Vec<T>> {
    let mut ss = String::new();
    for _ in 0..n {
        std::io::stdin().read_line(&mut ss).ok();
    }
    let mut v = ss.split("\n").collect::<Vec<&str>>();
    v.pop();
    v.iter()
        .map(
            |s| {
                s.trim().split_whitespace()
                    .map(|c| c.parse().ok().unwrap())
                    .collect()
            }
        )
        .collect()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().split_whitespace()
        .map(|c| c.parse().ok().unwrap())
        .collect()
}
//  [rust]
use proconio::input;
use proconio::marker::Usize1;
use std::collections::HashMap;

fn main() {
  input! {
    n: usize,
    m: usize,
  }
  
  let mut map: HashMap<usize, Vec<usize>> = HashMap::new();
  for i in 0..m {
    input! {
      nn: usize,
      switches: [Usize1;nn]
    }
    map.insert(i, switches.into_iter().collect::<Vec<usize>>());
  }
  
  input! {
    needs: [usize;m]
  }
  
  let mut total = 0;
  for mut i in 0..2usize.pow(n as u32) {
    let mut ons: Vec<usize> = vec![0;n];
    let mut index = 0;
    while 0 <  i {
      if i & 1 == 1 {
        ons[index] = 1;
      }
      index += 1;
      i >>= 1;
    }
    
    let mut flag = true;
    for (index, key) in map.keys().enumerate() {
      let mut sum = 0;
      for ii in map.get(key).unwrap() {
        if ons[*ii] == 1 {
          sum += 1;
        }
      }
      if sum % 2 != needs[index] {
        flag = false;
      }
    }
    
    if flag {
      total += 1;
    }
  }
  println!("{}", total);
}
//  [swift]
func readInts() -> [Int]{
    return readLine()!.split(separator: " ").map{Int($0)!};
}
let a = readInts();
let N = a[0], M = a[1];
var A: Array<Array<Int>> = Array();
for i in 0 ..< M {
    let b = readInts();
    A.append([Int]());
    for j in 0 ..< N {
        A[i].append(0);
    }
    for j in 1 ... b[0] {
        A[i][b[j]-1] = 1;
    }
}
var answer = 0;
let p = readInts();
for bit in 0 ..< (1<<N) {
    var rock = 0;
    var check: Array<Int> = Array(repeating: 0, count: 12);
    for i in 0 ..< N {
        if bit & 1<<i > 0 {
            check[i] = 1;
        }
    }
    for i in 0 ..< M {
        var count = 0;
        for j in 0 ..< N {
            if check[j] == 1 && A[i][j] == 1 {
                count += 1;
            }
        }
        if count % 2 == p[i] {
            rock += 1;
        }
    }
    if rock == M {
        answer += 1;
    }
}
print(answer);
//  [swift]
func readInts() -> [Int]{
    return readLine()!.split(separator: " ").map{Int($0)!};
}
let a = readInts();
let N = a[0], M = a[1];
var A: Array<Array<Int>> = Array();
for i in 0 ..< a[1] {
    let b = readInts();
    let k = b[0];
    A.append([Int]());
    for j in 0 ..< N {
        A[i].append(0);
    }
    for j in 1 ... k {
        A[i][b[j]-1] = 1;
    }
}
var answer = 0;
let p = readInts();
for bit in 0 ..< (1<<N) {
    var rock = 0;
    var check: Array<Int> = Array(repeating: 0, count: 12);
    for i in 0 ..< N {
        if bit & 1<<i > 0 {
            check[i] = 1;
        }
    }
    for i in 0 ..< M {
        var count = 0;
        for j in 0 ..< N {
            if check[j] == 1 && A[i][j] == 1 {
                count += 1;
            }
        }
        if count % 2 == p[i] {
            rock += 1;
        }
    }
    if rock == M {
        answer += 1;
    }
}
print(answer);
//  [swift]
import Foundation
 
// 標準入力からnとmを受け取る
let nm = readLine()!.split(separator:" ").map{Int($0)!}
let n = nm[0]
let m = nm[1]
 
// 標準入力からkとsを受け取る
// 要素がすべて0で初期化されたn*mの2次元配列Sを用意
var S = [[Int]](repeating:[Int](repeating:0, count:m), count:n)
// Sに入力値を入れていく
for i in 0..<m{
    let s = readLine()!.split(separator:" ").map{Int($0)!}
    // s[0]==k
    for j in 0...s[0]{
        // kは除く
        if j == 0 {
            continue
        }
        S[s[j]-1][i] = 1
    }
}
 
// 標準入力からpを受け取る (答えの配列)
let p = readLine()!.split(separator:" ").map{Int($0)!}
 
// 答えを入れる変数を用意
var ans = 0
 
// 要素数nの集合についてbit全探索を行う
// 0~n^2のループ
for bit in 0..<(1<<n){
 
    // 電球の状態を持つ配列 (点灯しているなら1,消えているなら0)
    var check = [Int](repeating:0, count:m)
    
    // 順に左にシフトさせ最下位bitのチェックを行う
    for i in 0..<n{
    
        // フラグが立っているかどうかの判定
        if 1<<i > 0 {
        
            // フラグが立っていた時の処理 (フラグが立つ = スイッチを入れる)
            // 各電球に対して全探索
            for j in 0..<m{
            
                // S[i][j] == 1ならばスイッチと電球はつながっている
                // スイッチを入れると点灯と消灯が反転する
                if S[i][j] == 1 && check[j] == 1{
                    check[j] = 0
                }
                else if S[i][j] == 1 && check[j] == 0{
                    check[j] = 1
                }
            }
        }
    }
    
    // 一致しているならすべて点灯している
    if p == check{
        ans += 1
    }
}
 
// 答えの出力
print(ans)
//  [swift]
import Foundation

// 標準入力からnとmを受け取る
let nm = readLine()!.split(separator:" ").map{Int($0)!}
let n = nm[0]
let m = nm[1]

// 標準入力からkとsを受け取る
// 要素がすべて0で初期化されたn*mの2次元配列Sを用意
var S = [[Int]](repeating:[Int](repeating:0, count:m), count:n)
// Sに入力値を入れていく
for i in 0..<m{
    let s = readLine()!.split(separator:" ").map{Int($0)!}
    // s[0]==k
    for j in 0...s[0]{
        // kは除く
        if j == 0 {
            continue
        }
        S[j-1][i] = 1
    }
}

// 標準入力からpを受け取る (答えの配列)
let p = readLine()!.split(separator:" ").map{Int($0)!}

// 答えを入れる変数を用意
var ans = 0

// 要素数nの集合についてbit全探索を行う
// 0~n^2のループ
for bit in 0..<(1<<n){

    // 電球の状態を持つ配列 (点灯しているなら1,消えているなら0)
    var check = [Int](repeating:0, count:m)
    
    // 順に左にシフトさせ最下位bitのチェックを行う
    for i in 0..<n{
    
        // フラグが立っているかどうかの判定
        if bit & 1<<i > 0 {
        
            // フラグが立っていた時の処理 (フラグが立つ = スイッチを入れる)
            // 各電球に対して全探索
            for j in 0..<m{
            
                // S[i][j] == 1ならばスイッチと電球はつながっている
                // スイッチを入れると点灯と消灯が反転する
                if S[i][j] == 1 && check[j] == 1{
                    check[j] = 0
                }
                else if S[i][j] == 1 && check[j] == 0{
                    check[j] = 1
                }
            }
        }
    }
    
    // 一致しているならすべて点灯している
    if p == check{
        ans += 1
    }
}

// 答えの出力
print(ans)
//  [swift]
import Foundation

// 標準入力からnとmを受け取る
let nm = readLine()!.split(separator:" ").map{Int($0)!}
let n = nm[0]
let m = nm[1]

// 標準入力からkとsを受け取る
// 要素がすべて0で初期化されたn*mの2次元配列Sを用意
var S = [[Int]](repeating:[Int](repeating:0, count:m), count:n)
// Sに入力値を入れていく
for i in 0..<m{
    let s = readLine()!.split(separator:" ").map{Int($0)!}
    // s[0]==k
    for j in 0...s[0]{
        // kは除く
        if j == 0 {
            continue
        }
        S[j-1][i] = 1
    }
}

// 標準入力からpを受け取る (答えの配列)
let p = readLine()!.split(separator:" ").map{Int($0)!}

// 答えを入れる変数を用意
var ans = 0

// 要素数nの集合についてbit全探索を行う
// 0~n^2のループ
for bit in 0..<(1<<n){

　　// 電球の状態を持つ配列(点灯しているなら1,消えているなら0)
    var check = [Int](repeating:0, count:m)
    
    // 順に左にシフトさせ最下位bitのチェックを行う
    for i in 0..<n{
    
        // フラグが立っているかどうかの判定
        if bit & 1<<i > 0 {
        
            // フラグが立っていた時の処理 (フラグが立つ = スイッチを入れる)
            // 各電球に対して全探索
            for j in 0..<m{
            
                // S[i][j] == 1ならばスイッチと電球はつながっている
                // スイッチを入れると点灯と消灯が反転する
                if S[i][j] == 1 && check[j] == 1{
                    check[j] = 0
                }
                else if S[i][j] == 1 && check[j] == 0{
                    check[j] = 1
                }
            }
        }
    }
    
    // 一致しているならすべて点灯している
    if p == check{
        ans += 1
    }
}

// 答えの出力
print(ans)
//  [typescript]
export class Main {
  static main(input): string {
    const tmp: string[] = input.split("\n");
    const [n, m]: number[] = tmp[0].split(" ").map(Number);
    const p: number[] = tmp[m + 1].split(" ").slice(0, m).map(Number);
    const list: ((onList: number[]) => boolean)[] = [];
    for (let i = 1; i <= m; ++i) {
      const [k, ...sList]: number[] = tmp[i].split(" ").map(Number);
      const tmpS: number[] = sList.slice(0, k).map(s => s - 1);
      const tmpP: number = p[i - 1];
      list.push(onList => {
        let t: number = 0;
        for (let j = 0, len = tmpS.length; j < len; ++j) {
          t += onList[tmpS[j]];
        }
        return t % 2 == tmpP;
      });
    }
    let result: number = 0;
    for (let i = 0, len = Math.pow(2, n); i < len; ++i) {
      const indexList: number[] = [];
      for (let j = 1; j < len; j *= 2) {
        indexList.push((i & j) == j ? 1 : 0);
      }
      if (list.every(f => f(indexList))) {
        ++result;
      }
    }
    return `${result}`;
  }

}
console.log(Main.main(require("fs").readFileSync("/dev/stdin", "utf8")));