#include <bits/stdc++.h>   using namespace std;   const double EPS = -1e8;   const double Pi = acos(-1);   bool inline equ(double a, double b) { return fabs(a - b) < EPS; }   int _R(int& x) { return scanf( %d , &x); }   int _R(long long& x) { return scanf( %  PRId64, &x); }   int _R(double& x) { return scanf( %lf , &x); }   int _R(char* s) { return scanf( %s , s); }   int R() { return 0; }   template <typename T1, typename... T2>   int R(T1& x, T2&... tail) {     int tmp = _R(x);     return tmp + R(tail...);   }   template <typename Iter, typename F>   inline void out(Iter s, Iter e, F of) {     bool flag = 0;     for (Iter it = s; it != e; it++) {       if (flag)         printf(   );       else         flag = 1;       of(*it);     }     puts(  );   }   const int MAXN = 1e5 + 10;   struct Edge {     int u, v;     long long c;     bool operator<(const Edge& e) const { return c < e.c; }   };   int n, m;   Edge es[MAXN * 2];   struct DSJ {     int mom[MAXN], sz[MAXN];     void init() {       for (int i = (1); i <= (n); i++) mom[i] = i;     }     int find(int x) { return mom[x] = mom[x] == x ? x : find(mom[x]); }     void merge(int a, int b) {       a = find(a), b = find(b);       mom[b] = a;     }   } dsj;   struct Tree {     static const int LOG = 22;     vector<pair<int, int> > g[MAXN];     int dep[MAXN];     int mom[LOG][MAXN], mx[LOG][MAXN];     int sz[MAXN], root[MAXN];     inline void adde(Edge& e) {       g[e.u].push_back(pair<int, int>(e.v, e.c));       g[e.v].push_back(pair<int, int>(e.u, e.c));     }     void dfs(int u, int p, int c, int d, int rt) {       mom[0][u] = p;       mx[0][u] = c;       dep[u] = d;       root[u] = rt;       for (pair<int, int> e : g[u]) {         int v, tc;         tie(v, tc) = e;         if (v == p) continue;         dfs(v, u, tc, d + 1, rt);       }     }     inline void predo() {       for (int i = (1); i <= (n); i++)         if (!dep[i]) {           dfs(i, -1, 0, 1, i);         }       for (int j = (1); j <= (LOG - 1); j++)         for (int i = (1); i <= (n); i++) {           mom[j][i] = mom[j - 1][mom[j - 1][i]];           mx[j][i] = max(mx[j - 1][i], mx[j - 1][mom[j - 1][i]]);         }       for (int i = (1); i <= (n); i++) sz[root[i]]++;     }     inline int lca(int a, int b) {       if (dep[a] < dep[b]) swap(a, b);       int jmp = dep[a] - dep[b];       for (int k = 0; k < (LOG); k++)         if ((jmp >> k) & 1) a = mom[k][a];       if (a == b) return a;       for (int k = (LOG - 1); k >= (0); k--)         if (mom[k][a] != mom[k][b]) {           a = mom[k][a];           b = mom[k][b];         }       return mom[0][a];     }     inline int qry(int a, int b) {       int anc = lca(a, b);       int res = 0;       {         int jmp = dep[a] - dep[anc];         for (int k = 0; k < (LOG); k++)           if ((jmp >> k) & 1) {             res = max(res, mx[k][a]);             a = mom[k][a];           }       }       {         int jmp = dep[b] - dep[anc];         for (int k = 0; k < (LOG); k++)           if ((jmp >> k) & 1) {             res = max(res, mx[k][b]);             b = mom[k][b];           }       }       return res;     }   } tree;   int main() {     R(n, m);     for (int i = (1); i <= (m); i++) R(es[i].u, es[i].v, es[i].c);     sort(es + 1, es + 1 + m);     long long mst_cst = 0ll;     dsj.init();     for (int i = (1); i <= (m); i++) {       Edge& e = es[i];       if (dsj.find(e.u) != dsj.find(e.v)) {         dsj.merge(e.u, e.v);         mst_cst += e.c;         tree.adde(e);       }     }     tree.predo();     int q;     R(q);     while (q--) {       int a, b;       R(a, b);       if (tree.root[a] == tree.root[b]) {         if (tree.sz[tree.root[a]] < n)           puts( -1 );         else           printf( %I64d n , mst_cst - tree.qry(a, b));       } else {         if (tree.sz[tree.root[a]] + tree.sz[tree.root[b]] < n)           puts( -1 );         else           printf( %I64d n , mst_cst);       }     }   }