#include <bits/stdc++.h>
struct Block {
  int col, sz;
  Block *fa;
  Block() { fa = NULL, sz = 1; }
  Block(int col = 0, int sz = 1, Block *fa = NULL) {
    this->col = col, this->sz = sz, this->fa = fa;
  }
  bool operator<(const Block &B) const { return col < B.col; }
  bool operator==(const Block &B) const { return col == B.col; }
};
inline Block *GetAnc(Block *u) { return u->fa ? u->fa = GetAnc(u->fa) : u; }
inline void Union(Block *u, Block *v) {
  u = GetAnc(u), v = GetAnc(v);
  if (u == v) return;
  if (u->sz < v->sz) std::swap(u, v);
  v->fa = u, u->sz += v->sz;
}
inline bool Connect(Block *u, Block *v) {
  if (u == NULL || v == NULL) return false;
  u = GetAnc(u), v = GetAnc(v);
  return u == v;
}
int a[100010LL], b[100010LL], c[100010LL];
std::vector<Block> col[100010LL];
int Get_tmp;
inline Block *Get(int p, int c) {
  Get_tmp = std::lower_bound(col[p].begin(), col[p].end(), (Block){c}) -
            col[p].begin();
  return Get_tmp < col[p].size() ? &col[p][Get_tmp] : NULL;
}
std::map<std::pair<int, int>, int> mp;
int main() {
  int n, m, i, q, u, v, ans;
  Block *w;
  scanf("%d%d", &n, &m);
  for (i = (1); i <= (m); i++) {
    scanf("%d%d%d", &a[i], &b[i], &c[i]);
    col[a[i]].push_back((Block){c[i]}), col[b[i]].push_back((Block){c[i]});
  }
  for (i = (1); i <= (n); i++) {
    std::sort(col[i].begin(), col[i].end());
    col[i].erase(std::unique(col[i].begin(), col[i].end()), col[i].end());
  }
  for (i = (1); i <= (m); i++) Union(Get(a[i], c[i]), Get(b[i], c[i]));
  scanf("%d", &q);
  while (q-- > 0) {
    scanf("%d%d", &u, &v);
    ans = 0;
    if (col[u].size() > col[v].size()) std::swap(u, v);
    if (mp.find(std::make_pair(u, v)) == mp.end()) {
      for (i = (0); i < (col[u].size()); i++) {
        w = &col[u][i];
        if (Connect(w, Get(v, w->col))) ans++;
      }
      mp[std::make_pair(u, v)] = ans;
    } else
      ans = mp[std::make_pair(u, v)];
    printf("%d\n", ans);
  }
  return 0;
}
