#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<numeric>
#include<string>
#include<stack>
#include<queue>
#include<string.h>
#include<array>
#include<climits>
#include<algorithm>
#include<cmath>
using namespace std;
#define ff first
#define ss second
#define int long long
#define pb push_back
#define endl '\n'
const int maxn = 1e5 + 2;
const int Mx = 1e12;
const int oo = 1e18;
const int LG = 20;
int dist[maxn];
vector<pair<int, int>> tree[maxn];
vector<pair<int, int>> g[maxn];
int n, m;
int up[maxn][LG];
int mn[maxn][LG];
int depth[maxn];
struct Edge{
int u, v, w;
};
vector<Edge> edges;
void dijkstra(vector<int>& npp){
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
for(int i = 1; i <= n; i++){
dist[i] = oo;
}
for(auto v : npp){
dist[v] = 0;
pq.push({0, v});
}
while(!pq.empty()){
auto T = pq.top();
pq.pop();
int d = T.ff;
int v = T.ss;
if(d > dist[v]) continue;
for(auto f : g[v]){
int x = f.ff;
int y = f.ss;
if(dist[v] + y < dist[x]){
dist[x] = dist[v] + y;
pq.push({dist[x], x});
}
}
}
}
vector<int> p;
vector<int> sz;
int find(int u){
if(u == p[u]) return u;
return p[u] = find(p[u]);
}
bool unite(int u, int v){
int a = find(u);
int b = find(v);
if(a == b) return false;
if(sz[a] < sz[b]) swap(a, b);
sz[a] += sz[b];
p[b] = a;
return true;
}
void build_mst(int n){
p.resize(n + 1);
sz.resize(n + 1);
for(int i = 1; i <= n; i++){
p[i] = i;
sz[i] = 1;
}
sort(edges.begin(), edges.end(),
[](Edge a, Edge b){
return a.w > b.w;
}
);
for(auto e : edges){
if(unite(e.u, e.v)){
tree[e.u].push_back({e.v, e.w});
tree[e.v].push_back({e.u, e.w});
}
}
}
void dfs(int v, int p, int w){
up[v][0] = p;
mn[v][0] = w;
for(auto t : tree[v]){
if(t.ff == p) continue;
depth[t.ff] = depth[v] + 1;
dfs(t.ff, v, t.ss);
}
}
void build_lca(){
for(int j = 1; j < LG; j++){
for(int i = 1; i <= n; i++){
up[i][j] = up[up[i][j - 1]][j - 1];
mn[i][j] = min(mn[i][j - 1], mn[up[i][j - 1]][j - 1]);
}
}
}
int query(int u, int v){
int ans = (int)1e18;
if(depth[u] < depth[v]) swap(u, v);
for(int i = LG - 1; i >= 0; i--){
if(depth[u] - (1 << i) >= depth[v]){
ans = min(ans, mn[u][i]);
u = up[u][i];
}
}
if(u == v) return ans;
for(int i = LG - 1; i >= 0; i--){
if(up[u][i] != up[v][i]){
ans = min(ans, mn[u][i]);
ans = min(ans, mn[v][i]);
u = up[u][i];
v = up[v][i];
}
}
ans = min(ans, mn[u][0]);
ans = min(ans, mn[v][0]);
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for(int i = 0; i < m; i++){
int u, v, w;
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
}
int k;
cin >> k;
vector<int> npp(k);
for(int i = 0; i < k; i++){
cin >> npp[i];
}
dijkstra(npp);
for(int i = 1; i <= n; i++){
for(auto t : g[i]){
if(i < t.ff){
int nw = min(dist[i], dist[t.ff]);
edges.pb({i, t.ff, nw});
}
}
}
build_mst(n);
depth[1] = 0;
dfs(1, 0, 1e18);
build_lca();
int T;
cin >> T;
while(T--){
int a, b;
cin >> a >> b;
cout << query(a, b) << endl;
}
}