#include <bits/stdc++.h>
using namespace std;
struct edge {
  int v;
  int w;
};
int n;
int m;
vector<edge> v[1001];
int visited[1001];
stack<int> st;
int flag = 0;
void dfs(int s, int r) {
  visited[s] = 1;
  for (int i = 0; i < v[s].size(); i++) {
    edge x = v[s][i];
    if (visited[x.v] == -1) {
      dfs(x.v, r);
    } else if (visited[x.v] == 1 && x.v == r) {
      flag = 1;
    }
  }
  st.push(s);
}
int main() {
  cin >> n;
  cin >> m;
  int tap[n];
  int tank[n];
  for (int i = 0; i < n; i++) {
    visited[i] = -1;
    tank[i] = tap[i] = 0;
  }
  for (int i = 0; i < m; i++) {
    edge e;
    int x, y;
    cin >> x >> y >> e.w;
    e.v = y - 1;
    v[x - 1].push_back(e);
    tap[x - 1] = 1;
    tank[y - 1] = 1;
  }
  if (m == 0) {
    cout << "0" << endl;
    return 0;
  }
  vector<int> ans;
  for (int i = 0; i < n; i++) {
    if (tank[i] == 0) {
      dfs(i, i);
      if (!flag) {
        int x = st.top();
        int y;
        int we = INT_MAX;
        while (!st.empty()) {
          y = st.top();
          if (v[y].size() >= 1 && v[y][0].w < we) {
            we = v[y][0].w;
          }
          st.pop();
        }
        if (x != y) {
          ans.push_back(x + 1);
          ans.push_back(y + 1);
          ans.push_back(we);
        }
        flag = 0;
      }
    }
  }
  cout << (int)ans.size() / 3 << endl;
  for (int i = 0; i < ans.size(); i = i + 3) {
    cout << ans[i] << " " << ans[i + 1] << " " << ans[i + 2] << endl;
  }
  return 0;
}
