### BUGGY CODE ###

def dijkstra(s,n,w,cost):
    #始点sから各頂点への最短距離
    #n:頂点数,　w:辺の数, cost[u][v] : 辺uvのコスト(存在しないときはinf)
    d = [float("inf")] * n
    used = [False] * n
    d[s] = 0
    
    while True:
        v = -1
        #まだ使われてない頂点の中から最小の距離のものを探す
        for i in range(n):
            if (not used[i]) and (v == -1):
               v = i
            elif (not used[i]) and d[i] < d[v]:
                v = i
        if v == -1:
               break
        used[v] = True
               
        for j in range(n):
               d[j] = min(d[j],d[v]+cost[v][j])
    return d

################################

n,m,l = map(int,input().split()) #n:頂点数　w:辺の数

cost = [[float("inf") for i in range(n)] for i in range(n)] 
#cost[u][v] : 辺uvのコスト(存在しないときはinf この場合は10**10)
for i in range(m):
    x,y,z = map(int,input().split())
    x-=1
    y-=1
    cost[x][y] = z
    cost[y][x] = z

kyolist=[]
for i in range(n):
    kyolist.append(dijkstra(i,n,m,cost))
"""
for kyl in kyolist:
    print(kyl)
"""
llist=[]
for i in range(n):
    nowlist=[1000]*n
    nowlist[i]=0
    next=[i]
    kaisu=1
    now=0
    while next!=[]:
        newnext=[]
        for nx in next:
            for j in range(n):
                if kyolist[j][nx]<=l and nowlist[j]==1000:
                    nowlist[j]=now
                    newnext.append(j)
        next=newnext
        now+=1
    llist.append(nowlist)

#print(llist)
q=int(input())
for i in range(q):
    s, t = (int(i) for i in input().split())
    kotae=llist[s-1][t-1]
    if kotae==1000:
        print(-1)
    else:
        print(kotae)

### FIXED CODE ###

def dijkstra(s,n,w,cost):
    #始点sから各頂点への最短距離
    #n:頂点数,　w:辺の数, cost[u][v] : 辺uvのコスト(存在しないときはinf)
    d = [float("inf")] * n
    used = [False] * n
    d[s] = 0
    
    while True:
        v = -1
        #まだ使われてない頂点の中から最小の距離のものを探す
        for i in range(n):
            if (not used[i]) and (v == -1):
               v = i
            elif (not used[i]) and d[i] < d[v]:
                v = i
        if v == -1:
               break
        used[v] = True
               
        for j in range(n):
               d[j] = min(d[j],d[v]+cost[v][j])
    return d

################################

n,m,l = map(int,input().split()) #n:頂点数　w:辺の数

cost = [[float("inf") for i in range(n)] for i in range(n)] 
#cost[u][v] : 辺uvのコスト(存在しないときはinf この場合は10**10)
for i in range(m):
    x,y,z = map(int,input().split())
    cost[x-1][y-1] = z
    cost[y-1][x-1] = z

kyolist=[]
for i in range(n):
    kyolist.append(dijkstra(i,n,m,cost))
zerolist=[]

for i in range(n):
    nowzero=[]
    for j in range(n):
        if i!=j and kyolist[i][j]<=l:
            nowzero.append(j)
    zerolist.append(nowzero)


llist=[]
for i in range(n):
    nowlist=[1000]*n
    nowlist[i]=0
    next=[i]
    now=0
    while next!=[]:
        newnext=[]
        for nx in next:
            for ima in zerolist[nx]:
                if nowlist[ima]==1000:
                    nowlist[ima]=now
                    newnext.append(ima)
        next=newnext
        now+=1
    llist.append(nowlist)

q=int(input())
for i in range(q):
    s, t = (int(i) for i in input().split())
    kotae=llist[s-1][t-1]
    if kotae==1000:
        print(-1)
    else:
        print(kotae)