#include <iostream>
#include <queue>
#include <vector>
#include <stack>

using namespace std;

const int MAX_N = 1e5 + 10;

struct edge {
int to;
int cost;
};

vector<edge> G[MAX_N];

bool viz[MAX_N];

int idx[MAX_N];
int low[MAX_N];

int deg[MAX_N];

int DP[MAX_N];
int cnt[MAX_N];

bool hasCyc[MAX_N];

stack<int> st;

vector<vector<int> > comp;

int belong[MAX_N];

void dfs(const int nod) {

    viz[nod] = 1;
    static int at = 1;
    idx[nod] = low[nod] = at;
    st.push(nod);

    at++;

    for(auto i: G[nod]) {
        int to = i.to;

        if(!viz[to])
            dfs(to);

        if(low[to] < low[nod]) {
            low[nod] = low[to];
        }
    }

    static int cat = 0;
    if(low[nod] == idx[nod]) {
        vector<int> now;
        int x;

        do {
            x = st.top(); st.pop();
            now.push_back(x);
        }while(x != nod);

        for(auto i: now)
            belong[i] = cat;

        comp.push_back(now);

        cat++;

    }
}

int n, m;

void show(vector<int> &i) {
    for(auto j: i)
        cerr << j << " ";
    cerr << "\n";
}

void show(vector<vector<int>> & v) {
    for(auto i: v) {
        show(i);
    }
}

bool detect(const vector<int> &v) {
    int st = v[0];
    queue<int> Q;
    Q.push(st);
    DP[st] = 0;

    bool fnd = 0;

    while(!Q.empty()) {
        int now = Q.front(); Q.pop();
        cnt[now]++;

        if(cnt[now] >= m + 1) {
            return true;
        }

        for(auto e: G[now]) {
            int to = e.to, c = e.cost;

            if(belong[to] != belong[now])
                continue;

            
            if(DP[now] + c < DP[to]) {
                DP[to] = DP[now] + c;
                Q.push(to);
            }
        }
    }
    return false;
}


bool cyc(int nod) {
    if(viz[nod])
        return hasCyc[nod];

    viz[nod] = 1;

    for(auto v: comp[nod]) {
        for(auto e: G[v]) {
            int to = belong[e.to];
            if(cyc(to)) {
                hasCyc[nod] = 1;
                return 1;
            }
        }
    }

    return 0;
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m;

    for(int i = 1; i <= m; ++i) {
        int x, y, c;
        cin >> x >> y >> c;
        G[x].push_back((edge){y, c});
    }

    for(int i = 1; i <= n; ++i) {
        if(viz[i])
            continue;
        dfs(i);
    }

    for(int i = 1; i <= n; ++i)
        DP[i] = (1 << 30);

    for(int i = 1; i <= n; ++i) {
        for(auto e: G[i]) {
            int to = e.to;
            deg[belong[to]]++;
        }
    }

    for(int i = 0; i < comp.size(); ++i) {
        hasCyc[i] = detect(comp[i]);

    }


    for(int i = 1; i <= n; ++i)
        viz[i] = 0;

    queue<int> Q;

    for(int i = 0; i < comp.size(); ++i) {
        cyc(i);
    }

    int sol = 0;

    for(int i = 0; i < comp.size(); ++i)
        sol += hasCyc[i] * comp[i].size();

    cout << sol << "\n";

    return 0;
}