#include <bits/stdc++.h>
using namespace std;
template <typename X>
ostream& operator<<(ostream& x, const vector<X>& v) {
  for (long long i = 0; i < v.size(); ++i) x << v[i] << " ";
  return x;
}
template <typename X>
ostream& operator<<(ostream& x, const set<X>& v) {
  for (auto it : v) x << it << " ";
  return x;
}
template <typename X, typename Y>
ostream& operator<<(ostream& x, const pair<X, Y>& v) {
  x << v.ff << " " << v.ss;
  return x;
}
template <typename T, typename S>
ostream& operator<<(ostream& os, const unordered_map<T, S>& v) {
  for (auto it : v) os << it.first << "=>" << it.second << endl;
  return os;
}
struct pair_hash {
  inline std::size_t operator()(
      const std::pair<long long, long long>& v) const {
    return v.first * 31 + v.second;
  }
};
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC targett("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
const int N = 100005;
;
int dis[N];
vector<pair<int, int>> dp[N];
bool vis[N];
int dpp[N];
int pth;
int n;
int xx;
int f(int i, int j) {
  if (i == n - 1) {
    return 0;
  }
  if (dis[i] + j != pth) {
    return -1000000007;
  }
  if (dpp[i] != -1) {
    return dpp[i];
  }
  dpp[i] = 0;
  for (pair<int, int> k : dp[i]) {
    dpp[i] = max(dpp[i], k.second + f(k.first, j + 1));
  }
  return dpp[i];
}
set<pair<pair<int, int>, int>> ans;
void recover(int i, int j) {
  if (i == n - 1) {
    return;
  }
  int mx = -1;
  int vr = -1;
  int ff;
  for (pair<int, int> k : dp[i]) {
    if (mx <= f(k.first, j + 1) + k.second) {
      mx = f(k.first, j + 1) + k.second;
      vr = k.first;
      ff = k.second ^ 1;
    }
  }
  if (ff == 1)
    ans.insert({{min(i, vr), max(i, vr)}, ff});
  else
    ans.erase({{min(i, vr), max(i, vr)}, ff});
  recover(vr, j + 1);
}
int main() {
  int m;
  cin >> n >> m;
  int on = 0;
  pair<pair<int, int>, int> ed[m];
  for (long long i = 0; i < m; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    --x;
    --y;
    ed[i] = {{x, y}, z};
    on += z;
    dp[x].push_back({y, z});
    dp[y].push_back({x, z});
  }
  queue<pair<int, int>> q;
  q.push({n - 1, 0});
  vis[n - 1] = true;
  while (q.size()) {
    int dd = q.front().second;
    int curr = q.front().first;
    q.pop();
    dis[curr] = dd;
    for (pair<int, int> i : dp[curr]) {
      if (!vis[i.first]) {
        vis[i.first] = true;
        q.push({i.first, dd + 1});
      }
    }
  }
  pth = dis[0];
  memset(dpp, -1, sizeof dpp);
  int xxp = f(0, 0);
  cout << on + pth - 2 * dpp[0] << endl;
  for (long long i = 0; i < m; i++) {
    if (ed[i].second == 1) {
      ans.insert({{min(ed[i].first.first, ed[i].first.second),
                   max(ed[i].first.first, ed[i].first.second)},
                  ed[i].second ^ 1});
    }
  }
  recover(0, 0);
  for (auto it = ans.begin(); it != ans.end(); ++it) {
    cout << (*it).first.first + 1 << " " << (*it).first.second + 1 << " "
         << (*it).second << endl;
  }
}
