/*
题意:F个区域和P条路径,每个区域有a头牛且能遮蔽b头牛,求其中牛走得最远的路径的最短长度,并且
所有牛都可以进入遮蔽处。
题解:最大流+二分+floyd+拆点;
牛从所在的位置走向遮蔽处必然是走最短路线,因此先用floyd将两两点之间的最短路径先求出,再根据这
个最短路径建立图,源点到每个点加边,权值为牛数a,将区域拆成两个点,并且对相连的区域之间加边,
权值为INF,注意自己和自己也有加上边,就是被这里坑了很久,区域到汇点加边,权值为遮蔽数b;二分
的方法将长于mid的边去除从而建图;然后求出最大流等于牛数目即可。
注意:题目有重边,只记录最小边即可,路径的长度会超过32为,因此用__int64记录路径长度。
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define EMAX 505000
#define VMAX 500
#define MAX 0x7FFFFFFFFFFFFFF
const int INF = 0xFFFFFFF;
int head[VMAX],dis[VMAX],cur[VMAX],gap[VMAX],pre[VMAX];
int EN;
struct edge
{
int to;
int weight;
int next;
}e[EMAX];
struct cow
{
int a,b;
}te[VMAX];
__int64 map[205][205];
void insert(int u,int v,int w)
{
e[EN].to = v;
e[EN].weight = w;
e[EN].next = head[u];
head[u] = EN++;
e[EN].to = u;
e[EN].weight = 0;
e[EN].next = head[v];
head[v] = EN++;
}
int sap(int s,int t, int n)//sap求最大流模版
{
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
for(int i=0; i<=n; i++)
cur[i] = head[i];
int u = s;
pre[s] = s;
int ret = 0;
int temp = -1;
gap[0] = n;
bool flag;
while(dis[s] < n)
{
flag = false;
for(int &i = cur[u]; i != -1; i = e[i].next)
{
int v = e[i].to;
if(e[i].weight && dis[u] == dis[v] + 1)
{
if (temp == -1 || temp>e[i].weight)
temp = e[i].weight;
pre[v] = u;
u = v;
if(v == t)
{
ret += temp;
for(u = pre[u];v != s;v = u,u = pre[u])
{
e[cur[u]].weight -= temp;
e[cur[u]^1].weight += temp;
}
temp = -1;
}
flag = true;
break;
}
}
if (flag)
continue;
int mindis = n;
for(int i = head[u]; i != -1 ; i = e[i].next)
{
int v = e[i].to;
if(e[i].weight && mindis > dis[v])
{
cur[u] = i;
mindis = dis[v];
}
}
gap[dis[u]]--;
if( gap[dis[u]] == 0)
break;
dis[u] = mindis+1;
gap[dis[u]]++;
u = pre[u];
}
return ret;
}
void floyd(int n)
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if (MAX != map[j][i])
for(int k=1; k<=n; k++)
if (map[j][i] + map[i][k] < map[j][k])
map[j][k] = map[j][i] + map[i][k];
}
void build(int f,__int64 mid)//建图
{
memset(head,-1,sizeof(head));
EN = 0;
for(int i=1; i<=f; i++)
{
insert(0,i,te[i].a);
insert(f+i,2*f+1,te[i].b);
}
for(int i=1; i<=f; i++)
for(int j=1; j<=f; j++)
if (map[i][j]<=mid)//去除大于mid的边
insert(i,f+j,INF);
}
__int64 bin(int f, int sum)//二分
{
__int64 left=0,right=MAX,mid;
while (left < right)
{
mid = (left+right)/2;
build(f,mid);
if (sap(0,2*f+1,2*f+2) < sum)
left = mid+1;
else
right = mid;
}
if (right == MAX)
return -1;
else
return right;
}
int main(void)
{
int f,p,a,b,l;
while (~scanf("%d%d",&f,&p))
{
int sum = 0;
for(int i=1; i<=f; i++)
for(int j=1; j<=f; j++)
{
if (i != j)
map[i][j] = MAX;
else
map[i][j] = 0;
}
for(int i=1; i<=f; i++)
{
scanf("%d%d",&te[i].a,&te[i].b);
sum += te[i].a;//求牛的总数
}
for(int i=1; i<=p; i++)
{
scanf("%d%d%d",&a,&b,&l);
if (map[a][b] > l)
map[a][b] = map[b][a] = l;
}
floyd(f);
printf("%I64d\n",bin(f,sum));
}
return 0;
}