// https://atcoder.jp/contests/abc143/tasks/abc143_e

#include "algorithm"
#include "iostream"
#include "queue"
#include "set"
#include "vector"
#define rep(i, to) for (ll i = 0; i < (to); ++i)
#define repf(i, from, to) for (ll i = from; i < (to); ++i)
using namespace std;
typedef long long ll;
template <typename T>
using V = vector<T>;
using VL = V<ll>;
using VVL = V<VL>;
using PL = pair<ll, ll>;
template <typename T>
inline bool chmax(T& a, T b);
template <typename T>
inline bool chmin(T& a, T b);
void print_ints(vector<ll> v);
template <typename T>
void drop(T a);

// ワーシャルフロイド２回 O(N^3)
void solve() {
  ll N, M, L;
  cin >> N >> M >> L;

  ll INF = 1 << 30;

  auto ds = VVL(N, VL(N, INF));

  rep(i, M) {
    ll a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;

    if (c > L) continue;

    ds[a][b] = c;
    ds[b][a] = c;
  }

  // ワーシャルフロイド
  rep(k, N) rep(i, N) rep(j, N) {
    ds[i][j] = min(ds[i][j], ds[i][k] + ds[k][j]);
  }

  auto cts = VVL(N, VL(N, INF));

  rep(i, N) rep(j, N) {
    if (i == j) continue;

    if (ds[i][j] <= L) {
      cts[i][j] = 1;
    }
  }

  rep(k, N) rep(i, N) rep(j, N) {
    cts[i][j] = min(cts[i][j], cts[i][k] + cts[k][j]);
  }

  ll Q;
  cin >> Q;
  rep(i, Q) {
    ll s, t;
    cin >> s >> t;
    s--;
    t--;

    ll res = cts[s][t] == INF ? -1 : cts[s][t] - 1;
    cout << res << endl;
  }
}

// ダイクストラ N 回 O (N^3 Log N)?
void solve2() {
  ll N, M, L;
  cin >> N >> M >> L;

  ll INF = 1 << 30;

  auto G = VVL(N, VL(N, INF));
  rep(i, N) G[i][i] = 0;

  rep(i, M) {
    ll a, b, c;
    cin >> a >> b >> c;
    a--, b--;

    if (c > L) continue;

    G[a][b] = G[b][a] = c;
  }

  // first: times, second: used としてこれの最小値をダイクストラで得る
  V<V<PL>> dist(N, V<PL>(N, {INF, INF}));
  rep(i, N) dist[i][i] = {0, 0};

  rep(s, N) {
    // デフォルトでは大きい値から取り出されることに注意
    // priority_queue<pair<PL, ll>> q;
    priority_queue<pair<PL, ll>, V<pair<PL, ll>>, greater<pair<PL, ll>>> q;

    q.push({PL(0, 0), s});

    while (!q.empty()) {
      auto p = q.top();
      q.pop();

      ll v = p.second;
      ll times = p.first.first;
      ll used = p.first.second;

      if (p.first > dist[s][v]) continue;

      rep(nv, N) {
        if (nv == v) continue;
        if (G[v][nv] > L) continue;
        ll n_used = used + G[v][nv];

        auto np = n_used > L ? PL(times + 1, G[v][nv]) : PL(times, n_used);

        if (chmin(dist[s][nv], np)) {
          q.push({np, nv});
        }
      }
    }
  }

  ll Q;
  cin >> Q;

  rep(i, Q) {
    ll s, t;
    cin >> s >> t;
    s--, t--;

    ll res = dist[s][t].first == INF ? -1 : dist[s][t].first;
    cout << res << endl;
  }
}

struct exit_exception : public std::exception {
  const char* what() const throw() { return "Exited"; }
};

#ifndef TEST
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  try {
    solve();
  } catch (exit_exception& e) {
  }

  return 0;
}
#endif

template <typename T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}

template <typename T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

void print_ints(vector<ll> v) {
  rep(i, v.size()) {
    if (i > 0) {
      cout << " ";
    }

    cout << v[i];
  }

  cout << endl;
}

template <typename T>
void drop(T res) {
  cout << res << endl;
  throw exit_exception();
}


Measured memory_bytes: 1920