#include <bits/stdc++.h>
using namespace std;
struct data {
  long long u, v, w;
  data(){};
  data(long long u, long long v, long long w) : u(u), v(v), w(w){};
};
const long long N = 1e5 + 100, LOG = 20, oo = 1e16;
long long n, m;
data Edge[N];
vector<pair<long long, long long> > adj[N];
long long dad[N];
vector<long long> ver;
vector<pair<long long, long long> > tree[N];
long long getRoot(long long u) {
  return (dad[u] < 0) ? u : (dad[u] = getRoot(dad[u]));
}
bool Merge(long long u, long long v) {
  u = getRoot(u);
  v = getRoot(v);
  if (u == v) return false;
  if (dad[u] > dad[v]) swap(u, v);
  dad[u] += dad[v];
  dad[v] = u;
  return true;
}
void Build_Tree() {
  for (long long i = 1; i <= n; ++i) dad[i] = -1;
  for (long long i = 1; i <= m; ++i) {
    long long u = Edge[i].u, v = Edge[i].v, w = Edge[i].w;
    if (Merge(u, v)) {
      tree[u].push_back(pair<long long, long long>(w, v));
      tree[v].push_back(pair<long long, long long>(w, u));
    } else {
      ver.push_back(u);
      ver.push_back(v);
    }
  }
}
long long par[N][LOG + 4], sum[N][LOG + 4], hei[N];
void DFS(long long mom, long long u) {
  hei[u] = hei[mom] + 1;
  for (long long i = 0; i < (long long)tree[u].size(); ++i) {
    long long v = tree[u][i].second, val = tree[u][i].first;
    if (v == mom) continue;
    par[v][0] = u;
    sum[v][0] = val;
    DFS(u, v);
  }
}
void Build_LCA() {
  DFS(0, 1);
  for (long long j = 1; j <= LOG; ++j)
    for (long long i = 1; i <= n; ++i) {
      sum[i][j] = sum[i][j - 1] + sum[par[i][j - 1]][j - 1];
      par[i][j] = par[par[i][j - 1]][j - 1];
    }
}
long long LCA(long long u, long long v) {
  if (hei[u] < hei[v]) swap(u, v);
  long long res = 0;
  for (long long i = LOG; i >= 0; --i)
    if (hei[u] - (1 << i) >= hei[v]) {
      res += sum[u][i];
      u = par[u][i];
    }
  if (u == v) return res;
  for (long long i = LOG; i >= 0; --i)
    if (par[u][i] != 0 && par[v][i] != 0 && par[u][i] != par[v][i]) {
      res += sum[u][i] + sum[v][i];
      u = par[u][i];
      v = par[v][i];
    }
  res += sum[u][0] + sum[v][0];
  return res;
}
long long d[45][N];
priority_queue<pair<long long, long long>, vector<pair<long long, long long> >,
               greater<pair<long long, long long> > >
    pq;
void Dijkstra(long long id, long long st) {
  for (long long i = 1; i <= n; ++i) d[id][i] = oo;
  d[id][st] = 0;
  pq.push(pair<long long, long long>(0, st));
  while (pq.size()) {
    long long u = pq.top().second, du = pq.top().first;
    pq.pop();
    if (du != d[id][u]) continue;
    for (long long i = 0; i < (long long)adj[u].size(); ++i) {
      long long v = adj[u][i].second, uv = adj[u][i].first;
      if (du + uv < d[id][v]) {
        d[id][v] = du + uv;
        pq.push(pair<long long, long long>(d[id][v], v));
      }
    }
  }
}
void Answer_Query() {
  long long Q, u, v;
  cin >> Q;
  while (Q--) {
    cin >> u >> v;
    long long res = LCA(u, v);
    for (long long i = 0; i < (long long)ver.size(); ++i) {
      res = min(res, d[i][u] + d[i][v]);
    }
    cout << res << '\n';
  }
}
void sol() {
  Build_Tree();
  Build_LCA();
  sort(ver.begin(), ver.end());
  ver.resize(unique(ver.begin(), ver.end()) - ver.begin());
  for (long long i = 0; i < (long long)ver.size(); ++i) {
    Dijkstra(i, ver[i]);
  }
  Answer_Query();
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  long long u, v, w;
  for (long long i = 1; i <= m; ++i) {
    cin >> u >> v >> w;
    adj[u].push_back(pair<long long, long long>(w, v));
    adj[v].push_back(pair<long long, long long>(w, u));
    Edge[i] = data(u, v, w);
  }
  sol();
  return 0;
}
