#include <bits/stdc++.h>
using namespace std;
int read() {
  int ret = 0;
  char c = getchar();
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') {
    ret = ret * 10 + c - '0';
    c = getchar();
  }
  return ret;
}
const int LOG = 20;
const int MAXN = 100000, MAXM = 200000;
int Log[MAXN + 10];
void buildLog(int first) {
  for (int i = 1, a = -1, b = 1; i <= first; i++) {
    if (i == b) {
      a++;
      b <<= 1;
    }
    Log[i] = a;
  }
  return;
}
int n, m;
namespace Tree {
int m;
pair<int, int> front[(MAXN << 1) + 10];
int orderx[(MAXN << 1) + 10], stdx[MAXN + 10];
void sortx() {
  static int num[MAXN + 10];
  memset(num, 0, sizeof(num));
  for (int i = 1; i <= m; i++) num[front[i].first]++;
  for (int i = 1; i <= n; i++) stdx[i] = num[i] += num[i - 1];
  for (int i = 1; i <= m; i++) orderx[++num[front[i].first - 1]] = i;
  return;
}
int cost[(MAXN << 1) + 10];
void addedge(int first, int second, int c) {
  front[++m] = make_pair(first, second);
  cost[m] = c;
  front[++m] = make_pair(second, first);
  cost[m] = c;
  return;
}
int D[LOG + 5][MAXN + 10];
int f[LOG + 5][MAXN + 10];
int dep[MAXN + 10];
int up(int first, int step) {
  while (step) {
    int nxt = Log[step];
    first = f[nxt][first];
    step -= (1 << nxt);
  }
  return first;
}
int lca(int first, int second) {
  if (dep[first] > dep[second])
    first = up(first, dep[first] - dep[second]);
  else
    second = up(second, dep[second] - dep[first]);
  int d = Log[dep[first]];
  while (first != second) {
    while (d >= 0 && f[d][first] == f[d][second]) d--;
    if (d == -1) return f[0][first];
    first = f[d][first];
    second = f[d][second];
  }
  return first;
}
int dis(int first, int second) {
  int ret = 0, d = Log[dep[first]];
  while (first != second) {
    while (!f[d][first] || dep[f[d][first]] < dep[second]) d--;
    ret = ((ret) > (D[d][first]) ? (ret) : (D[d][first]));
    first = f[d][first];
  }
  return ret;
}
bool vis[MAXN + 10];
void dfs(int pre, int first) {
  for (int i = 1; f[i - 1][first]; i++) {
    f[i][first] = f[i - 1][f[i - 1][first]];
    D[i][first] = ((D[i - 1][first]) > (D[i - 1][f[i - 1][first]])
                       ? (D[i - 1][first])
                       : (D[i - 1][f[i - 1][first]]));
  }
  vis[first] = true;
  for (int i = stdx[first - 1] + 1; i <= stdx[first]; i++) {
    int next = front[orderx[i]].second;
    if (next != pre) {
      dep[next] = dep[first] + 1;
      f[0][next] = first;
      D[0][next] = cost[orderx[i]];
      dfs(first, next);
    }
  }
  return;
}
void build() {
  sortx();
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs(-1, i);
  return;
}
}  // namespace Tree
struct Edge {
  int u, v, cost;
  bool operator<(const Edge &R) const { return cost < R.cost; }
} p[MAXM + 10];
int fa[MAXN + 10];
int find(int first) {
  if (!fa[first]) return first;
  return fa[first] = find(fa[first]);
}
void init() {
  n = read();
  buildLog(n);
  m = read();
  for (int i = 1; i <= m; i++) {
    p[i].u = read();
    p[i].v = read();
    p[i].cost = read();
  }
  sort(p + 1, p + m + 1);
  int cnt = n;
  long long ans = 0;
  for (int i = 1; i <= m; i++) {
    int first = find(p[i].u), second = find(p[i].v);
    if (first != second) {
      ans += p[i].cost;
      fa[first] = second;
      cnt--;
      Tree::addedge(p[i].u, p[i].v, p[i].cost);
    }
  }
  Tree::build();
  int q = read();
  while (q--) {
    int first = read(), second = read();
    if (cnt > 2)
      puts("-1");
    else if (cnt == 2) {
      if (find(first) == find(second))
        puts("-1");
      else
        printf("%I64d\n", ans);
    } else {
      int lca = Tree::lca(first, second);
      printf("%I64d\n",
             ans - ((Tree::dis(first, lca)) > (Tree::dis(second, lca))
                        ? (Tree::dis(first, lca))
                        : (Tree::dis(second, lca))));
    }
  }
  return;
}
int main() {
  init();
  return 0;
}
