Problem:
Score : 500 points

Problem Statement

There are N towns numbered 1 to N and M roads. The i-th road connects Town A_i and Town B_i bidirectionally and has a length of C_i.

Takahashi will travel between these towns by car, passing through these roads. The fuel tank of his car can contain at most L liters of fuel, and one liter of fuel is consumed for each unit distance traveled. When visiting a town while traveling, he can full the tank (or choose not to do so). Travel that results in the tank becoming empty halfway on the road cannot be done.

Process the following Q queries:

The tank is now full. Find the minimum number of times he needs to full his tank while traveling from Town s_i to Town t_i. If Town t_i is unreachable, print -1.

Constraints

All values in input are integers.

2 \leq N \leq 300

0 \leq M \leq \frac{N(N-1)}{2}

1 \leq L \leq 10^9

1 \leq A_i, B_i \leq N

A_i \neq B_i

\left(A_i, B_i\right) \neq \left(A_j, B_j\right) (if i \neq j)

\left(A_i, B_i\right) \neq \left(B_j, A_j\right) (if i \neq j)

1 \leq C_i \leq 10^9

1 \leq Q \leq N\left(N-1\right)

1 \leq s_i, t_i \leq N

s_i \neq t_i

\left(s_i, t_i\right) \neq \left(s_j, t_j\right) (if i \neq j)

Input

Input is given from Standard Input in the following format:

N M L
A_1 B_1 C_1
:
A_M B_M C_M
Q
s_1 t_1
:
s_Q t_Q

Output

Print Q lines.

The i-th line should contain the minimum number of times the tank needs to be fulled while traveling from Town s_i to Town t_i. If Town t_i is unreachable, the line should contain -1 instead.

Sample Input 1

3 2 5
1 2 3
2 3 3
2
3 2
1 3

Sample Output 1

0
1

To travel from Town 3 to Town 2, we can use the second road to reach Town 2 without fueling the tank on the way.

To travel from Town 1 to Town 3, we can first use the first road to get to Town 2, full the tank, and use the second road to reach Town 3.

Sample Input 2

4 0 1
1
2 1

Sample Output 2

-1

There may be no road at all.

Sample Input 3

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

Sample Output 3

0
0
1
2
0
0
1
2
0
0
0
1
1
1
0
0
2
2
1
0

