#include <bits/stdc++.h>

// 立ってるビットの数を数える (https://www.slideshare.net/KMC_JP/ss-45855264)
// 01111001 -> 5
inline std::uint64_t popcount(std::uint64_t x) {
    x = ((x & 0xaaaaaaaaaaaaaaaa) >>  1) + (x & 0x5555555555555555);
    x = ((x & 0xcccccccccccccccc) >>  2) + (x & 0x3333333333333333);
    x = ((x & 0xf0f0f0f0f0f0f0f0) >>  4) + (x & 0x0f0f0f0f0f0f0f0f);
    x = ((x & 0xff00ff00ff00ff00) >>  8) + (x & 0x00ff00ff00ff00ff);
    x = ((x & 0xffff0000ffff0000) >> 16) + (x & 0x0000ffff0000ffff);
    x = ((x & 0xffffffff00000000) >> 32) + (x & 0x00000000ffffffff);
    return x; }

// ビット列同士のハミング距離を計算 (https://www.slideshare.net/KMC_JP/ss-45855264)
// 01101011, 10110000 -> 6
inline std::uint64_t hamming(std::uint64_t a, std::uint64_t b) {
    return popcount(a ^ b); }

// 立ってる一番下のビットのみを立てる (https://www.slideshare.net/KMC_JP/ss-45855264)
// 0100110 -> 0000010
inline std::uint64_t bit_under(std::uint64_t x) {
    return x & -x; }
// 立ってる一番下のビットをクリア (https://www.slideshare.net/KMC_JP/ss-45855264)
// 0100110 -> 0100100
inline std::uint64_t bit_clear(std::uint64_t x) {
    return x & (x - 1); }
// 立ってる一番下のビットの位置を数える (https://siokoshou.hatenadiary.org/entry/20090704/p1)
// 0100100 -> 2
inline std::uint64_t ntz(std::uint64_t x) {
    std::uint64_t hash = 0x03F566ED27179461;
    unsigned int table[64];
    for (char i = 0; i < 64; i++) table[hash >> 58] = i, hash <<= 1;
    return table[static_cast<std::uint64_t>((x & -x) * 0x03F566ED27179461) >> 58]; }

// 立ってる一番下のビットより上のビットをすべて立てる (https://www.slideshare.net/KMC_JP/ss-45855264)
// 010110 -> 111100
inline std::uint64_t bit_toper(std::uint64_t x) {
    return x ^ -x; }
// 立ってる一番下のビット含む上のビットをすべて立てる (https://www.slideshare.net/KMC_JP/ss-45855264)
// 010110 -> 111110
inline std::uint64_t bit_etoper(std::uint64_t x) {
    return x | -x; }
// 立ってる一番下のビット含む下のビットをすべて立てる (https://www.slideshare.net/KMC_JP/ss-45855264)
// 00110100 -> 00000111
inline std::uint64_t bit_eunder(std::uint64_t x) {
    return x ^ (x - 1); }

// 立ってる一番上のビットを求める (https://www.slideshare.net/KMC_JP/ss-45855264)
// 0110110 -> 0100000
inline std::uint64_t bit_top(std::uint64_t x) {
    x = (x & 0xffffffff00000000) ? (x & 0xffffffff00000000) : x;
    x = (x & 0xffff0000ffff0000) ? (x & 0xffff0000ffff0000) : x;
    x = (x & 0xff00ff00ff00ff00) ? (x & 0xff00ff00ff00ff00) : x;
    x = (x & 0xf0f0f0f0f0f0f0f0) ? (x & 0xf0f0f0f0f0f0f0f0) : x;
    x = (x & 0xcccccccccccccccc) ? (x & 0xcccccccccccccccc) : x;
    x = (x & 0xaaaaaaaaaaaaaaaa) ? (x & 0xaaaaaaaaaaaaaaaa) : x;
    return x; }

// ビットの並びを反転 (https://www.slideshare.net/KMC_JP/ss-45855264)
inline std::uint64_t bit_inverce(std::uint64_t x) {
    x = ( x                       >> 32) | ( x                       << 32);
    x = ((x & 0xffff0000ffff0000) >> 16) | ((x & 0x0000ffff0000ffff) << 16);
    x = ((x & 0xff00ff00ff00ff00) >>  8) | ((x & 0x00ff00ff00ff00ff) <<  8);
    x = ((x & 0xf0f0f0f0f0f0f0f0) >>  4) | ((x & 0x0f0f0f0f0f0f0f0f) <<  4);
    x = ((x & 0xcccccccccccccccc) >>  2) | ((x & 0x3333333333333333) <<  2);
    x = ((x & 0xaaaaaaaaaaaaaaaa) >>  1) | ((x & 0x5555555555555555) <<  1);
    return x; }

// ビット列を一部だけ入れ替える (https://www.slideshare.net/KMC_JP/ss-45855264)
// ********************ABCDEFGH**************abcdefgh*******
//                     |---------delta-------|-size-|
//                     |
//                     start
//                               ||
//                              \  /
//                               \/
// ********************abcdefgh**************ABCDEFGH*******
inline std::uint64_t delta_swap(std::uint64_t x, char start, char size, char delta) {
    std::uint64_t mask = 1;
    for (char i = 0; i < size; i++)
        mask = (mask << 1) + 1;
    mask <<= (start - delta);

    std::uint64_t b = (x ^ (x >> delta)) & mask;
    return x ^ (b ^ (b << delta)); }


std::uint64_t addMod(std::uint64_t a, std::uint64_t b, std::uint64_t m) {
    std::uint64_t c = a + b;
    return c >= m ? c - m : c;
}
std::uint64_t subMod(std::uint64_t a, std::uint64_t b, std::uint64_t m) {
    std::uint64_t c = a - b;
    return c >= m ? c - m : c;
}


using namespace std;

void bit_() {
    std::uint64_t hash = 0x03F566ED27179461;
    unsigned int table[64];
    for (char i = 0; i < 64; i++) table[hash >> 58] = i, hash <<= 1;

    unsigned int n, x;
    cin >> n >> x;

    vector<unsigned int> a(n);
    for (unsigned int i = 0; i < n; i++) cin >> a[i];

    unsigned int sum = 0;
    for (x &= (1 << (n-1)) ^ ((1 << (n-1))-1); x != 0; x &= x - 1) sum += a[table[static_cast<std::uint64_t>((x & -x) * 0x03F566ED27179461) >> 58]];
    cout << sum << endl;
}

int main() {
    int N, M;

    cin >> N >> M;

    vector<int> k(M);
    long long p;
    vector<long long> s(M);

    int temp;
    //cout << endl << "s : ";
    for (int i = 0; i < M; i++) {
        cin >> k[i];
        s[i] = 0;
        for (int j = 0; j < k[i]; j++) {
            cin >> temp;
            s[i] |= 0x1 << (temp - 1);
        }
        //cout << "(" << i << ", " << s[i] << ")" << " ";
    }
    //cout << endl;
    p = 0;
    for (int i = 0; i < M; i++) {
        cin >> temp;
        p |= temp << i;
    }
    //cout << "p : " << p << endl;


    int counter = 0;
    long long h;
    for (long long i = 0; i < (1 << N); i++) {
        h = 0;
        for (int j = 0; j < M; j++) {
            //cout << i << ", " << j << " : " << (popcount(i & s[j]) & 0x1) << endl;
            h |= (popcount(i & s[j]) & 0x1) << j;
        }
        if (h == p)
            counter++;
    }

    cout << counter << endl;

    return 0;
}



Measured memory_bytes: 256