Problem:
Score : 700 points

Problem Statement

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.

Partial Scores

In the test set worth 200 points, Q = 1.

In the test set worth another 300 points, Q ≦ 3000.

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.

Sample Input 1

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

Sample Output 1

8
7

We will examine each round:

In the 1-st round, choosing edges 1 and 3 achieves the minimum total weight of 8.

In the 2-nd round, choosing edges 1 and 2 achieves the minimum total weight of 7.

Sample Input 2

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

Sample Output 2

8

This input satisfies the additional constraints for both partial scores.

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		
		List<int>[] E = new List<int>[N];
		for(int i=0;i<N;i++) E[i] = new List<int>();
		
		Pair[] P = new Pair[M];
		for(int i=0;i<M;i++){
			P[i] = new Pair(i, C[i]);
		}
		
		Array.Sort(P, (p, q) => p.Cost.CompareTo(q.Cost));
		
		var UF = new UnionFind(N);
		long totalCost = 0;
		for(int i=0;i<M;i++){
			int a = A[P[i].Idx];
			int b = B[P[i].Idx];
			if(UF.IsUnited(a, b)) continue;
			UF.Unite(a, b);
			E[a].Add(P[i].Idx);
			E[b].Add(P[i].Idx);
			totalCost += C[P[i].Idx];
		}
		
		long[][] maxBottle = new long[N][];
		for(int i=0;i<N;i++){
			maxBottle[i] = new long[N];
			for(int j=0;j<N;j++) maxBottle[i][j] = -1;
		}
		
		for(int i=0;i<N;i++){
			var q = new Queue<int>();
			q.Enqueue(i);
			maxBottle[i][i] = 0;
			while(q.Count > 0){
				var now = q.Dequeue();
				foreach(var nidx in E[now]){
					int nxt = A[nidx] == now ? B[nidx] : A[nidx];
					long cost = C[nidx];
					if(maxBottle[i][nxt] != -1) continue;
					maxBottle[i][nxt] = Math.Max(maxBottle[i][now], cost);
					q.Enqueue(nxt);
				}
			}
		}
		
		var sb = new StringBuilder();
		for(int i=0;i<Q;i++){
			sb.AppendLine((totalCost - maxBottle[S[i]][T[i]]).ToString());
		}
		Console.Write(sb.ToString());
		
	}
	int N,M;
	int[] A,B;
	long[] C;
	
	int Q;
	int[] S,T;
	public Sol(){
		
		var d = ria();
		N = d[0]; M = d[1];
		A = new int[M];
		B = new int[M];
		C = new long[M];
		for(int i=0;i<M;i++){
			d = ria();
			A[i] = d[0] - 1;
			B[i] = d[1] - 1;
			C[i] = d[2];
		}
		
		Q = ri();
		
		S = new int[Q];
		T = new int[Q];
		for(int i=0;i<Q;i++){
			d = ria();
			S[i] = d[0] - 1;
			T[i] = d[1] - 1;
		}
		
		
		
		
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}

class Pair{
	public int Idx;
	public long Cost;
	public Pair (int idx, long cost){
		Idx = idx; Cost = cost;
	}
}
class UnionFind{
	
	int[] parent;
	int[] mem;
	int compo;
	int N;
	public UnionFind(int n_){
		Initialize(n_);
	}
	
	public void Initialize(int n_){
		N=n_;
		parent=new int[N];
		mem=new int[N];
		for(int i=0;i<N;i++){
			parent[i]=i;
			mem[i]=1;
		}
		compo=N;
	}
	
	public int Parent(int a){
		if(parent[a]==a)return a;
		return parent[a]=Parent(parent[a]);
	}
	
	public bool IsUnited(int a,int b){
		return Parent(a) == Parent(b);
	}
	
	public void Unite(int a,int b){
		a=Parent(a);b=Parent(b);
		if(a==b)return;
		parent[a]=b;
		mem[b]+=mem[a];
		compo-=1;
	}
	
	public bool IsRoot(int x){
		return x==parent[x];
	}
	public int MemCnt(int x){
		return mem[Parent(x)];
	}
	
	public void Dump(){
		for(int i=0;i<parent.Length;i++){
			Console.Write(i==0?"{0}":" {0}",parent[i]);
		}
		Console.WriteLine("");
	}
	
	public int Compo{
		get{
			return compo;
		}
	}
	
}