// RandomUsername (Nikola Jovanovic) // MindCoding Round 2 // D #include #define DBG false #define debug(x) if(DBG) printf("(ln %d) %s = %d\n", __LINE__, #x, x); #define lld long long #define ff(i,a,b) for(int i=a; i<=b; i++) #define fb(i,a,b) for(int i=a; i>=b; i--) #define par pair #define fi first #define se second #define mid (l+r)/2 #define INF 1000000000 #define MAXN 100005 using namespace std; struct node { vector adj; vector w; bool OK; bool visited; lld iter; lld pathTo; }; node g[MAXN]; lld n, m; lld A, B, W; lld currIter; void DFS(lld curr, lld pathW) { g[curr].iter = currIter; g[curr].visited = true; g[curr].pathTo = pathW; bool reachable = false; lld limit = g[curr].adj.size(); ff(i, 0, limit - 1) { lld nxt = g[curr].adj[i]; lld w = g[curr].w[i]; if(!g[nxt].visited) DFS(nxt, pathW + w); // tree edge else if(g[nxt].iter == currIter && (pathW + w) - g[nxt].pathTo < 0) reachable = true; // back edge reachable |= g[nxt].OK; // cross edge } g[curr].OK = reachable; } int main() { scanf("%lld %lld", &n, &m); ff(i, 1, m) { scanf("%lld %lld %lld", &A, &B, &W); g[A].adj.push_back(B); g[A].w.push_back(W); } currIter = 1; ff(i, 1, n) { if(!g[i].visited) { DFS(i, 0LL); currIter++; } } lld ret = 0LL; ff(i, 1, n) { ret += g[i].OK; } printf("%lld\n", ret); return 0; }