// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

#define num 1000000007

//#define num 998244353

#define REP(i,a,n) for(ll i=a;i<n;i++)

#define inarr(i,a,n,A) for(ll i=a;i<n;i++) { cin>>A[i]; }

#define vll vector<long long>

#define pii pair <int,int>

#define pll pair<long long, long long>

#define vpii vector< pair <int,int>>

#define vpll vector< pair<long long, long long>>

//#define max(a,b) ((a>b)?a:b)

//#define min(a,b) ((a>b)?b:a)

#define max3(a,b,c) ((a>b)?(a>c)?a:c:(b>c)?b:c)

#define min3(a,b,c) ((a<b)?(a<c)?a:c:(b<c)?b:c)

#define avg(a,b) ((a)+(b))/2

#define pb push_back

#define pob pop_back

#define sf int flag=0     //Remember semicolon

// #define assmin(a,b) if(b<=a) { a=b; }

// #define assmax(a,b) if(b>=a) { a=b; }

#define f first

#define s second

#define fix(f,n) std::fixed<<std::setprecision(n)<<f

#define all(x) x.begin(), x.end()

#define M_PI 3.14159265358979323846

#define epsilon (double)(0.00000000001)

#define side 1e9

#define watch(x) cout << (#x) << " is " << (x) << endl

typedef long long ll;

ll mod(ll a, ll b)

{

	if(a%b<0)

	{

		return a%b + b;

	}

	return a%b;

}

 

 

ll mod_exp(ll a, ll b, ll c)

{

	ll res=1;

	a=a%c;

	while(b>0)

	{

		if(b%2==1)

		{

			res=(res*a)%c;

		}

		b/=2;

		a=(a*a)%c;

	}

	return res;

}

ll mymod(ll a,ll b)

{

    return ((a%b)+b)%b;

}

bool prime[200001];

void SieveOfEratosthenes() 

{ 

    memset(prime, true, sizeof(prime)); 

    prime[1]=false;

    for (int p=2; p*p<=200000; p++) 

    { 

        if (prime[p] == true) 

        { 

            for (int i=p*p; i<=200000; i += p) 

                prime[i] = false; 

        } 

    } 

    return;

}

ll powe[200005];

void power()

{

    powe[0]=1;

    REP(i,1,200005)

    {

        powe[i]=mymod(2*powe[i-1],num);

    }

}

ll gcdExtended(ll,ll,ll *,ll *);

ll modInverse(ll a, ll m) 

{ 

    ll x, y; 

    ll g = gcdExtended(a, m, &x, &y); 

        ll res = (x%m + m) % m;

        return res;

} 

ll gcdExtended(ll a, ll b, ll *x, ll *y) 

{ 

    if (a == 0) 

    { 

        *x = 0, *y = 1; 

        return b; 

    } 

    ll x1, y1; 

    ll gcd = gcdExtended(b%a, a, &x1, &y1); 

    *x = y1 - (b/a) * x1; 

    *y = x1; 

    return gcd; 

}

struct node

{

	vpll adj;

    ll biggest;

    ll op;

    ll size;

};

bool myfunc(pll a, pll b)

{

    return a.s<b.s;

}

int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    cout.tie(NULL);

    ll n,m,l;

    cin>>n>>m>>l;

    node N[n+1];

    ll edge[305][305]={};

    REP(i,0,m)

    {

        ll a,b,c;

        cin>>a>>b>>c;

        if(c<=l)

        {

            N[a].adj.pb({b,c});

            N[b].adj.pb({a,c});

            edge[a][b] = edge[b][a] = c;

        }

    }

    REP(i,1,n+1)

    {

        sort(all(N[i].adj), myfunc);

    }

    pll times[n+1][n+1];

    REP(i,0,n+1)

    {

        REP(j,0,n+1)

        {

            times[i][j] = {1e10, -1};

        }

    }

    REP(i,1,n+1)

    {

       // cout<<i<<" ";

        times[i][i] = {0,l};

        queue<pll> q;

        q.push({i,l});

        ll c=0;

        while(!q.empty())

        {

            

            pll f = q.front();

            q.pop();

            if(f.second!=times[i][f.first].second)

            {

                continue;

            }

            for(auto x: N[f.first].adj)

            {

                ll sz = edge[f.first][x.first];

                pll p = times[i][f.first];

                pll r = times[i][x.first];

                if(f.second>=sz && (r.first>p.first || (r.first==p.first && r.second<f.second - sz)))

                {

                    times[i][x.first] = {p.first, f.second - sz};

                    q.push({x.first, times[i][x.first].second});

                }

                else if(f.second<sz && (r.first > p.first+1 || (r.first == p.first + 1 && r.second<l - sz)))

                {

                    times[i][x.first] = {p.first+1, l - sz};

                    q.push({x.first, times[i][x.first].second});

                }

            }

        }

        //cout<<c<<"\n";

    }

    ll q;

    cin>>q;

    REP(i,0,q)

    {

        ll a,b;

        cin>>a>>b;

       cout<<((times[a][b].first<1e9) ? times[a][b].first : -1ll)<<"\n";

    }

    return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

