#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
const int inf = 1e6;
set<pair<int, int> > edge[2];
vector<pair<int, int> > g[N + 100];
pair<int, int> dist[N + 100];
int pre[N + 100];
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    edge[z].insert(make_pair(min(x, y), max(x, y)));
    g[x].push_back(make_pair(y, z));
    g[y].push_back(make_pair(x, z));
  }
  for (int i = 1; i <= n; i++) {
    dist[i] = make_pair(inf, inf);
  }
  dist[1] = make_pair(0, 0);
  priority_queue<pair<pair<int, int>, int>, vector<pair<pair<int, int>, int> >,
                 greater<pair<pair<int, int>, int> > >
      pq;
  pq.push(make_pair(make_pair(0, 0), 1));
  while (!pq.empty()) {
    pair<pair<int, int>, int> A = pq.top();
    pq.pop();
    int c1 = A.first.first, c2 = A.first.second;
    int v = A.second;
    if (dist[v] != make_pair(c1, c2)) continue;
    for (auto it : g[v]) {
      int cost;
      if (it.second == 1)
        cost = 0;
      else
        cost = 1;
      if (dist[it.first] > make_pair(c1 + 1, c2 + cost)) {
        dist[it.first] = make_pair(c1 + 1, c2 + cost);
        pre[it.first] = v;
        pq.push(make_pair(dist[it.first], it.first));
      }
    }
  }
  int cur = n;
  vector<pair<int, int> > ans;
  while (cur != 1) {
    int p = pre[cur];
    if (edge[1].find(make_pair(min(p, cur), max(p, cur))) != edge[1].end()) {
      edge[1].erase(make_pair(min(p, cur), max(p, cur)));
    } else {
      ans.push_back(make_pair(p, cur));
    }
    cur = p;
  }
  printf("%d\n", dist[n].second + (int)edge[1].size());
  for (auto it : ans) {
    printf("%d %d %d\n", it.first, it.second, 1);
  }
  for (auto it : edge[1]) {
    printf("%d %d %d\n", it.first, it.second, 0);
  }
}
