#include <bits/stdc++.h>
using namespace std;
inline int toint(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class t>
inline string tostring(t x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
using ll = long long;
using ull = unsigned long long;
template <class ll>
inline ll getCeilExponent(ll a) {
  if (a <= 0) {
    throw invalid_argument("vaule equal to or less than 0 should not be valid");
  }
  ll index = 0;
  --a;
  for (; a != 0; a >>= 1) {
    ++index;
  }
  return index;
}
template <class ll>
inline ll getFloorExponent(ll a) {
  if (a <= 0) {
    throw invalid_argument("vaule equal to or less than 0 should not be valid");
  }
  ll index = 0;
  a >>= 1;
  for (; a != 0; a >>= 1) {
    ++index;
  }
  return index;
}
template <class ll>
inline ll getGcd(ll a, ll b) {
  if (b == 0) {
    return a;
  }
  return getGcd(b, a % b);
}
template <class ll>
inline pair<ll, ll> getBezoutsIdentitySolution(ll a, ll b) {
  if (b == 0) {
    return {1, 0};
  }
  auto sol = getBezoutsIdentitySolution(b, a % b);
  return {sol.second, sol.first - (a / b) * sol.second};
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll N, M;
  cin >> N >> M;
  ll K, v;
  vector<vector<ll>> ss(M);
  for (ll i = 0; i < M; ++i) {
    cin >> K;
    vector<ll> vs(K);
    for (ll j = 0; j < K; ++j) {
      cin >> v;
      vs[j] = v;
    }
    ss[i] = vs;
  }
  vector<ll> ps(M);
  for (ll i = 0; i < M; ++i) {
    cin >> ps[i];
  }
  vector<bool> is_on(N);
  ll res = 0;
  for (ll i = 0; i < (1 << N); ++i) {
    for (ll j = 0; j < N; ++j) {
      is_on[j] = (((i >> j) % 2) == 1);
    }
    ll switch_count = 0;
    bool is_all_on = true;
    for (ll j = 0; j < M; ++j) {
      for (ll k = 0; k < ss[j].size(); ++k) {
        if (is_on[ss[j][k] - 1]) {
          ++switch_count;
        }
      }
      if (switch_count % 2 != ps[j]) {
        is_all_on = false;
        break;
      }
    }
    if (is_all_on) {
      ++res;
    }
  }
  cout << res << endl;
  return 0;
}
