#include <bits/stdc++.h>
using namespace std;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
struct node {
  int v, nxt;
  long long w;
  bool operator<(const node& a) const { return w > a.w; }
  node() {}
  node(int v, long long w) : v(v), w(w) {}
} e[2 * maxn];
int head[maxn], tot, n, m, q;
void add_edge(int u, int v, int w) {
  e[tot].v = v;
  e[tot].w = w;
  e[tot].nxt = head[u];
  head[u] = tot++;
}
vector<int> P;
int sz, ver[2 * maxn], deep[2 * maxn], first[maxn], dp[2 * maxn][30], vis[maxn];
long long dir[maxn];
void init(int n) {
  for (int i = 0; i <= n; i++) dir[i] = vis[i] = 0;
  sz = 0;
}
void dfs(int u, int dep, int pre) {
  vis[u] = 1;
  ver[++sz] = u;
  first[u] = sz;
  deep[sz] = dep;
  for (int i = head[u]; ~i; i = e[i].nxt) {
    int v = e[i].v;
    if (v == pre) continue;
    if (vis[v]) {
      P.push_back(v);
      P.push_back(u);
      continue;
    }
    dir[v] = dir[u] + e[i].w;
    dfs(v, dep + 1, u);
    ver[++sz] = u;
    deep[sz] = dep;
  }
}
void ST(int n) {
  for (int i = 1; i <= n; i++) dp[i][0] = i;
  for (int j = 1; (1 << j) <= n; j++) {
    for (int i = 1; i + (1 << j) - 1 <= n; i++) {
      int a = dp[i][j - 1], b = dp[i + (1 << (j - 1))][j - 1];
      dp[i][j] = deep[a] < deep[b] ? a : b;
    }
  }
}
int RMQ(int l, int r) {
  int k = 0;
  while ((1 << (k + 1)) <= r - l + 1) k++;
  int a = dp[l][k], b = dp[r - (1 << k) + 1][k];
  return deep[a] < deep[b] ? a : b;
}
int LCA(int u, int v) {
  int x = first[u], y = first[v];
  if (x > y) swap(x, y);
  int ret = RMQ(x, y);
  return ver[ret];
}
void pre_solve(int n) {
  init(n);
  dir[1] = 0;
  dfs(1, 1, -1);
  ST(sz);
}
long long dis[55][maxn];
void dij(int num) {
  memset((vis), 0, sizeof(vis));
  memset((dis[num]), 0x3f, sizeof(dis[num]));
  int start = P[num];
  dis[num][start] = 0;
  priority_queue<node> q;
  q.push(node(start, 0));
  while (!q.empty()) {
    int u = q.top().v;
    q.pop();
    if (vis[u]) continue;
    vis[u] = 1;
    for (int i = head[u]; ~i; i = e[i].nxt) {
      int v = e[i].v;
      if (vis[v]) continue;
      if (dis[num][v] > dis[num][u] + e[i].w) {
        dis[num][v] = dis[num][u] + e[i].w;
        q.push(node(v, dis[num][v]));
      }
    }
  }
}
int main() {
  memset((head), -1, sizeof(head));
  tot = 0;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    add_edge(u, v, w);
    add_edge(v, u, w);
  }
  pre_solve(n);
  sort(P.begin(), P.end());
  P.erase(unique(P.begin(), P.end()), P.end());
  int cnt = P.size();
  for (int i = 0; i < cnt; i++) {
    dij(i);
  }
  scanf("%d", &q);
  while (q--) {
    int x, y;
    scanf("%d%d", &x, &y);
    long long ans = dir[x] + dir[y] - 2 * dir[LCA(x, y)];
    for (int i = 0; i < cnt; i++) {
      ans = min(ans, dis[i][x] + dis[i][y]);
    }
    printf("%I64d\n", ans);
  }
  return 0;
}
