#include <bits/stdc++.h>
using namespace std;
typedef struct {
  string name;
  int point;
  int number;
} REST_INFO;
bool cmp(REST_INFO &a, REST_INFO &b) {
  if (a.name == b.name) {
    return (a.point > b.point);
  } else {
    int result = a.name.compare(b.name);
    return (0 < result) ? false : true;
  }
}
int main() {
  int swNum, lgtNum;
  cin >> swNum >> lgtNum;
  vector<vector<bool>> connectList(swNum, vector<bool>(lgtNum, false));
  for (int(i) = 0; (i) < (int)(lgtNum); ++(i)) {
    int connectNum;
    cin >> connectNum;
    for (int(j) = 0; (j) < (int)(connectNum); ++(j)) {
      int swNo;
      cin >> swNo;
      swNo--;
      connectList[swNo][i] = true;
    }
  }
  vector<int> lgtCntCndition(lgtNum, 0);
  for (int(i) = 0; (i) < (int)(lgtNum); ++(i)) {
    cin >> lgtCntCndition[i];
  }
  int ret = 0;
  int swPtn = 1 << swNum;
  for (int(i) = 0; (i) < (int)(swPtn); ++(i)) {
    vector<int> lgtCntList(lgtNum, -1);
    for (int(j) = 0; (j) < (int)(swNum); ++(j)) {
      if ((i & 0x1 << j)) {
        for (int(k) = 0; (k) < (int)(lgtNum); ++(k)) {
          if (connectList[j][k]) {
            if (lgtCntList[k] == -1) {
              lgtCntList[k] = 1;
            } else {
              lgtCntList[k]++;
            }
          }
        }
      }
    }
    bool isOn = true;
    for (int(k) = 0; (k) < (int)(lgtNum); ++(k)) {
      if (lgtCntList[k] == -1) {
        isOn = false;
        break;
      }
      if (lgtCntCndition[k] != lgtCntList[k] % 2) {
        isOn = false;
        break;
      }
    }
    if (isOn) ret++;
  }
  cout << ret;
  cout << endl;
}
