#include <bits/stdc++.h>
using namespace std;
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cout << *it << " = " << a << "\n";
  err(++it, args...);
}
const long long N = 1e5 + 5, M = 1e9 + 7, inf = 1e6;
vector<int> g[N];
vector<pair<int, int>> dp(N, {inf, inf}), ans, cm;
map<pair<int, int>, int> m;
set<pair<int, int>> sp;
int pre[N];
void dijkstra() {
  set<pair<pair<int, int>, int>> s;
  dp[1] = {0, 0};
  s.insert({dp[1], 1});
  while (not s.empty()) {
    int u = s.begin()->second;
    s.erase(s.begin());
    for (int v : g[u]) {
      bool f = m[{u, v}] == 0;
      if (dp[v] > make_pair(dp[u].first + 1, dp[u].second + f)) {
        s.erase({dp[v], v});
        dp[v] = make_pair(dp[u].first + 1, dp[u].second + f);
        pre[v] = u;
        s.insert({dp[v], v});
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  ;
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < q; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    g[x].push_back(y);
    g[y].push_back(x);
    cm.push_back({x, y});
    m[{x, y}] = m[{y, x}] = z;
  }
  dijkstra();
  int u = n;
  while (pre[u] != 0) {
    sp.insert({u, pre[u]});
    sp.insert({pre[u], u});
    u = pre[u];
  }
  for (auto e : cm) {
    if (sp.find(e) != sp.end() and m[e] == 0) {
      ans.push_back(e);
    }
    if (sp.find(e) == sp.end() and m[e] == 1) {
      ans.push_back(e);
    }
  }
  cout << ans.size() << "\n";
  for (auto e : ans) {
    cout << e.first << " " << e.second << " " << (1 ^ m[{e.first, e.second}])
         << "\n";
  }
}
