#define _USE_MATH_DEFINES
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
int dx2[] = {1, -1, 0, 0, -1, 1, -1, 1};
int dy2[] = {0, 0, 1, -1, 1, 1, -1, -1};
int knightX[] = {-2, -2, 2, 2, 1, 1, -1, -1};
int knightY[] = {-1, 1, -1, 1, -2, 2, -2, 2};
const ll INF = 2e18;
const int N = 1e6 + 10, K = 100 + 10, LOG = 20;
const ll MOD = 1e9 + 7;
struct DSU {
vector<ll> f, siz, points;
DSU() {}
DSU(int n) {
init(n + 1);
}
void init(int n) {
f.resize(n);
points.resize(n, 0);
iota(f.begin(), f.end(), 0);
siz.assign(n, 1);
}
int leader(int x) {
if(x == f[x]){
return f[x];
}
return f[x] = leader(f[x]);
}
bool same(int x, int y) {
return leader(x) == leader(y);
}
bool merge(int x, int y) {
x = leader(x);
y = leader(y);
if (x == y) {
return false;
}
if (siz[x] < siz[y]) {
swap(x , y);
}
points[y] -= points[x];
siz[x] += siz[y];
f[y] = x;
return true;
}
void add(int u, ll val){
points[leader(u)] += val;
}
ll get(int u){
if(f[u] == u){
return points[u];
}
return points[u] + get(f[u]);
}
int size(int x) {
return siz[leader(x)];
}
};
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int t = 1;
// cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<array<int, 3>> ed;
vector<vector<pair<int, int>>> adj(n + 1);
for(int i = 0; i < m; i++){
int u, v, w;
cin >> u >> v >> w;
adj[u].push_back({v, w});
adj[v].push_back({u, w});
ed.push_back({u, v, w});
}
vector<ll> dis(n + 1, INF);
priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;
int k;
cin >> k;
for(int i = 0; i < k; i++){
int x;
cin >> x;
dis[x] = 0;
pq.push({0, x});
}
while(!pq.empty()){
auto [cur, u] = pq.top();
pq.pop();
if(cur != dis[u]){
continue;
}
for(auto &[v, w] : adj[u]){
ll ndis = w + dis[u];
if(dis[v] > ndis){
dis[v] = ndis;
pq.push({ndis, v});
}
}
}
for(auto &[u, v, w] : ed){
w = min(dis[u], dis[v]);
}
sort(ed.begin(), ed.end(), [&](auto& a, auto& b){
return a[2] > b[2];
});
vector<vector<int>> tree(2 * n + 1);
vector<ll> val(2 * n + 1);
DSU d(2 * n);
int cur = n;
for(auto &[u, v, w] : ed){
u = d.leader(u), v = d.leader(v);
if(u == v){
continue;
}
int neww = ++cur;
val[neww] = w;
tree[neww].push_back(u);
tree[neww].push_back(v);
d.f[u] = neww;
d.f[v] = neww;
d.siz[neww] = d.siz[u] + d.siz[v];
}
int timer = 0;
vector<vector<int>> up(LOG, vector<int>(cur + 1));
vector<int> in(cur + 1), out(cur + 1), dep(cur + 1);
auto dfs = [&](auto&& self, int u, int p) -> void{
in[u] = ++timer;
up[0][u] = p;
for(int i = 1; i < LOG; i++){
up[i][u] = up[i - 1][up[i - 1][u]];
}
for(auto &i : tree[u]){
if(i != p){
dep[i] = dep[u] + 1;
self(self, i, u);
}
}
out[u] = timer;
};
int r = d.leader(1);
dfs(dfs, r, r);
auto is_ans = [&](int u, int v){
return in[u] <= in[v] && out[u] >= out[v];
};
auto lca = [&](int u, int v){
if(is_ans(u, v)){
return u;
}
if(is_ans(v, u)){
return v;
}
if(dep[u] < dep[v]){
swap(u, v);
}
int cur = dep[u] - dep[v];
for(int i = 0; i < LOG; i++){
if(cur >> i & 1){
u = up[i][u];
}
}
if(u == v){
return u;
}
for(int i = LOG - 1; i >= 0; i--){
if(up[i][u] != up[i][v]){
u = up[i][u];
v = up[i][v];
}
}
return up[0][u];
};
int q;
cin >> q;
while(q--){
int u, v;
cin >> u >> v;
cout << val[lca(u, v)] << endl;
}
}
return 0;
}