#include <bits/stdc++.h>
using namespace std;
struct edge {
  long long x, y, val, kk;
} r[100010];
bool cmp(edge a, edge b) { return a.val < b.val; }
struct node {
  long long nxt, to, val;
} o[100010 * 2];
long long n, m, q, cnt = 1, Cnt, head[100010];
void add(long long u, long long v, long long w) {
  o[cnt].val = w;
  o[cnt].to = v;
  o[cnt].nxt = head[u];
  head[u] = cnt++;
}
long long fa[100010];
long long find(long long x) {
  if (x == fa[x]) return fa[x];
  return fa[x] = find(fa[x]);
}
void kruskal() {
  for (long long i = 1; i <= n; i++) fa[i] = i;
  sort(r + 1, r + 1 + m, cmp);
  long long numedge = 0;
  for (long long i = 1; i <= m; i++) {
    if (numedge == n - 1) break;
    long long f1 = find(r[i].x), f2 = find(r[i].y);
    if (f1 != f2) fa[f1] = f2, numedge++, r[i].kk = 1;
  }
}
long long deep[100010], f[100010][17], dista[100010];
void dfs(long long now, long long fa, long long dep) {
  f[now][0] = fa;
  for (long long i = head[now]; i != -1; i = o[i].nxt) {
    long long t = o[i].to;
    if (t != fa) {
      deep[t] = dep + 1, dista[t] = dista[now] + o[i].val;
      dfs(t, now, dep + 1);
    }
  }
}
long long lca(long long x, long long y) {
  long long fin = 0;
  if (deep[x] < deep[y]) swap(x, y);
  for (long long i = 16; i >= 0; i--)
    if (deep[f[x][i]] >= deep[y]) x = f[x][i];
  if (x == y) return x;
  for (long long i = 16; i >= 0; i--) {
    if (f[x][i] != f[y][i])
      x = f[x][i], y = f[y][i];
    else
      fin = f[x][i];
  }
  return fin;
}
struct app {
  long long dist, id;
  friend bool operator<(app a, app b) { return a.dist > b.dist; }
};
long long vis[100010], dis[50][100010];
void dijkstra(long long start) {
  Cnt++;
  memset(vis, 0, sizeof(vis));
  priority_queue<app> q;
  q.push((app){0, start});
  dis[Cnt][start] = 0;
  while (!q.empty()) {
    app temp = q.top();
    q.pop();
    long long now = temp.id;
    if (vis[now]) continue;
    vis[now] = 1;
    for (long long i = head[now]; i != -1; i = o[i].nxt) {
      long long t = o[i].to;
      if (dis[Cnt][t] > dis[Cnt][now] + o[i].val) {
        dis[Cnt][t] = dis[Cnt][now] + o[i].val;
        q.push((app){dis[Cnt][t], t});
      }
    }
  }
}
signed main() {
  scanf("%I64d%I64d", &n, &m);
  memset(head, -1, sizeof(head));
  memset(dis, 0x3f, sizeof(dis));
  for (long long i = 1; i <= m; i++)
    scanf("%I64d%I64d%I64d", &r[i].x, &r[i].y, &r[i].val);
  kruskal();
  for (long long i = 1; i <= m; i++) {
    if (r[i].kk) add(r[i].x, r[i].y, r[i].val), add(r[i].y, r[i].x, r[i].val);
  }
  deep[1] = 1;
  dfs(1, -1, 1);
  for (long long j = 1; j <= 16; j++)
    for (long long i = 1; i <= n; i++) f[i][j] = f[f[i][j - 1]][j - 1];
  for (long long i = 1; i <= m; i++) {
    if (!r[i].kk) add(r[i].x, r[i].y, r[i].val), add(r[i].y, r[i].x, r[i].val);
  }
  for (long long i = 1; i <= m; i++) {
    if (!r[i].kk) dijkstra(r[i].x);
  }
  scanf("%I64d", &q);
  while (q--) {
    long long a, b;
    scanf("%I64d%I64d", &a, &b);
    if (a == b) {
      printf("0\n");
      continue;
    }
    long long LCA = lca(a, b);
    long long ans = dista[a] + dista[b] - dista[LCA] * 2;
    for (long long i = 1; i <= Cnt; i++) {
      ans = min(ans, dis[i][a] + dis[i][b]);
    }
    printf("%I64d\n", ans);
  }
  return 0;
}
