This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <iostream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
using namespace std;
#define ll long long
#define sz(x) (int)x.size()
#define pii pair < int, int >
#define METH ios::sync_with_stdio(0); cin.tie(0);
#define BEGIN cout << "BEGIN" << endl;
#define END cout << "END" << endl;
const int N = 1e5 + 9;
const int mod = 1e9 + 7;															/// ANOTHER HASH MOD: 228228227
const int log = 20;															/// ANOTHER HASH MOD: 228228227
const int prime = 29;																	/// ANOTHER HASH PRIME: 997
const int INF = 1e9 + 7;
int used[N], anc[N][log], tout[N];
int n, m, k, q, boss[N], tin[N], tamer;
vector < int > dist(N, INF), ng[N];
vector < pii > g[N];
inline void read() {
	int a, b, c;
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		cin >> a >> b >> c;
		g[a].push_back({b, c});
		g[b].push_back({a, c});
	}
}
void dij() {
	priority_queue < pii > pq;
	cin >> k;
	int a;
	for (int i = 1; i <= k; i++) {
		cin >> a;
		pq.push({0, a});
		dist[a] = 0;
	}
	while (pq.size()) {
		int cur = pq.top().second;
		int d = -pq.top().first;
		pq.pop();
		if (d > dist[cur]) {
			continue;
		}
		for (pii i : g[cur]) {
			int u = i.first;
			int len = i.second;
			if (dist[cur] + len < dist[u]) {
				dist[u] = dist[cur] + len;
				pq.push({-dist[u], u});
			}
		}
	}
}
int get_par(int a) {
	if (a == boss[a]) {
		return a;
	}
	return boss[a] = get_par(boss[a]);
}
void connect(int a, int b) {
	a = get_par(a);
	b = get_par(b);
	if (a != b) {
		boss[a] = b;
	}
}
void dfs(int v, int p = 0) {
	tin[v] = ++tamer;
	anc[v][0] = p;
	for (int i = 1; i <= log; i++) {
		anc[v][i] = anc[anc[v][i - 1]][i - 1];
	}
	for (int i : ng[v]) {
		if (i == p) {
			continue;
		}
		dfs(i, v);
	}
	tout[v] = tamer;
}
void build_tree() {
	vector < pii > temp;
	for (int i = 1; i <= n; i++) {
		temp.push_back({dist[i], i});
		boss[i] = i;
	}
	sort(temp.begin(), temp.end(), greater < pii >());
	int last = 0;
	for (pii i : temp) {
		int a = i.second;
		used[a] = 1;
		last = a;
		for (pii j : g[a]) {
			int b = j.first;
			if (used[b]) {
				b = get_par(b);
				if (a != b) {
					connect(b, a);
					ng[a].push_back(b);
					ng[b].push_back(a);
				}
			}
		}
	}
	dfs(last);
}
bool upper(int a, int b) {
	return tin[a] <= tin[b] && tout[a] >= tout[b];
}
int get_lca(int a, int b) {
	if (upper(a, b)) {
		return a;
	}
	if (upper(b, a)) {
		return b;
	}
	for (int i = log; i >= 0; i--) {
		if (!upper(anc[a][i], b) && anc[a][i]) {
			a = anc[a][i];
		}
	}
	return anc[a][0];
}
inline void solve() {
	dij();
	build_tree();
	cin >> q;
	for (int i = 1; i <= q; i++) {
		int s, t; scanf("%d %d", &s, &t);
		int lca = get_lca(s, t);
		cout << dist[lca] << endl;
	}
}
int main() {
	int t = 1;
	while (t--) {
		read();
		solve();
	}
}
Compilation message (stderr)
plan.cpp: In function 'void solve()':
plan.cpp:158:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   int s, t; scanf("%d %d", &s, &t);
             ~~~~~^~~~~~~~~~~~~~~~~
plan.cpp: In function 'void dfs(int, int)':
plan.cpp:88:13: warning: iteration 19 invokes undefined behavior [-Waggressive-loop-optimizations]
   anc[v][i] = anc[anc[v][i - 1]][i - 1];
   ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
plan.cpp:87:20: note: within this loop
  for (int i = 1; i <= log; i++) {
                  ~~^~~~~~| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |