/*
    
    點(diǎn)權(quán)一般變?yōu)檫厵?quán)
    這里轉(zhuǎn)化為求最小割

    題意:有一些模塊(modules)和一個雙核處理器,一個模塊可以在任意一個核上處理,每個核對應(yīng)每個模塊有個開銷。
    現(xiàn)在有一些模塊間需要數(shù)據(jù)交換,如果需要數(shù)據(jù)交換的模塊在一個核上處理,則不需要額外開銷,否則需要加上一個開銷。
    現(xiàn)在需要完成所有模塊,問最小需要多少開銷。
    如果沒有這個額外的開銷,那么每個模塊只要選擇開銷小的那個核就行了。額外的開銷給選擇加上了限制。

    網(wǎng)絡(luò)流的模型:
    每個模塊一個節(jié)點(diǎn),原點(diǎn)與所有模塊節(jié)點(diǎn)連接(稱為上邊),邊權(quán)為第一個核對應(yīng)該模塊的開銷。
    所有模塊節(jié)點(diǎn)連接到匯點(diǎn)(稱為下邊),權(quán)為第二個核對應(yīng)該模塊的開銷。
    然后需要數(shù)據(jù)交換的兩個模塊結(jié)點(diǎn)之間連接雙向邊(兩個單向邊,稱為中邊),權(quán)為對應(yīng)的那個額外開銷。

    這樣,該圖的最小割中,原點(diǎn)和模塊節(jié)點(diǎn)之間的邊,或者模塊節(jié)點(diǎn)與匯點(diǎn)之間的邊至少一條在割之中。
    同時,如果數(shù)據(jù)交換的結(jié)點(diǎn)選擇了不同的核,那么他們之間的中邊一定也在割集中    (如果不在,那么可以構(gòu)造出更小的割)。
    如果選擇了相同的核,那么模塊節(jié)點(diǎn)之間的那條表一定在割之中模塊節(jié)點(diǎn)之間的那條表一定不在割之中(因?yàn)槭亲钚「睿?br>

    
http://blog.csdn.net/biran007/archive/2009/05/26/4218454.aspx
*/

#include
<cstdio>
#include
<cstring>
#include
<algorithm>
using namespace std;

const int MAXN = 20000;
const int INF = 1000000000;

struct Edge
{
    
int v,cap;
    Edge 
*next,*pair;
}
edge[MAXN*22*2+10];

struct Graph
{
    Edge 
*G[MAXN+10],*cur[MAXN+10],*pE;
    
int dist[MAXN+10],num[MAXN+10];
    
int n,s,t;
    
void init(int nn,int ss,int tt)
    
{
        n
=nn;
        s
=ss,t=tt;
        memset(G,
0,sizeof(G));
        pE
=edge;
    }

    
void add(int u,int v,int cap,Edge *pair)
    
{
        pE
->v=v;
        pE
->cap=cap;
        pE
->next=G[u];
        pE
->pair=pair;
        G[u]
=pE++;
    }

    
void add(int u,int v,int cap)
    
{
        add(u,v,cap,pE
+1);
        add(v,u,
0,pE-1);
    }

    
int aug(int u,int preCap)
    
{
        
if(u==t)return preCap;
        
int leftCap=preCap;
        
for(Edge *&it=cur[u];it;it=it->next)
        
{
            
if(it->cap&&dist[it->v]+1==dist[u])
            
{
                
int d=aug(it->v,min(leftCap,it->cap));
                it
->cap-=d;
                it
->pair->cap+=d;
                leftCap
-=d;
                
if(leftCap==0||dist[s]==n)return preCap-leftCap;
            }

        }


        
int minDist=n;
        
for(Edge *it=cur[u]=G[u];it;it=it->next)
            
if(it->cap)minDist=min(minDist,dist[it->v]+1);//+1
        if(--num[dist[u]]==0)dist[s]=n;
        
else num[dist[u]=minDist]++;
        
return preCap-leftCap;
    }

    
int maxFlow()
    
{
        memset(dist,
0,sizeof(dist));
        memset(num,
0,sizeof(num));
        memmove(cur,G,
sizeof(G));
        num[
0]=n;
        
int flow=0;
        
while(dist[s]<n)flow+=aug(s,INF);
        
return flow;
    }

}
graph;
int main()
{    
    
int n,m,a,b,c;
    
while(~scanf("%d%d",&n,&m))
    
{
        graph.init(n
+2,0,n+1);
        
for(int i=1;i<=n;i++)
        
{
            scanf(
"%d%d",&a,&b);
            graph.add(
0,i,a);
            graph.add(i,n
+1,b);
        }

        
for(int i=0;i<m;i++)
        
{
            scanf(
"%d%d%d",&a,&b,&c);
            graph.add(a,b,c);
            graph.add(b,a,c);
        }

        printf(
"%d\n",graph.maxFlow());
    }

    
return 0;
}