#include <bits/stdc++.h>
using namespace std;
const long long inf = 1e18 + 5;
const int N = 1e5 + 35;
const int DEG = 21;
long long dis[55][N];
struct Edge {
  int u;
  int v;
  int next;
  long long w;
} edge1[N * 2], edge[N * 2];
int tot1;
int head1[N];
int tot;
int head[N];
int f[N];
int fa[N][25];
int deg[N];
long long dep[N];
int n, m;
int se[50];
int scnt;
int vis[N];
vector<Edge> ve[N];
void adde1(int u, int v, long long w) {
  edge1[++tot1].u = u;
  edge1[tot1].v = v;
  edge1[tot1].w = w;
  edge1[tot1].next = head1[u];
  head1[u] = tot1;
}
void add(int u, int v, long long w) {
  edge[++tot].v = v;
  edge[tot].w = w;
  edge[tot].next = head[u];
  head[u] = tot;
}
void init() {
  tot = tot1 = 0;
  memset(head, -1, sizeof(head));
  memset(head1, -1, sizeof(head1));
}
void bfs(int rt) {
  queue<int> que;
  deg[rt] = 0;
  dep[rt] = 0;
  fa[rt][0] = rt;
  que.push(rt);
  while (!que.empty()) {
    int tmp = que.front();
    que.pop();
    for (int i = 1; i < DEG; i++) {
      fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1];
    }
    for (int i = head[tmp]; i != -1; i = edge[i].next) {
      int v = edge[i].v;
      if (v == fa[tmp][0]) continue;
      deg[v] = deg[tmp] + 1;
      dep[v] = dep[tmp] + edge[i].w;
      fa[v][0] = tmp;
      que.push(v);
    }
  }
}
int LCA(int u, int v) {
  if (deg[u] > deg[v]) swap(u, v);
  int hu = deg[u];
  int hv = deg[v];
  int tu = u, tv = v;
  for (int det = hv - hu, i = 0; det; det >>= 1, i++) {
    if (det & 1) tv = fa[tv][i];
  }
  if (tu == tv) return tu;
  for (int i = DEG - 1; i >= 0; i--) {
    if (fa[tu][i] == fa[tv][i]) continue;
    tu = fa[tu][i];
    tv = fa[tv][i];
  }
  return fa[tu][0];
}
bool cmp(Edge a, Edge b) { return a.w < b.w; }
void dij(int id, int s) {
  for (int i = 0; i <= n + 2; i++) {
    vis[i] = 0;
    dis[id][i] = inf;
  }
  dis[id][s] = 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, s));
  while (!q.empty()) {
    pair<long long, int> tmp = q.top();
    q.pop();
    int u = tmp.second;
    if (tmp.first > dis[id][u]) continue;
    vis[u] = 1;
    for (int i = 0; i < ve[u].size(); i++) {
      int v = ve[u][i].v;
      long long w = ve[u][i].w;
      if (vis[v]) continue;
      if (dis[id][v] > dis[id][u] + w) {
        dis[id][v] = dis[id][u] + w;
        q.push(pair<long long, int>(dis[id][v], v));
      }
    }
  }
}
int getf(int x) { return f[x] == x ? x : (f[x] = getf(f[x])); }
int merge(int x, int y) {
  int t1 = getf(x);
  int t2 = getf(y);
  if (t1 != t2) {
    f[t2] = t1;
    return 1;
  }
  return 0;
}
int main() {
  scanf("%d %d", &n, &m);
  int u, v;
  long long w;
  init();
  for (int i = 1; i <= m; i++) {
    scanf("%d %d %lld", &u, &v, &w);
    adde1(u, v, w);
    ve[u].push_back((Edge){u, v, 0, w});
    ve[v].push_back((Edge){v, u, 0, w});
  }
  sort(edge1 + 1, edge1 + tot1 + 1, cmp);
  for (int i = 0; i <= n + 2; i++) {
    f[i] = i;
  }
  for (int i = 1; i <= tot1; i++) {
    u = edge1[i].u;
    v = edge1[i].v;
    if (merge(u, v)) {
      add(u, v, edge1[i].w);
      add(v, u, edge1[i].w);
    } else {
      se[++scnt] = u;
      se[++scnt] = v;
    }
  }
  bfs(1);
  sort(se + 1, se + scnt + 1);
  scnt = unique(se + 1, se + scnt + 1) - (se + 1);
  for (int i = 1; i <= scnt; i++) {
    dij(i, se[i]);
  }
  int q;
  scanf("%d", &q);
  while (q--) {
    scanf("%d %d", &u, &v);
    long long ans = inf;
    int lca = LCA(u, v);
    ans = dep[u] + dep[v] - 2 * dep[lca];
    for (int i = 1; i <= scnt; i++) {
      ans = min(ans, dis[i][u] + dis[i][v]);
    }
    printf("%lld\n", ans);
  }
  return 0;
}
