unittest
{
	assert( [ "2 2", "2 1 2", "1 2", "0 1" ].parse.expand.solve == 1 );
	assert( [ "2 3", "2 1 2", "1 1", "1 2", "0 0 1" ].parse.expand.solve == 0 );
	assert( [ "5 2", "3 1 2 5", "2 2 3", "1 0" ].parse.expand.solve == 8 );
}



import core.bitop;
import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto nm = input.front.split.to!( long[] );
	auto ss = new long[][ nm[ 1 ] ];
	foreach( ref s; ss )
	{
		input.popFront;
		s = input.front.split.to!( long[] )[ 1 .. $ ];
	}
	input.popFront;
	auto ps = input.front.split.to!( long[] );
	return tuple( nm[ 0 ], ss, ps );
}

auto solve( long n, long[][] ss, long[] ps )
{
	// 電球に対応しているスイッチをビットパターンに変換
	auto pbs = new uint[]( ps.length );
	foreach( ref pb, s; lockstep( pbs, ss ) )
	{
		foreach( w; s )
		{
			pb |= 1 << ( w - 1 );
		}
	}
	
	// 各スイッチのON/OFF状態をビットパターンで列挙
	auto ans = 0L;
	auto m = 1U << n;
	for( auto b = 0U; b < m; b++ )
	{
		//  電球に対応しているスイッチと各スイッチのON/OFF状態のANDを取って電球の状態を判定
		auto on = 0L;
		foreach( pb, p; lockstep( pbs, ps ) )
		{
			on += ( ( b & pb ).popcnt % 2 == p );
		}
		
		// 全ての電球が付いていたら答えに足す
		ans += ( on == ps.length );
	}
	
	return ans;
}
