#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 100, INF = 1e9;
struct edge {
  long long to, cost, id;
};
vector<edge> g[N];
long long d[N], cost[N], path[N], used[N];
pair<long long, long long> from[N];
long long n, m;
void bfs() {
  fill(d, d + n, INF);
  d[0] = 0;
  queue<long long> q;
  q.push(0);
  while ((long long)q.size()) {
    long long v = q.front();
    q.pop();
    if (used[v]) continue;
    used[v] = 1;
    for (auto i : g[v]) {
      long long u = i.to;
      long long c = cost[v] + i.cost;
      if (d[v] + 1 < d[u] || (d[v] + 1 == d[u] && c < cost[u])) {
        d[u] = d[v] + 1;
        from[u] = {v, i.id};
        cost[u] = c;
        q.push(u);
      }
    }
  }
  long long v = n - 1;
  while (v != 0) {
    long long id = from[v].second;
    path[id] = 1;
    v = from[v].first;
  }
}
signed main() {
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  vector<pair<pair<long long, long long>, long long>> ed(m);
  for (long long i = 0; i < m; i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    ed[i] = {{a, b}, c};
    c ^= 1;
    g[a].push_back({b, c, i});
    g[b].push_back({a, c, i});
  }
  bfs();
  long long ans = 0;
  for (long long i = 0; i < m; i++) {
    if (path[i] && ed[i].second == 0 || (!path[i] && ed[i].second == 1)) ans++;
  }
  cout << ans << '\n';
  for (long long i = 0; i < m; i++) {
    if (path[i] && ed[i].second == 0 || (!path[i] && ed[i].second == 1))
      cout << ed[i].first.first + 1 << ' ' << ed[i].first.second + 1 << ' '
           << (ed[i].second ^ 1) << '\n';
  }
}
