#include <iostream>
#include <math.h>
#include <numeric>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <queue>
#include <queue>
#include <sstream>
#include <set>
typedef  long long ll;
const int dx[8]={1,0,-1,0,1,-1,-1,1};
const int dy[8]={0,1,0,-1,1,1,-1,-1};
const int dr[4] = {-1, 0, 1, 0};
const int dc[4] = { 0, 1, 0,-1};
const int INF = 1e9;
#define FOR(i, a, n) for(int i = (int)(a); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define SORT(a) sort(a.begin(),a.end())
#define REVERSE(a) reverse(a.begin(),a.end())
int guki (int a){
    if(a%2==0) return 0;
    else return 1;
}
int gcd(int a, int b){
    if(a%b==0){
        return b;
    }else{
        return (gcd(b,a%b));
    }
}
int lcm(int a, int b){
    int x = gcd(a,b);
    return (a*b/x);
}
using namespace std;
int main(){
   ll n,m,ans=0;
   cin >> n >> m;

   vector<vector<ll>> vec(m);

   REP(i,m){
       ll a;
       cin >> a;

       vec[i].resize(a);
       REP(j,a){
           cin >> vec[i][j];
           vec[i][j] --;
       }
    } 
    vector<ll> h(m);
    REP(i,m){
        cin >> h[i];
    }

    REP(i,(1<<n)){

        vector<ll> b(n);
        REP(j,m){
            if(i & (1<<j)){
                b[j] = true;
            }
        }
        bool fl = true;
        REP(k,m){
            ll cnt =0;
            REP(l,vec[k].size()){
                if(b[vec[k][l]]) cnt ++;
            }
            if(cnt % 2 != h[k]){ 
                fl = false;
                break;
        }
        if(fl) ans++;
    }

    cout << ans <<endl;
}