Problem:
Score : 500 points

Problem Statement

There are N towns numbered 1 to N and M roads. The i-th road connects Town A_i and Town B_i bidirectionally and has a length of C_i.

Takahashi will travel between these towns by car, passing through these roads. The fuel tank of his car can contain at most L liters of fuel, and one liter of fuel is consumed for each unit distance traveled. When visiting a town while traveling, he can full the tank (or choose not to do so). Travel that results in the tank becoming empty halfway on the road cannot be done.

Process the following Q queries:

The tank is now full. Find the minimum number of times he needs to full his tank while traveling from Town s_i to Town t_i. If Town t_i is unreachable, print -1.

Constraints

All values in input are integers.

2 \leq N \leq 300

0 \leq M \leq \frac{N(N-1)}{2}

1 \leq L \leq 10^9

1 \leq A_i, B_i \leq N

A_i \neq B_i

\left(A_i, B_i\right) \neq \left(A_j, B_j\right) (if i \neq j)

\left(A_i, B_i\right) \neq \left(B_j, A_j\right) (if i \neq j)

1 \leq C_i \leq 10^9

1 \leq Q \leq N\left(N-1\right)

1 \leq s_i, t_i \leq N

s_i \neq t_i

\left(s_i, t_i\right) \neq \left(s_j, t_j\right) (if i \neq j)

Input

Input is given from Standard Input in the following format:

N M L
A_1 B_1 C_1
:
A_M B_M C_M
Q
s_1 t_1
:
s_Q t_Q

Output

Print Q lines.

The i-th line should contain the minimum number of times the tank needs to be fulled while traveling from Town s_i to Town t_i. If Town t_i is unreachable, the line should contain -1 instead.

Sample Input 1

3 2 5
1 2 3
2 3 3
2
3 2
1 3

Sample Output 1

0
1

To travel from Town 3 to Town 2, we can use the second road to reach Town 2 without fueling the tank on the way.

To travel from Town 1 to Town 3, we can first use the first road to get to Town 2, full the tank, and use the second road to reach Town 3.

Sample Input 2

4 0 1
1
2 1

Sample Output 2

-1

There may be no road at all.

Sample Input 3

5 4 4
1 2 2
2 3 2
3 4 3
4 5 2
20
2 1
3 1
4 1
5 1
1 2
3 2
4 2
5 2
1 3
2 3
4 3
5 3
1 4
2 4
3 4
5 4
1 5
2 5
3 5
4 5

Sample Output 3

0
0
1
2
0
0
1
2
0
0
0
1
1
1
0
0
2
2
1
0

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.DataInputStream;
import java.util.PriorityQueue;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.AbstractCollection;
import java.util.Comparator;
import java.io.InputStream;

/**
 * Built using CHelper plug-in Actual solution is at the top
 *
 * @author MaxHeap
 */
public class Main {

  public static void main(String[] args) {
    InputStream inputStream = System.in;
    OutputStream outputStream = System.out;
    InputReader in = new InputReader(inputStream);
    PrintWriter out = new PrintWriter(outputStream);
    ETravelByCar solver = new ETravelByCar();
    solver.solve(1, in, out);
    out.close();
  }

  static class ETravelByCar {

    List<Edge>[] g;
    int n;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
      n = in.nextInt();
      int m = in.nextInt();
      int capacity = in.nextInt();
      g = Graphs.createWeightedGraph(n + 1);
      for (int i = 0; i < m; ++i) {
        int u = in.nextInt(), v = in.nextInt(), c = in.nextInt();
        if (c > capacity) {
          continue;
        }
        g[u].add(new Edge(v, c));
        g[v].add(new Edge(u, c));
      }
      int[][] distance = ArrayUtils.createIntMatrix(n + 1, n + 1, Constants.INF32);
      for (int i = 0; i <= n; ++i) {
        distance[i][i] = 0;
      }
      boolean[] seen = new boolean[n + 1];
      int q = in.nextInt();
      while (q-- > 0) {
        int u = in.nextInt(), v = in.nextInt();
        out.println(computeAnswer(u, v, capacity));
      }
    }

