#include <bits/stdc++.h>
using namespace std;
int n, m, shortestPath, totalGoods;
vector<pair<pair<long long, long long>, int> > adj[101010];
pair<pair<long long, long long>, int> path[101010];
int distFromEnd[101010], dp[101010];
bool visited[101010], taken[101010];
vector<pair<pair<long long, long long>, int> > workingEdges;
vector<pair<long long, long long> > takenEdges;
void bfs2() {
  queue<int> q;
  q.push(n);
  visited[n] = 1;
  for (int sz = q.size(), currDist = 0; !q.empty(); sz = q.size(), currDist++) {
    while (sz--) {
      int node = q.front();
      q.pop();
      distFromEnd[node] = currDist;
      for (int i = 0; i < adj[node].size(); i++) {
        int child = adj[node][i].first.first;
        if (!visited[child]) {
          visited[child] = 1;
          q.push(child);
        }
      }
    }
  }
}
int bfs3() {
  queue<int> q;
  q.push(1);
  dp[1] = 0;
  for (int sz = q.size(), dist = 0; !q.empty(); sz = q.size(), dist++) {
    while (sz--) {
      int u = q.front();
      q.pop();
      taken[u] = 1;
      for (int i = 0; i < adj[u].size(); i++) {
        pair<pair<long long, long long>, int> child = adj[u][i];
        if (!taken[child.first.first]) {
          if (dist + 1 + distFromEnd[child.first.first] == shortestPath) {
            if (dp[u] + child.first.second >= dp[child.first.first]) {
              dp[child.first.first] = dp[u] + child.first.second;
              q.push(child.first.first);
              path[child.first.first] =
                  make_pair(pair<long long, long long>(u, child.first.second),
                            child.second);
            }
          }
        }
      }
    }
  }
  return dp[n];
}
void showTakenEdges(int node) {
  if (node == 1) return;
  pair<pair<long long, long long>, int> curr = path[node];
  if (!curr.first.second)
    takenEdges.push_back(pair<long long, long long>(node, curr.first.first));
  visited[curr.second] = 1;
  showTakenEdges(curr.first.first);
}
int main() {
  ios_base::sync_with_stdio(0);
  memset(dp, -1, sizeof dp);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int from, to, functionallity;
    cin >> from >> to >> functionallity;
    adj[from].push_back(
        make_pair(pair<long long, long long>(to, functionallity), i));
    adj[to].push_back(
        make_pair(pair<long long, long long>(from, functionallity), i));
    if (functionallity) {
      workingEdges.push_back(
          make_pair(pair<long long, long long>(from, to), i));
      totalGoods++;
    }
  }
  memset(visited, 0, sizeof visited);
  bfs2();
  memset(visited, 0, sizeof visited);
  shortestPath = distFromEnd[1];
  int functioned = bfs3();
  memset(taken, 0, sizeof taken);
  showTakenEdges(n);
  int badsInShortestPath = shortestPath - functioned;
  int changesByTheGang = badsInShortestPath + totalGoods - functioned;
  cout << changesByTheGang << endl;
  for (int i = 0; i < takenEdges.size(); i++) {
    pair<long long, long long> edges = takenEdges[i];
    cout << edges.first << " " << edges.second << " " << 1 << endl;
  }
  for (int i = 0; i < workingEdges.size(); i++) {
    pair<pair<long long, long long>, int> edges = workingEdges[i];
    if (!visited[edges.second])
      cout << edges.first.first << " " << edges.first.second << " " << 0
           << endl;
  }
}
