#include <bits/stdc++.h>
using namespace std;
vector<int> ind[100010];
class UnionFind {
 private:
  vector<int> p, rank, setSize;
  int numSets;

 public:
  vector<vector<int> > elem;
  UnionFind() {}
  UnionFind(int N) {
    setSize.assign(N, 1);
    numSets = N;
    rank.assign(N, 0);
    elem.assign(N, vector<int>());
    p.assign(N, 0);
    for (int i = 0; i < N; i++) p[i] = i;
  }
  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      numSets--;
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        setSize[x] += setSize[y];
      } else {
        p[x] = y;
        setSize[y] += setSize[x];
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
  int numDisjointSets() { return numSets; }
  int sizeOfSet(int i) { return setSize[findSet(i)]; }
  void build(int c, int N) {
    for (int i = 0; i < N; i++) elem[findSet(i)].push_back(ind[c][i]);
  }
} uf[100010];
map<int, int> Map[100010];
map<pair<int, int>, int> Ans;
int ncol[100010];
struct edge {
  int a, b, c;
  edge(int _a, int _b, int d) {
    a = _a;
    b = _b;
    c = d;
  }
};
vector<edge> E;
vector<int> cols[100010];
vector<vector<int> > Val;
int isBig[100010];
vector<int> sup[100010];
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  int a, b, c;
  for (int i = 0; i < m; i++) {
    scanf("%d %d %d", &a, &b, &c);
    E.push_back(edge(a, b, c));
    if (Map[c].count(a) == 0) {
      sup[a].push_back(ncol[c]);
      Map[c][a] = ncol[c]++;
      ind[c].push_back(a);
      cols[a].push_back(c);
    }
    if (Map[c].count(b) == 0) {
      sup[b].push_back(ncol[c]);
      Map[c][b] = ncol[c]++;
      ind[c].push_back(b);
      cols[b].push_back(c);
    }
  }
  for (int i = 1; i <= m; i++)
    if (ncol[i]) uf[i] = UnionFind(ncol[i]);
  for (int i = 0; i < m; i++)
    uf[E[i].c].unionSet(Map[E[i].c][E[i].a], Map[E[i].c][E[i].b]);
  for (int i = 1; i <= m; i++)
    if (ncol[i]) uf[i].build(i, ncol[i]);
  vector<int> num;
  memset(isBig, -1, sizeof(isBig));
  int nbig = 0;
  for (int i = 1; i <= n; i++)
    if (cols[i].size() >= 450) {
      isBig[i] = nbig++;
      num.assign(n + 1, 0);
      for (int j = 0; j < cols[i].size(); j++) {
        int u = sup[i][j];
        u = uf[cols[i][j]].findSet(u);
        for (int k = 0; k < uf[cols[i][j]].elem[u].size(); k++)
          num[uf[cols[i][j]].elem[u][k]]++;
      }
      num[i] = 0;
      Val.push_back(num);
    }
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    if (isBig[a] != -1) {
      printf("%d\n", Val[isBig[a]][b]);
      continue;
    }
    if (isBig[b] != -1) {
      printf("%d\n", Val[isBig[b]][a]);
      continue;
    }
    if (Ans.count(make_pair(a, b))) {
      printf("%d\n", Ans[make_pair(a, b)]);
      continue;
    }
    if (Ans.count(make_pair(b, a))) {
      printf("%d\n", Ans[make_pair(b, a)]);
      continue;
    }
    int ans = 0;
    for (int j = 0; j < cols[a].size(); j++) {
      int v;
      if (Map[cols[a][j]].count(b))
        v = Map[cols[a][j]][b];
      else
        continue;
      int u = sup[a][j];
      if (uf[cols[a][j]].isSameSet(u, v)) ans++;
    }
    Ans[make_pair(a, b)] = ans;
    printf("%d\n", ans);
  }
  return 0;
}
