#include <stdio.h>
#include <vector>
#define mp make_pair
#define Max(a,b) (a>b ? a:b)
using namespace std;
FILE *f,*g;
vector <pair <int,int> > graf[153];
int Dinamic[3510][153],Amenda[3510][153],N,M,K,P;
void Read()
{
fscanf(f,"%d%d%d%d",&N,&M,&K,&P);
int i,j,X,Y,C;
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++)///la momentul Y în intersecția X amenda va fi C
fscanf(f,"%d%d%d",&X,&Y,&C),Amenda[Y][X]=C;
}
void DynamicProgamming()
{
int i,j,T,siz,Node,Time;
Dinamic[0][1]=Amenda[0][1];
for(T=1;T<=3510;++T)
{
for(i=1;i<=N;++i)
{
siz=graf[i].size();
for(j=0;j<siz;++j)
{
Node=graf[i][j].first;
Time=graf[i][j].second;
if(T>=Time)///amenda până la momentul nodului vecin
Dinamic[T][i]=Max(Dinamic[T-Time][Node],Dinamic[T][i]);
}
Dinamic[T][i]=Max(Dinamic[T-1][i],Dinamic[T][i]);
if(!Dinamic[T][i])
Dinamic[T][i]+=Amenda[T][i];
}
}
}
void Displaying()
{
int X,Y;
while(P)
{
--P;
fscanf(f,"%d %d",&X,&Y);
if(Dinamic[X][Y])fprintf(g,"%d\n",Dinamic[X][Y]);
else fprintf(g,"-1\n");
}
}
int main()
{
f=fopen("amenzi.in","r");g=fopen("amenzi.out","w");
Read();DynamicProgamming();Displaying();
fclose(f);
fclose(g);
return 0;
}