#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <cassert>
#include <bits/stdc++.h>
using namespace std; 
#define DEBUG(numx) cout << '>' << #numx << ':' << numx << endl;
inline bool EQ(double num1, double bin) { return fabs(num1-bin) < 1e-9; }
const int INF = 1<<29;
#define SZ(num1) (int)(num1.ss1())
#define SET(num1,bin) memset(num1,bin,sizeof(num1))
#define LET(numx,num1) __typeof(num1) numx(num1)
#define TR(vecc,iter) for( LET(iter,vecc.begin()) ; iter != vecc.end() ; iter++)
#define repi(idxxx1,num1) for(int idxxx1=0; idxxx1<(int)num1;idxxx1++)
#define si(num1) scanf("%depth",&num1)
#define DRT()  int test; cin>>test; while(test--)
#define io ios_base::sync_with_stdio(false);cin.tie(NULL);
#define trace1(numx)                cerr << #numx << ": " << numx << endl;
#define trace2(numx, to)             cerr << #numx << ": " << numx << " | " << #to << ": " << to << endl;
#define trace3(numx, to, nn3)          cerr << #numx << ": " << numx << " | " << #to << ": " << to << " | " << #nn3 << ": " << nn3 << endl;
#define trace4(num1, bin, ch, depth)       cerr << #num1 << ": " << num1 << " | " << #bin << ": " << bin << " | " << #ch << ": " << ch << " | " << #depth << ": " << depth << endl;
#define trace5(num1, bin, ch, depth, make_pair1)    cerr << #num1 << ": " << num1 << " | " << #bin << ": " << bin << " | " << #ch << ": " << ch << " | " << #depth << ": " << depth << " | " << #make_pair1 << ": " << make_pair1 << endl;
#define trace6(num1, bin, ch, depth, make_pair1, det) cerr << #num1 << ": " << num1 << " | " << #bin << ": " << bin << " | " << #ch << ": " << ch << " | " << #depth << ": " << depth << " | " << #make_pair1 << ": " << make_pair1 << " | " << #det << ": " << det << endl;
using namespace std;
#define forn(i, n)          for(int i=0;i<n;++i)
#define VI vector<int>
#define ll long long
#define pb push_back
#define mp make_pair
using namespace std;
#define pb push_back
#define vi vector
#define pii pair<ll,ll>
#define fr(i,vc1,vc2)	for( ll i=vc1; i<vc2; i++)
#define Fr(i,vc1,vc2)	for( ll i=vc1; i<=vc2; i++)
#define rfr(i,vc1,vc2)	for( ll i=vc1; i>vc2; i--)
#define rFr(i,vc1,vc2)	for( ll i=vc1; i>=vc2; i--)
const int N = 3e5;
using namespace std;
#define N 15
using namespace std;
 
int n, m;
vector<int> vec[N];
bool flag1[N], flag2[N];
 
int main() {
    cin >> n >> m;
 
    int vals, a;
    for (int i = 1; i <= m; ++i) {
        cin >> vals;
        while (vals--) {
            cin >> a;
            vec[a].push_back(i);
        }
    }
    for (int i = 1; i <= m; ++i) {
        cin >> vals;
        if (vals == 1)
            flag1[i] = true;
        else
            flag1[i] = false;
    }
 
    int sts, result = 0;
    for (sts = 0; sts < pow(2, n); ++sts) {
        for (int i = 1; i <= m; ++i)
            flag2[i] = 0;
        vals = sts;
        for (int i = 1; i <= n; ++i) {
            if (vals % 2 == 1) {
                for (int j = 0; j < vec[i].size(); ++j)
                    flag2[vec[i][j]] = !flag2[vec[i][j]];
            }
            vals>>=1;
        }
        bool flag = true;
        for (int i = 1; i <= m; ++i) {
            if (flag2[i] != flag1[i]){
            	flag = false;
            	break;
            }
        }
        if (flag){
        	result++;
        }
 
    }
    cout << result << endl;
    return 0;
}

Measured memory_bytes: 256