Solution in C++14 (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

//#define _AOJ_


        /*vvv>
        zzzzzI
 .---.  zzuzuI                 .vgggg&,.
+++++=  dAC:|I  .WbbWo       JMM9^```?TMB`  ..&gNNg,.   gggggggJ,   qgggggggg] (&&&&&&&&[   c+OA&J,   (&&&&&&+J,   .cJeAA&-.  (&&&&&&&&x   .&AA&=-.
+++++=  dTqk|I  Xpbpbp      JM#`           (M#^   ?MMp  MM|   +TMN. JMF      ' |yk      ` dVY    7Vk,  Vy     XV  cVf     ?Y!  JM         V$      `
+++++=  dcf:|I  Xppppp      dMN           .MM+     .MM  MM|     MM] JMMMMMM+   |@tqkoh)  ,y0      (V$  yyyyyyyV7  VV           JMWyZWr    TWVVVVW&,
++++++  d7qk|0  Xppppp      ^HMN,    _.db  WMm,   .MMF  MM|   ..MM` JMF      . |yk       .WV&.   .XW'  yy   4yn.  jyn      +.  JM                #S
`++++`  ?ZZZX=  ?WWWW=        -THMMMMH9^    (TMMMMM9!   MMMMMMM""   JMMMMMMMME |UU.        ?TUUUUY=    UU.   (UU-  ^7TUUUV7!   JUUUUUUUU  7TUNKO*/

#include "bits/stdc++.h"
using namespace std;typedef long long lint;typedef vector<lint> liv;
//#define rep(i,n) for(int i=0;i<n;++i)
#define all(v) v.begin(),v.end()

#define pb push_back
#define _vcppunko4(tuple) _getname4 tuple
#define _getname4(_1,_2,_3,_4,name,...) name
#define _getname3(_1,_2,_3,name,...) name
#define _trep2(tuple) _rep2 tuple
#define _trep3(tuple) _rep3 tuple
#define _trep4(tuple) _rep4 tuple
#define _rep1(n) for(lint i=0;i<n;++i)
#define _rep2(i,n) for(lint i=0;i<n;++i)
#define _rep3(i,a,b) for(lint i=a;i<b;++i)
#define _rep4(i,a,b,c) for(lint i=a;i<b;i+=c)
#define _trrep2(tuple) _rrep2 tuple
#define _trrep3(tuple) _rrep3 tuple
#define _trrep4(tuple) _rrep4 tuple
#define _rrep1(n) for(lint i=n-1;i>=0;--i)
#define _rrep2(i,n) for(lint i=n-1;i>=0;--i)
#define _rrep3(i,a,b) for(lint i=b-1;i>=a;--i)
#define _rrep4(i,a,b,c) for(lint i=a+(b-a-1)/c*c;i>=a;i-=c)
template<class T>
istream& operator>>(istream& is,vector<T>& vec);
template<class T,size_t size>
istream& operator>>(istream& is,array<T,size>& vec);
template<class T,class L>
istream& operator>>(istream& is,pair<T,L>& p);
template<class T>
ostream& operator<<(ostream& os,vector<T>& vec);
template<class T,class L>
ostream& operator<<(ostream& os,pair<T,L>& p);
template<class T>
istream& operator>>(istream& is,vector<T>& vec){ for(T& x: vec) is>>x;return is; }
template<class T,class L>
istream& operator>>(istream& is,pair<T,L>& p){ is>>p.first;is>>p.second;return is; }
template<class T,class L>
ostream& operator<<(ostream& os,pair<T,L>& p){ os<<p.first<<" "<<p.second;return os; }

inline void in(){}
template <class Head,class... Tail>
inline void in(Head&& head,Tail&&... tail){ cin>>head;in(move(tail)...); }
inline bool out(){ cout<<'\n';return 0; }
template <class T>
inline bool out(T t){ cout<<t<<'\n';return 0; }
template <class Head,class... Tail>
inline bool out(Head head,Tail... tail){ cout<<head<<' ';out(move(tail)...);return 0; }
inline void ssize(lint s){}
template <class Head,class... Tail>
inline void ssize(lint s,Head&& head,Tail&&... tail){ head.resize(s);ssize(s,move(tail)...); }

#define rep(...) _vcppunko4((__VA_ARGS__,_trep4,_trep3,_trep2,_rep1))((__VA_ARGS__))
#define rrep(...) _vcppunko4((__VA_ARGS__,_trrep4,_trrep3,_trrep2,_rrep1))((__VA_ARGS__))

template<class T>
ostream& operator<<(ostream& os,vector<T>& vec){ os<<vec[0];rep(i,1,vec.size())os<<' '<<vec[i];return os; }
template<class T>
ostream& operator<<(ostream& os,deque<T>& deq){ os<<deq[0];rep(i,1,deq.size())os<<' '<<deq[i];return os; }

#define each(v) for(auto &i:v)
#define lin(...) lint __VA_ARGS__;in(__VA_ARGS__)
#define stin(...) string __VA_ARGS__;in(__VA_ARGS__)
#define vin(type,name,size) vector<type> name(size);in(name)
#define fi e.first
#define se e.second
#define YES(c) cout<<((c)?"YES\n":"NO\n"),0
#define Yes(c) cout<<((c)?"Yes\n":"No\n"),0
#define POSSIBLE(c) cout<<((c)?"POSSIBLE\n":"IMPOSSIBLE\n"),0
#define Possible(c) cout<<((c)?"Possible\n":"Impossible\n"),0
#define o(p) cout<<p<<endl,0
#define sp(p) cout<<p<<" "
#define no(p) cout<<p
#ifdef __ENV_TQK__
#define deb(p) cout<<p<<endl,0
#else
#define deb(p) 0
#endif
#define dd(n) cout<<fixed<<setprecision(n)
//mint
#define md_tmp template<uint_fast64_t md=1000000007>
md_tmp class mint{
	using u64=uint_fast64_t;

public:
	u64 a;

	constexpr mint(const u64 x=0) noexcept: a(x%md){}
	constexpr u64 &value() noexcept{ return a; }
	constexpr const u64 &value() const noexcept{ return a; }
	constexpr mint operator+(const mint rhs) const noexcept{
		return mint(*this)+=rhs;
	}
	constexpr mint operator-(const mint rhs) const noexcept{
		return mint(*this)-=rhs;
	}
	constexpr mint operator*(const mint rhs) const noexcept{
		return mint(*this)*=rhs;
	}
	constexpr mint operator^(const lint rhs) const noexcept{
		return mint(*this)^=rhs;
	}
	constexpr mint operator/(const mint rhs) const noexcept{
		return mint(*this)/=rhs;
	}
	constexpr mint &operator+=(const mint rhs) noexcept{
		a+=rhs.a;
		if(a>=md)a-=md;
		return *this;
	}
	constexpr mint &operator-=(const mint rhs) noexcept{
		if(a<rhs.a)a+=md;
		a-=rhs.a;
		return *this;
	}
	constexpr mint &operator*=(const mint rhs) noexcept{
		a=a*rhs.a%md;
		return *this;
	}
	constexpr mint &operator^=(const lint rhs) noexcept{
		if(!rhs)return *this=1;
		u64 exp=rhs-1;
		mint base=this->a;
		while(exp){
			if(exp&1)*this*=base;
			base*=base;
			exp>>=1;
		}
		return *this;
	}
	constexpr mint &operator/=(const mint rhs) noexcept{
		a=(*this*(rhs^(md-2))).a;
		return *this;
	}
};
md_tmp istream& operator>>(istream& os,mint<md>& m){
	os>>m.a,m.a%=md;
	return os;
}
md_tmp ostream& operator<<(ostream& os,const mint<md>& m){
	return os<<m.a;
}
md_tmp mint<md> ncr(lint n,lint r){
	if(n<r||n<0||r<0)return mint<md>(0);
	mint<md>ncr_res=1,ncr_div=1;
	rep(r)ncr_res*=(n-i),ncr_div*=(r-i);
	return ncr_res/ncr_div;
}
#ifndef _AOJ_
mint<> operator""m(unsigned long long n){ return mint<>(n); }
mint<998244353> operator""m9(unsigned long long n){ return mint<998244353>(n); }
mint<1000003> operator""m3(unsigned long long n){ return mint<1000003>(n); }
#endif
using mi=mint<>;

////P
//class P{ public:lint f,s; constexpr P(lint a,lint b):f(a),s(b){};constexpr P():f(0),s(0){}; };
//istream& operator>>(istream& is,P& p){ is>>p.f>>p.s;return is; }
//ostream& operator<<(ostream& os,const P& p){ return os<<p.f<<" "<<p.s<<endl; }
//bool operator<(const P& l,const P& r){ return(l.f-r.f?l.f<r.f:l.s<r.s); }
//bool operator>(const P& l,const P& r){ return(l.f-r.f?l.f>r.f:l.s>r.s); }
struct C{ lint f,s,t; };
bool operator<(const C& l,const C& r){ return l.t<r.t; }
bool operator>(const C& l,const C& r){ return l.t>r.t; }

#define linf 1152921504606846976
#define inf linf//INT_MAX
#define MAXN 330
#define md_1e9_7 1000000007
#define md_998244353 998244353
//#define mod md_1e9_7

const int d4[5]={0,1,0,-1,0};

//funcs
#define flint(s) [](lint a,lint b){return(s);}

inline void eraseunique(string &v){//nの変更を忘れるな
	v.erase(unique(all(v)),v.end());
}

template<typename T>
vector<pair<T,lint>> runlength(vector<T> v){
	lint n=v.size();
	vector<pair<T,lint>> ret(1,{v[0],1});
	rep(n){
		if(ret[ret.size()-1].first==v[i])++ret[ret.size()-1].second;
		else ret.push_back({v[i],1});
	}
	return ret;
}

template<typename T,class F>//ラムダ式の受け取り方
vector<T> ruiseki(vector<T> a,F f,lint e){
	lint n=a.size();
	vector<T> s(n+1);
	rep(n)s[i+1]=f(s[i],a[i]);
	return s;
}

set< lint > divisor(lint n){
	set< lint > ret;
	for(lint i = 1; i * i <= n; i++){
		if(n % i == 0){
			ret.insert(i);
			if(i * i != n) ret.insert(n / i);
		}
	}
	return (ret);
}


//\funcs



//namespace FastFourierTransform{
//	using C = complex< double >;
//
//	void DiscreteFourierTransform(vector< C > &F,bool rev){
//		const int N = (int)F.size();
//		const double PI = (rev ? -1 : 1) * acos(-1);
//		for(int i = 0,j = 1; j + 1 < N; j++){
//			for(int k = N >> 1; k > (i ^= k); k >>= 1);
//			if(i > j) swap(F[i],F[j]);
//		}
//		C w,s,t;
//		for(int i = 1; i < N; i <<= 1){
//			for(int k = 0; k < i; k++){
//				w = polar(1.0,PI / i * k);
//				for(int j = 0; j < N; j += i * 2){
//					s = F[j + k];
//					t = C(F[j + k + i].real() * w.real() - F[j + k + i].imag() * w.imag(),
//						  F[j + k + i].real() * w.imag() + F[j + k + i].imag() * w.real());
//					F[j + k] = s + t,F[j + k + i] = s - t;
//				}
//			}
//		}
//		if(rev) for(int i = 0; i < N; i++) F[i] /= N;
//	}
//
//	vector< long long > Multiply(const vector< int > &A,const vector< int > &B){
//		int sz = 1;
//		while(sz < A.size() + B.size() - 1) sz <<= 1;
//		vector< C > F(sz),G(sz);
//		for(int i = 0; i < A.size(); i++) F[i] = A[i];
//		for(int i = 0; i < B.size(); i++) G[i] = B[i];
//		DiscreteFourierTransform(F,false);
//		DiscreteFourierTransform(G,false);
//		for(int i = 0; i < sz; i++) F[i] *= G[i];
//		DiscreteFourierTransform(F,true);
//		vector< long long > X(A.size() + B.size() - 1);
//		for(int i = 0; i < A.size() + B.size() - 1; i++) X[i] = F[i].real() + 0.5;
//		return (X);
//	}
//};

struct edge{
	lint from,to,cost;
};
vector<edge>g[MAXN];
vector<edge>edges;
int n,m,l;

//define pfs,bellmanford,etc.

struct cont{
	pair<lint,lint>first;//リットル、回数
	lint second;//頂点
};

//pfs
//d,edge,g,P,q;
pair<lint,lint> d[MAXN];
lint prv[MAXN];
typedef cont P;


bool bigger(pair<lint,lint> l,pair<lint,lint> r){
	if(l.second==r.second)return l.first<r.first;
	return l.second>r.second;
}
bool operator>(const P l,const P r){
	return bigger(l.first,r.first);
}

priority_queue<P,vector<P>,greater<P>> q;

void pfs(int s){
	rep(300)d[i]={0,inf};
	d[s]={l,0};q.push({{l,0},s});
	pair<lint,lint>cd;//リットル、回数
	lint /*cd,*/cv;//頂点

	while(q.size()){
		cd=q.top().first;
		cv=q.top().second;
		q.pop();
		if(cd>d[cv])continue;
		for(edge &e:g[cv]){
			if(e.cost>l)continue;
			pair<lint,lint>cn=cd;
			if(cd.first>=e.cost)cn.first-=e.cost;
			else{
				cn.second++;
				cn.first=l-e.cost;
			}
			if(bigger(d[e.to],cn)){
				d[e.to]=cn;
				prv[e.to]=cv;
				q.push({d[e.to],e.to});
			}
		}
	}
}


bool vis[330];

int main(){
	in(n,m,l);
	lint a,b,c;
	rep(m){
		in(a,b,c);--a,--b;
		g[a].pb({a,b,c});
		g[b].pb({b,a,c});
	}
	//pfs,bellmanford,etc.
	lin(q);
	rep(Q,q){
		lint s,t;in(s,t);--s,--t;
		pfs(s);
		if(d[t].second==inf)o(-1);
		else o(d[t].second);
	}
}


//sub-EOF