import std.stdio, std.algorithm, std.conv, std.array, std.string, std.math, std.typecons, std.numeric;

void main()
{
    auto nml = readln.split.to!(int[]);
    auto N = nml[0];
    auto M = nml[1];
    auto L = nml[2];

    auto G = new int[][](N, N);
    foreach (i; 0..N) {
        foreach (j; 0..N) {
            G[i][j] = int.max;
        }
    }
    foreach (_; 0..M) {
        auto abc = readln.split.to!(int[]);
        auto A = abc[0]-1;
        auto B = abc[1]-1;
        auto C = abc[2];
        if (C > L) continue;
        G[A][B] = C;
        G[B][A] = C;
    }

    auto Q = readln.chomp.to!int;
    foreach (_; 0..Q) {
        auto st = readln.split.to!(int[]);
        auto s = st[0]-1;
        auto t = st[1]-1;
        auto MEMO = new int[][](N, N);
        auto FLG = new bool[][](N, N);
        int walk(int i, int l, int f) {
            if (i == t) {
                return l;
            }
            FLG[i][l] = true;
            MEMO[i][l] = f;
            auto res = N;
            foreach (j, jf; G[i]) {
                if (jf > L) continue;
                auto ff = f - jf;
                auto ll = l;
                if (ff < 0) {
                    ff = L - jf;
                    ++ll;
                }
                if (ll >= N || (FLG[j][ll] && MEMO[j][ll] <= ff)) continue;
                res = min(res, walk(j.to!int, ll, ff));
            }
            return res;
        }
        auto res = walk(s, 0, L);
        writeln(res == N ? -1 : res);
    }
}