#include <bits/stdc++.h>
using namespace std;
const long long INF = (long long)1e16;
const int maxn = 1e5 + 10;
struct Node {
  int u, v;
  long long w;
  Node(int a, int b, long long c) : u(a), v(b), w(c) {}
  Node() {}
  bool operator<(const Node& b) const { return w < b.w; }
};
vector<Node> P, G[maxn], rest, gra[maxn];
long long h[maxn], dis[22][maxn];
int fa[maxn][20], depth[maxn];
int par[maxn];
int n, m;
int seek(int x) { return par[x] == x ? x : par[x] = seek(par[x]); }
void dfs(int u, int f) {
  depth[u] = depth[f] + 1;
  fa[u][0] = f;
  for (int i = 0; i < G[u].size(); i++) {
    int v = G[u][i].v;
    long long w = G[u][i].w;
    if (v != f) {
      h[v] = h[u] + w;
      dfs(v, u);
    }
  }
}
void dij(int st, long long* d) {
  for (int i = 0; i < maxn; i++) d[i] = INF;
  d[st] = 0;
  priority_queue<pair<long long, int>, vector<pair<long long, int> >,
                 greater<pair<long long, int> > >
      q;
  q.push(pair<long long, int>(0, st));
  while (!q.empty()) {
    pair<long long, int> t = q.top();
    q.pop();
    long long u = t.second;
    if (d[u] < t.first) continue;
    for (int i = 0; i < gra[u].size(); i++) {
      Node& es = gra[u][i];
      if (d[es.v] > d[u] + es.w) {
        d[es.v] = d[u] + es.w;
        q.push(pair<long long, int>(d[es.v], es.v));
      }
    }
  }
}
void pre_deal() {
  sort(P.begin(), P.end());
  for (int i = 0; i < maxn; i++) {
    par[i] = i;
  }
  for (int i = 0; i < P.size(); i++) {
    int u = P[i].u, v = P[i].v;
    long long w = P[i].w;
    int a = seek(u), b = seek(v);
    if (a != b) {
      G[u].push_back(Node(u, v, w));
      G[v].push_back(Node(v, u, w));
      par[a] = b;
    } else {
      if (u < v) rest.push_back(Node(u, v, w));
    }
  }
  depth[0] = -1;
  h[1] = 0;
  dfs(1, 0);
  for (int j = 1; j <= 19; j++) {
    for (int i = 1; i <= n; i++) {
      fa[i][j] = fa[fa[i][j - 1]][j - 1];
    }
  }
  for (int i = 0; i < rest.size(); i++) {
    dij(rest[i].u, dis[i]);
  }
}
int LCA(int x, int y) {
  if (depth[x] < depth[y]) {
    swap(x, y);
  }
  for (int i = 19; i >= 0; i--) {
    if (depth[x] - (1 << i) >= depth[y]) {
      x = fa[x][i];
    }
  }
  if (x == y) return x;
  for (int i = 19; i >= 0; i--) {
    if (fa[x][i] != fa[y][i]) {
      x = fa[x][i];
      y = fa[y][i];
    }
  }
  return fa[x][0];
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; i++) {
    int u, v;
    long long w;
    scanf("%d %d %lld", &u, &v, &w);
    P.push_back(Node(u, v, w));
    gra[u].push_back(Node(u, v, w));
    gra[v].push_back(Node(v, u, w));
  }
  pre_deal();
  int q;
  scanf("%d", &q);
  while (q--) {
    int u, v;
    scanf("%d %d", &u, &v);
    long long ans = h[u] + h[v] - h[LCA(u, v)] * 2;
    for (int i = 0; i < rest.size(); i++) {
      ans = min(ans, dis[i][u] + dis[i][v]);
    }
    cout << ans << endl;
  }
  return 0;
}
