#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define FIN "amenzi.in"
#define FOUT "amenzi.out"
#define MAXN 151
#define MAXK 12000 // nr de "conditii" de amenzi
#define MAXP 8000 // locatii posibile de final
#define MAXTime 3501
#define ul unsigned long
#define INF 0x3f3f3f3f
/* Liste de adiacenta */
typedef struct item *point;
struct item { int y, c; item *r; };
point L[MAXN];
typedef ul graf[MAXN][MAXN];
struct ts { int t, x; } Fin[MAXP];
struct amenda { int t, x, c; } Amenzi[MAXK];
/* Vector dinamica */
int A[MAXTime][MAXN];
graf G;
int N, M, K, P;
void debug()
{
int i, j;
for (i=1; i<=N; ++i) {
for (j=1;j<=N; ++j)
printf("%3d ", G[i][j]);
printf("\n");
}
}
inline bool Compar(const amenda &A, const amenda &B)
{
// fields: t, x, c
return (A.t < B.t ||
(A.t == B.t &&
(A.x < B.x ||
A.x == B.x && A.c < B.c
)
)
);
}
inline void rf(graf &G)
{
int i, j, k;
for (k=1; k<=N; ++k)
for (i=1; i<=N; ++i)
for (j=1; j<=N; ++j)
if (G[i][j] > G[i][k] + G[k][j])
G[i][j] = G[i][k] + G[k][j];
}
void rez()
{
int i, j, crt = 0;
//rf(G);
sort(Amenzi, Amenzi + K, Compar);
memset(A, 0xFF, sizeof(A));
A[0][1] = 0;
for (i=0; i<=MAXTime; ++i)
for (j=1; j<=N; ++j)
if (A[i][j] != -1) {
// crt = "amenda" curenta
// iau si updatez toate nodurile in care pot ajunge..
for (; crt < K && Amenzi[crt].t < i ||
Amenzi[crt].t == i && Amenzi[crt].x < j; ++crt);
while (crt < K && Amenzi[crt].t == i && Amenzi[crt].x == j)
A[i][j] += Amenzi[crt++].c;
if (i+1<MAXTime && A[i+1][j] < A[i][j])
A[i+1][j] = A[i][j];
if (! (i && A[i-1][j] == A[i][j]))
for (point p = L[j]; p; p = p->r)
if (p->c+i < MAXTime && A[p->c+i][p->y] < A[i][j])
A[p->c+i][p->y] = A[i][j];
}
/*
for (i=0; i<=50; ++i) {
printf("%2d: ", i);
for (j=1; j<=N; ++j)
printf("%5d ", A[i][j]);
printf("\n");
}
*/
for (i=0; i<P; ++i)
printf("%d\n", A[ Fin[i].t ][ Fin[i].x ]);
}
void add_edge(int a, int b, int c)
{
point temp = new item;
temp->y = b; temp->c = c;
temp->r = L[a];
L[a] = temp;
}
void citire()
{
int i, x, y, c;
freopen(FIN, "r", stdin);
freopen(FOUT, "w", stdout);
scanf("%ld %ld %ld %ld", &N, &M, &K, &P);
memset(G, INF, sizeof(G));
for (i=0; i<M; ++i)
{
scanf("%ld %ld %ld", &x, &y, &c);
add_edge(x, y, c); add_edge(y, x, c);
G[x][y] = c; G[y][x] = c;
}
for (i=0; i<K; ++i)
{
scanf("%ld %ld %ld", &x, &y, &c); // nod x, timp y, amenda c
Amenzi[i].x = x; Amenzi[i].t = y; Amenzi[i].c = c;
}
for (i=0; i<P; ++i)
{
scanf("%d %d", &x, &y);
Fin[i].x = x; Fin[i].t = y;
}
}
int main()
{
citire();
rez();
return 0;
}