#include <bits/stdc++.h>
using namespace std;
long long power(long long x, long long y, long long p) {
  long long res = 1;
  x = x % p;
  while (y > 0) {
    if (y & 1) res = (res * x) % p;
    y = y >> 1;
    x = (x * x) % p;
  }
  return res;
}
long long PO(long long a, long long n) {
  long long val = 1;
  for (long long i = 0; i < n; i++) val *= a;
  return val;
}
bool sortbysec(const pair<long long, long long> &a,
               const pair<long long, long long> &b) {
  return (a.second < b.second);
}
vector<long long> gr[3000];
long long vis[3000] = {0};
long long minval;
long long last;
map<long long, long long> incoming, outgoing, pp;
void dfs(long long parent, long long node) {
  last = node;
  if (vis[node])
    return;
  else {
    if (outgoing[node]) minval = min(minval, pp[node]);
    vis[node] = parent;
    for (auto it : gr[node]) dfs(parent, it);
  }
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long n, m;
  cin >> n >> m;
  map<long long, pair<long long, long long> > ans;
  for (long long i = 0; i < m; i++) {
    long long u, v, dia;
    cin >> u >> v >> dia;
    pp[u] = dia;
    gr[u].push_back(v);
    outgoing[u] = 1;
    incoming[v] = 1;
  }
  for (long long i = 1; i <= n; i++) {
    if (vis[i]) continue;
    if (!incoming[i] && outgoing[i]) {
      minval = pp[i];
      dfs(i, i);
      ans[i].first = last;
      ans[i].second = minval;
    }
  }
  cout << ans.size() << "\n";
  for (auto it : ans) {
    cout << it.first << " " << it.second.first << " " << it.second.second
         << "\n";
  }
}
