unittest
{
	assert( [ "3", "2", "1 2", "10", "2", "1 1", "10", "6", "2 3 4 5 6 7", "111000" ].parse.expand.solve == "1\n0\n0" );
}



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 t = input.front.to!( long );
	auto asss = new Tuple!( long[], dchar[] )[ t ];
	foreach( ref ass; asss )
	{
		input.popFront;
		input.popFront;
		auto as = input.front.split.to!( long[] );
		input.popFront;
		auto s = input.front.to!( dchar[] );
		ass = tuple( as, s );
	}
	return tuple( asss );
}

auto solve( Tuple!( long[], dchar[] )[] asss )
{
	auto anss = new long[ asss.length ];
	foreach( ref ans, ass; lockstep( anss, asss ) )
	{
		long[] bs;		// 最上位bitが全部違う数の集合
		
		// ゲームの終わりから遡って考える
		foreach_reverse( a, c; lockstep( ass[ 0 ], ass[ 1 ] ) )
		{
			// aの立っているbitをできるだけ下ろす
			foreach( b; bs )
			{
				a = min( a, a ^ b );		// bの最上位bitと同じ位置のaのbitを下ろす
			}
			
			if( a == 0 ) continue;
			
			if( c == '0' )
			{
				// 元のaとa^bではなく、最上位bitがbsのどれとも違う状態にしてからbsに加えることでパターン数を圧縮する
				bs ~= a;
			}
			else
			{
				// このaを使えば、残りのターンを全て使っても絶対 x==0 にできないので結果が確定する
				ans = 1;
				break;
			}
		}
	}
	return anss.to!( string[] ).join( "\n" );
}
