#pragma GCC optimize ("O3,Ofast,inline,fast-math,unroll-loops,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;
const double EPS=1e-7;
const int MOD=1e9+7;
// #define int int64_t
#define double long double
// typedef
#define vdef(t,T) typedef vector<t> V##T;typedef vector<V##T> VV##T;typedef vector<VV##T> VVV##T;
#define pdef(t1,t2,T) typedef pair<t1,t2> P##T;vdef(P##T,P##T)
vdef(int,I)vdef(double,D)vdef(char,C)vdef(string,S)pdef(int,int,II)pdef(int,PII,III)
pdef(string,PII,SII)
#define VCL vector<C>
#define VVCL vector<VCL>
#define PCC pair<C1,C2>
// define use frequently
#define emb emplace_back
#define pub push_back
#define pob pop_back
#define mp make_pair
#define mp3(a,b,c) mp(a,mp(b,c))
#define fi first
#define se second
#define fir fi
#define sec se.fi
#define thi se.se
#define fou(i,a,n) for(int i=a;i<n;i++)
#define fod(i,a,n) for(int i=n-1;i>=a;i--)
#define rep(n) fou(_,0,n)
#define tra(a,x) for(auto& a : x)
#define elif(c) else if(c)
#define si(vec) ((int)(vec).size())
#define all(vec) vec.begin(),vec.end()
#define lla(vec) vec.rbegin(),vec.rend()
#define range(vec,x,y) vec.begin()+x,vec.begin()+y
#define sortup(vec) sort(all(vec))
#define sortdown(vec) sort(lla(vec))
#define eraseif(vec,condition_VAR) vec.erase(remove_if(all(vec),[&](auto VAR){return condition_VAR;}),vec.end())
#define erase_unique(vec) vec.erase(unique(all(vec)),vec.end())
#define rotateleft(vec,n) rotate(vec.begin(),vec.begin()+n,vec.end())
#define rotateright(vec,n) rotate(vec.rbegin(),vec.rbegin()+n,vec.rend())
template<class C>int mine(VCL&vec){int s=si(vec);C m=0;fou(i,1,s)if(vec[i]<vec[m])m=i;return m;}
template<class C>int maxe(VCL&vec){int s=si(vec);C m=0;fou(i,1,s)if(vec[i]>vec[m])m=i;return m;}
template<class C>void mini(C&a,const C&b){a=min(a,b);}
template<class C>void maxi(C&a,const C&b){a=max(a,b);}
// make_pair,vector calculate
#define opall(calc) calc(+)calc(-)calc(*)calc(/)calc(%)calc(<<)calc(>>)calc(&)calc(|)calc(^)
#define p1c(op) template<class C1,class C2,class CC>PCC operator op(const PCC&l,const CC&r){return mp(l.fi op r,l.se op r);}
#define p2c(op) template<class C1,class C2>PCC operator op(const PCC l,const PCC&r){return mp(l.fi op r.fi,l.se op r.se);}
#define v1c(op) template<class C,class CC>VCL operator op(VCL l,const CC&r){int s=si(l);fou(i,0,s)l[i]=l[i] op r;return l;}
#define v2c(op) template<class C>VCL operator op(VCL l,const VCL&r){int s=min(si(l),si(r));fou(i,0,s)l[i]=l[i] op r[i];return l;}
#define opeq(op) template<class C1,class C2>C1 operator op##=(C1&l,const C2&r){return l=l op r;}
opall(p1c)opall(p2c)opall(v1c)opall(v2c)opall(opeq)
// iostream
#define in(T,...) T __VA_ARGS__;_cin(__VA_ARGS__)
#define out(...) _cout(__VA_ARGS__)
void _cin(){}template<class Head,class...Tail>void _cin(Head&head,Tail&&...tail){cin>>head;_cin(forward<Tail>(tail)...);}
template<class Head>void _cout(const Head&head){cout<<head<<endl;}template<class Head,class...Tail>void _cout(const Head&head,Tail...tail){cout<<head<<" ";_cout(forward<Tail>(tail)...);}
template<class C1,class C2>istream&operator>>(istream&is,PCC&p){return is>>p.fi>>p.se;}
template<class C>istream&operator>>(istream&is,VCL&vec){tra(v,vec)is>>v;return is;}
template<class C1,class C2>ostream&operator<<(ostream&os,const PCC&p){os<<p.fi<<" "<<p.se;return os;}
template<class C>ostream&operator<<(ostream&os,const VCL&vec){int vecsize=si(vec);fou(i,0,vecsize-1)os<<vec[i]<<" ";os<<vec[vecsize-1];return os;}
// math
template<class C>C sign(C a){return (a>0)-(a<0);}
int gcd_sub(const int&a,const int&b){if(b)return gcd_sub(b,a%b);else return a;}int gcd(const int&a,const int&b){return gcd_sub(max(a,b),min(a,b));}
int lcm(const int&a,const int&b){return a/gcd(a,b)*b;}
int fact(const int&n){return n==0?1:n*fact(n-1);}
PII comb_sub(const int&m,const int&n){return n==0?mp((int)1,(int)1):mp(m,n)*comb_sub(m-1,n-1);}int comb(const int&m,const int&n){PII p=comb_sub(m,min(n,m-n));return p.fi/p.se;}
int mnum(const int&a){return a%MOD+(a<0?MOD:0);}
int minv(int a){a=mnum(a);int b=MOD,u=0,v=1;while(a>1){u-=b/a*v;b%=a;swap(a,b);swap(u,v);}return mnum(v);}
#define modcalc(ops,op) int m##ops(const int&a,const int&b){return mnum(mnum(a) op mnum(b));}
modcalc(add,+)modcalc(sub,-)modcalc(mul,*)
int mdiv(const int&a,const int&b){return mmul(a,minv(b));}
int mpow(int a,int b){int r=1;while(b>0){if(b&1)r=mmul(r,a);a=mmul(a,a);b>>=1;}return r;}
// algorithm
template<class C>vector<C>cumsum(vector<C>vec){int s=si(vec);fou(i,1,s)vec[i]+=vec[i-1];return vec;}
template<class C>vector<vector<C>>cumsum2(vector<vector<C>>vec){int s=si(vec);fou(i,1,s)vec[i]+=vec[i-1];fou(i,0,s)vec[i]=cumsum(vec[i]);return vec;}
template<class C>int binarysearch(const vector<C>vec,const C&n,const char&c){
  int left=-1;int right=si(vec);bool outleft=(c=='d'||c=='U');int getmin=(c=='u'||c=='d')?1:-1;
  while(right-left>1){
    int mid=left+(right-left)/2;
    bool OK=vec[mid]*getmin>=n*getmin;
    if(outleft==OK) left=mid;else right=mid;
  }
  return outleft?left:right;
}

