#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e5 + 5, M = N << 1;
struct edge {
  int u, v;
  ll w;
  bool operator<(const edge& o) const { return w > o.w; }
} e[N];
bool vis[N];
map<int, int> mp;
int n, m, q;
ll h[N], d[44][N];
vector<int> tree, be;
vector<int> adj[N], g[N];
struct LCA_orz {
  int id = 0;
  int h[N], tin[M], tout[M], euler[M], LOG[M];
  struct node {
    int h, v;
    bool operator<(const node& o) const { return h < o.h; }
  } mn[18][M];
  void dfs(int v) {
    euler[++id] = v;
    for (auto u : g[v]) {
      if (h[u] == 0) {
        h[u] = h[v] + 1;
        dfs(u);
        euler[++id] = v;
      }
    }
  }
  void setup() {
    for (int i = 1; i < M; ++i) {
      LOG[i] = (i & 1) ? LOG[i - 1] : LOG[i >> 1] + 1;
    }
    for (int j = 0; j <= 17; ++j) {
      for (int i = 1; i <= id; ++i) {
        mn[j][i].h = INT_MAX;
      }
    }
    dfs(h[1] = 1);
    memset(tin, 0x3f, sizeof tin);
    for (int i = 1; i <= id; ++i) {
      int x = euler[i];
      tin[x] = min(tin[x], i);
      tout[x] = max(tout[x], i);
      mn[0][i] = {h[x], x};
    }
    for (int j = 1; j <= 17; ++j) {
      for (int i = 1; i <= id - (1 << j) + 1; ++i) {
        mn[j][i] = min(mn[j - 1][i], mn[j - 1][i + (1 << (j - 1))]);
      }
    }
  }
  int get_min(int l, int r) {
    int k = LOG[r - l + 1];
    return min(mn[k][l], mn[k][r - (1 << k) + 1]).v;
  }
  int get(int u, int v) {
    return get_min(min(tin[u], tin[v]), max(tout[u], tout[v]));
  }
} LCA;
void dfs(int v) {
  for (auto& i : adj[v]) {
    int u = v ^ e[i].u ^ e[i].v, w = e[i].w;
    if (vis[u]) continue;
    vis[u] = 1;
    h[u] = h[v] + w;
    g[v].push_back(u);
    g[u].push_back(v);
    tree.push_back(i);
    dfs(u);
  }
}
void dijkstra(int s, ll* d) {
  priority_queue<edge> pq;
  for (int i = 1; i <= n; i++) {
    d[i] = 1e18;
    vis[i] = 0;
  }
  pq.push({s, s, d[s] = 0});
  while (!pq.empty()) {
    int v = pq.top().v;
    pq.pop();
    if (vis[v]) continue;
    vis[v] = 1;
    for (auto& i : adj[v]) {
      int u = v ^ e[i].u ^ e[i].v;
      ll w = e[i].w;
      if (d[u] > d[v] + w) {
        pq.push({v, u, d[u] = d[v] + w});
      }
    }
  }
}
int32_t main() {
  cin.tie(0)->sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 1, u, v, w; i <= m; i++) {
    cin >> u >> v >> w;
    adj[u].push_back(i);
    adj[v].push_back(i);
    e[i] = {u, v, w};
  }
  dfs(vis[1] = 1);
  LCA.setup();
  sort(begin(tree), end(tree));
  for (int i = 1; i <= m; i++) {
    if (!binary_search(begin(tree), end(tree), i)) {
      be.push_back(i);
      mp[e[i].u] = mp[e[i].v] = 0;
    }
  }
  int id = 0;
  for (auto& x : mp) {
    x.second = ++id;
  }
  for (auto x : mp) {
    int v = x.first;
    dijkstra(v, d[mp[v]]);
  }
  cin >> q;
  while (q--) {
    int u, v;
    cin >> u >> v;
    ll ans = h[u] + h[v] - 2 * h[LCA.get(u, v)];
    for (auto& i : be) {
      int w = e[i].u, z = e[i].v;
      ll wei = e[i].w;
      ans = min({ans, d[mp[w]][u] + wei + d[mp[z]][v],
                 d[mp[w]][v] + wei + d[mp[z]][u]});
    }
    cout << ans << '\n';
  }
}
