#include <bits/stdc++.h>
const double pi = 4.0 * atan(1.0);
const double e = exp(1.0);
const int maxn = 1e5 + 8;
const long long mod = 998244353;
const unsigned long long base = 1e7 + 7;
using namespace std;
long long dis[45][maxn];
long long di[45];
int pre[maxn];
int f[maxn][22];
long long ee[maxn][22];
pair<int, int> vnt[48];
struct edge {
  int to, nxt;
  long long val;
} g[maxn * 2];
struct hh {
  int x, y, val;
} gg[maxn];
int wai[maxn];
bool cmp(hh a, hh b) { return a.val < b.val; }
int cnt = 0;
int head[maxn];
int de[maxn];
void add(int u, int v, long long val) {
  g[cnt].to = v;
  g[cnt].nxt = head[u];
  g[cnt].val = val;
  head[u] = cnt++;
}
bool vis[maxn];
void Dij(int s, int u) {
  memset(vis, 0, sizeof(vis));
  memset(dis[u], 0x3f3f3f3f, sizeof(dis[u]));
  dis[u][s] = 0;
  priority_queue<pair<long long, int>, vector<pair<long long, int> >,
                 greater<pair<long long, int> > >
      que;
  while (!que.empty()) {
    que.pop();
  }
  que.push({0, s});
  while (!que.empty()) {
    pair<int, int> now = que.top();
    int k = now.second;
    que.pop();
    if (vis[k]) continue;
    vis[k] = 1;
    int tt = head[k];
    while (tt != -1) {
      if (dis[u][g[tt].to] > dis[u][k] + g[tt].val) {
        dis[u][g[tt].to] = dis[u][k] + g[tt].val;
        if (!vis[g[tt].to]) {
          que.push({dis[u][g[tt].to], g[tt].to});
        }
      }
      tt = g[tt].nxt;
    }
  }
}
int Find(int u) {
  if (u == pre[u]) return u;
  return pre[u] = Find(pre[u]);
}
void dfs(int u, int fa, int val, int d) {
  f[u][0] = fa;
  ee[u][0] = val;
  de[u] = d;
  int t = head[u];
  while (t != -1) {
    if (g[t].to != fa) {
      dfs(g[t].to, u, g[t].val, d + 1);
    }
    t = g[t].nxt;
  }
}
long long get(int x, int y) {
  long long k = 0;
  if (de[x] < de[y]) {
    swap(x, y);
  }
  while (de[x] != de[y]) {
    for (int j = 20; j >= 0; j--) {
      if (de[f[x][j]] >= de[y]) {
        k += ee[x][j];
        x = f[x][j];
      }
    }
  }
  while (f[x][0] != f[y][0]) {
    for (int j = 20; j >= 0; j--) {
      if (f[x][j] != f[y][j]) {
        k += ee[x][j];
        k += ee[y][j];
        x = f[x][j];
        y = f[y][j];
      }
    }
  }
  if (x != y) {
    k += ee[x][0];
    k += ee[y][0];
  }
  return k;
}
int main() {
  int n, m;
  memset(head, -1, sizeof(head));
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    pre[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%lld", &gg[i].x, &gg[i].y, &gg[i].val);
  }
  sort(gg + 1, gg + 1 + m, cmp);
  int x, y;
  int cou = 0;
  for (int i = 1; i <= m; i++) {
    x = Find(gg[i].x);
    y = Find(gg[i].y);
    if (x != y) {
      pre[x] = y;
      add(gg[i].x, gg[i].y, gg[i].val);
      add(gg[i].y, gg[i].x, gg[i].val);
    } else {
      vnt[cou] = {gg[i].x, gg[i].y};
      wai[cou] = i;
      cou++;
    }
  }
  dfs(1, 0, 0, 1);
  for (int i = 1; i <= 20; i++) {
    for (int j = 1; j <= n; j++) {
      f[j][i] = f[f[j][i - 1]][i - 1];
      ee[j][i] = ee[j][i - 1] + ee[f[j][i - 1]][i - 1];
    }
  }
  for (int i = 0; i < cou; i++) {
    x = gg[wai[i]].x;
    y = gg[wai[i]].y;
    add(x, y, gg[wai[i]].val);
    add(y, x, gg[wai[i]].val);
  }
  for (int i = 0; i < cou; i++) {
    x = gg[wai[i]].x;
    y = gg[wai[i]].y;
    Dij(x, i * 2);
    Dij(y, i * 2 + 1);
    di[i] = gg[wai[i]].val;
  }
  int q;
  scanf("%d", &q);
  while (q--) {
    scanf("%d%d", &x, &y);
    long long ans = get(x, y);
    for (int k = 0; k < cou; k++) {
      ans = min(ans, dis[k * 2][x] + dis[k * 2 + 1][y] + di[k]);
      ans = min(ans, dis[k * 2][y] + dis[k * 2 + 1][x] + di[k]);
    }
    printf("%lld\n", ans);
  }
}
