#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int id;
  int u, v, w;
} edges[100005];
int n, m;
int d[100005], cost[100005];
bool path[100005];
vector<Edge> G[100005], ans;
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    edges[i].u = u, edges[i].v = v, edges[i].w = w, edges[i].id = i;
    G[u].push_back(edges[i]);
    G[v].push_back(edges[i]);
  }
  d[1] = 0;
  cost[1] = 0;
  queue<int> que;
  que.push(1);
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (size_t i = 0; i < G[u].size(); i++) {
      Edge e = G[u][i];
      int v = e.u;
      if (v == u) v = e.v;
      if (v != 1 && d[v] == 0) {
        d[v] = d[u] + 1;
        que.push(v);
      }
      if (d[v] == d[u] + 1) cost[v] = max(cost[v], cost[u] + e.w);
    }
  }
  int u = n;
  while (d[u] != 0) {
    for (size_t i = 0; i < G[u].size(); i++) {
      Edge e = G[u][i];
      int v = e.u;
      if (v == u) v = e.v;
      if (d[v] != d[u] - 1) continue;
      if ((e.w == 1 && cost[v] == cost[u] - 1) ||
          (e.w == 0 && cost[v] == cost[u])) {
        path[e.id] = true;
        u = v;
        break;
      }
    }
  }
  for (int ind = 0; ind < m; ind++) {
    if (path[ind] && edges[ind].w == 0) {
      ans.push_back(edges[ind]);
    } else if (!path[ind] && edges[ind].w == 1) {
      ans.push_back(edges[ind]);
    }
  }
  cout << ans.size() << endl;
  for (vector<Edge>::iterator it = ans.begin(); it != ans.end(); ++it) {
    cout << it->u << " " << it->v << " " << (it->w ^ 1) << endl;
  }
  return 0;
}
