#include <stdio.h>
#define mp make_pair
#include <vector>
#define Max(a,b) (a>b ? a:b)
using namespace std;
FILE *f,*g;
int Penal[3510][155],Dynamic[3510][155],N,M,K,P;
vector <pair <int,int> > graf[160];
void UpdateMatrix()
{
int i,j;
for(i=0;i<=3500;++i)
for(j=1;j<=N;++j)Dynamic[i][j]=-1;
}
void Read()
{
int i,j,X,Y,C;
fscanf(f,"%d %d %d %d\n",&N,&M,&K,&P);
for(i=1;i<=M;++i)
{
fscanf(f,"%d %d %d",&X,&Y,&C);
graf[X].push_back(mp(Y,C));
graf[Y].push_back(mp(X,C));
}
for(i=1;i<=K;++i)fscanf(f,"%d %d %d",&X,&Y,&C),Penal[Y][X]=C;///la momentul Y, în intersecția X, amenda va fi C
UpdateMatrix();
}
void DynamicProgramming()
{
int i,T,Node,Time,siz,j;
Dynamic[0][1]=Penal[0][1];
for(T=1;T<=3500;++T)///parcurg intervalul de timp
for(i=1;i<=N;++i)///parcurg fiecare nod și caut suma amenzilor maximă cu care aș putea ajunge în el din nodurile vecine
{
siz=graf[i].size();
for(j=0;j<siz;++j)
{
Node=graf[i][j].first,Time=graf[i][j].second;
if(T>=Time) Dynamic[T][i]=Max(Dynamic[T][i],Dynamic[T-Time][Node]);
}
Dynamic[T][i]=Max(Dynamic[T-1][i],Dynamic[T][i]);///verific dacă cu o unitate de timp în urmă am avut o amendă mai "neconvenabilă" :)
if(Dynamic[T][i]!=-1)Dynamic[T][i]+=Penal[T][i];
}
}
void Displaying()
{
int X,Y;
while(P)
{
fscanf(f,"%d %d",&X,&Y);
fprintf(g,"%d\n",Dynamic[Y][X]);
--P;
}
}
int main()
{
f=fopen("amenzi.in","r");g=fopen("amenzi.out","w");
Read();DynamicProgramming();Displaying();
fclose(f);fclose(g);
return 0;
}