import std.algorithm, std.array, std.bitmanip, std.conv, std.stdio, std.string,std.typecons;

T diff(T)(const ref T a, const ref T b) { return a > b ? a - b : b - a; }

void main() {
    immutable ip = readln.split.to!(ulong[]);
    immutable n = ip[0], m = ip[1];

    auto sw_vec = new BitArray[m];

    for (int i = 0; i < m; i++) {
        immutable ip1 = readln.split.to!(ulong[]);
        sw_vec[i] = BitArray(new bool[n]);
        for (int j = 0; j < ip1[0]; j++) {
            sw_vec[i][ip1[j+1]-1] = true;
        }
    }

    immutable res_vec = readln.split.to!(ulong[]);

    auto check_vec = BitArray(new bool[n]);
    const auto all_set = {
        auto b = BitArray(new bool[n]);
        foreach (ref v ; b) {
            v = !v;
        }
        return b;
    }();

    ulong valid = 0;
    while(check_vec != all_set) {
        for(int i = 0; i < m; i++) {
            ulong cnt = (sw_vec[i] & check_vec).bitsSet.count % 2;
            if (cnt != res_vec[i]) goto LEND;
        }
        valid++;
LEND:;
     for (int i = 0; i < n; i++) {
         if (check_vec[i] == true) check_vec[i] = false;
         else { check_vec[i] = true; break; }
     }
    }

    for(int i = 0; i < m; i++) {
        ulong cnt = (sw_vec[i] & check_vec).bitsSet.count % 2;
        if (cnt != res_vec[i]) goto FINAL;
    }
    valid++;
FINAL:

    writeln(valid);
}
