#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <map>
#include <stack>
#include <queue>
#include <vector>

static const int IINF = 1 << 30;
static const long long LINF = 1LL << 60;
static const long long MOD = 1.0e+9 + 7;

template <typename T> std::vector<T> vectors(std::size_t n, T val) {
  return std::vector<T>(n, val);
}

template <typename T, typename... Args>
auto vectors(std::size_t n, Args... args) {
  return std::vector<decltype(vectors<T>(args...))>(n, vectors<T>(args...));
}

template <class T> inline bool chmin(T &a, const T &b) {
  return (a > b) ? a = b, true : false;
}

template <class T> inline bool chmax(T &a, const T &b) {
  return (a < b) ? a = b, true : false;
}

template <class T> inline void chadd(T &a, const T &b) {
  a += b, a %= MOD;
  // TODO minus case
}

template <class T>
std::ostream &operator<<(std::ostream &s, const std::vector<T> &v) {
  if (v.empty())
    return s;
  s << *v.begin();
  for (auto iter = v.begin() + 1; iter != v.end(); ++iter)
    if (std::is_fundamental<T>::value)
      s << " " << *iter;
    else
      s << std::endl << *iter;
  return s;
}

// void bfs(const Graph & g, const int s) {

// }

using Graph = std::vector<std::vector<std::pair<int, int>>>;

int main() {
  int n, m, l;
  std::cin >> n >> m >> l;
  std::vector<int> a(m);
  std::vector<int> b(m);
  std::vector<int> c(m);
  for (int i = 0; i < m; ++i) {
    std::cin >> a[i] >> b[i] >> c[i];
    a[i] -= 1;
    b[i] -= 1;
  }

  int q;
  std::cin >> q;
  std::vector<int> s(q);
  std::vector<int> t(q);
  for (int k = 0; k < q; ++k) {
    std::cin >> s[k] >> t[k];
    s[k] -= 1;
    t[k] -= 1;
  }

  Graph g_org(n);
  for (int i = 0; i < m; ++i) {
    if (c[i] > l)
      continue;
    g_org[a[i]].push_back(std::make_pair(b[i], c[i]));
    g_org[b[i]].push_back(std::make_pair(a[i], c[i]));
  }

  // 全頂点対間最短路を求める
  std::vector<std::vector<long long>> dp(n, std::vector<long long>(n, LINF));
  for (int i = 0; i < n; ++i)
    dp[i][i] = 0;
  for (int i = 0; i < m; ++i) {
    dp[a[i]][b[i]] = c[i];
    dp[b[i]][a[i]] = c[i];
  }
  for (int k = 0; k < n; ++k) {
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        dp[i][j] = std::min(dp[i][j], dp[i][k] + dp[k][j]);
      }
    }
  }

  Graph g_new(n);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      if (i == j)
        continue;
      if (dp[i][j] > l)
        continue;
      g_new[i].push_back(std::make_pair(j, dp[i][j]));
    }
  }

  // for (int v = 0; v < n; ++v) {
  //   std::cout << v << ": ";
  //   for (auto wc : g_new[v]) {
  //     std::cout << wc.first << "," << wc.second << " ";
  //   }
  //   std::cout << std::endl;
  // }

  std::vector<std::vector<long long>> dp_new(n, std::vector<long long>(n, LINF));
  for (int i = 0; i < n; ++i)
    dp_new[i][i] = 0;
  // for (int i = 0; i < m; ++i) {
  //   dp[a[i]][b[i]] = c[i];
  //   dp[b[i]][a[i]] = c[i];
  // }
  for (int v = 0; v < n; ++v) {
    for (auto wc: g_new[v])
      dp_new[v][wc.first] = 1;
  }
  for (int k = 0; k < n; ++k) {
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        dp_new[i][j] = std::min(dp_new[i][j], dp_new[i][k] + dp_new[k][j]);
      }
    }
  }

  for (int k = 0; k < q; ++k) {
    if (dp_new[s[k]][t[k]] == LINF)
      std::cout << -1 << std::endl;
    else
      std::cout << dp_new[s[k]][t[k]] - 1 << std::endl;
  }

  return 0;
}


Measured memory_bytes: 5504