    private int computeAnswer(int from, int to, int capacity) {
      PriorityQueue<ETravelByCar.State> pq = new PriorityQueue<>(
          Comparator.comparingInt((ETravelByCar.State st) -> st.fillCount)
              .thenComparingInt(st -> -st.capacity));
      pq.add(new ETravelByCar.State(from, 0, capacity));
      int[] fills = ArrayUtils.createIntArray(n + 1, Constants.INF32);
      while (!pq.isEmpty()) {
        ETravelByCar.State curState = pq.poll();
//      fills[curState.node] = Math.min(fills[curState.node], curState.fillCount);
        for (Edge ev : g[curState.node]) {
          int v = ev.to;
          int len = (int) ev.cost;
          if (len > curState.capacity) {
            if (curState.fillCount + 1 < fills[v]) {
              fills[v] = curState.fillCount + 1;
              ETravelByCar.State newState = new ETravelByCar.State(v, fills[v], capacity - len);
              pq.add(newState);
            }
          } else {
            if (fills[v] > curState.fillCount) {
              fills[v] = curState.fillCount;
              ETravelByCar.State newState = new ETravelByCar.State(v, curState.fillCount,
                  curState.capacity - len);
              pq.add(newState);
            }
          }
        }
      }
      return fills[to] == Constants.INF32 ? -1 : fills[to];
    }

    static class State {

      int node;
      int fillCount;
      int capacity;

      public State(int node, int fillCount, int capacity) {
        this.node = node;
        this.fillCount = fillCount;
        this.capacity = capacity;
      }

    }

  }

  static class ArrayUtils {

    public static int[] createIntArray(final int size, final int initialValue) {
      int[] ret = new int[size];
      for (int i = 0; i < size; ++i) {
        ret[i] = initialValue;
      }
      return ret;
    }

    public static int[][] createIntMatrix(final int rows, final int columns,
        final int initialValue) {
      int[][] ret = new int[rows][];
      for (int i = 0; i < rows; ++i) {
        ret[i] = createIntArray(columns, initialValue);
      }
      return ret;
    }

  }

  static class Graphs {

    private Graphs() {
    }

    public static List<Edge>[] createWeightedGraph(int n) {
      List<Edge>[] graph = new ArrayList[n];
      for (int i = 0; i < n; i++) {
        graph[i] = new ArrayList<>();
      }
      return graph;
    }

  }

  static interface FastInput {

  }

  static class Edge implements Comparable<Edge> {

    public int to;
    public long cost;

    public String toString() {
      return "Edge{" +
          "to=" + to +
          ", cost=" + cost +
          '}';
    }

    public Edge(int to, long cost) {
      this.cost = cost;
      this.to = to;
    }

    public int compareTo(Edge o) {
      return Long.compare(cost, o.cost);
    }

    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }

      Edge edge = (Edge) o;

      if (to != edge.to) {
        return false;
      }
      return cost == edge.cost;
    }

    public int hashCode() {
      long result = to;
      result = 31L * result + cost;
      return (int) result;
    }

  }

  static class InputReader implements FastInput {

    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer;
    private int bytesRead;

    public InputReader(InputStream is) {
      din = new DataInputStream(is);
      buffer = new byte[BUFFER_SIZE];
      bufferPointer = bytesRead = 0;
    }

    public InputReader(String file_name) throws IOException {
      din = new DataInputStream(new FileInputStream(file_name));
      buffer = new byte[BUFFER_SIZE];
      bufferPointer = bytesRead = 0;
    }

    public int nextInt() {
      int ret = 0;
      byte c = read();
      while (c <= ' ') {
        c = read();
      }
      boolean neg = (c == '-');
      if (neg) {
        c = read();
      }
      do {
        ret = ret * 10 + c - '0';
      } while ((c = read()) >= '0' && c <= '9');

      if (neg) {
        return -ret;
      }
      return ret;
    }

    private void fillBuffer() {
      try {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
      } catch (IOException e) {
        throw new RuntimeException("trying to read from null input, verify constraints ");
      }
      if (bytesRead == -1) {
        buffer[0] = -1;
      }
    }

    private byte read() {
      if (bufferPointer == bytesRead) {
        fillBuffer();
      }
      return buffer[bufferPointer++];
    }

  }

  static abstract class Constants {

    public static final int INF32 = 1 << 30;

  }
}