#include <stdio.h>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <numeric>
#include <complex>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <cassert>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
const double EPS = 1e-9;
typedef vector<int> vint;
typedef vector<vector<int>> v2int;
typedef vector<ll> vll;
typedef vector<vector<ll>> v2ll;
typedef list<int> liint;
typedef pair<int, int> pint;
const int INF = int(2e9);
const ll LINF = ll(2e9) * ll(2e9);
#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << #a << " " << a << endl;
#define REP(i, x, n) for(int i = x; i < n; i++)
template<class T, class C> void chmax(T& a, C b) { a > b ? : a = b; }
template<class T, class C> void chmin(T& a, C b) { a < b ? : a = b; }



#include <algorithm>
#include <vector>
#include <functional>
#include <climits>

class warshall_floyd
{
private:
    int node_num;
    bool is_negative_graph;
    std::vector<std::vector<long long>> cost_matrix;//隣接行列を構築
    std::vector<std::vector<int>> pred;//経路（遷移元）を保持

public:
    warshall_floyd(const int node_num, const std::vector<std::vector<long long>> &adj_matrix);
    long long get_cost(int start, int end) const;
    std::vector<int> get_min_path(int start, int end) const;
};

warshall_floyd::warshall_floyd(const int node_num,
    const std::vector<std::vector<long long>> &adj_matrix) :
    cost_matrix(adj_matrix),
    node_num(node_num),
    is_negative_graph(false),
    pred(node_num + 1, std::vector<int>(node_num + 1, INT_MAX))
{
    //predの初期化
    for (int i = 0; i <= node_num; i++) {
        for (int j = 0; j <= node_num; j++) {
            if (i == j) pred[i][j] = -1;
            else if (adj_matrix[i][j] < LLONG_MAX) {
                pred[i][j] = i;
            }
        }
    }
    //ワーシャルフロイドの更新式
    for (int k = 0; k <= node_num; k++) {
        for (int i = 0; i <= node_num; i++) {
            for (int j = 0; j <= node_num; j++) {
                if (cost_matrix[i][k] < LLONG_MAX && cost_matrix[k][j] < LLONG_MAX) {
                    if (cost_matrix[i][k] + cost_matrix[k][j] < cost_matrix[i][j]) {
                        cost_matrix[i][j] = cost_matrix[i][k] + cost_matrix[k][j];
                        //経路復元用
                        //pred[i][j]にはi→jの最短経路におけるjの1つ前の頂点が入る。
                        //pred[k][j]にはk→jの最短経路におけるjの1つ前の頂点が入っている。
                        //この処理を通るということは最短経路がkを使った経路に変わる
                        //ということでありi→jへの経路の中にk→jの最短経路を含むことになる。
                        //従って新しいi→jにおけるjの１つ前の頂点は
                        //k→jにおけるjの１つ前の頂点、すなわちpred[k][j]となる。
                        pred[i][j] = pred[k][j];
                    }
                }
            }
        }
    }

}




long long warshall_floyd::get_cost(int start, int end) const {
    return cost_matrix[start][end];
}

std::vector<int> warshall_floyd::get_min_path(int start, int end) const {
    int node = end;
    std::vector<int> vec;
    vec.push_back(node);
    //終点から始点までの経路をたどる
    while (1) {
        //負のサイクルを含む頂点or
        //始点から辿れない頂点or
        //始点であれば終了
        if (node == start) break;
        if (cost_matrix[node][node] < 0 ||
            pred[start][node] >= INT_MAX ||
            pred[start][node] == -1) break;
        node = pred[start][node];
        vec.push_back(node);
    }
    std::reverse(vec.begin(), vec.end());
    return vec;
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int N, M;
    ll L;
    cin >> N >> M >> L;
    v2ll adj_matrix(N + 1, vll(N + 1, LLONG_MAX));
    rep(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
     
        adj_matrix[a][b] = c;
        adj_matrix[b][a] = c;
  
    }
    warshall_floyd wf(N, adj_matrix);
    v2ll new_adj_matrix(N + 1, vll(N + 1, LLONG_MAX));
    REP(i, 1, N + 1) {
        REP(j, i + 1, N + 1) {
            if (wf.get_cost(i, j) < LLONG_MAX) {
                if (wf.get_cost(i, j) <= L) {
                    new_adj_matrix[i][j] = 1;
                    new_adj_matrix[j][i] = 1;
                }

            }
        }
    }
    warshall_floyd wf2(N, new_adj_matrix);
    int Q;
    cin >> Q;
    vint s(Q), t(Q);
    vll ans(Q);
    rep(i, Q) {
        cin >> s[i] >> t[i];
        if (wf2.get_cost(s[i], t[i]) >= LLONG_MAX) {
            cout << -1 << endl;
        }
        else {
            cout << wf2.get_cost(s[i], t[i]) - 1 << endl;
        }
    }
    
    return 0;
}

Measured memory_bytes: 6400