#include <bits/stdc++.h>

using namespace std;

const int NMAX = 100005;

vector <int> inv_graph[NMAX];
vector <pair <int, int> > graph[NMAX];

bool vis[NMAX];

int _stack[NMAX];
int stack_sz;

void dfs_inv(int node) {
    vis[node] = true;
    for (auto it: inv_graph[node])
        if (!vis[it])
            dfs_inv(it);
    _stack[++ stack_sz] = node;
}

int label[NMAX];
int sz[NMAX];
bool special[NMAX];

void dfs(int node, int comp) {
    vis[node] = true;
    label[node] = comp;
    ++ sz[comp];
    for (auto it: graph[node])
        if (!vis[it.first])
            dfs(it.first, comp);
}

//Bellman
long long dist[NMAX];

bool in_queue[NMAX];
int de_cate_ori[NMAX];
queue <int> coada;


bool bellman(int node) {
    dist[node] = 0;
    vis[label[node]] = true;
    coada.push(node);
    in_queue[node] = true;
    de_cate_ori[node] = 1;

    int y;
    bool are_ciclu = false;
    while (!coada.empty() && !are_ciclu) {
        y = coada.front();
        coada.pop();
        in_queue[y] = false;

        //cout << "expand " << y << endl;
        for (auto it: graph[y])
            if (label[it.first] == label[node] && dist[y] + it.second < dist[it.first]) {
                //cout << "update pe " << it.first << endl;

                dist[it.first] = dist[y] + it.second;
                if (!in_queue[it.first]) {
                    in_queue[it.first] = true;
                    de_cate_ori[it.first] ++;
                    coada.push(it.first);

                    if (de_cate_ori[it.first] >= sz[label[node]] + 2) {
                        are_ciclu = true;
                        break;
                    }
                }
            }
    }

    while (!coada.empty())
        coada.pop();

    return are_ciclu;
}

vector <int> new_graph[NMAX];

void dfs3(int node) {
    vis[node] = true;
    for (auto it: new_graph[node]) {
        if (!vis[it])
            dfs3(it);

        if (special[it])
            special[node] = true;
    }
}

int main()
{
    ios_base :: sync_with_stdio(false);

    int n;
    cin >> n;

    int m = 0;
    cin >> m;

    int a, b, w;
    while (m --) {
        cin >> a >> b >> w;
        graph[a].push_back(make_pair(b, w));
        inv_graph[b].push_back(a);
    }

    for (int i = 1; i <= n; ++ i)
        if (!vis[i])
            dfs_inv(i);

    memset(vis, 0, sizeof(vis));

    int comps = 0;
    for (int i = n; i; -- i)
        if (!vis[_stack[i]])
            dfs(_stack[i], ++ comps);

    //for (int i = 1; i <= n; ++ i)
    //    cout << "nodul " << i << ' ' << label[i] << ' ' << sz[label[i]] << endl;

    memset(vis, 0, sizeof vis);
    for (int i = 1; i <= n; ++ i)
        dist[i] = 1e18 + 15;

    //for (int i = 1; i <= n; ++ i)
    //    cout << i << ' ' << label[i] << endl;

    for (int i = 1; i <= n; ++ i) {
        for (auto it: graph[i])
            if (label[i] != label[it.first]) {
                new_graph[label[i]].push_back(label[it.first]);
      //      cout << "muchie " << label[i] << ' ' << label[it.first] << endl;
        }
    }

    for (int i = 1; i <= comps; ++ i)
        if (!vis[label[i]])
            special[label[i]] = bellman(i);

    memset(vis, 0, sizeof vis);
    for (int i = 1; i <= comps; ++ i)
        if (!vis[i])
            dfs3(i);

    int ans = 0;
    for (int i = 1; i <= comps; ++ i)
        ans += special[i] * sz[i];

    cout << ans << '\n';
    return 0;
}