#include <bits/stdc++.h>
using namespace std;
struct node {
  int x, y, z;
  node() {}
  node(int a, int b, int c) {
    x = a;
    y = b;
    z = c;
  }
  void show() { printf("%d %d %d\n", x + 1, y + 1, z); }
};
bool les(node a, node b) {
  if (a.x < b.x) return true;
  if (a.x > b.x) return false;
  if (a.y < b.y) return true;
  if (a.y > b.y)
    return false;
  else
    return (a.z < b.z);
}
vector<vector<pair<int, int> > > g;
vector<node> cum;
vector<int> cnt;
vector<int> used;
void dfs(int st, int v, int _min) {
  used[v] = true;
  if (g[v].size() == 0) cum.push_back(node(st, v, _min));
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i].first;
    int c = g[v][i].second;
    if (used[to] == 0) dfs(st, to, min(c, _min));
  }
}
void oku() {
  int n, p;
  scanf("%d%d", &n, &p);
  g.assign(n, vector<pair<int, int> >(0));
  used.assign(n, 0);
  cnt.assign(n, 0);
  int x, y, c;
  for (int i = 0; i < p; i++) {
    scanf("%d%d%d", &x, &y, &c);
    x--;
    y--;
    cnt[y]++;
    g[x].push_back(make_pair(y, c));
  }
  for (int i = 0; i < n; i++) {
    used.assign(n, 0);
    if (g[i].size() == 1 && cnt[i] == 0) dfs(i, i, 10000000);
  }
  sort((cum).begin(), (cum).end(), les);
  cout << cum.size() << endl;
  for (int i = 0; i < cum.size(); i++) cum[i].show();
}
int main() {
  oku();
  return 0;
}
