#include<iostream>
#include <algorithm>
#include <set>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
using namespace std;
typedef long long ll;
const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const int MOD = 1000000007;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
//forとか代入しない場合は++iでもi++でも同じ


int main() {
  int N,M;
  cin >> N >> M;
  vector<int> K(M),P(M);
  vector<set<int>> S(M);
  for (int i = 0; i < M; i++)
  { 
      cin >> K[i];
      for (int j = 0; j < K[i]; j++)
      {
          int s;
          cin >> s;
          S[j].insert(s);
      }      
  }

  for (int i = 0; i < M; i++)
  {
      cin >> P[i];
  }
  
  int count = 0;
  for (int bit = 0; bit < 1<<N; bit++)
  {
      for (int i = 0; i < N; i++)
      {
         set<int> on_switch;
         if(bit&(1<<i)){
            on_switch.insert(bit&(1<<i));
         }
         
         bool ok = true;
         for (int j = 0; j < M; j++)
         {
             set<int> intersectSet;
             //今onにしているところと条件でonにしたい部分の積集合
             set_intersection(on_switch.begin(),on_switch.end(),S[j].begin(),S[j].end(),back_inserter(intersectSet));

             if(intersectSet.size()%2 != P[j] ){
                 //点灯していないとき
                 ok = false;
             }
         }

         if(ok){
             count++;
         }
         
      }
      
  }

  cout << count <<endl;

}


