#include <bits/stdc++.h>
using namespace std;
template <typename T>
struct Graph {
  int vSize;
  vector<pair<T, int> > *adj;
  T inf;
  T *d;
  int *parent;
  Graph(int n) {
    this->inf = 10000000;
    this->vSize = n;
    adj = new vector<pair<T, int> >[n];
  }
  void addEdge(int u, int v, T w) { adj[u].push_back(make_pair(w, v)); }
  T *SSSP(int s) {
    d = (T *)malloc(vSize * sizeof(T));
    for (int i = 0; i < vSize; i++) {
      d[i] = inf;
    }
    d[s] = 0;
    priority_queue<pair<T, int>, vector<pair<T, int> >, greater<pair<T, int> > >
        pq;
    pq.push(make_pair(0, s));
    while (!pq.empty()) {
      int cur = pq.top().second;
      T curw = pq.top().first;
      pq.pop();
      if (curw > d[cur]) {
        continue;
      }
      for (int i = 0; i < adj[cur].size(); i++) {
        int to = adj[cur][i].second;
        T nw = adj[cur][i].first;
        if (d[cur] + nw < d[to]) {
          d[to] = d[cur] + nw;
          pq.push(make_pair(d[to], to));
        }
      }
    }
    return d;
  }
  vector<T> getSSSPVector() {
    vector<T> distance;
    for (int i = 0; i < vSize; i++) {
      distance.push_back(d[i]);
    }
    return distance;
  }
  vector<int> getPath(int u, int v) {
    vector<int> path;
    vector<int> hasil;
    int cur = v;
    path.push_back(cur);
    while (parent[cur] != -1) {
      cur = parent[cur];
      path.push_back(cur);
    }
    if (cur != u) {
      return vector<int>();
    }
    for (int i = path.size() - 1; i >= 0; i--) {
      hasil.push_back(path[i]);
    }
    return hasil;
  }
  int *getParentArray(int s) {
    queue<int> q;
    vector<bool> visited(vSize, false);
    visited[s] = true;
    parent = (int *)malloc(vSize * sizeof(int));
    for (int i = 0; i < vSize; i++) {
      parent[i] = -1;
    }
    q.push(s);
    while (!q.empty()) {
      int cur = q.front();
      q.pop();
      for (int i = 0; i < adj[cur].size(); i++) {
        T w = adj[cur][i].first;
        int to = adj[cur][i].second;
        if (visited[to] == false && d[to] == d[cur] + w) {
          visited[to] = true;
          parent[to] = cur;
          q.push(to);
        }
      }
    }
    return parent;
  }
  T *bfs(int s) {
    d = (T *)malloc(vSize * sizeof(T));
    for (int i = 0; i < vSize; i++) {
      d[i] = inf;
    }
    d[s] = 0;
    deque<int> q;
    q.push_front(s);
    while (!q.empty()) {
      int cur = q.front();
      q.pop_front();
      for (int i = 0; i < adj[cur].size(); i++) {
        T w = adj[cur][i].first;
        int to = adj[cur][i].second;
        if (d[cur] + w < d[to]) {
          d[to] = d[cur] + w;
          if (w == 1) {
            q.push_back(to);
          } else {
            q.push_front(to);
          }
        }
      }
    }
    return d;
  }
};
int main() {
  int n, m;
  cin >> n >> m;
  Graph<int> *g = new Graph<int>(n + 1);
  int edges[m][3];
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    w ^= 1;
    g->addEdge(u, v, 1);
    g->addEdge(v, u, 1);
    edges[i][0] = w;
    edges[i][1] = u;
    edges[i][2] = v;
  }
  int *distance = g->bfs(1);
  Graph<int> *g2 = new Graph<int>(n + 1);
  for (int i = 0; i < m; i++) {
    int from = edges[i][1];
    int to = edges[i][2];
    int w = edges[i][0];
    if (distance[from] + 1 == distance[to]) {
      g2->addEdge(from, to, w);
    }
    if (distance[to] + 1 == distance[from]) {
      g2->addEdge(to, from, w);
    }
  }
  distance = g2->bfs(1);
  g2->getParentArray(1);
  vector<int> path = g2->getPath(1, n);
  set<pair<int, int> > pathused;
  for (int i = 0; i < path.size() - 1; i++) {
    pathused.insert(make_pair(path[i], path[i + 1]));
    pathused.insert(make_pair(path[i + 1], path[i]));
  }
  vector<pair<int, pair<int, int> > > hasil;
  for (int i = 0; i < m; i++) {
    if (pathused.find(make_pair(edges[i][1], edges[i][2])) != pathused.end()) {
      if (edges[i][0] == 1) {
        hasil.push_back(
            make_pair(edges[i][0], make_pair(edges[i][1], edges[i][2])));
      }
    } else {
      if (edges[i][0] == 0) {
        hasil.push_back(
            make_pair(edges[i][0], make_pair(edges[i][1], edges[i][2])));
      }
    }
  }
  cout << hasil.size() << "\n";
  for (int i = 0; i < hasil.size(); i++) {
    cout << hasil[i].second.first << " " << hasil[i].second.second << " "
         << hasil[i].first << "\n";
  }
}
