fun main(args: Array<String>) {
    val (n, m) = readPair().toList().map(String::toLong)
    val sList = mutableListOf<MutableList<Long>>()
    m.rep(0) {
        val list = readLongList()
        val memC = list.subList(1, list.size).toMutableList()
        sList.add(memC)
    }
    val p = readLongList()

    val _mem = mutableListOf<Boolean>()
    n.rep {
        _mem.add(false)
    }

    var ans = 0

    fun checkDfs(mem: List<Boolean>, index: Int) {
        if (index == n.toInt()) {
            if (sList.filterIndexed { index, mutableList ->
                    mutableList.filter { mem[it.toInt() - 1] }.size % 2 == p[index].toInt()
                }.size == sList.size) {
                ans++
            }
        } else {
            checkDfs(mem, index + 1)
            val copy = mem.copy().toMutableList()
            copy[index] = true
            checkDfs(copy, index + 1)
        }
    }

    checkDfs(_mem, 0)



    println(ans)

}


fun readList() = readLine()!!.split(' ')
fun readLongList() = readList().map(String::toLong)

fun readLong() = readLine()!!.toLong()
fun readString() = readLine()!!

fun readPair(): Pair<String, String> {
    val splite = readLine()!!.split(' ')
    return Pair(splite[0], splite[1])
}

fun <T> List<T>.copy() = this.map { it }

// 速度のためforEachは避ける
fun Int.rep(start: Int = 0, body: (Int) -> Unit) {
    for (i in start until this) {
        body(i)
    }
}

fun Long.rep(start: Long = 0, body: (Long) -> Unit) {
    for (i in start until this) {
        body(i)
    }
}