#include <bits/stdc++.h>
using namespace std;
long long fac[2000005] = {0};
void factorial() {
  fac[0] = 1;
  fac[1] = 1;
  for (long long i = 2; i < 200005; i++)
    fac[i] = ((i % 1000000007) * (fac[i - 1] % 1000000007)) % 1000000007;
}
long long power(long long n, long long m) {
  long long p = 1;
  if (m == 0) return 1;
  p = (power(n, m / 2) % 1000000007);
  p = (p % 1000000007 * p % 1000000007) % 1000000007;
  return (m & 1 ? ((p % 1000000007 * n % 1000000007) % 1000000007)
                : (p % 1000000007));
}
long long ncr(long long n, long long r) {
  return ((fac[n] * power(fac[r], 1000000007 - 2)) % 1000000007 *
          power(fac[n - r], 1000000007 - 2)) %
         1000000007;
}
long long n, m, d1;
long long a[1001] = {0};
long long d[1001][1001] = {0};
vector<pair<long long, pair<long long, long long>>> v1;
vector<long long> graph[1001];
vector<long long> v2;
long long used[1001] = {0}, par;
long long mx = 1e9;
void dfs(long long x) {
  used[x] = 1;
  v2.push_back(x);
  for (auto v : graph[x]) {
    if (used[v] == 0) {
      dfs(v);
      mx = min(mx, d[x][v]);
    }
  }
}
void ram5564() {
  cin >> n >> m;
  vector<long long> v;
  memset(used, 0, sizeof(used));
  for (long long i = 1; i < m + 1; i++) {
    long long x, y;
    cin >> x >> y >> d1;
    d[x][y] = d1;
    d[y][x] = d1;
    a[y] += 1;
    graph[x].push_back(y);
  }
  if (m == 0) {
    cout << 0;
    return;
  }
  for (long long i = 1; i < n + 1; i++) {
    if (a[i] == 0) v.push_back(i);
  }
  if ((long long)v.size() == 0) {
    cout << 0;
    return;
  }
  for (auto x : v) {
    v2.clear();
    mx = 1e9;
    if (used[x] == 0) {
      dfs(x);
      if (mx != 1e9) v1.push_back({x, {v2[(long long)v2.size() - 1], mx}});
    }
  }
  cout << (long long)v1.size() << "\n";
  for (auto x : v1) {
    cout << x.first << " " << x.second.first << " " << x.second.second << "\n";
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long t = 1;
  while (t--) ram5564();
  return 0;
}
