
fn count(comb: usize, s_arr: &Vec<usize>) -> usize {
    let mut result = 0;
    for s in s_arr {
        if (comb & (1usize << s)) != 0 {
            result += 1;
        }
    }
    result
}

fn solve(n: usize, m: usize, s_arr_arr: Vec<Vec<usize>>, p: Vec<usize>) ->
 usize {
    let mut comb: usize = 0;
    let end: usize = 1 << n;
    let mut result = 0;
    while comb < end {
        if (0..m).map(|i| {
            count(comb, &s_arr_arr[i]) % 2 == p[i]
        }).all(|a| { a })
        {
            result += 1;
        }
        comb += 1;
    }
    result
}

fn main() {
    let mut buf = String::new();
    std::io::stdin().read_to_string(&mut buf).unwrap();
    let mut iter = buf.split_whitespace();

    let n: usize = iter.next().unwrap().parse().unwrap();
    let m: usize = iter.next().unwrap().parse().unwrap();
    let s: Vec<Vec<usize>> = (0..m).map(|_| {
        let k: usize = iter.next().unwrap().parse().unwrap();
        (0..k).map(|_| {
            iter.next().unwrap().parse::<usize>().unwrap() - 1usize
        }).collect()
    }).collect();
    let p: Vec<usize> = (0..m).map(|_| {
        iter.next().unwrap().parse().unwrap()
    }).collect();
    println!("{}", solve(n, m, s, p));
}