#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=4005;
const int inf=0x3f3f3f3f;
//求这n天每天从1到m的距离和与更改道路的价值之和的最小值.
int dp[N],now[N],limit[N][N],dist[N];
bool st[N];
int h[N],e[N],ne[N],idx,w[N];
int n,m,K,E;
int a,b,c,d,p;
void add(int a,int b,int c)
{
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
int spfa()
{
memset(dist,inf,sizeof dist);
queue<int>q;
q.push(1);
dist[1]=0;
st[1]=1;
while(q.size())
{
int u=q.front();
q.pop();
st[u]=0;
for(int i=h[u]; i!=-1; i=ne[i])
{
int j=e[i];
if(dist[j]>dist[u]+w[i]&&now[j]==0)
{
dist[j]=dist[u]+w[i];
if(st[j]==0)
{
st[j]=1;
q.push(j);
}
}
}
}
return dist[m];
}
int main()
{
memset(h,-1,sizeof h);
cin>>n>>m>>K>>E;
for(int i=1; i<=E; i++)
{
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
cin>>d;
for(int i=1; i<=d; i++)
{
cin>>p>>a>>b;
//码头p 从a到b天内无法使用
for(int j=a; j<=b; j++)
limit[j][p]=1;
}
memset(dp,inf,sizeof dp);
dp[0]=-K;//第一次选择路径是不算做跟改路径的
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
now[j]=0;
for(int j=i; j>=1; j--)
{
for(int k=1; k<=m; k++)
if(limit[j][k])
now[k]=1;
int get=spfa();
if(get>=inf)
break;
//如果取后者,就说明改路线了
dp[i]=min(dp[i],dp[j-1]+(i-j+1)*get+K);
}
}
cout<<dp[n]<<endl;
return 0;
}