#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
const long long inf = 1e13;
int n, m, q;
const int lim = 300;
struct edgenode {
  int nxt, v, w;
} e[200005];
int b[N], en;
vector<int> tomo, nr, vq[N];
int colorcnt[N];
int qa[N], qb[N];
int ans[N];
int cf[N], vis[N];
struct edge {
  int u, v, w;
} er[N];
void addedge(int u, int v, int w) {
  e[en].v = v;
  e[en].w = w;
  e[en].nxt = b[u];
  b[u] = en++;
}
void dfs(int u, int s) {
  vis[u] = s;
  for (int j = b[u]; j != -1; j = e[j].nxt)
    if (!vis[e[j].v]) dfs(e[j].v, s);
}
void dfs2(int u) {
  vis[u] = 1;
  nr.push_back(u);
  for (int j = b[u]; j != -1; j = e[j].nxt)
    if (!vis[e[j].v]) dfs2(e[j].v);
}
void buildedge(int c) {
  int p = cf[c];
  if (p == 0) return;
  en = 0;
  tomo.clear();
  for (int i = p; i <= m; i++) {
    if (er[i].w != c) return;
    addedge(er[i].u, er[i].v, er[i].w);
    addedge(er[i].v, er[i].u, er[i].w);
    tomo.push_back(er[i].u);
    tomo.push_back(er[i].v);
  }
}
void destroyedge() {
  for (auto i : tomo) {
    b[i] = -1;
    vis[i] = false;
  }
  en = 0;
}
void work1(int c) {
  buildedge(c);
  int s = 0;
  for (auto v : tomo) {
    if (!vis[v]) dfs(v, ++s);
  }
  for (int i = 1; i <= q; i++)
    if (vis[qa[i]] == vis[qb[i]] && vis[qa[i]] != 0) ans[i]++;
  destroyedge();
}
void work2(int c) {
  buildedge(c);
  for (auto v : tomo) {
    if (!vis[v]) {
      nr.clear();
      dfs2(v);
      int len = ((int)(nr).size());
      for (int i = 0; i <= len - 1; i++)
        for (int j = 0; j <= len - 1; j++)
          if (i != j) vq[nr[j]].push_back(nr[i]);
    }
  }
  destroyedge();
}
void work3() {
  for (int i = 1; i <= n; i++) sort(vq[i].begin(), vq[i].end());
  for (int i = 1; i <= q; i++) {
    if (((int)(vq[qa[i]]).size()))
      ans[i] += upper_bound(vq[qa[i]].begin(), vq[qa[i]].end(), qb[i]) -
                lower_bound(vq[qa[i]].begin(), vq[qa[i]].end(), qb[i]);
  }
}
bool cmp(const edge& A, const edge& B) { return A.w < B.w; }
int main() {
  cin >> n >> m;
  int u, v, w;
  memset(b, -1, sizeof(b));
  en = 0;
  memset(colorcnt, 0, sizeof(colorcnt));
  memset(ans, 0, sizeof(ans));
  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= m; i++) {
    scanf("%d %d %d", &u, &v, &w);
    er[i].u = u;
    er[i].v = v;
    er[i].w = w;
    colorcnt[w]++;
  }
  sort(1 + er, 1 + m + er, cmp);
  memset(cf, 0, sizeof(cf));
  for (int i = 1; i <= m; i++) {
    if (cf[er[i].w] == 0) cf[er[i].w] = i;
  }
  cin >> q;
  for (int i = 1; i <= q; i++) {
    scanf("%d %d", &u, &v);
    qa[i] = u;
    qb[i] = v;
  }
  for (int i = 1; i <= m; i++) {
    if (colorcnt[i] > lim)
      work1(i);
    else if (colorcnt[i] > 0)
      work2(i);
  }
  work3();
  for (int i = 1; i <= q; i++) printf("%d\n", ans[i]);
  return 0;
}
