#include <bits/stdc++.h>   using namespace std;   const int maxn = 1e5 + 100;   const long long inf = 1e18;   int bcg[maxn];   struct Edge {     int u, v, nxt;     long long w;   } edge[maxn * 2], edge1[maxn * 2];   vector<Edge> vec[maxn];   struct Node {     long long p;     int v;     friend bool operator<(Node a, Node b) { return a.p > b.p; }     Node() {}     Node(long long x, int y) { p = x, v = y; }   };   int head[maxn], head1[maxn];   long long deep[maxn];   int depth[maxn];   int bian[maxn * 2];   long long dis[50][maxn];   int lca[maxn][25];   int vis[maxn];   int cnt, cnt1, tot;   int n, m;   int findd(int x) { return bcg[x] == x ? bcg[x] : bcg[x] = findd(bcg[x]); }   bool cmp(Edge a, Edge b) { return a.w < b.w; }   void add_e1(int x, int y, long long w) {     ++cnt1;     edge1[cnt1].u = x;     edge1[cnt1].v = y;     edge1[cnt1].w = w;     edge1[cnt1].nxt = head1[x];     head1[x] = cnt1;   }   void add_e(int x, int y, long long w) {     ++cnt;     edge[cnt].u = x;     edge[cnt].v = y;     edge[cnt].w = w;     edge[cnt].nxt = head[x];     head[x] = cnt;   }   int merges(int x, int y) {     int xx = findd(x);     int yy = findd(y);     if (xx != yy) {       bcg[xx] = yy;       return 1;     }     return 0;   }   void init() {     cnt = cnt1 = 0;     tot = 0;     memset(deep, 0, sizeof(deep));     memset(head, 0, sizeof(head));     memset(head1, 0, sizeof(head1));   }   void dfs(int x, int ff) {     lca[x][0] = ff;     for (int i = 1; i <= 20; i++) lca[x][i] = lca[lca[x][i - 1]][i - 1];     for (int i = head[x]; i; i = edge[i].nxt) {       int v = edge[i].v;       if (v == ff) continue;       deep[v] = deep[x] + edge[i].w;       depth[v] = depth[x] + 1;       dfs(v, x);     }   }   int LCA(int x, int y) {     if (depth[x] < depth[y]) swap(x, y);     int ff = depth[x] - depth[y];     for (int i = 20; i >= 0; i--) {       if (ff & (1 << i)) x = lca[x][i];     }     if (x == y) return y;     for (int i = 20; i >= 0; i--) {       if (lca[x][i] != lca[y][i]) x = lca[x][i], y = lca[y][i];     }     return lca[y][0];   }   priority_queue<Node> que;   void dij(int id, int x) {     for (int i = 0; i <= n + 4; i++) {       dis[id][i] = inf;       vis[i] = 0;     }     dis[id][x] = 0;     while (!que.empty()) que.pop();     que.push(Node(0, x));     while (!que.empty()) {       Node vv = que.top();       que.pop();       if (vis[vv.v] || vv.p > dis[id][vv.v]) continue;       vis[vv.v] = 1;       for (int i = 0; i < (int)vec[vv.v].size(); i++) {         Edge k = vec[vv.v][i];         int sw = k.v;         if (vis[sw]) continue;         if (dis[id][sw] > dis[id][vv.v] + k.w) {           dis[id][sw] = dis[id][vv.v] + k.w;           que.push(Node(dis[id][sw], sw));         }       }     }   }   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);       add_e1(u, v, w);       vec[u].push_back((Edge){u, v, 0, w});       vec[v].push_back((Edge){v, u, 0, w});     }     sort(edge1 + 1, edge1 + cnt1 + 1, cmp);     for (int i = 1; i <= n + 4; i++) bcg[i] = i;     for (int i = 1; i <= cnt1; i++) {       int x = edge1[i].u, y = edge1[i].v;       if (merges(x, y)) {         add_e(x, y, edge1[i].w);         add_e(y, x, edge1[i].w);       } else {         bian[++tot] = x;         bian[++tot] = y;       }     }     depth[1] = 0;     deep[1] = 0;     dfs(1, 0);     sort(bian + 1, bian + 1 + tot);     int sz = unique(bian + 1, bian + 1 + tot) - (bian + 1);     for (int i = 1; i <= sz; i++) {       dij(i, bian[i]);     }     int q;     scanf( %d , &q);     int x, y;     while (q--) {       scanf( %d%d , &x, &y);       long long ans = inf;       int pq = LCA(x, y);       ans = deep[x] + deep[y] - 2 * deep[pq];       for (int i = 1; i <= sz; i++) {         ans = min(ans, dis[i][x] + dis[i][y]);       }       cout << ans <<   n ;     }     return 0;   }