#include <bits/stdc++.h>
using namespace std;
int p[200005];
int rk[200005];
int root(int a) { return ((p[a] == a)) ? a : p[a] = root(p[a]); }
void un(int a, int b) {
  a = root(a);
  b = root(b);
  if (a == b)
    return;
  else if (rk[a] < rk[b])
    swap(a, b);
  if (rk[a] == rk[b]) rk[a]++;
  p[b] = a;
}
map<pair<int, int>, int> save;
unordered_set<int> cols[200005];
vector<long long> discr;
vector<pair<long long, long long> > edges;
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int x = 0; x < m; x++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    cols[a].insert(c);
    cols[b].insert(c);
    long long nd1 = (c - 1) * (long long)n + a;
    long long nd2 = (c - 1) * (long long)n + b;
    discr.push_back(nd1);
    discr.push_back(nd2);
    edges.push_back({nd1, nd2});
  }
  for (int x = 0; x <= discr.size(); x++) {
    p[x] = x;
  }
  sort(discr.begin(), discr.end());
  for (auto x : edges) {
    int nd1 = lower_bound(discr.begin(), discr.end(), x.first) - discr.begin();
    int nd2 = lower_bound(discr.begin(), discr.end(), x.second) - discr.begin();
    un(nd1, nd2);
  }
  int q;
  scanf("%d", &q);
  for (int x = 0; x < q; x++) {
    int a, b;
    scanf("%d%d", &a, &b);
    if (cols[a].size() > cols[b].size()) swap(a, b);
    if (save.count({a, b})) {
      printf("%d\n", save[{a, b}]);
      continue;
    }
    int ans = 0;
    for (auto x : cols[a]) {
      if (cols[b].count(x) == 0) continue;
      long long v1 = (x - 1) * (long long)n + a;
      long long v2 = (x - 1) * (long long)n + b;
      int nd1 = lower_bound(discr.begin(), discr.end(), v1) - discr.begin();
      int nd2 = lower_bound(discr.begin(), discr.end(), v2) - discr.begin();
      if (root(nd1) == root(nd2)) ans++;
    }
    printf("%d\n", ans);
    save[{a, b}] = ans;
  }
}
