#include <bits/stdc++.h>   using namespace std;   vector<int> adjc[100005];   vector<int> cadj[100005];   struct edge {     int u, v, c;   };   class dsu {    public:     dsu(vector<int> vert) : vert(vert) {       n = vert.size();       par.resize(n);       iota(par.begin(), par.end(), 0);     }     int root(int u) {       if (par[u] == u) {         return u;       }       return (par[u] = root(par[u]));     }     void merge(int u, int v) {       int ui = lower_bound(vert.begin(), vert.end(), u) - vert.begin();       int vi = lower_bound(vert.begin(), vert.end(), v) - vert.begin();       int ru = root(ui), rv = root(vi);       if (ru != rv) {         if (rand() % 2) {           swap(ru, rv);         }         par[ru] = rv;       }     }     bool ced(int u, int v) {       int ui = lower_bound(vert.begin(), vert.end(), u) - vert.begin();       int vi = lower_bound(vert.begin(), vert.end(), v) - vert.begin();       if ((ui == n || (vert[ui] != u)) || (vi == n || (vert[vi] != v))) return 0;       return (root(ui) == root(vi));     }     int n;     vector<int> vert, par;   };   int main() {     ios_base::sync_with_stdio(false);     cin.tie(NULL);     int n, m;     cin >> n >> m;     vector<edge> e;     for (int i = 0; i < m; i++) {       int u, v, c;       cin >> u >> v >> c;       e.push_back({u, v, c});       cadj[c].push_back(u);       cadj[c].push_back(v);       adjc[u].push_back(c);       adjc[v].push_back(c);     }     for (int i = 1; i <= n; i++) {       sort(adjc[i].begin(), adjc[i].end());       adjc[i].resize(unique(adjc[i].begin(), adjc[i].end()) - adjc[i].begin());     }     vector<dsu> cdsu;     for (int i = 1; i <= m; i++) {       sort(cadj[i].begin(), cadj[i].end());       cadj[i].resize(unique(cadj[i].begin(), cadj[i].end()) - cadj[i].begin());       cdsu.emplace_back(cadj[i]);     }     for (edge ed : e) {       cdsu[ed.c - 1].merge(ed.u, ed.v);     }     map<pair<int, int>, int> dp;     int q;     cin >> q;     while (q--) {       int u, v;       cin >> u >> v;       if (adjc[u].size() > adjc[v].size()) {         swap(u, v);       }       if (dp.find({u, v}) != dp.end()) {         cout << dp[{u, v}] << endl;         continue;       }       int ans = 0;       for (auto c : adjc[u]) {         ans += cdsu[c - 1].ced(u, v);       }       cout << ans << endl;       dp[{u, v}] = ans;     }     return 0;   }   