#include "bits/stdc++.h"
using namespace std;
#define int long long
const int mod = 1e9 + 7;
const int N = 1e5 + 100;
#define ll long long
struct DSU {
vector<int> rank, parent, size;
DSU(int n) {
size = rank = parent = vector<int>(n + 1, 1);
for (int i = 0; i <= n; i++) {
parent[i] = i;
}
}
int find_set(int v) {
return v == parent[v] ? v : parent[v] = find_set(parent[v]);
}
void link(int par, int node) {
parent[node] = par;
size[par] += size[node];
if (rank[par] == rank[node])
rank[par]++;
}
bool union_sets(int v, int u) {
v = find_set(v), u = find_set(u);
if (v != u) {
if (rank[v] < rank[u])swap(v, u);
link(v, u);
}
return v != u;
}
bool same_set(int v, int u) {
return find_set(v) == find_set(u);
}
int size_set(int v) {
return size[find_set(v)];
}
};
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, m;
cin >> n >> m;
vector<vector<pair<int, int>>> adj(n + 1);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
vector<int> dis(n + 2, LLONG_MAX);
vector<pair<int, int>> arr(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});
}
int k;
cin >> k;
for (int i = 0; i < k; i++) {
int x;
cin >> x;
dis[x] = 0;
pq.emplace(0, x);
}
while (!pq.empty()) {
auto [c, u] = pq.top();
pq.pop();
if (c > dis[u]) continue;
for (auto& it: adj[u]) {
int nc = it.second + c;
if (dis[it.first] > nc) {
dis[it.first] = nc;
pq.emplace(nc, it.first);
}
}
}
for (int i = 1; i <= n; i++) {
arr[i] = {dis[i], i};
}
int q;
cin >> q;
vector<array<int, 3>> queries(q + 1);
vector<int> ans(q + 1), l(q + 1), r(q + 1);
for (int i = 1; i <= q; i++) {
cin >> queries[i][0] >> queries[i][1];
queries[i][2] = i;
l[i] = 1, r[i] = n;
}
sort(arr.rbegin(), arr.rend() - 1);
for (auto& it: arr) {
cout << it.first << " "<< it.second << endl;
}
cout << endl;
bool f = 1;
while (f) {
f = 0;
vector<int> mids[n + 1];
for (int i = 1; i <= q; i++) {
if (l[i] <= r[i]) {
f = 1;
mids[(l[i] + r[i]) >> 1].push_back(i);
}
}
DSU dsu(n);
vector<int> vis(n + 1);
for (int i = 1; i <= n; i++) {
int cost = arr[i].first;
int node = arr[i].second;
for (auto& it: adj[node]) {
if (!vis[it.first]) continue;
cout << node << " "<< it.first << endl;
dsu.union_sets(node, it.first);
}
for (auto& it: mids[i]) {
int x = queries[it][0];
int y = queries[it][1];
int idx = queries[it][2];
if (dsu.same_set(x, y)) {
r[it] = i - 1;
ans[idx] = i;
}else {
l[it] = i + 1;
}
}
vis[node] = 1;
}
}
for (int i = 1; i <= q; i++) {
int id = ans[i];
cout << arr[id].first << '\n';
}
return 0;
}