#include using namespace std; const int Nmax = 1e5 + 10; const int inf = 0x3f3f3f3f; int n , m , i , S , crt , ans; int nr[Nmax] , bst[Nmax]; bool marked[Nmax] , cycle , ap[Nmax] , used[Nmax]; vector < pair < int , int > > g[Nmax]; vector < int > p[Nmax] , t; queue < int > q; void Bford() { memset(bst , inf , sizeof(bst)); for (q.push(S),marked[S]=1,bst[S]=0; !q.empty(); q.pop()) { int node = q.front(); marked[node] = 0; for (auto &it : g[node]) { int newN , crtCost; tie(newN , crtCost) = it; if (bst[newN] > bst[node] + crtCost) { if (nr[newN] == n-1) { t.push_back(newN); return; } nr[newN]++; bst[newN] = bst[node] + crtCost; if (!ap[newN]) ap[newN] = 1, crt++; if (!marked[newN]) marked[newN] = 1, q.push(newN); } } } } void dfs(int node) { used[node] = 1; ans++; for (auto &it : p[node]) if (!used[it]) dfs(it); } int main() { #ifndef ONLINE_JUDGE freopen("input.in","r",stdin); freopen("output.out","w",stdout); #endif // ONLINE_JUDGE scanf("%d %d", &n, &m); S = 1; for (i = 1 ; i <= m; ++i) { int node1, node2, cost; scanf("%d %d %d", &node1, &node2, &cost); g[node1].push_back({node2 , cost}); p[node2].push_back(node1); } for (i = 1; i <= n; ++i) { if (ap[i]) continue; S = i; crt = 0; cycle = 0; Bford(); //if (cycle) ans += crt; } for (auto &it : t) if (!used[it]) dfs(it); printf("%d\n", ans); return 0; }