#include <bits/stdc++.h>
using namespace std;
struct edge {
  long long x, y, w;
};
long long n, m, q;
vector<vector<pair<long long, long long> > > g;
vector<bool> used;
map<pair<long long, long long>, edge> edges, edgesall;
vector<long long> ti, to, rootdst;
vector<vector<long long> > pred;
long long timer = 0;
long long lg = 1;
void dfs(long long v, long long p) {
  used[v] = true;
  ti[v] = timer++;
  pred[v][0] = p;
  for (long long i = 1; i <= lg; i++) {
    pred[v][i] = pred[pred[v][i - 1]][i - 1];
  }
  for (long long i = 0; i < g[v].size(); i++) {
    long long to = g[v][i].first;
    long long w = g[v][i].second;
    if (!used[to]) {
      rootdst[to] = rootdst[v] + w;
      edges.erase({v, to});
      edges.erase({to, v});
      dfs(to, v);
    }
  }
  to[v] = timer++;
}
vector<vector<long long> > dst;
bool upper(long long a, long long b) {
  return ti[a] <= ti[b] && to[a] >= to[b];
}
void dijkstra(long long s) {
  used.assign(n, false);
  dst.push_back(vector<long long>(n, 1e18));
  dst.back()[s] = 0;
  used[s] = true;
  set<pair<long long, long long> > q;
  q.insert({0ll, s});
  while (!q.empty()) {
    auto p = *q.begin();
    q.erase(q.begin());
    long long v = p.second;
    long long d = p.first;
    for (long long i = 0; i < g[v].size(); i++) {
      long long w = g[v][i].second;
      long long to = g[v][i].first;
      if (dst.back()[to] > dst.back()[v] + w) {
        q.erase({dst.back()[to], to});
        dst.back()[to] = dst.back()[v] + w;
        q.insert({dst.back()[to], to});
      }
    }
  }
}
long long lca(long long a, long long b) {
  if (upper(a, b)) return a;
  if (upper(b, a)) return b;
  for (long long i = lg; i >= 0; i--) {
    if (!upper(pred[a][i], b)) {
      a = pred[a][i];
    }
  }
  return pred[a][0];
}
int main() {
  cin >> n >> m;
  g.resize(n);
  used.resize(n);
  ti.resize(n);
  to.resize(n);
  for (long long i = 0; i < m; i++) {
    long long x, y, w;
    cin >> x >> y >> w;
    x--;
    y--;
    edges[{x, y}] = edge{x, y, w};
    edgesall[{x, y}] = edge{x, y, w};
    edgesall[{y, x}] = edge{x, y, w};
    g[x].push_back({y, w});
    g[y].push_back({x, w});
  }
  while ((1 << lg) < n) {
    lg++;
  }
  pred.assign(n, vector<long long>(lg + 1, -1));
  rootdst.resize(n);
  rootdst[0] = 0;
  dfs(0, 0);
  cin >> q;
  for (auto e : edges) {
    dijkstra(e.second.x);
  }
  for (long long i = 0; i < q; i++) {
    long long x, y;
    cin >> x >> y;
    x--;
    y--;
    long long d1 = 1e18;
    for (long long j = 0; j < dst.size(); j++) {
      d1 = min(d1, dst[j][y] + dst[j][x]);
    }
    long long ca = lca(x, y);
    long long d2 = rootdst[x] + rootdst[y] - 2ll * rootdst[ca];
    long long ans = min(d1, d2);
    cout << ans << '\n';
  }
  return 0;
}
