#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const long long INF = 1e9;
vector<pair<int, long long> > g[N];
unordered_map<long long, int> mp;
vector<pair<pair<int, int>, int> > rg;
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  rg.resize(m);
  for (int i = 0; i < m; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    x--;
    y--;
    z = INF - z;
    g[x].push_back({y, z});
    g[y].push_back({x, z});
    rg[i] = {{x, y}, z};
  }
  priority_queue<pair<long long, int> > q;
  q.push({0, 0});
  vector<long long> d(n, INF * INF);
  vector<int> p(n, -1);
  p[0] = 0;
  d[0] = 0;
  while (!q.empty()) {
    long long r = -q.top().first, v = q.top().second;
    q.pop();
    if (r > d[v]) continue;
    for (auto to : g[v]) {
      if (d[to.first] > d[v] + to.second) {
        d[to.first] = d[v] + to.second;
        p[to.first] = v;
        q.push({-d[to.first], to.first});
      }
    }
  }
  int x = p[n - 1], y = n - 1;
  while (x != y) {
    mp[(x * INF) + y] = 1;
    mp[(y * INF) + x] = 1;
    y = x;
    x = p[x];
  }
  vector<pair<pair<int, int>, int> > ans;
  for (auto it : rg) {
    if (mp[it.first.first * INF + it.first.second] && it.second == INF) {
      ans.push_back({it.first, 1});
    } else if (!mp[it.first.first * INF + it.first.second] &&
               it.second != INF) {
      ans.push_back({it.first, 0});
    }
  }
  cout << ans.size() << endl;
  for (auto it : ans) {
    cout << it.first.first + 1 << " " << it.first.second + 1 << " " << it.second
         << endl;
  }
  return 0;
}
