#include <bits/stdc++.h>
#define all(v) begin(v), end(v)
#define dbg(x) "[" #x " = " << x << "]"
#define ii pair<int, long long>
#define fi first
#define se second
#define siz(v) (int)(v).size()
#define lli pair<long long, int>
#define BIT(x, i) (((x) >> (i)) & 1)
using namespace std;
const int infINT = 1e9 + 1323;
const long long inf = 1e18 + 123123;
template<class X, class Y> bool minimize(X &x, const Y &y){return x > y ? x = y, 1: 0;}
template<class X, class Y> bool maximize(X &x, const Y &y){return x < y ? x = y, 1: 0;}
struct E{
int u, v;
long long w;
E(int _u = 0, int _v = 0, long long _w = 0):
u(_u), v(_v), w(_w) {};
bool operator <(const E &other) const{
return w > other.w;
}
};
struct dsu{
int n;
vector<int > par, sz;
dsu(int _n = 0): n(_n){
par.assign(n + 1, 0);
sz.assign(n + 1, 1);
for(int i = 1; i <= n; i++) par[i] = i;
}
int root(int v){
return v == par[v] ? v: par[v] = root(par[v]);
}
bool join(int u, int v){
u = root(u), v = root(v);
if (u == v) return 0;
if (sz[u] < sz[v]) swap(u, v);
par[v] = u; sz[u] += sz[v];
return 1;
}
};
const int MAXN = 1e5 + 5, MAXM = 2e5 + 5, LOG = 18;
int numNode, numEdge, numDanger, numQuery, danger[MAXN], up[LOG][MAXN], h[MAXN];
long long dist[MAXN], minVal[LOG][MAXN];
E edge[MAXN];
vector<ii > adj[MAXN];
void input(){
cin >> numNode >> numEdge;
for(int i = 1; i <= numEdge; i++){
int u, v, w; cin >> u >> v >> w;
adj[u].emplace_back(v, w);
adj[v].emplace_back(u, w);
edge[i] = E(u, v, w);
}
cin >> numDanger;
for(int i = 1; i <= numDanger; i++) cin >> danger[i];
}
void dijsktra(){
priority_queue<lli, vector<lli>, greater<lli > > q;
memset(dist, 0x3f, sizeof dist);
for(int i = 1; i <= numDanger; i++){
q.emplace(dist[danger[i]] = 0, danger[i]);
}
while(siz(q)){
int u = q.top().se;
long long len = q.top().fi;
q.pop();
if (len > dist[u]) continue;
for(ii x: adj[u]){
int v = x.fi, w = x.se;
if (minimize(dist[v], dist[u] + w)) q.emplace(dist[v], v);
}
}
}
void dfs(int u, int par = 0){
for(ii x: adj[u]) if (x.fi != par) {
int v = x.fi;
long long w = x.se;
up[0][v] = u;
minVal[0][v] = w;
for(int i = 1; i < LOG; i++){
up[i][v] = up[i - 1][up[i - 1][v]];
minVal[i][v] = min(minVal[i - 1][v], minVal[i - 1][up[i - 1][v]]);
}
h[v] = h[u] + 1;
dfs(v, u);
}
}
long long getMin(int u, int v){
if (h[u] < h[v]) swap(u, v);
int k = h[u] - h[v];
long long mi = dist[u];
for(int i = LOG - 1; i >= 0; i--) if (BIT(k, i)) {
mi = min(mi, minVal[i][u]);
u = up[i][u];
}
if (u == v) return mi;
for(int i = LOG - 1; i >= 0; i--) if (up[i][u] != up[i][v]){
mi = min(mi, min(minVal[i][u], minVal[i][v]));
u = up[i][u]; v = up[i][v];
}
mi = min(mi, min(minVal[0][u], minVal[0][v]));
return mi;
}
void solve(){
dijsktra();
for(int u = 1; u <= numNode; u++){
adj[u].clear();
}
for(int i = 1; i <= numEdge; i++){
int &u = edge[i].u, &v = edge[i].v;
long long &w = edge[i].w;
w = min(dist[u], dist[v]);
}
sort(edge + 1, edge + 1 + numEdge);
dsu mySet(numNode);
for(int i = 1; i <= numEdge; i++){
int &u = edge[i].u, &v = edge[i].v;
long long &w = edge[i].w;
if (mySet.join(u, v)){
adj[u].emplace_back(v, w);
adj[v].emplace_back(u, w);
}
}
dfs(1);
cin >> numQuery;
for(int q = 1; q <= numQuery; q++){
int sta, fin; cin >> sta >> fin;
cout << getMin(sta, fin) << '\n';
}
}
bool M1;
bool M2;
signed main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define task "EXIT"
if (fopen(task".inp", "r")){
freopen(task".inp", "r", stdin);
freopen(task".out", "w", stdout);
}
input();
solve();
cerr << (&M2 - &M1) / 1048576 << " mb\n";
cerr << (1.0 * clock()) / CLOCKS_PER_SEC << ".s\n";
}