import std.stdio, std.algorithm;


/** Warshall-Floyd algorithm to compute min cost

Parameters:
    d = path cost matrix. if a -> b path is not available: d[a][b] == T.max
        this function overwrites d to have min path cost.
 */
void minPathCost(T)(T[][] d) {
    debug foreach (x; d) {
        assert(x.length == d.length);
    }
    auto N = d.length;
    foreach (k; 0 .. N) {
        foreach (i; 0 .. N) {
            foreach (j; 0 .. N) {
                if (d[i][k] == T.max || d[k][j] == T.max) continue;
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
            }
        }
    }
}

///
unittest {
    int[][] d = [
        [0, 10, 2],             // a -> b = 10,   a -> c = 2
        [1, 0, 5],              // b -> a = 1,    b -> c = 5
        [int.max, 5, 0]         // c -> a = none, c -> b = 5
    ];
    minPathCost(d);
    // min (b -> c) = (b -> a -> c) = 1 + 2
    assert(d[1][2] == 3);
    // min (c -> b) = (c -> b) = 5
    assert(d[2][1] == 5);
    // min (c -> a) = (c -> b -> a) = 5 + 1
    assert(d[2][0] == 6);
}


void main() {
    int n, m, l;
    readf("%d %d %d\n", &n, &m, &l);
    auto dist = new int[][](n, n);
    foreach (d; dist) {
        d[] = int.max;
    }
    foreach (i; 0 .. m) {
        int a, b, c;
        readf("%d %d %d\n", &a, &b, &c);
        dist[a-1][a-1] = 0;
        dist[b-1][b-1] = 0;
        dist[a-1][b-1] = c;
        dist[b-1][a-1] = c;
    }

    minPathCost(dist);

    // convert dist to flags of accecible within l steps
    foreach (d; dist) {
        foreach (ref x; d) {
            x = x <= l ? 1 : int.max;
        }
    }
    minPathCost(dist);
    
    int q;
    readf("%d\n", &q);
    foreach (i; 0 .. q) {
        int s, t;
        readf("%d %d\n", &s, &t);
        auto d = dist[s-1][t-1];
        if (d == int.max) {
            writeln(-1);
        } else {
            writeln(d - 1);
        }
    }
}
