type
edgenode=^node;
node=record
adjvex:integer;
weight:integer;
next:edgenode;
end;
vexnode=record
c,u,indegree:integer;
link:edgenode;
end;
var
inn:array[1..250] of boolean;
g,go:array[1..250] of vexnode;
toplist,outl,stack:array[1..250] of integer;
a,b,c,n,top,outn,e,i,j,k:integer;
p:edgenode;
null:boolean;
begin
///init
assign(input,'in.in');reset(input);
readln(n,e);
for i:=1 to n do
readln(go[i].c,go[i].u);
for i:=1 to e do begin
readln(a,b,c);
new(p);
p^.adjvex:=a;
p^.weight:=c;
p^.next:=go[b].link;
go[b].link:=p;
inc(go[a].indegree);
new(p);
p^.adjvex:=b;
p^.next:=g[a].link;
g[a].link:=p;
inc(g[b].indegree);
end;
close(input);
///main_topsearch
fillchar(toplist,sizeof(toplist),0);
for i:=1 to n do
if g[i].indegree=0 then begin
inc(top);
stack[top]:=i;
inn[i]:=true;
end;
k:=0;
while top>0 do begin
i:=stack[top];
dec(top);inc(k);
p:=g[i].link;
toplist[k]:=i;
while p<>nil do begin
j:=p^.adjvex;
dec(g[j].indegree);
if g[j].indegree=0 then begin
inc(top);
stack[top]:=j;
end;
p:=p^.next;
end;
end;
///get ans from the opposit graph
for i:=1 to k do begin
j:=toplist[i];
p:=go[j].link;
while p<>nil do begin
a:=p^.adjvex;
b:=p^.weight;
if go[a].c>0 then
go[j].c:=go[j].c+go[a].c*b;
p:=p^.next;
end;
if not inn[j] then
go[j].c:=go[j].c-go[j].u;
end;
for i:=1 to n do
if go[i].indegree=0 then begin
inc(outn);
outl[outn]:=i;
end;
null:=true;
for i:=1 to outn do
if go[outl[i]].c>0 then begin
null:=false;
break;
end;
if null then writeln('NULL')
else for i:=1 to outn do
if go[outl[i]].c>0 then writeln(outl[i],' ',go[outl[i]].c);
end.