#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("Ofast")
const int maxn = 1e5 + 10, N = 3e6, SQ = 1000, base = 800287, mod = 1e9 + 7,
          INF = 1e9 + 10, lg = 22;
const long double eps = 1e-4;
int n, m, q;
unordered_map<int, int> par[maxn], res[maxn];
inline int root(int v, int x) {
  return (par[v][x] <= 0 ? v : par[v][x] = root(par[v][x], x));
}
void merge(int v, int u, int x) {
  if ((v = root(v, x)) == (u = root(u, x))) {
    return;
  }
  par[u][x] = v;
}
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int x, y, z;
    cin >> x >> y >> z;
    merge(x, y, z);
  }
  cin >> q;
  while (q--) {
    int v, u;
    cin >> v >> u;
    int ans = 0;
    if ((int)par[v].size() < (int)par[u].size()) {
      swap(v, u);
    }
    if (res[v].find(u) != res[v].end()) {
      cout << res[v][u] << '\n';
      continue;
    }
    for (auto i : par[u]) {
      if (par[v].find(i.first) == par[v].end()) {
        continue;
      }
      if (root(v, i.first) == root(u, i.first)) {
        ans++;
      }
    }
    res[v][u] = res[u][v] = ans;
    cout << ans << '\n';
  }
}
