#include <bit>
#include <bitset>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <queue>
#include <stack>


typedef long double ld;
typedef long long ll;

using namespace std;

ll MOD = ((ll)1e9 + 7);

struct mod {
	ll x;

	mod(ll tx = 0) {
		x = tx;
	}
	
	mod& operator=(const ll & tx) {
		x = tx;
		return *this;
	}
	
	mod& operator=(const mod & m2) {
		x = m2.x;
		return *this;
	}

	mod operator+(const mod& m2) const {
		return (x + m2.x) % MOD;
	}

	mod& operator+=(const mod& m2) {
		x += m2.x;
		x %= MOD;
		return *this;
	}

	mod operator-(const mod & m2) const {
		return (x - m2.x + MOD) % MOD;
	}

	mod& operator-=(const mod & m2) {
		x -= m2.x;
		x = (x + MOD) % MOD;
		return *this;
	}

	mod operator*(const mod & m2) const {
		return (x * m2.x) % MOD;
	}

	mod& operator*=(const mod & m2) {
		x *= m2.x;
		x %= MOD;
		return *this;
	}

	mod mypow(ll k) const {
		mod ret = 1;
		mod cur = x;
		while (k) {
			if (k & 1) {
				ret *= cur;
			}
			cur *= cur;
			k >>= 1;
		}
		return ret;
	}

	mod inv() const {
		return mypow(MOD - 2);
	}

	mod operator/(const mod & m2) const {
		return mod(((*this).x * (*this).inv().x) % MOD);
	}

	mod& operator/=(const mod & m2) {
		x *= m2.inv().x;
		x %= MOD;
		return *this;
	}

	bool operator<(const mod & m2) const {
		return x < m2.x;
	}
};

ostream &operator<<(ostream & os, const mod & m) {
	return os << m.x;
}

/* TEMPLATE ENDS HERE */

#define MAXN (1 << 9)
#define INF (1LL << 60)
#define INF2 (1 << 14)

int n, m, l;
ll d[MAXN][MAXN];
int dd[MAXN][MAXN];
//unsigned char v[MAXN];
//short int dist[MAXN][MAXN];
//queue<int> q;

int main() {
	//freopen("input.txt", "r", stdin);
	cin >> n >> m >> l;	
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			d[i][j] = INF;
		}
	}
	for (int i = 0; i < m; i++) {
		int v1, v2, c;
		cin >> v1 >> v2 >> c;
		v1--;
		v2--;
		d[v1][v2] = c;
		d[v2][v1] = c;
	}
	for (int k = 0; k < n; k++) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				ll cur = d[i][k] + d[k][j];
				d[i][j] = min(d[i][j], cur);
			}
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			dd[i][j] = INF2;
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (d[i][j] <= l) {
				dd[i][j] = 1;
			}
		}
	}
	for (int k = 0; k < n; k++) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int cur = dd[i][k] + dd[k][j];
				dd[i][j] = min(dd[i][j], cur);
			}
		}
	}
/*	for (int i = 0; i < n; i++) {
		memset(v, 0, sizeof(v));
		for (int j = 0; j < n; j++) {
			dist[i][j] = INF2;
		}
		dist[i][i] = 0;
		q.push(i);
		while (!q.empty()) {
			int cur = q.front();
			q.pop();
			v[cur] = 1;
			for (int j = 0; j < n; j++) {
				if (!v[j] && dd[cur][j]) {
					q.push(j);
					short int curd = dist[i][cur] + 1;
					if (curd < dist[i][j]) {
						dist[i][j] = curd;
					}
				}
			}
		}
	}*/
	int q;
	cin >> q;
	for (int i = 0; i < q; i++) {
		int s, t;
		cin >> s >> t;
		s--;
		t--;
		if (dd[s][t] < INF2) {
			cout << dd[s][t] - 1 << endl;
		} else {
			cout << -1 << endl;
		}
	}
	return 0;
}


Measured memory_bytes: 4956