#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e5 + 1;
int n, m, x, y, w;
map<int, int> answer[MAX];
vector<int> adj[MAX];
bool hasColor(int u, int c) {
  int l = 0, r = adj[u].size() - 1, mid;
  while (l <= r) {
    mid = (l + r) / 2;
    if (adj[u][mid] == c) return true;
    if (adj[u][mid] > c)
      r = mid - 1;
    else
      l = mid + 1;
  }
  return false;
}
class DSU {
 private:
  unordered_map<int, int> parent, rank;

 public:
  int find_parent(int u) {
    if (u == parent[u]) return u;
    return parent[u] = find_parent(parent[u]);
  }
  void link(int u, int v) {
    if (rank[v] > rank[u]) swap(v, u);
    parent[v] = u;
    if (rank[v] == rank[u]) rank[u]++;
  }
  void unoin_set(int u, int v) {
    if (parent.find(u) == parent.end()) parent[u] = u;
    if (parent.find(v) == parent.end()) parent[v] = v;
    if (rank.find(u) == rank.end()) rank[u] = 0;
    if (rank.find(v) == rank.end()) rank[v] = 0;
    int x = find_parent(v), y = find_parent(u);
    if (x != y) link(x, y);
  }
  bool isTheSameRoot(int u, int v) { return find_parent(u) == find_parent(v); }
} dsu[MAX];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  while (m--) {
    cin >> x >> y >> w;
    adj[x].push_back(w);
    adj[y].push_back(w);
    dsu[w].unoin_set(x, y);
  }
  for (int i = 1; i <= n; i++) {
    set<int> second(adj[i].begin(), adj[i].end());
    adj[i].assign(second.begin(), second.end());
  }
  cin >> m;
  while (m--) {
    int ans = 0;
    cin >> x >> y;
    if (x > y) swap(x, y);
    if (answer[x].find(y) != answer[x].end()) {
      cout << answer[x][y] << "\n";
      continue;
    }
    if (adj[x].size() > adj[y].size()) swap(x, y);
    for (const auto &v : adj[x])
      if (hasColor(y, v) && dsu[v].isTheSameRoot(x, y)) ans++;
    if (x > y) swap(x, y);
    answer[x][y] = ans;
    cout << ans << "\n";
  }
  return 0;
}
