unittest
{
	assert( [ "3", "1 2", "2 3", "1", "1 3" ].parse.expand.solve == 3 );
	assert( [ "2", "1 2", "1", "1 2" ].parse.expand.solve == 1 );
	assert( [ "5", "1 2", "3 2", "3 4", "5 3", "3", "1 3", "2 4", "2 5" ].parse.expand.solve == 9 );
	assert( [ "8", "1 2", "2 3", "4 3", "2 5", "6 3", "6 7", "8 6", "5", "2 7", "3 5", "1 6", "2 8", "7 8" ].parse.expand.solve == 62 );
}



import core.bitop;
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 n = input.front.to!( long );
	auto abs = new long[ 2 ][ n - 1 ];
	foreach( ref ab; abs )
	{
		input.popFront;
		ab = input.front.split.to!( long[] );
		ab[] -= 1;
	}
	input.popFront;
	auto m = input.front.to!( long );
	auto uvs = new long[ 2 ][ m ];
	foreach( ref uv; uvs )
	{
		input.popFront;
		uv = input.front.split.to!( long[] );
		uv[] -= 1;
	}
	return tuple( n, abs, uvs );
}

auto solve( long n, long[ 2 ][] abs, long[ 2 ][] uvs )
{
	// 辺配列を隣接リストに変換
	auto nss = new Tuple!( long, long )[][ n ];
	foreach( i, ab; abs )
	{
		nss[ ab[ 0 ] ] ~= tuple( ab[ 1 ], 1L << i );		// 辺番号を付与
		nss[ ab[ 1 ] ] ~= tuple( ab[ 0 ], 1L << i );		// 辺番号を付与
	}
	
	// 制約に含まれる辺集合をビット列で作成
	auto ws = new long[ uvs.length ];
	foreach( ref w, uv; lockstep( ws, uvs ) )
	{
		w = dfs( nss, -1, uv[ 0 ], uv[ 1 ] );
	}
	
	// 全制約を満たすパターンの数を計算
	auto ans = 0L;
	foreach( wt; 1L .. ( 1L << uvs.length.signed ) )
	{
		// 制約集合wtに含まれる辺集合をビット列で作成
		auto nt = 0L;
		for( auto i = 0L, b = wt; 0 < b; i++, b >>= 1 )
		{
			if( b & 1 ) nt |= ws[ i ];
		}
		
		// 制約集合wtを満たす塗り方のパターン数を計算
		auto nc = nt._popcnt;
		auto nr = abs.length.signed - nc;
		auto p = ( 2L ^^ nc - 1 ) * ( 2L ^^ nr );
		
		// 包除原理に沿ってパターン数合計を増やしたり減らしたりする
		if( wt._popcnt % 2 == 1 ) ans += p;
		else                      ans -= p;
	}
	return ans;
}

long dfs( Tuple!( long, long )[][] nss, long p, long s, long e )
{
	foreach( n; nss[ s ] )
	{
		if( n[ 0 ] == p ) continue;
		if( n[ 0 ] == e ) return n[ 1 ];
		auto b = dfs( nss, s, n[ 0 ], e );
		if( b != 0 ) return n[ 1 ] | b;
	}
	return 0L;
}
