#include <bits/stdc++.h>
using namespace std;
template <typename T>
using graph = vector<pair<pair<int64_t, int64_t>, T>>;
template <typename T>
class SplitWise {
 private:
  set<pair<T, int64_t>> borrower, creditor;
  vector<T> profit;
  void generateFlow(int64_t n) {
    int64_t cnt = 0;
    vector<vector<pair<int64_t, int64_t>>> res(n + 1);
    while (!creditor.empty() && !borrower.empty()) {
      auto cFir = *creditor.begin();
      auto bFir = *borrower.begin();
      creditor.erase(creditor.begin());
      borrower.erase(borrower.begin());
      if (cFir.first - bFir.first > 0)
        creditor.insert({cFir.first - bFir.first, cFir.second});
      else if (bFir.first - cFir.first > 0)
        borrower.insert({bFir.first - cFir.first, bFir.second});
      res[bFir.second].push_back({cFir.second, min(bFir.first, cFir.first)});
      cnt++;
    }
    cout << cnt << '\n';
    for (int64_t i = 1; i <= n; i++) {
      for (const auto &p : res[i])
        cout << i << " " << p.first << " " << p.second << '\n';
    }
  }
  void printFlow(const graph<T> &res) {
    cout << res.size() << '\n';
    int64_t cnt = 1;
    for (const auto p : res) {
      cout << p.first.first << " " << p.first.second << " " << p.second << '\n';
    }
  }

 public:
  void addTransactions(int64_t n, graph<T> &transactions) {
    profit.assign(n + 1, 0);
    for (const auto &transaction : transactions) {
      int64_t uid = transaction.first.first;
      int64_t vid = transaction.first.second;
      T w = transaction.second;
      profit[uid] -= w;
      profit[vid] += w;
    }
    for (int64_t i = 1; i <= n; i++) {
      if (profit[i] == 0)
        ;
      else if (profit[i] > 0)
        creditor.insert({profit[i], i});
      else
        borrower.insert({-profit[i], i});
    }
  }
  void giveOptimalFlow(int64_t n) { generateFlow(n); }
};
int32_t main() {
  int64_t n, m;
  cin >> n >> m;
  SplitWise<int64_t> splitWise;
  graph<int64_t> g(m);
  int64_t u, v, w;
  for (int64_t i = 0; i < m; i++)
    cin >> g[i].first.first >> g[i].first.second >> g[i].second;
  splitWise.addTransactions(n, g);
  splitWise.giveOptimalFlow(n);
  return 0;
}
