import java.io.PrintWriter

object Scanner {
  private val buf = new Array[Byte](1024); private var ptr = 0; private var len = 0
  @inline private def isPrintableChar(c: Int): Boolean = 33 <= c && c <= 126
  @inline private def hasNextByte(): Boolean =
    if (ptr >= len) { ptr = 0; len = System.in.read(buf); len > 0 } else { true }
  @inline private def hasNext(): Boolean = {
    while (hasNextByte() && !isPrintableChar(buf(ptr))) ptr += 1
    hasNextByte()
  }
  @inline private def readByte(): Byte =
    if (hasNextByte()) { val res = buf(ptr); ptr += 1; res } else { -1 }
  def next(): String = {
    if(!hasNext()) ???
    val sb = new StringBuilder; var b = readByte()
    while (isPrintableChar(b)) { sb.append(b.toChar); b = readByte() }
    sb.toString
  }
  def nextInt(): Int = {
    val n = nextLong()
    if (n < Int.MinValue || Int.MaxValue < n) ???
    n.toInt
  }
  def nextLong(): Long = {
    if(!hasNext()) ???
    var minus = false; var b = readByte()
    if (b == '-') { minus = true; b = readByte() }
    def go (b: Byte, n: Long = 0): Long =
      if ('0' <= b && b <= '9') { go(readByte(), n * 10 + b - '0') }
      else if (minus) { -n } else { n }
    go(b)
  }
  def nextDouble(): Double = next.toDouble
}

object OutPut {
  def print(f:PrintWriter => Unit): Unit = {
    val pw: PrintWriter = new java.io.PrintWriter(System.out)
    //pw.println("")
    f(pw)
    pw.flush()
  }
}
object MyDataFormat {
  def double(x: Double, precision: Int): String = {
    var num = x
    val sb = new StringBuilder
    if (num < 0) {
      sb.append("-")
      num = -num
    }
    num += Math.pow(10, -precision) / 2
    sb.append(num.toLong)
    sb.append(".")
    num -= num.toLong
    (0 until precision).foreach(i => {
      num *= 10
      sb.append(num.toInt)
      num -= num.toInt
    })
    sb.toString
  }

  def array2(arr: scala.collection.mutable.ArrayBuffer[scala.collection.mutable.ArrayBuffer[Int]], x: Int, y: Int): Option[Int] = {
    try { Some(arr(x)(y)) } catch {
      case _: Exception => None
    }
  }
}

object Loop {
  @inline def rep(n: Int, f: => Unit): Unit = { var c = 0; while (c < n) { f; c += 1 } }
  @inline def rep(n: Int, f: Int => Unit): Unit = { var c = 0; while (c < n) { f(c); c += 1 } }
}

object Search {
  def find(data: Array[Int], key: Int): Option[Int] = {
    val res = java.util.Arrays.binarySearch(data, key)
    if (res >= 0) Some(res) else None
  }
}

object WarshallFloyd {
  def distanceVector(n: Int, vectorMap: Array[Array[Float]]): Array[Array[Float]] = {
    Loop.rep(n, k => {
      Loop.rep(n, i => {
        Loop.rep(n, j => {
          val a = getValue(i, j, vectorMap)
          val b = getValue(i, k, vectorMap)
          val c = getValue(k, j, vectorMap)
          val distance = Math.min(a, b + c)
          vectorMap(i)(j) = distance
        })
      })
    })
    vectorMap
  }
  def getValue(x: Int, y: Int, vectorMap: Array[Array[Float]]): Float = {
    if (x == y) 0f else vectorMap(x)(y)
  }
}

object Main extends App {
  val n, m, l = Scanner.nextInt()

  val data: Array[Array[Int]] = Array.fill(m, 3)(Scanner.nextInt())
  val q = Scanner.nextInt()
  val test: Array[Array[Int]] = Array.fill(q, 2)(Scanner.nextInt())

  val distanceArray: Array[Array[Float]] = Array.fill[Float](n, n)(Float.PositiveInfinity)
  val fuelArray: Array[Array[Float]] = Array.fill[Float](n, n)(Float.PositiveInfinity)

  data.map { a => distanceArray(a(0) - 1)(a(1) - 1) = a(2) }
  val tidyDistanceVector = WarshallFloyd.distanceVector(n, distanceArray)

  Loop.rep(n, x => {
    Loop.rep(n, y => {
      if (tidyDistanceVector(x)(y) <= l) fuelArray(x)(y) = 1
    })
  })
  val tidyFuelVector = WarshallFloyd.distanceVector(n, fuelArray)
  
  test.foreach { q =>
    val a = q(0) - 1
    val b = q(1) - 1
    val c = if (a <= b) tidyFuelVector(a)(b) else tidyFuelVector(b)(a)
    println((if (c.isPosInfinity) -1 else c - 1).toInt)
  }
}