#include <bits/stdc++.h>
using namespace std;
const long long N_NODE = 100010, LOG_N_NODE = 20;
long long n, m, sz, first[N_NODE], nxt[N_NODE * 2], tail[N_NODE * 2],
    len[N_NODE * 2], dep[N_NODE], wdep[N_NODE], li[N_NODE], eul[N_NODE * 2],
    tree[N_NODE * 2], b, minv[LOG_N_NODE][N_NODE * 2], dist[50][50];
vector<long long> vec;
void addedge(long long u, long long v, long long w) {
  sz++;
  tail[sz] = v;
  len[sz] = w;
  nxt[sz] = first[u];
  first[u] = sz;
}
void dfs(long long u) {
  eul[++eul[0]] = u;
  li[u] = eul[0];
  long long v, e;
  for (e = first[u]; e; e = nxt[e]) {
    v = tail[e];
    if (li[v]) continue;
    tree[e] = tree[e ^ 1] = 1;
    dep[v] = dep[u] + 1;
    wdep[v] = wdep[u] + len[e];
    dfs(v);
    eul[++eul[0]] = u;
  }
}
void rmq() {
  b = sizeof(unsigned int) * 8 - __builtin_clz(n * 2 - 1) - 1;
  long long i, j;
  for (i = 1; i <= n * 2 - 1; i++) minv[0][i] = eul[i];
  for (i = 1; i <= b; i++)
    for (j = 1; j <= n * 2 - 1; j++)
      if (j + (1 << (i - 1)) > n * 2 - 1 ||
          dep[minv[i - 1][j]] < dep[minv[i - 1][j + (1 << (i - 1))]])
        minv[i][j] = minv[i - 1][j];
      else
        minv[i][j] = minv[i - 1][j + (1 << (i - 1))];
}
long long query(long long l, long long r) {
  long long w = sizeof(unsigned int) * 8 - __builtin_clz(r - l + 1) - 1;
  if (dep[minv[w][l]] < dep[minv[w][r - (1 << w) + 1]])
    return minv[w][l];
  else
    return minv[w][r - (1 << w) + 1];
}
long long lca(long long u, long long v) {
  return query(std::min(li[u], li[v]), std::max(li[u], li[v]));
}
inline long long tree_dist(long long u, long long v) {
  return wdep[u] + wdep[v] - wdep[lca(u, v)] * 2;
}
int main() {
  scanf("%lld%lld", &n, &m);
  long long i, j, k, u, v, w;
  memset(first, 0, sizeof(first));
  for (sz = 1, i = 1; i <= m; i++) {
    scanf("%lld%lld%lld", &u, &v, &w);
    addedge(u, v, w);
    addedge(v, u, w);
  }
  dep[1] = wdep[1] = 0;
  dfs(1);
  rmq();
  for (i = 2; i <= sz; i++)
    if (!tree[i]) vec.push_back(tail[i]);
  sort(vec.begin(), vec.end());
  vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
  long long c = vec.size();
  for (i = 0; i < c; i++)
    for (j = 0; j < c; j++) dist[i][j] = tree_dist(vec[i], vec[j]);
  long long p, q;
  for (i = 2; i <= sz; i += 2) {
    if (tree[i]) continue;
    u = tail[i];
    v = tail[i + 1];
    p = lower_bound(vec.begin(), vec.end(), u) - vec.begin();
    q = lower_bound(vec.begin(), vec.end(), v) - vec.begin();
    dist[p][q] = dist[q][p] = min(dist[p][q], len[i]);
  }
  for (k = 0; k < c; k++)
    for (i = 0; i < c; i++)
      for (j = 0; j < c; j++)
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
  long long qry, ans;
  scanf("%lld", &qry);
  while (qry--) {
    scanf("%lld%lld", &u, &v);
    for (ans = tree_dist(u, v), i = 0; i < c; i++)
      for (j = 0; j < c; j++)
        ans =
            min(ans, tree_dist(u, vec[i]) + dist[i][j] + tree_dist(v, vec[j]));
    printf("%lld\n", ans);
  }
  return 0;
}
