#include <bits/stdc++.h>
using namespace std;
vector<bool> sieve(long long n) {
  vector<bool> prime(n + 1, true);
  for (long long p = 2; p * p <= n; p++) {
    if (prime[p] == true) {
      for (long long i = p * p; i <= n; i += p) {
        prime[i] = false;
      }
    }
  }
  prime[1] = false;
  return prime;
}
long long powerM(long long x, long long y) {
  if (y == 0) {
    return 1;
  }
  long long p = powerM(x, y / 2) % 1000000007;
  p = (p * p) % 1000000007;
  return (y % 2 == 0) ? p : (x * p) % 1000000007;
}
long long power(long long x, long long y) {
  if (y == 0) {
    return 1;
  }
  long long p = power(x, y / 2);
  p = (p * p);
  return (y % 2 == 0) ? p : (x * p);
}
long long gcd(long long a, long long b) {
  if (b == 0) {
    return a;
  }
  return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return (a / gcd(a, b)) * b; }
bool isPalindrome(string s) {
  long long n = s.length();
  long long N = n % 2 == 0 ? n / 2 : n / 2 + 1;
  for (long long i = 0; i < N; i++) {
    if (s[i] != s[n - i - 1]) {
      return false;
    }
  }
  return true;
}
vector<long long> tanks;
map<long long, bool> intermediate;
vector<vector<long long> > ans;
void dfs(long long at, long long index, long long n,
         vector<pair<long long, long long> > adj[], long long d,
         vector<bool> &visited) {
  visited[at] = true;
  if (adj[at].size() == 0 && intermediate[at]) {
    vector<long long> v;
    v.push_back(tanks[index]);
    v.push_back(at);
    v.push_back(d);
    ans.push_back(v);
    return;
  }
  long long node = adj[at][0].first;
  long long diameter = adj[at][0].second;
  if (!visited[node]) {
    dfs(node, index, n, adj, min(d, diameter), visited);
  }
}
void solve(long long n, vector<pair<long long, long long> > adj[]) {
  for (long long i = 0; i < tanks.size(); i++) {
    vector<bool> visited(n, false);
    dfs(tanks[i], i, n, adj, INT_MAX, visited);
  }
}
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  long long t = 1;
  while (t--) {
    long long n, p;
    cin >> n >> p;
    n++;
    vector<pair<long long, long long> > adj[n];
    for (long long i = 0; i < p; i++) {
      long long a, b, d;
      cin >> a >> b >> d;
      adj[a].push_back(make_pair(b, d));
      intermediate[b] = true;
    }
    for (long long i = 1; i < n; i++) {
      if (!intermediate[i] && adj[i].size()) {
        tanks.push_back(i);
      }
    }
    solve(n, adj);
    cout << ans.size() << "\n";
    for (long long i = 0; i < ans.size(); i++) {
      cout << ans[i][0] << " " << ans[i][1] << " " << ans[i][2] << "\n";
    }
  }
  return 0;
}
