#include <bits/stdc++.h>
using namespace std;
struct graph {
  int node, d, c;
  bool operator<(graph A) const {
    if (d != A.d) return d > A.d;
    return c > A.c;
  }
};
int n, m;
vector<graph> adj[100010];
map<pair<int, int>, bool> mp;
vector<pair<pair<int, int>, int>> edges, ans;
int dis[100010], cs[100010], par[100010];
void solve() {
  priority_queue<graph> pq;
  for (int i = 1; i <= n; ++i) {
    dis[i] = INT_MAX;
    cs[i] = INT_MAX;
  }
  graph s;
  s.node = 1;
  dis[1] = 0;
  cs[1] = 0;
  pq.push(s);
  while (!pq.empty()) {
    graph u = pq.top();
    pq.pop();
    for (graph v : adj[u.node]) {
      int w = dis[u.node] + 1;
      int cost = cs[u.node] + v.c;
      if (dis[v.node] > w) {
        par[v.node] = u.node;
        dis[v.node] = w;
        cs[v.node] = cost;
        v.d = w;
        v.c = cost;
        pq.push(v);
      } else if (dis[v.node] == w && cs[v.node] > cost) {
        par[v.node] = u.node;
        v.d = w;
        v.c = cost;
        cs[v.node] = cost;
        pq.push(v);
      }
    }
  }
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; ++i) {
    int u, v, w;
    scanf("%d %d %d", &u, &v, &w);
    adj[u].push_back({v, 0, 1 ^ w});
    adj[v].push_back({u, 0, 1 ^ w});
    edges.push_back({{u, v}, w});
  }
  solve();
  int cur = n;
  while (par[cur] != 0) {
    mp[{cur, par[cur]}] = 1;
    mp[{par[cur], cur}] = 1;
    cur = par[cur];
  }
  for (auto p : edges) {
    int u = p.first.first;
    int v = p.first.second;
    int w = p.second;
    if (mp[{u, v}] && !w)
      ans.push_back({{u, v}, 1});
    else if (!mp[{u, v}] && w)
      ans.push_back({{u, v}, 0});
  }
  printf("%d\n", (int)ans.size());
  for (auto p : ans)
    printf("%d %d %d\n", p.first.first, p.first.second, p.second);
}
