#include <bits/stdc++.h>
using namespace std;
const int OO = 1e9;
const long long INF = 1e18;
const int irand(int lo, int hi) {
  return ((double)rand() / (RAND_MAX + 1.0)) * (hi - lo + 1) + lo;
}
const long long lrand(long long lo, long long hi) {
  return ((double)rand() / (RAND_MAX + 1.0)) * (hi - lo + 1) + lo;
}
template <typename T>
T getnum() {
  int sign = 1;
  T ret = 0;
  char c;
  do {
    c = getchar();
  } while (c == ' ' || c == '\n');
  if (c == '-')
    sign = -1;
  else
    ret = c - '0';
  while (1) {
    c = getchar();
    if (c < '0' || c > '9') break;
    ret = 10 * ret + c - '0';
  }
  return sign * ret;
}
inline void ini(int& x) { x = getnum<int>(); }
inline void scani(int& x) { scanf("%d", &x); }
const int N = 1e5 + 5;
const int LOG = 16;
int n, m, q;
vector<pair<int, int> > lst[N];
int edgestaken = 0;
long long mstcost = 0;
vector<pair<int, pair<int, int> > > edges;
int p[N];
int cek(int x) {
  if (p[p[x]] != p[x]) p[x] = cek(p[x]);
  return p[x];
}
int depth[N];
int sparset[LOG + 1][N];
int maxedge[LOG + 1][N];
void dfs(int now, int par) {
  sparset[0][now] = par;
  for (int i = 0; i < lst[now].size(); i++) {
    int to = lst[now][i].first;
    if (to == par) continue;
    int c = lst[now][i].second;
    depth[to] = depth[now] + 1;
    maxedge[0][to] = c;
    dfs(to, now);
  }
}
void prec_sparse() {
  for (int i = 0; i <= LOG - 1; i += 1) {
    for (int j = 1; j <= n; j += 1) {
      if (sparset[i][j] == -1) {
        sparset[i + 1][j] = -1;
        maxedge[i + 1][j] = maxedge[i][j];
      } else {
        sparset[i + 1][j] = sparset[i][sparset[i][j]];
        maxedge[i + 1][j] = max(maxedge[i][j], maxedge[i][sparset[i][j]]);
      }
    }
  }
}
int getmaxedge(int a, int b) {
  int ret = -1;
  if (depth[a] > depth[b]) swap(a, b);
  for (int i = LOG; i >= 0; i -= 1) {
    if (sparset[i][b] != -1 && depth[sparset[i][b]] >= depth[a]) {
      ret = max(ret, maxedge[i][b]);
      b = sparset[i][b];
    }
  }
  if (a == b) return ret;
  for (int i = LOG; i >= 0; i -= 1) {
    if (sparset[i][a] != sparset[i][b]) {
      ret = max(ret, maxedge[i][a]);
      ret = max(ret, maxedge[i][b]);
      a = sparset[i][a];
      b = sparset[i][b];
    }
  }
  ret = max(ret, maxedge[0][a]);
  ret = max(ret, maxedge[0][b]);
  return ret;
}
void mst() {
  for (int i = 1; i <= n; i += 1) p[i] = i;
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; i++) {
    int a = edges[i].second.first;
    int b = edges[i].second.second;
    int c = edges[i].first;
    if (cek(a) != cek(b)) {
      p[cek(b)] = cek(a);
      lst[a].push_back(make_pair(b, c));
      lst[b].push_back(make_pair(a, c));
      mstcost += c;
      edgestaken++;
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= m; i += 1) {
    int a, b, c;
    cin >> a >> b >> c;
    edges.push_back(make_pair(c, make_pair(a, b)));
  }
  mst();
  for (int i = 1; i <= n; i += 1) {
    if (sparset[0][i] == 0) {
      depth[i] = 0;
      maxedge[0][i] = -1;
      dfs(i, -1);
    }
  }
  prec_sparse();
  cin >> q;
  for (int i = 1; i <= q; i += 1) {
    int a, b;
    cin >> a >> b;
    if (edgestaken == n - 1) {
      cout << mstcost - getmaxedge(a, b) << endl;
    } else if (edgestaken == n - 2) {
      if (cek(a) == cek(b))
        cout << -1 << endl;
      else
        cout << mstcost << endl;
    } else {
      cout << -1 << endl;
    }
  }
  return 0;
}
