#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e+14;
const int M = 100200;
struct triple {
  int from;
  int to;
  int value;
  bool operator<(triple c) const {
    if (from != c.from) return from < c.from;
    return to < c.to;
  }
  bool operator==(triple c) const { return (from == c.from) && (to == c.to); }
};
inline triple make_triple(int f, int t, int v) {
  triple ans;
  ans.from = f;
  ans.to = t;
  ans.value = v;
  return ans;
}
int main() {
  ios_base::sync_with_stdio(0);
  int n, m, i, a, b, z, good = 0;
  cin >> n >> m;
  vector<vector<pair<int, long long> > > g(n + 1);
  set<triple> arr;
  set<triple>::iterator it;
  for (i = 0; i < m; i++) {
    cin >> a >> b >> z;
    g[a].push_back(make_pair(b, M + (1 - z)));
    g[b].push_back(make_pair(a, M + (1 - z)));
    arr.insert(make_triple(min(a, b), max(a, b), z));
    if (z) good++;
  }
  int s = 1;
  vector<long long> d(n + 1, INF);
  vector<int> p(n + 1);
  d[s] = 0;
  priority_queue<pair<long long, int> > q;
  q.push(make_pair(0, s));
  while (!q.empty()) {
    int v = q.top().second;
    long long cur_d = -q.top().first;
    q.pop();
    if (cur_d > d[v]) continue;
    for (size_t j = 0; j < g[v].size(); ++j) {
      int to = g[v][j].first;
      long long len = g[v][j].second;
      if (d[v] + len < d[to]) {
        d[to] = d[v] + len;
        p[to] = v;
        q.push(make_pair(-d[to], to));
      }
    }
  }
  long long repair = d[n] % M;
  long long go = d[n] / M;
  long long other = go - repair;
  long long explode = good - other;
  cout << explode + repair << endl;
  s = n;
  int from;
  while (s != 1) {
    from = p[s];
    it = arr.find(make_triple(min(from, s), max(from, s), 0));
    if (it == arr.end()) {
      printf("ololo");
      return 0;
    }
    if (it->value == 0) {
      printf("%d %d 1\n", from, s);
    }
    arr.erase(it);
    s = from;
  }
  for (it = arr.begin(); it != arr.end(); it++) {
    if (it->value == 1) printf("%d %d 0\n", it->from, it->to);
  }
}
