#include <bits/stdc++.h>
inline int getint() {
  int x = 0, p = 1;
  char c;
  c = getchar();
  while (c <= 32) c = getchar();
  while (c > 32) x = x * 10 + c - 48, c = getchar();
  return x * p;
}
inline void put_int(int x) {
  if (x == 0) return;
  put_int(x / 10);
  putchar(x % 10 + 48);
}
inline void putint(int x) {
  if (x == 0)
    putchar(48);
  else
    put_int(x);
}
using namespace std;
const int maxn = 1e5 + 5;
int B = 450;
int n, m, t, Mp[maxn], cnt, ok[maxn];
vector<pair<int, int> > G[maxn], E[maxn];
vector<int> ans[maxn], v, ic[maxn];
unordered_set<int> vis[maxn];
unordered_map<int, vector<int> > gG[maxn];
vector<bool> good;
namespace U {
int par[maxn];
void fnew(int x) { par[x] = x; }
int fF(int x) {
  if (par[x] == x) return x;
  return par[x] = fF(par[x]);
}
inline void fU(int x, int y) {
  x = fF(x);
  y = fF(y);
  par[x] = y;
}
}  // namespace U
queue<pair<int, int> > qu;
void presolve() {
  memset(Mp, -1, sizeof(Mp));
  for (int(i) = 0; (i) < (n); (i)++)
    if (G[i].size() > B) {
      Mp[i] = cnt++;
      for (int(j) = 0; (j) < (n); (j)++) vis[j].clear(), ans[j].emplace_back(0);
      for (int(j) = 0; (j) < (G[i].size()); (j)++) {
        qu.push(G[i][j]);
        vis[G[i][j].first].insert(G[i][j].second);
        ans[G[i][j].first][Mp[i]]++;
      }
      while (!qu.empty()) {
        int u = qu.front().first, col = qu.front().second;
        qu.pop();
        for (int(j) = 0; (j) < (gG[u][col].size()); (j)++)
          if (gG[u][col][j] != i &&
              vis[gG[u][col][j]].find(col) == vis[gG[u][col][j]].end()) {
            vis[gG[u][col][j]].insert(col);
            qu.push(make_pair(gG[u][col][j], col));
            ans[gG[u][col][j]][Mp[i]]++;
          }
      }
    }
}
void finit() {
  cnt = 0;
  for (int i = 1; i <= m; i++) {
    v.clear();
    for (int(j) = 0; (j) < (E[i].size()); (j)++) {
      v.emplace_back(E[i][j].first);
      v.emplace_back(E[i][j].second);
    }
    sort(v.begin(), v.end());
    v.resize(unique(v.begin(), v.end()) - v.begin());
    for (int(j) = 0; (j) < (v.size()); (j)++) {
      U::fnew(v[j]);
      ok[v[j]] = -1;
    }
    for (int(j) = 0; (j) < (E[i].size()); (j)++)
      U::fU(E[i][j].first, E[i][j].second);
    for (int(j) = 0; (j) < (v.size()); (j)++) {
      int x = U::fF(v[j]);
      if (ok[x] < 0) {
        ok[x] = cnt++;
        good.push_back(0);
      }
      ic[v[j]].emplace_back(ok[x]);
    }
  }
}
inline void work(int x, int y) {
  int res = 0;
  if (ic[x].size() > ic[y].size()) swap(x, y);
  for (int(i) = 0; (i) < (ic[x].size()); (i)++) good[ic[x][i]] = 1;
  for (int(i) = 0; (i) < (ic[y].size()); (i)++)
    if (good[ic[y][i]]) res++;
  for (int(i) = 0; (i) < (ic[x].size()); (i)++) good[ic[x][i]] = 0;
  putint(res);
}
int main() {
  n = getint();
  m = getint();
  for (int(i) = 0; (i) < (m); (i)++) {
    int x = getint() - 1, y = getint() - 1, z = getint();
    G[x].push_back(make_pair(y, z));
    G[y].push_back(make_pair(x, z));
    gG[x][z].push_back(y);
    gG[y][z].push_back(x);
    E[z].push_back(make_pair(x, y));
  }
  presolve();
  finit();
  t = getint();
  for (int(i) = 0; (i) < (t); (i)++) {
    int x = getint() - 1, y = getint() - 1;
    if (Mp[x] >= 0)
      putint(ans[y][Mp[x]]);
    else if (Mp[y] >= 0)
      putint(ans[x][Mp[y]]);
    else
      work(x, y);
    putchar('\n');
  }
  return 0;
}
