#include <bits/stdc++.h>
using namespace std;
const int K = 200;
vector<int> vs;
struct edge {
  int u, v, c;
  bool operator<(const edge &e) const { return c < e.c; }
} E[100005];
struct query {
  int u, v, t;
  query() {}
  query(int u, int v, int t) : u(u), v(v), t(t) {}
  bool operator<(const query &e) const {
    if (u == e.u) {
      if (v == e.v) return t < e.t;
      return v < e.v;
    }
    return u < e.u;
  }
} A[100005];
bool cmp(const edge &a, const edge &b) {
  if (a.u == b.u) return a.v < b.v;
  return a.u < b.u;
}
int par[100005], num[100005], ans[100005], N, M;
int parfind(int x) { return x == par[x] ? x : par[x] = parfind(par[x]); }
void unite(int u, int v) {
  u = parfind(u);
  v = parfind(v);
  if (u == v) return;
  if (num[u] > num[v]) swap(u, v);
  par[u] = v;
  num[v] += num[u];
}
bool used[100005];
void init() {
  for (int i = 1; i <= N; i++) {
    par[i] = i;
    num[i] = 1;
  }
}
int main() {
  while (scanf("%d%d", &N, &M) != EOF) {
    int m = 0;
    init();
    memset(ans, 0, sizeof ans);
    for (int i = 0; i < M; i++) {
      scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].c);
      m = max(m, E[i].c);
    }
    sort(E, E + M);
    int q;
    scanf("%d", &q);
    for (int i = 0; i < q; i++) {
      scanf("%d%d", &A[i].u, &A[i].v);
      A[i].t = i;
    }
    sort(A, A + q);
    memset(used, 0, sizeof used);
    for (int i = 1, j = 0; i <= m; i++) {
      vs.clear();
      for (; j < M && E[j].c == i; j++) {
        unite(E[j].u, E[j].v);
        if (!used[E[j].u]) {
          used[E[j].u] = true;
          vs.push_back(E[j].u);
        }
        if (!used[E[j].v]) {
          used[E[j].v] = true;
          vs.push_back(E[j].v);
        }
      }
      if (vs.size() > K) {
        for (int k = 0; k < q; k++) {
          if (parfind(A[k].u) == parfind(A[k].v)) {
            ans[A[k].t]++;
          }
        }
      } else {
        for (int k = 0; k < vs.size(); k++) {
          for (int h = 0; h < vs.size(); h++) {
            if (h == k) continue;
            if (parfind(vs[k]) != parfind(vs[h])) continue;
            int pos = upper_bound(A, A + q, query(vs[k], vs[h], -1)) - A;
            while (pos < q && A[pos].u == vs[k] && A[pos].v == vs[h]) {
              ans[A[pos].t]++;
              pos++;
            }
          }
        }
      }
      for (int k = 0; k < vs.size(); k++) {
        used[vs[k]] = false;
        par[vs[k]] = vs[k];
        num[vs[k]] = 1;
      }
    }
    for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
  }
  return 0;
}
