unittest
{
	assert( [ "3 2 5", "1 2 3", "2 3 3", "2", "3 2", "1 3" ].parse.expand.solve == "0\n1" );
	assert( [ "4 0 1", "1", "2 1" ].parse.expand.solve == "-1" );
	assert( [ "5 4 4", "1 2 2", "2 3 2", "3 4 3", "4 5 2", "20", "2 1", "3 1", "4 1", "5 1", "1 2", "3 2", "4 2", "5 2", "1 3", "2 3", "4 3", "5 3", "1 4", "2 4", "3 4", "5 4", "1 5", "2 5", "3 5", "4 5" ].parse.expand.solve == "0\n0\n1\n2\n0\n0\n1\n2\n0\n0\n0\n1\n1\n1\n0\n0\n2\n2\n1\n0" );
}



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 nml = input.front.split.to!( long[] );
	auto abcs = new long[ 3 ][ nml[ 1 ] ];
	foreach( ref abc; abcs )
	{
		input.popFront;
		abc = input.front.split.to!( long[] );
		abc[ 0 .. 2 ] -= 1;
	}
	input.popFront;
	auto q = input.front.to!( long );
	auto sts = new long[ 2 ][ q ];
	foreach( ref st; sts )
	{
		input.popFront;
		st = input.front.split.to!( long[] );
		st[] -= 1;
	}
	
	return tuple( nml[ 0 ], nml[ 2 ], abcs, sts );
}

auto solve( long n, long l, long[ 3 ][] abcs, long[ 2 ][] sts )
{
	// 辺配列を隣接リストに変換
	auto nss = new Tuple!( long, long )[][ n ];
	foreach( e; abcs )
	{
		if( l < e[ 2 ] ) continue;
		nss[ e[ 0 ] ] ~= tuple( e[ 1 ], e[ 2 ] );
		nss[ e[ 1 ] ] ~= tuple( e[ 0 ], e[ 2 ] );
	}
	
	// 最小補給回数を計算
	auto dss = new long[][ n ];
	foreach( i, ref ds; dss )
	{
		ds = dijkstraEx!( true )( n, nss, abcs.length, i, l );
	}
	
	// クエリに回答
	auto anss = new long[ sts.length ];
	foreach( ref ans, st; lockstep( anss, sts ) )
	{
		ans = dss[ st[ 0 ] ][ st[ 1 ] ];
		if( ans == long.max ) ans = -1;
	}
	return anss.to!( string[] ).join( "\n" );
}

// 正の重み付きグラフの始点指定最短経路探索（ダイクストラ法）
auto dijkstraEx( bool undirected = false )( long n, Tuple!( long, long )[][] nss, long ec, long s, long l )
{
	import std.container.binaryheap;
	
	auto ds = new long[ n ];
	ds[] = long.max;
	ds[ s ] = 0;
	auto us = new bool[ n ];
	auto uc = 0L;
	auto queue = heapify!( ( a, b ) => ( a[ 1 ] != b[ 1 ] ) ? b[ 1 ] < a[ 1 ] : a[ 2 ] < b[ 2 ] )( new Tuple!( long, long, long )[ ec ], 0 );
	queue.insert( tuple( s, 0L, l ) );
	while( !queue.empty )
	{
		auto fi = queue.front[ 0 ];
		auto fc = queue.front[ 1 ];
		auto ff = queue.front[ 2 ];
		queue.popFront();
		
		if( us[ fi ] ) continue;
		us[ fi ] = true;
		uc++;
		if( uc == us.length ) break;
		
		foreach( t; nss[ fi ] )
		{
			auto ti = t[ 0 ];
			auto tc = fc + ( ff - t[ 1 ] < 0 );
			auto tf = ( ( ff - t[ 1 ] < 0 ) ? l : ff ) - t[ 1 ];
			
			if( ds[ ti ] <= tc ) continue;
			ds[ ti ] = tc;
			queue.insert( tuple( ti, tc, tf ) );
		}
	}
	return ds;
}
