#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 7, INF = 1e9 + 7;
vector<int> adj[MAXN], trace[MAXN];
int n, m, d[MAXN] = {}, cnt, id[MAXN], pn, work = 0, g[MAXN], w[MAXN], tr[MAXN],
          x[MAXN];
bitset<MAXN> vis;
void bfs() {
  fill(d + 2, d + 1 + n, INF), d[1] = 0;
  queue<int> q;
  q.push(1);
  while (q.size()) {
    int u = q.front();
    q.pop();
    for (auto i : adj[u]) {
      int v = g[i] - u, z = w[i];
      if (d[v] == d[u] + 1) trace[v].push_back(i);
      if (d[v] > d[u] + 1) d[v] = d[u] + 1, q.push(v), trace[v].push_back(i);
    }
  }
}
void dfs(int u) {
  vis[u] = 1;
  for (auto v : adj[u])
    if (!vis[g[v] - u]) dfs(g[v] - u);
  if (u == n) pn = cnt;
  id[cnt] = u, --cnt;
}
void upd(int u, int v, int z, int i) {
  int val = d[v] + (z ? -1 : 1);
  if (d[u] > val) d[u] = val, tr[u] = i;
}
void solve() {
  bfs();
  for (int i = 1; i <= n; ++i) adj[i].clear();
  for (int i = 1; i <= n; ++i)
    for (auto it : trace[i]) adj[g[it] - i].push_back(it);
  cnt = n;
  dfs(1);
  fill(d + 1, d + 1 + n, INF);
  d[n] = work;
  for (int i = pn - 1; i >= 1; --i) {
    int u = id[i];
    for (auto it : adj[u]) {
      int v = g[it] - u, z = w[it];
      upd(u, v, z, it);
    }
  }
  vis.reset();
  int tmp = 1;
  while (tmp != n) vis[tr[tmp]] = 1, tmp = g[tr[tmp]] - tmp;
  cout << d[1] << '\n';
  for (int i = 1; i <= m; ++i)
    if (vis[i] != w[i])
      cout << x[i] << ' ' << g[i] - x[i] << ' ' << vis[i] << '\n';
}
void init() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v >> w[i], work += w[i];
    g[i] = u + v, x[i] = u;
    adj[u].push_back(i), adj[v].push_back(i);
  }
}
int main() {
  init();
  solve();
  return 0;
}
