#include <bits/stdc++.h>
using namespace std;

int N,M,L;
long INF=1e15;
long d[500][500],e[500][500];
int Q;
void wf1(int N){
  for(int k=0;k<N;k++){
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
}

void wf2(int N){
  for(int k=0;k<N;k++){
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        e[i][j]=min(e[i][j],e[i][k]+e[k][j]);
      }
    }
  }
}

int main() {
  cin >>N>>M>>L;
  // 繋がってない街間のコストはINF、繋がっているならcを代入
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++) d[i][j]=INF;
  }
  for(int i=0;i<M;i++){
    int a,b,c;
    cin>>a>>b>>c;
    d[a-1][b-1]=c;
    d[b-1][a-1]=c;
  }
  // ワーシャルフロイド1回目街間の最小コストを求める
  wf1(N);
  // 街間のコストがL以下なら補給回数1を代入
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++) {
      if(d[i][j]<=L) e[i][j]=1;
      else e[i][j]=INF;
    }
  }
  wf2(N);

  cin>>Q;
  for(int i=0;i<Q;i++){
    int s,t;
    cin>>s>>t;
    // 最初はタンクはいっぱいなので1を引く
    if(e[s-1][t-1]<INF) cout<<e[s-1][t-1]-1<<endl;
    else cout<<-1<<endl;
  }
}
