#include <algorithm>
#include <cassert>
#include <cfloat>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
 
#define FOR(i,k,n) for (int (i)=(k); (i)<(n); ++(i))
#define rep(i,n) FOR(i,0,n)
#define all(v) begin(v), end(v)
#define debug(x) cerr<< #x <<": "<<x<<endl
#define debug2(x,y) cerr<< #x <<": "<< x <<", "<< #y <<": "<< y <<endl
 
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<ll> vll;
typedef vector<vector<ll> > vvll;
typedef deque<bool> db;
template<class T> using vv=vector<vector< T > >;

class UF {
private:
  vector<int> data; // parent or size
  vector<int> next;
  vector<int> last;
  void init(int n) {
    data.assign(n, -1);
    next.assign(n, -1);
    last.resize(n);
    for (int i = 0; i < n; ++i) {
      last[i] = i;
    }
  }

public:
  UF() {}
  UF(int n) {
    init(n);
  }
  int root(int x) {
    if (data[x] < 0) return x;
    return data[x] = root(data[x]);
  }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (data[x] > data[y]) swap(x, y); // data[x] and data[y] are negative.
    data[x] += data[y];
    data[y] = x;
    next[last[x]] = y;
    last[x] = last[y];
    return true;
  }
  int size(int x) {
    return -data[root(x)];
  }
  bool same(int x, int y) {
    return root(x) == root(y);
  }
  int get_next(int x) {
    return next[x];
  }
};

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  vvi edge(m, vi(3));
  rep (i, m) {
    scanf("%d%d%d", &edge[i][1], &edge[i][2], &edge[i][0]);
    edge[i][1] -= 1; edge[i][2] -= 1;
  }
  sort(all(edge));
  UF uf(n);
  vvi maxcost(n, vi(n));
  ll cost = 0;
  cost += edge[0][0];
  uf.unite(edge[0][1], edge[0][2]);
  maxcost[edge[0][1]][edge[0][2]] = maxcost[edge[0][2]][edge[0][1]] = edge[0][0];
  FOR (i, 1, m) {
    int x = edge[i][1];
    int y = edge[i][2];
    if (!(uf.same(x, y))) {
      cost += edge[i][0];
      for (int j = uf.root(x); j != -1; j = uf.get_next(j)) {
        for (int k = uf.root(y); k != -1; k = uf.get_next(k)) {
          maxcost[j][k] = maxcost[k][j] = edge[i][0];
        }
      }
      uf.unite(x, y);
    }
  }
 
  int q;
  cin >> q;
  vll ans(q, 0);
  rep (j, q) {
    int s, t;
    cin >> s >> t;
    s -= 1; t -= 1;
    ans[j] = cost - maxcost[s][t];
  }
  rep (i, q) {
    printf("%lld\n", ans[i]);
  }
 
  return 0;
}

### Prompt

In Cpp, your task is to solve the following problem:

Takahashi found an undirected connected graph with N vertices and M edges. The vertices are numbered 1 through N. The i-th edge connects vertices a_i and b_i, and has a weight of c_i.

He will play Q rounds of a game using this graph. In the i-th round, two vertices S_i and T_i are specified, and he will choose a subset of the edges such that any vertex can be reached from at least one of the vertices S_i or T_i by traversing chosen edges.

For each round, find the minimum possible total weight of the edges chosen by Takahashi.

Constraints

* 1 ≦ N ≦ 4,000
* 1 ≦ M ≦ 400,000
* 1 ≦ Q ≦ 100,000
* 1 ≦ a_i,b_i,S_i,T_i ≦ N
* 1 ≦ c_i ≦ 10^{9}
* a_i \neq b_i
* S_i \neq T_i
* The given graph is connected.

Input

The input is given from Standard Input in the following format:


N M
a_1 b_1 c_1
a_2 b_2 c_2
:
a_M b_M c_M
Q
S_1 T_1
S_2 T_2
:
S_Q T_Q


Output

Print Q lines. The i-th line should contain the minimum possible total weight of the edges chosen by Takahashi.

Examples

Input

4 3
1 2 3
2 3 4
3 4 5
2
2 3
1 4


Output

8
7


Input

4 6
1 3 5
4 1 10
2 4 6
3 2 2
3 4 5
2 1 3
1
2 3


Output

8

### Response

```cpp
#include <algorithm>
#include <cassert>
#include <cfloat>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
 
#define FOR(i,k,n) for (int (i)=(k); (i)<(n); ++(i))
#define rep(i,n) FOR(i,0,n)
#define all(v) begin(v), end(v)
#define debug(x) cerr<< #x <<": "<<x<<endl
#define debug2(x,y) cerr<< #x <<": "<< x <<", "<< #y <<": "<< y <<endl
 
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<ll> vll;
typedef vector<vector<ll> > vvll;
typedef deque<bool> db;
template<class T> using vv=vector<vector< T > >;

class UF {
private:
  vector<int> data; // parent or size
  vector<int> next;
  vector<int> last;
  void init(int n) {
    data.assign(n, -1);
    next.assign(n, -1);
    last.resize(n);
    for (int i = 0; i < n; ++i) {
      last[i] = i;
    }
  }

public:
  UF() {}
  UF(int n) {
    init(n);
  }
  int root(int x) {
    if (data[x] < 0) return x;
    return data[x] = root(data[x]);
  }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (data[x] > data[y]) swap(x, y); // data[x] and data[y] are negative.
    data[x] += data[y];
    data[y] = x;
    next[last[x]] = y;
    last[x] = last[y];
    return true;
  }
  int size(int x) {
    return -data[root(x)];
  }
  bool same(int x, int y) {
    return root(x) == root(y);
  }
  int get_next(int x) {
    return next[x];
  }
};

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  vvi edge(m, vi(3));
  rep (i, m) {
    scanf("%d%d%d", &edge[i][1], &edge[i][2], &edge[i][0]);
    edge[i][1] -= 1; edge[i][2] -= 1;
  }
  sort(all(edge));
  UF uf(n);
  vvi maxcost(n, vi(n));
  ll cost = 0;
  cost += edge[0][0];
  uf.unite(edge[0][1], edge[0][2]);
  maxcost[edge[0][1]][edge[0][2]] = maxcost[edge[0][2]][edge[0][1]] = edge[0][0];
  FOR (i, 1, m) {
    int x = edge[i][1];
    int y = edge[i][2];
    if (!(uf.same(x, y))) {
      cost += edge[i][0];
      for (int j = uf.root(x); j != -1; j = uf.get_next(j)) {
        for (int k = uf.root(y); k != -1; k = uf.get_next(k)) {
          maxcost[j][k] = maxcost[k][j] = edge[i][0];
        }
      }
      uf.unite(x, y);
    }
  }
 
  int q;
  cin >> q;
  vll ans(q, 0);
  rep (j, q) {
    int s, t;
    cin >> s >> t;
    s -= 1; t -= 1;
    ans[j] = cost - maxcost[s][t];
  }
  rep (i, q) {
    printf("%lld\n", ans[i]);
  }
 
  return 0;
}

```