#include <bits/stdc++.h>
using namespace std;
class dsu {
  unordered_map<int, int> vertices;
  vector<int> p, r;
  void add_vertex(int v) {
    if (vertices.count(v)) {
      return;
    }
    int new_number = p.size();
    vertices[v] = new_number;
    p.push_back(new_number);
    r.push_back(0);
  }
  int find(int v) { return p[v] == v ? v : p[v] = find(p[v]); }
  void unite(int v, int u) {
    v = find(v);
    u = find(u);
    if (v == u) {
      return;
    }
    if (r[u] > r[v]) {
      swap(u, v);
    }
    p[u] = v;
    if (r[u] == r[v]) {
      r[v]++;
    }
  }

 public:
  dsu(const vector<pair<int, int> > &edges) {
    for (int i = 0; i < edges.size(); ++i) {
      add_vertex(edges[i].first);
      add_vertex(edges[i].second);
      unite(vertices[edges[i].first], vertices[edges[i].second]);
    }
  }
  bool check(int v, int u) { return find(vertices[v]) == find(vertices[u]); }
};
int main() {
  srand(time(NULL));
  int n, m;
  scanf("%d %d\n", &n, &m);
  vector<unordered_set<int> > colors(n);
  vector<vector<pair<int, int> > > edges(m);
  for (int i = 0; i < m; ++i) {
    int a, b, c;
    scanf("%d %d %d\n", &a, &b, &c);
    --a, --b, --c;
    colors[a].insert(c);
    colors[b].insert(c);
    edges[c].push_back({a, b});
  }
  vector<dsu> a;
  for (int i = 0; i < m; ++i) {
    a.push_back(dsu(edges[i]));
  }
  int q;
  scanf("%d", &q);
  map<pair<int, int>, int> answers;
  while (q-- > 0) {
    int v, u;
    scanf("%d %d\n", &v, &u);
    --v, --u;
    if (colors[v].size() > colors[u].size() ||
        colors[v].size() == colors[u].size() && v > u) {
      swap(v, u);
    }
    if (answers.count({v, u})) {
      printf("%d\n", answers[{v, u}]);
      continue;
    }
    int ans = 0;
    for (auto c : colors[v]) {
      if (!colors[u].count(c)) {
        continue;
      }
      if (a[c].check(v, u)) {
        ans++;
      }
    }
    answers[{v, u}] = ans;
    printf("%d\n", ans);
  }
  return 0;
}
