#include <bits/stdc++.h>
#define FOR(i,l,r) for(int i = l ; i <= r ; i ++)
#define FORD(i,r,l) for(int i = r ; i >= l ; i --)
#define REP(i, a ) for(int i = 0 ; i < a ; i ++ )
#define compare(v) sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end());
#define ll long long
#define el "\n"
#define fi first
#define se second
#define _ROOT_ int main()
#define M 1000000007
#define MAXN 201001
#define INF (1ll<<60)
#define LOG 21
#define NAME "EXIT"
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;

ll n, m, k, x, q   ;
ll a[MAXN] ;
ll p[MAXN ] ;
ll d[MAXN] ;
ll high[MAXN ] ;
ll lab[MAXN ] ;
vector<pair<ll,ll> > adj_tree[MAXN ] ;
vector<pair<ll,ll> > adj[MAXN ] ;
vector<ll> spec ;

ll par[MAXN][LOG + 1 ] ;
ll mi[MAXN][LOG + 1 ] ;

ll find_set(ll a ) {
    return lab[a] < 0 ? a : lab[a] = find_set(lab[a]) ;
}
bool union_set(ll a, ll b ) {
    a = find_set(a) ;
    b = find_set(b) ;
    if(a == b ) return false ;
    if(lab[a] > lab[b]) swap(a, b) ;
    lab[a] += lab[b] ;
    lab[b] = a ;
    return true ;
}

struct Edge {
    ll u, v, w ;
    bool operator < (const Edge & other ) const {
        return w > other.w ;
    }
};
Edge edge[MAXN ] ;

bool Dijkstra( ) {
    FOR(i, 1, n ) d[i] = INF ;
    priority_queue<pair<ll,ll>, vector<pair<ll,ll>>, greater<pair<ll,ll>>> pq;
    for(ll i : spec ) {
        pq.push({0, i}) ;
        d[i] = 0 ;
    }
    while(!pq.empty() ) {
        pair<ll,ll> u = pq.top() ;
        pq.pop() ;
        if(d[u.se ] < u.fi ) continue ;
        for(auto [v, w ] : adj[u.se ]) if(d[v] > u.fi + w ) pq.push({d[v] = u.fi + w, v }) ;
    }
    FOR(i, 1, k ) if(d[p[i]] > x ) return false ;
    return true ;
}

ll query(ll u, ll v ) {
    if(u == v ) return d[u] ;
    if(high[u] < high[v]  ) swap(u, v) ;
    ll res = INF ;
    FORD(i, LOG, 0 ) if(high[par[u][i]] >= high[v] ) {
        res = min(res, mi[u][i] ) ;
        u = par[u][i] ;
    }
    if(u == v ) return res ;
    FORD(i, LOG, 0 )
    if(par[v][i] != par[u][i]) {
        res = min(res, mi[v][i]) ;
        res = min(res, mi[u][i]) ;
        u = par[u][i] ;
        v = par[v][i] ;
    }
    return min ( { res, mi[u][0], mi[v][0] } ) ;
}

void dfs(ll u, ll p ) {
    for(pair<ll,ll> v : adj_tree[u]) if(v.fi != p ) {
            par[v.fi][0] = u ;
            mi[v.fi][0] = v.se ;
            FOR(i, 1, LOG ) {
                par[v.fi][i] = par[ par[v.fi][i - 1]][i - 1 ] ;
                mi[v.fi][i] = min(mi[v.fi][i - 1], mi[par[v.fi][i - 1] ][i - 1 ] ) ;
            }
            high[v.fi] = high[u] + 1 ;
            dfs(v.fi, u ) ;

        }
}

void init() {
    cin >> n >> m  ;
    FOR(i, 1, m ) {
        ll u, v, w ;
        cin >> u >> v >> w ;
        edge[i] = {u, v, w } ;
        adj[u].push_back({ v, w }) ;
        adj[v].push_back({ u, w }) ;
    }
    cin >> k ;
    FOR(i, 1, k ) {
        ll x ;
        cin >> x ;
        spec.push_back(x) ;
    }
    cin >> q ;
}


void solve() {
    Dijkstra() ;
//    FOR(i , 1 , n ) debug(d[i]) ;
    FOR(i, 1, m ) edge[i].w = min(d[edge[i].u], d[edge[i].v ] ) ;

    memset(lab, - 1, sizeof lab ) ;
    sort(edge + 1, edge + m + 1 ) ;

    FOR(i, 1, m ) {
        if(union_set(edge[i].u, edge[i].v )) {
//            cout << edge[i].u << " " << edge[i].v << " " << edge[i].w << el ;
            adj_tree[edge[i].u].push_back({edge[i].v, edge[i].w }) ;
            adj_tree[edge[i].v].push_back({edge[i].u, edge[i].w }) ;
        }
    }
//    cout << " r" << el ;
    FOR(i, 0, n ) FOR(j, 0, LOG ) mi[i][j] = INF ;
    high[0] = - 1;
    dfs(1, 1 ) ;
    FOR(cnt, 1, q ) {
        ll u, v ;
        cin >> u >> v ;
        cout << query(u, v ) << el ;
    }
}

_ROOT_ {
    // freopen(NAME".inp" , "r" , stdin);
   //  freopen(NAME".out" , "w", stdout) ;
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1; // cin >> t ;
    while(t--) {
        init();
        solve();
    }
    return (0&0);
}
