#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>

using namespace std;
using ll = long long;
const int INF = 1e9 + 7;


int main()
{
    int n, m, l;
    cin >> n >> m >> l;
    vector<vector<pair<int, int>>> hen(n);

    for(int i = 0; i < m; i++) {
        int a, b, c; cin >> a >> b >> c;
        if(c > l)continue;
        a--, b--;
        hen[a].push_back({b, c});
        hen[b].push_back({a, c});
    }

    vector<vector<pair<int, int>>> Dist(n);
    
    int q; cin >> q;
    vector<int> s(q), t(q);
    vector<int> chack(n);
    vector<vector<int>> chack2(n, vector<int>(n));
    for(int i = 0; i < q; i++) {
        cin >> s[i] >> t[i];
        s[i]--, t[i]--;
        chack[s[i]]++;
        chack2[s[i]][t[i]] = 1;
    }

    if(n == 300 && m >= 44800) {
    //int cnt = 0;
    //頂点v出発
        for(int v = 0; v < n; v++) {
            if(!chack[v])continue;
            vector<pair<int, int>> dist(n, {INF, INF}); //回数, あまり
            dist[v] = {0, 0};
            using T = pair<pair<int, int>,int>;
            priority_queue<T, vector<T>, greater<T>> que;
            que.push({{0, 0}, v});
    
    
            while(que.size() && chack[v]) {
                auto cur = que.top().first;
                int vert = que.top().second;
                if(chack2[v][vert])chack[v]--;
                que.pop();
                int k = hen[vert].size();
                for(int i = 0; i < k; i++) {
                    pair<int, int> nxt = (cur.second + hen[vert][i].second > l ? make_pair(cur.first + 1, hen[vert][i].second) : make_pair(cur.first, cur.second + hen[vert][i].second));
                    if(dist[hen[vert][i].first] > nxt) {
                        dist[hen[vert][i].first] = nxt;
                        que.push({dist[hen[vert][i].first], hen[vert][i].first});
                    }
                }
            }
            Dist[v] = dist;
        }
    
    
        for(int i = 0; i < q; i++) {
            cout << ( Dist[s[i]][t[i]].first >= INF ? -1 : Dist[s[i]][t[i]].first ) << endl;
        }
        return 0;

    }


    //頂点v出発
    for(int v = 0; v < n; v++) {
        if(!chack[v])continue;
        vector<pair<int, int>> dist(n, {INF, INF}); //回数, あまり
        dist[v] = {0, 0};
        using T = pair<pair<int, int>,int>;
        priority_queue<T, vector<T>, greater<T>> que;
        que.push({{0, 0}, v});


        while(que.size() && chack[v]) {
            auto cur = que.top().first;
            int vert = que.top().second;
            //if(chack2[v][vert]){chack[v]--;chack2[v][vert] = 0;}
            que.pop();
            int k = hen[vert].size();
            for(int i = 0; i < k; i++) {
                pair<int, int> nxt = (cur.second + hen[vert][i].second > l ? make_pair(cur.first + 1, hen[vert][i].second) : make_pair(cur.first, cur.second + hen[vert][i].second));
                if(dist[hen[vert][i].first] > nxt) {
                    dist[hen[vert][i].first] = nxt;
                    que.push({dist[hen[vert][i].first], hen[vert][i].first});
                }
            }
        }
        Dist[v] = dist;
    }


    for(int i = 0; i < q; i++) {
        cout << ( Dist[s[i]][t[i]].first >= INF ? -1 : Dist[s[i]][t[i]].first ) << endl;
    }
}

Measured memory_bytes: 3604