#include<cstring>
#include<cstdio>
#define FOR(i,f_start,f_end) for(int i=f_startl;i<=f_end;i++)
#define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr))
const int maxn=;
const int maxm=2e4+;
int size;
int n;
const int inf=0x3f3f3f3f;
using namespace std;
int head[maxn];
void init(){
size=;
MS(head,-);
}
struct Node{
int from,to,cap,next;
}edge[maxn];
void add(int u,int v,int w){
edge[size].from=u;
edge[size].to=v;
edge[size].cap=w;
edge[size].next=head[u];
head[u]=size++;
edge[size].from=v;
edge[size].to=u;
edge[size].cap=0;
edge[size].next=head[v];
head[v]=size++;
}
int dep[maxn];
int bfs(int start,int end){
int que[maxn];
int front,rear;
MS(dep,-);
que[rear++]=start;
dep[start]=;
while(front!=rear){
int u=que[front++];
if(front==maxn)front=;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(edge[i].cap>&&dep[v]==-){
dep[v]=dep[u]+;
que[rear++]=v;
if(rear>=maxn)rear=;
if(v==end)return ;//优化1 找到直接返回
}
}
}
return ;
}
int dinic(int start,int end){
int res=;
int top;
int stack[maxn];//非递归 手写栈
int cur[maxn];
while(bfs(start,end)){
memcpy(cur,head,sizeof(head));//当前弧预备工作
int u=start;
top=;
while(){
if(u==end){//当找到终点的时候
int min=inf;
int loc;
for(int i=;i<top;i++){//找到路径里面最小的流量
if(min>edge[stack[i]].cap){
min=edge[stack[i]].cap;
loc=i;//记下最小流量的边 之后的点都不可能到达了
}
}
for(int i=;i<top;i++){//减流量和加反向边
edge[stack[i]].cap-=min;
edge[stack[i]^].cap+=min;
}
res+=min;
top=loc;//退栈顶到那个流量已经清零的边的起点i
u=edge[stack[top]].from;
}
for(int i=cur[u];i!=-;cur[u]=i=edge[i].next)//当前弧优化如果存在以下情况的时候就可以break进行操作了
if(edge[i].cap!=&&dep[u]+==dep[edge[i].to])
break;
if(cur[u]!=-){//如果有边可以走 那么就把边和点入栈
stack[top++]=cur[u];
u=edge[cur[u]].to;
}
else {//如果从栈顶点出发找不到可以增广的路径了,那么如果栈已经空了 那可能就没有可以增广的路径了,而如果栈没有空 那么就退栈继续找
if(top==)break;
dep[u]=-;//因为从u已经找不到可以走的路径了 直接把dep[u]=-1相当于没有点可以可以通过dep[u]+1==dep[edge[i].to]的条件 也就是u以后也入不了栈了
u=edge[stack[--top]].from;
}
}
}
return res;
}
int main(){
int start,end;
int np,nc,m;
int u,v,z;
while(scanf("%d%d%d%d",&n,&np,&nc,&m)==){
init();
while(m--){
while(getchar()!='(');
scanf("%d,%d)%d",&u,&v,&z);
u++,v++;
add(u,v,z);
}
while(np--){
while(getchar()!='(');
scanf("%d)%d",&u,&z);
u++;
add(,u,z);
}
while(nc--){
while(getchar()!='(');
scanf("%d)%d",&u,&v);
u++;
add(u,n+,z);
}
start=;
end=n+;
int ans=dinic(start,end);
printf("%d\n",ans);
}
return ;
}