//include
//------------------------------------------
#include <vector>
#include <list>
#include <map>
#include <unordered_map>
#include <climits>
#include <set>
#include <unordered_set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <queue>
#include <random>
#include <complex>
#include <regex>
#include <locale>
#include <random>
#include <type_traits>

using namespace std;

#define SHOW_VECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";}
#define SHOW_MAP(v){std::cerr << #v << endl; for(const auto& xxx: v){std::cerr << xxx.first << " " << xxx.second << "\n";}}

using LL = long long;

//------------------------------------------
//------------------------------------------

constexpr LL INF = 1e16;

template<class T>
struct Edge {
    int from, to;
    T cost;

    Edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}

    explicit operator int() const { return to; }
};

template<class T>
using Edges = vector<Edge<T>>;

template<class T>
using WeightedGraph = vector<Edges<T>>;

using UnWeightedGraph = vector<vector<int>>;

template<class T>
using DistMatrix = vector<vector<T>>;

struct GraphAdapter {
    template<class T>
    static UnWeightedGraph to_unweighted_graph(const WeightedGraph<T> &origin) {
        int V = origin.size();
        UnWeightedGraph graph(V);
        for (int i = 0; i < V; i++) for (auto &e: origin[i]) graph[i].push_back((int) e);
        return graph;
    }

    static WeightedGraph<int> to_weighted_graph(const UnWeightedGraph &origin) {
        int V = origin.size();
        WeightedGraph<int> graph(V);
        for (int i = 0; i < V; i++) for (auto to: origin[i]) graph[i].push_back({i, to, 1});
        return graph;
    }

    template<class T>
    static DistMatrix<T> to_dist_matrix(const WeightedGraph<T> &origin, T INF) {
        int V = origin.size();
        DistMatrix<T> matrix(V, vector<T>(V, INF));
        for (int i = 0; i < V; i++) for (auto &e:origin[i]) matrix[i][e.to] = e.cost;
        for (int i = 0; i < V; i++) matrix[i][i] = 0;
        return matrix;
    }
};

template<class T>
class WarshallFloyd {
    int N;
    DistMatrix<T> matrix;
    T INF;

public:
    WarshallFloyd(const DistMatrix<T> matrix, const T INF) : matrix(matrix), N(matrix.size()), INF(INF) {
        build();
    }

    void build() {
        for (int i = 0; i < N; i++) matrix[i][i] = 0;
        for (int k = 0; k < N; k++) {
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if (matrix[i][k] == INF || matrix[k][j] == INF)continue;
                    matrix[i][j] = min(matrix[i][j], matrix[i][k] + matrix[k][j]);
                }
            }
        }
    }

    DistMatrix<T> get_matrix() const {
        return matrix;
    }

    bool has_minus_cycle() const {
        bool is_minus = false;
        for (int i = 0; i < N; i++) if (matrix[i][i] < 0) is_minus = true;
        return is_minus;
    }
};

int main() {

    int N, M;
    LL L;
    cin >> N >> M >> L;

    WeightedGraph<LL> graph(N);

    for (int i = 0; i < M; i++) {
        int a, b;
        LL c;
        cin >> a >> b >> c;
        a--, b--;
        graph[a].push_back({a, b, c});
        graph[b].push_back({b, a, c});
    }

    auto matrix = GraphAdapter::to_dist_matrix(graph, INF);
    WarshallFloyd<LL> warshallFloyd(matrix, INF);
    matrix = warshallFloyd.get_matrix();

    DistMatrix<LL> matrix2(N, vector<LL>(N, INF));
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (matrix[i][j] <= L) {
                matrix2[i][j] = 1;
            }
        }
    }

    warshallFloyd = WarshallFloyd<LL>(matrix2, INF);
    matrix = warshallFloyd.get_matrix();

    int Q;
    cin >> Q;

    while (Q--) {
        int a, b;
        cin >> a >> b;
        a--; b--;
        if(matrix[a][b] == INF) cout << -1 << endl;
        else cout << matrix[a][b] - 1 << endl;
    }

    return 0;
}





















































Measured memory_bytes: 6400