#include <bits/stdc++.h>

using namespace std;

///---------------------------------------------------
const int BUFFER_SIZE = (1 << 16);
char buffer[BUFFER_SIZE];
int position = BUFFER_SIZE;

inline char getChar()
{
    if ( position == BUFFER_SIZE )
    {
        position = 0;
        fread(buffer, BUFFER_SIZE, 1, stdin);
    }

    return buffer[position++];
}

inline int getInt()
{
    register int a = 0;
    char ch;
    int sgn = 1;

    do
    {
        ch = getChar();

    } while ( !isdigit(ch) && ch != '-' );

    if ( ch == '-' )
    {
        sgn = -1;
        ch = getChar();
    }

    do
    {
        a = (a << 3) + (a << 1) + ch - '0';
        ch = getChar();

    } while ( isdigit(ch) );

    return a * sgn;
}
///---------------------------------------------------

const int MAX_N = 100000 + 1;
const long long INF = numeric_limits<long long>::max() / 2;

vector<pair<int,int>> G[MAX_N];
vector<pair<int,int>> GT[MAX_N];

bool checked[MAX_N];
bool visited[MAX_N];
bool inQueue[MAX_N];
long long dist[MAX_N];
int accessed[MAX_N];
queue<int> Q;

int N, M;

void dfs(int node)
{
    inQueue[node] = false;
    dist[node] = INF;
    accessed[node] = 0;

    visited[node] = true;

    for (pair<int,int> v : G[node])
        if (!visited[v.first])
            dfs(v.first);
}

int bellmanFord(int node)
{
    for (int i = 1; i <= N; ++i)
    {
        inQueue[i] = 0;
        dist[i] = 0;
        accessed[i] = 0;
    }

    Q.push(node);
    inQueue[node] = true;
    dist[node] = 0;
    accessed[node] = 1;

    while (Q.empty() == false)
    {
        int nod = Q.front();
        Q.pop();

        inQueue[nod] = false;

        if (accessed[nod] > N)
            return nod;

        for (pair<int,int> pii : G[nod])
        {
            int v = pii.first;
            int c = pii.second;

            if (dist[v] > dist[nod] + c)
            {
                dist[v] = dist[nod] + c;

                if (!inQueue[v])
                {
                    inQueue[v] = true;
                    accessed[v]++;
                    Q.push(v);
                }
            }
        }
    }

    return 0;
}

void dfsT(int node, int &solution)
{
    checked[node] = true;
    solution++;

    for (pair<int,int> pii : GT[node])
        if (!checked[pii.first])
            dfsT(pii.first, solution);
}

int main()
{
    freopen("data.in", "r", stdin);

    N = getInt();
    M = getInt();

    for (int i = 1; i <= M; ++i)
    {
        int a, b, c;
        a = getInt(); b = getInt(); c = getInt();

        G[a].push_back({b, c});
        GT[b].push_back({a, c});
    }

    int solution = 0;

    for (int i = 1; i <= N; ++i)
        if (!checked[i])
        {
            int node = bellmanFord(i);

            if (node > 0)
                dfsT(node, solution);
        }

    cout << solution << "\n";

    return 0;
}