#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 10;
vector<pair<long long, long long> > edge[N];
vector<long long> cost(N, 0), used(N, 0);
void dfs(long long no) {
  used[no]++;
  for (pair<long long, long long> to : edge[no]) {
    cost[no] += to.second;
    cost[to.first] -= to.second;
    if (!used[to.first]) dfs(to.first);
  }
}
using T = tuple<long long, long long, long long>;
vector<T> ans;
void dfs2(long long no, long long r) {
  if (cost[no] < 0) {
    long long v = min(cost[r], -cost[no]);
    if (v) ans.push_back(T(r, no, v));
    cost[r] -= v;
    cost[no] += v;
  }
  if (used[no]) return;
  used[no]++;
  for (pair<long long, long long> to : edge[no]) {
    dfs2(to.first, r);
  }
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  long long n, m;
  cin >> n >> m;
  for (long long _ = (0); _ < ((m)); ++_) {
    long long x, y, d;
    cin >> x >> y >> d;
    edge[x - 1].emplace_back(y - 1, d);
  }
  for (long long i = (0); i < ((n)); ++i) {
    if (used[i]) continue;
    dfs(i);
  }
  vector<pair<long long, long long> > pos, neg;
  for (long long i = (0); i < ((n)); ++i) {
    if (cost[i] > 0)
      pos.push_back(pair<long long, long long>(i, cost[i]));
    else if (cost[i] < 0)
      neg.push_back(pair<long long, long long>(i, -cost[i]));
  }
  while (pos.size()) {
    long long v = min(pos.back().second, neg.back().second);
    ans.push_back(T(pos.back().first, neg.back().first, v));
    pos.back().second -= v;
    neg.back().second -= v;
    if (pos.back().second == 0) pos.pop_back();
    if (neg.back().second == 0) neg.pop_back();
  }
  cout << ans.size() << endl;
  for (long long i = (0); i < ((ans.size())); ++i) {
    long long x, y, d;
    tie(x, y, d) = ans[i];
    cout << x + 1 << " " << y + 1 << " " << d << "\n";
  }
  return 0;
}
