#include <bits/stdc++.h>   using namespace std;   struct edge {     int u, v;     long long c;     bool operator<(const edge& other) const { return c < other.c; }   };   vector<int> parent;   vector<int> size;   int get(int v) {     if (parent[v] == v) {       return v;     }     return parent[v] = get(parent[v]);   }   void unite(int a, int b) {     a = get(a), b = get(b);     if (size[a] < size[b]) {       swap(a, b);     }     parent[b] = a;     size[a] += size[b];   }   const int rmax = 18;   vector<vector<int> > p;   vector<vector<long long> > maxx;   vector<vector<edge> > g;   vector<int> tin, tout;   int timer = 0;   void dfs(int v, int par) {     tin[v] = timer++;     p[v][0] = par;     for (edge& e : g[v]) {       if (e.v != par) {         maxx[e.v][0] = e.c;         dfs(e.v, v);       }     }     tout[v] = timer++;   }   bool ancestor(int u, int v) { return tin[u] <= tin[v] && tout[u] >= tout[v]; }   int lca(int u, int v) {     if (ancestor(u, v)) {       return u;     }     for (int r = rmax - 1; r >= 0; --r) {       if (!ancestor(p[u][r], v)) {         u = p[u][r];       }     }     return p[u][0];   }   long long getMax(int u, int v) {     assert(u != v && ancestor(v, u));     long long ans = 0;     for (int r = rmax - 1; r >= 0; --r) {       if (!ancestor(p[u][r], v)) {         ans = max(ans, maxx[u][r]);         u = p[u][r];       }     }     return max(ans, maxx[u][0]);   }   int main() {     ios_base::sync_with_stdio(false);     cin.tie(0);     cout.tie(0);     int n, m;     cin >> n >> m;     vector<edge> edges(m);     for (int i = 0; i < m; ++i) {       int u, v;       long long c;       cin >> u >> v >> c;       --u, --v;       edges[i] = {u, v, c};     }     sort((edges).begin(), (edges).end());     parent.resize(n);     size.assign(n, 1);     for (int i = 0; i < n; ++i) {       parent[i] = i;     }     long long total = 0;     vector<edge> useful;     for (int i = 0; i < m; ++i) {       int u = edges[i].u, v = edges[i].v;       u = get(u), v = get(v);       if (u == v) {         continue;       }       unite(u, v);       total += edges[i].c;       useful.push_back(edges[i]);     }     set<int> s;     for (int i = 0; i < n; ++i) {       s.insert(get(i));     }     if ((int)(s).size() == 1) {       p = vector<vector<int> >(n, vector<int>(rmax));       maxx = vector<vector<long long> >(n, vector<long long>(rmax));       g.resize(n);       for (edge& e : useful) {         int u = e.u, v = e.v;         long long c = e.c;         g[u].push_back({u, v, c});         g[v].push_back({v, u, c});       }       tin.resize(n);       tout.resize(n);       dfs(0, 0);       for (int r = 0; r + 1 < rmax; ++r) {         for (int v = 0; v < n; ++v) {           int t = p[v][r];           p[v][r + 1] = p[t][r];           maxx[v][r + 1] = max(maxx[v][r], maxx[t][r]);         }       }     }     int q;     cin >> q;     while (q--) {       int a, b;       cin >> a >> b;       --a, --b;       if ((int)(s).size() > 2) {         cout <<  -1 n ;         continue;       }       if ((int)(s).size() == 2) {         a = get(a), b = get(b);         if (a == b) {           cout <<  -1 n ;           continue;         }         cout << total <<   n ;         continue;       }       int w = lca(a, b);       long long ans = 0;       if (a != w) {         ans = max(ans, getMax(a, w));       }       if (b != w) {         ans = max(ans, getMax(b, w));       }       cout << total - ans <<   n ;     }   }