#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>

#define rep(i, m, n) for(int i=int(m);i<int(n);i++)
#define all(c) begin(c),end(c)

template<typename T1, typename T2>
inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
using Int = long long int;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x)  cerr << #x << " = " << (x) << endl
#define MOD 1000000007


//edit
class Solve {
public:
    int N;
    int M;
    Int L;
    vector<vector<pair<Int, Int>>> G;
    vector<vector<Int>> ans;

    bool lt(pair<Int, Int> a, pair<Int, Int> b) {
        return a < b;
//        if (a.first != b.first) {
//            return a.first < b.first;
//        }
//        return a.second < b.second;
    }

    void bfs(int s) {
        using P = pair<pair<Int, Int>, Int>;
        priority_queue<pair<pair<Int, Int>, Int>, vector<P>, greater<P>> que;
        vector<pair<Int, Int>> dist(N, make_pair(INFl, 0));
        dist[s] = make_pair(0ll, 0);
        que.push(P(dist[s], s));

        while (!que.empty()) {
//            P p = que.front();
            P p = que.top();
            que.pop();

            Int v = p.second;
            if (dist[v] < p.first) continue;

            for (int i = 0; i < G[v].size(); ++i) {
                pair<Int, Int> e = G[v][i];
                pair<Int, Int> next = dist[v];
                if (next.first == INFl) continue;
                if (next.second + e.second <= L) {
//                    next.second -= e.second;
                    next.second += e.second;
                } else {
                    next.first++;
                    next.second = e.second;
                }
                if (next.second > L) {
                    continue;
                }

                if (next < dist[e.first] && !(dist[e.first].first == INFl && next.first >= INFl)) {
                    dist[e.first] = next;
                    que.push(P(next, e.first));
                }
            }
        }

        for (int i = 0; i < N; ++i) {
            ans[s][i] = dist[i].first;
        }
    }

    void solve() {
        cin >> N;
        cin >> M;
        cin >> L;
        G.resize(N);
        ans.resize(N, vector<Int>(N));

        for (int i = 0; i < M; ++i) {
            int a, b;
            Int c;
            cin >> a >> b >> c;
            a--, b--;
            G[a].emplace_back(b, c);
            G[b].emplace_back(a, c);
        }

        for (int i = 0; i < N; ++i) {
            bfs(i);
        }
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                if (ans[i][j] == INFl) ans[i][j] = -1;
            }
        }

        int Q;
        cin >> Q;
        while (Q--) {
            int s, t;
            cin >> s >> t;
            s--, t--;
            cout << ans[s][t] << endl;
        }


    }
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    Solve().solve();


    return 0;
}


Measured memory_bytes: 5504