/*
hdu5988 费用流
Time:2017-10-25
Author:lcy
读完题可以推出公式,假如每条路
的概率为pi,令di=1-pi,那么最终答案目标是
max{1-d1^c1*d2^c2*...*dn^cn}
等价于求d1^c1*d2^c2*...*dn^cn的最小值。
在式子上取对数,转化为加法,可以发现是个很典型的费用流
有一点需要注意,在建边时,需要加一条容量为1,费用为0
的边,用来满足题意。
*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define frr(i,a,b) for(int i=a;i>=b;i--)
#define ms(a,b) memset(a,b,sizeof(a))
#define scfd(a) scanf("%d",a)
#define scflf(a) scanf("%lf",a)
#define scfs(a) scanf("%s",a)
#define ptfd(a) printf("%d\n",a)
#define ptfs(a) printf("%s\n",a)
#define showd(a,b) printf(a"=%d\n",b)
#define showlf(a,b) printf(a"=%lf\n",b)
#define shows(a,b) printf(a"=%s\n",b)
#define mmcp(a,b) memcpy(a,b,sizeof(b))
#define pb(a) push_back(a)
const int MAXN=325;
const int MAXM=92005;
const double eps=1e-6;
const double INF=292929292.0;
const int INFF=2147483;
struct edge{
int f,t,cp,fl;
double cs;//price
edge(int aa,int bb,int cc,int dd,double ee){
f=aa,t=bb,cp=cc,fl=dd,cs=ee;
}
edge(){
}
};
edge e[MAXM];
vector<int>g[MAXN];
bool v[MAXN];
int a[MAXN],fa[MAXN],ed,flow;
double d[MAXN];
double cost;
void add_edge(int ff,int tt,int cc,double pp){
e[ed++]=edge(ff,tt,cc,0,pp);
e[ed++]=edge(tt,ff,0,0,-1.0*pp);
g[ff].push_back(ed-2);
g[tt].push_back(ed-1);
}
bool bmf(int start,int endd){
ms(v,false);
fr(i,1,endd)d[i]=INF;d[start]=0;
ms(a,0);
queue<int>q;
q.push(start);v[start]=true;a[start]=INFF;d[start]=0;
while(!q.empty()){
int t=q.front();q.pop();v[t]=false;
//printf("t=%d\n",t);
int sz=g[t].size();
fr(i,0,sz-1){
edge ne=e[g[t][i]];
if(ne.fl<ne.cp&&d[ne.t]-(d[ne.f]+ne.cs)>eps){
d[ne.t]=d[ne.f]+ne.cs;
a[ne.t]=min(a[ne.f],ne.cp-ne.fl);
fa[ne.t]=g[t][i];
//printf("now=%d,fa=%d,fa_point=%d,d=%lf\n",ne.t,fa[ne.t],ne.f,d[ne.t]);
if(!v[ne.t]){q.push(ne.t);v[ne.t]=true;}
}
}
}
if(!a[endd])return false;
for(int i=endd;i!=start;i=e[fa[i]].f){
// printf("i=%d\n",i);
e[fa[i]].fl+=a[endd];
e[fa[i]^1].fl-=a[endd];
}
flow+=a[endd];
cost+=d[endd]*a[endd];
return true;
}
void min_cost(int start,int end){
flow=cost=0;
while(bmf(start,end));
}
int start,endd,cases,n,m;
bool pos[MAXN];
int main(){
scfd(&cases);
while(cases--){
scanf("%d%d",&n,&m);
ed=start=0,endd=n+1;
int aa,bb;
fr(i,1,n){
scanf("%d%d",&aa,&bb);
int t=aa-bb;
if(t>0)
add_edge(start,i,t,0);
else
add_edge(i,endd,-1*t,0);
}
fr(i,1,m){
int aa,bb,cc;double dd;
scanf("%d%d%d%lf",&aa,&bb,&cc,&dd);
add_edge(aa,bb,1,0);
add_edge(aa,bb,cc-1,-1.0*log(1.0-dd));
}
min_cost(start,endd);
printf("%.2lf\n",1-exp(-1.0*cost));
fr(i,0,endd)g[i].clear();
}
return 0;
}