// class unionfind{vector<int> p;int n;public:unionfind(int _n):n(_n){p.resize(n);iota(all(p),0);}int get(const int&x){return (x==p[x]?x:(p[x]=get(p[x])));}void unite(int x,int y){x=get(x);y=get(y);if(x!=y)p[x]=y;}bool same(int x,int y){x=get(x);y=get(y);return x==y;}};
template<class C>class BIT{VCL tree;int n;public:BIT(int _n):n(_n){tree.resize(n);}void add(int x,C v){while(x<n){tree[x]+=v;x|=(x+1);}}C sum(int x){C v=0;while(x>=0){v+=tree[x];x=(x&(x+1))-1;}return v;}C part(int x,int y){return sum(y-1)-sum(x-1);}C get(int x){return part(x,x+1);}void set(int x,int y){add(x,-get(x)+y);}};

class unionfind{
  VI p;int n;public:unionfind(int _n):n(_n){p.resize(n);iota(all(p),1);}
  int get(const int&x){
    return p[x]==(x+1)?(x+1):(p[x]=sign(p[x])*get(abs(p[x])-1));
  }
  void unite(int y,int x){
    x=get(x);y=get(y);
    if(abs(x)!=abs(y))p[abs(x)-1]=y*sign(x);
  }
  void separate(int y,int x){
    x=get(x);y=get(y);
    if(abs(x)!=abs(y))p[abs(x)-1]=-y*sign(x);
  }
  bool same(int x,int y){
    x=get(x);y=get(y);
    return x==y;
  }
  bool diff(int x,int y){
    x=get(x);y=get(y);
    return x==-y;
  }
};
// weight




template<class C>class matrixdigraph{
  public:
  VVCL am,dm;
  int n,m;
  matrixdigraph(int _m,int _n):n(_n),m(_m){am=VVCL(_m,VCL(_n));dm=am;}
  void set(int i,int j,int w){
    am[i][j]=1;
  }
};






signed main(){IOS;
  in(int,n,m);

  VVI smap(m,VI(n));
  fou(i,0,m){
    in(int,k);
    fou(j,0,k){
      in(int,s);
      smap[i][j]=1;
    }
  }

  VI p(m);
  cin>>p;

  int ans=0;
  fou(i,0,1<<n){
    VI sw(n);
    fou(j,0,n){
      sw[j]=(i>>j)%2;
    }
    bool flag=true;
    fou(j,0,m){
      VI asw(n);
      asw=sw*smap[j];
      int sum=0;
      fou(k,0,n) sum+=asw[k];
      if(sum%2!=p[j]) flag=false;
    }
    if(flag) ans++;
  }

  out(ans);
}