#include<bits/stdc++.h>
using namespace std;
const int N = 110 , M = 1010;
int n , m;
int h[N] , e[M] , w[M] , ne[M] , idx;
int dout[N] , din[N];//每个点的出度和入度
long long c[N] , va[N];//c储存状态,v储存阈值
int q[N];//拓扑排序的队列
//建图方式
void add(int a , int b , int c)
{
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx ++;
dout[a] ++;
din[b] ++;
}
//拓扑排序
void topsort()
{
int hh = 0 , tt = -1;
for(int i = 1;i <= n;i ++)
if(!din[i]) q[++ tt] = i;
while(hh <= tt)
{
int u = q[hh ++];
for(int i = h[u]; ~i ;i = ne[i])
{
int j = e[i];
if(-- din[j] == 0)q[++ tt] = j;
}
}
}
void solve()
{
for(int i = 0;i < n;i ++)
{
int x = q[i];
c[x] -= va[x];//计算公式中的-Vi部分
if(c[x] <= 0) continue;//如果不大于0就无法继续走
cout << x << endl;
for(int k = h[x]; ~k ;k = ne[k])
{
int y = e[k];
c[y] += w[k] * c[x];//公式中的累加部分
}
}
}
int main()
{
cin >> n >> m;
memset(h , -1 , sizeof h);
for(int i = 1;i <= n;i ++)
{
cin >> c[i] >> va[i];
}
while(m --)
{
int a , b , c;
cin >> a >> b >> c;
add(a , b , c);
}
//拓扑排序
topsort();
solve();
int flag = 1;
for(int i = 1;i <= n;i ++)
if(!dout[i] && c[i] > 0) //默认出度为0的点是输出层
{
cout << i << " " << c[i]<< endl;
flag = 0;//判断
}
if(flag) cout << "NULL";
return 0;
}