#define num 1000000007

//#define num 998244353

#define REP(i,a,n) for(ll i=a;i<n;i++)

#define inarr(i,a,n,A) for(ll i=a;i<n;i++) { cin>>A[i]; }

#define vll vector<long long>

#define pii pair <int,int>

#define pll pair<long long, long long>

#define vpii vector< pair <int,int>>

#define vpll vector< pair<long long, long long>>

//#define max(a,b) ((a>b)?a:b)

//#define min(a,b) ((a>b)?b:a)

#define max3(a,b,c) ((a>b)?(a>c)?a:c:(b>c)?b:c)

#define min3(a,b,c) ((a<b)?(a<c)?a:c:(b<c)?b:c)

#define avg(a,b) ((a)+(b))/2

#define pb push_back

#define pob pop_back

#define sf int flag=0     //Remember semicolon

// #define assmin(a,b) if(b<=a) { a=b; }

// #define assmax(a,b) if(b>=a) { a=b; }

#define f first

#define s second

#define fix(f,n) std::fixed<<std::setprecision(n)<<f

#define all(x) x.begin(), x.end()

#define M_PI 3.14159265358979323846

#define epsilon (double)(0.00000000001)

#define side 1e9

#define watch(x) cout << (#x) << " is " << (x) << endl

typedef long long ll;

ll mod(ll a, ll b)

{

	if(a%b<0)

	{

		return a%b + b;

	}

	return a%b;

}

 

 

ll mod_exp(ll a, ll b, ll c)

{

	ll res=1;

	a=a%c;

	while(b>0)

	{

		if(b%2==1)

		{

			res=(res*a)%c;

		}

		b/=2;

		a=(a*a)%c;

	}

	return res;

}

ll mymod(ll a,ll b)

{

    return ((a%b)+b)%b;

}

bool prime[200001];

void SieveOfEratosthenes() 

{ 

    memset(prime, true, sizeof(prime)); 

    prime[1]=false;

    for (int p=2; p*p<=200000; p++) 

    { 

        if (prime[p] == true) 

        { 

            for (int i=p*p; i<=200000; i += p) 

                prime[i] = false; 

        } 

    } 

    return;

}

ll powe[200005];

void power()

{

    powe[0]=1;

    REP(i,1,200005)

    {

        powe[i]=mymod(2*powe[i-1],num);

    }

}

ll gcdExtended(ll,ll,ll *,ll *);

ll modInverse(ll a, ll m) 

{ 

    ll x, y; 

    ll g = gcdExtended(a, m, &x, &y); 

        ll res = (x%m + m) % m;

        return res;

} 

ll gcdExtended(ll a, ll b, ll *x, ll *y) 

{ 

    if (a == 0) 

    { 

        *x = 0, *y = 1; 

        return b; 

    } 

    ll x1, y1; 

    ll gcd = gcdExtended(b%a, a, &x1, &y1); 

    *x = y1 - (b/a) * x1; 

    *y = x1; 

    return gcd; 

}

struct node

{

	vll adj;

    ll biggest;

    ll op;

    ll size;

};

bool myfunc(pll a, pll b)

{

    return a.s<b.s;

}

int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    cout.tie(NULL);

    ll n,m,l;

    cin>>n>>m>>l;

    node N[n+1];

    ll dist[n+1][n+1];

    REP(i,0,n+1) REP(j,0,n+1) dist[i][j] = 1e18;

    REP(i,0,m)

    {

        ll a,b,c;

        cin>>a>>b>>c;

        if(c<=l)

        {

            N[a].adj.pb(b);

            N[b].adj.pb(a);

            dist[a][b] = c;

            dist[b][a] = c;

        }

    }

    REP(k,1,n+1)

    {

        REP(i,1,n+1)

        {

            REP(j,1,n+1)

            {

                if(i==j) dist[i][j] = 0;

                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);

            }

        }

    }

    node N2[n+1];

    ll dist2[n+1][n+1];

    REP(i,0,n+1)

    {

        REP(j,0,n+1)

        {

            if(i==j) dist2[i][j] = 0;

            else dist2[i][j] = 1e18;

        }

    }

    REP(i,1,n+1)

    {

        REP(j,1,n+1)

        {

            if(dist[i][j]<=l)

            {

                N2[i].adj.pb(j);

                N2[j].adj.pb(i);

                dist2[i][j] = 1;

                dist2[j][i] = 1;

            }

        }

    }

    REP(k,1,n+1)

    {

        REP(i,1,n+1)

        {

            REP(j,1,n+1)

            {

                if(i==j) dist[i][j] = 0;

                dist2[i][j] = min(dist2[i][j], dist2[i][k] + dist2[k][j]);

            }

        }

    }

    ll q;

    cin>>q;

    REP(i,0,q)

    {

        ll a,b;

        cin>>a>>b;

        cout<<((dist2[a][b]<1e16) ? dist2[a][b]-1 : -1)<<"\n";

    }

    return 0;

}

// Fastest known solution for this problem: