#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
#define pb push_back
#define pii pair<int, int>
#define pll pair<ll, ll>
#define st first
#define nd second
#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
#define debug 0
const int MAXN = 2000 + 17;
const int MAXL = 100 * 1000 + 17;
const ll INF = ll(1000 * 1000 * 1000) * ll(1000 * 1000 * 1000);
vector<pair<int, ll>> graf[MAXN];
ll odl[MAXN][2];
int wej[MAXN][2];
int ile1[MAXN];
int ile2[MAXN];
bool byl[MAXN][MAXN];
priority_queue<pair<ll, pii>> pq;
int X[MAXL];
vector<pair<ll, pii>> vec[MAXN][MAXN];
vector<pair<ll, pii>> baza[MAXN][MAXN];
vector<pair<ll, pii>> st[4 * MAXL];
int n;
void djikstra (int s, int k, ll sd) {
for (int i = 1; i <= n; i ++) {
odl[i][0] = INF;
odl[i][1] = INF;
}
odl[s][0] = sd;
wej[s][0] = k;
pq.push({-odl[s][0], {s, 0}});
while (!pq.empty()) {
pii v = pq.top().nd;
ll d = pq.top().st;
d *= (-1LL);
pq.pop();
if (odl[v.st][v.nd] < d) {
continue;
}
for (auto x : graf[v.st]) {
if (x.st == wej[v.st][v.nd]) {
continue;
}
if (odl[x.st][0] > d + x.nd) {
swap(odl[x.st][0], odl[x.st][1]);
swap(wej[x.st][0], wej[x.st][1]);
odl[x.st][0] = d + x.nd;
wej[x.st][0] = v.st;
pq.push({-odl[x.st][0], {x.st, 0}});
pq.push({-odl[x.st][1], {x.st, 1}});
} else if (wej[x.st][0] != v.st && odl[x.st][1] > d + x.nd) {
odl[x.st][1] = d + x.nd;
wej[x.st][1] = v.st;
pq.push({-odl[x.st][1], {x.st, 1}});
}
}
}
}
vector<pair<ll, pii>> lacz (vector<pair<ll, pii>> l, vector<pair<ll, pii>> r) {
vector<pair<ll, pii>> wyn = {};
for (auto x : l) {
for (auto y : r) {
if (x.nd.nd != y.nd.st) {
wyn.pb({min(INF, x.st + y.st), {x.nd.st, y.nd.nd}});
}
}
}
sort(wyn.begin(), wyn.end());
vector<pair<ll, pii>> wyn2 = {};
for (auto x : wyn) {
if (ile1[x.nd.st] <= 1 && ile2[x.nd.nd] <= 1 && !byl[x.nd.st][x.nd.nd]) {
wyn2.pb(x);
ile1[x.nd.st] ++;
ile2[x.nd.nd] ++;
byl[x.nd.st][x.nd.nd] = 1;
}
if (int(wyn2.size()) == 5) {
break;
}
}
for (auto x : wyn) {
ile1[x.nd.st] = 0;
ile2[x.nd.nd] = 0;
byl[x.nd.st][x.nd.nd] = 0;
}
return wyn2;
}
void buduj (int p, int k, int i) {
if (p == k) {
st[i] = baza[X[p]][X[p + 1]];
return;
}
int sr = (p + k)/ 2;
buduj(p, sr, i * 2);
buduj(sr + 1, k, i * 2 + 1);
st[i] = lacz(st[i * 2], st[i * 2 + 1]);
}
void aktualizuj (int p, int k, int ind, int i) {
if (p > ind || k < ind) {
return;
}
if (p == k) {
st[i] = baza[X[p]][X[p + 1]];
return;
}
int sr = (p + k)/ 2;
aktualizuj(p, sr, ind, i * 2);
aktualizuj(sr + 1, k, ind, i * 2 + 1);
st[i] = lacz(st[i * 2], st[i * 2 + 1]);
}
int main () {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int M, q, l;
cin >> n >> M >> q >> l;
int a, b;
ll c;
for (int i = 0; i < M; i ++) {
cin >> a >> b >> c;
graf[a].pb({b, c});
graf[b].pb({a, c});
}
for (int i = 0; i < l; i ++) {
cin >> X[i];
}
for (int i = 1; i <= n; i ++) {
for (auto x : graf[i]) {
djikstra(x.st, i, x.nd);
for (int j = 1; j <= n; j ++) {
vec[i][j].pb({odl[j][0], {x.st, wej[j][0]}});
vec[i][j].pb({odl[j][1], {x.st, wej[j][1]}});
}
}
}
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= n; j ++) {
if (i == j) {
continue;
}
sort(vec[i][j].begin(), vec[i][j].end());
for (auto x : vec[i][j]) {
if (ile1[x.nd.st] <= 1 && ile2[x.nd.nd] <= 1 && !byl[x.nd.st][x.nd.nd]) {
baza[i][j].pb(x);
ile1[x.nd.st] ++;
ile2[x.nd.nd] ++;
byl[x.nd.st][x.nd.nd] = 1;
}
if (int(baza[i][j].size()) == 5) {
break;
}
}
for (auto x : vec[i][j]) {
ile1[x.nd.st] = 0;
ile2[x.nd.nd] = 0;
byl[x.nd.st][x.nd.nd] = 0;
}
}
}
buduj(0, l - 2, 1);
while (q --) {
cin >> a >> b;
a --;
X[a] = b;
if (a != 0) {
aktualizuj(0, l - 2, a - 1, 1);
}
if (a != l - 1) {
aktualizuj(0, l - 2, a, 1);
}
if (st[1].empty() || st[1][0].st == INF) {
cout << -1 << "\n";
} else {
cout << st[1][0].st << "\n";
}
}
return 0;
}