#include <bits/stdc++.h>
using namespace std;
struct debugger {
  template <typename T>
  debugger &operator,(const T v) {
    cerr << v << " ";
    return *this;
  }
} dbg;
int BigMod(long long B, long long P, long long M) {
  long long R = 1;
  while (P > 0) {
    if (P % 2 == 1) {
      R = (R * B) % M;
    }
    P /= 2;
    B = (B * B) % M;
  }
  return (int)R;
}
struct data {
  int v, w, c;
  bool operator<(const data &p) const { return p.w < w; }
};
int n, m;
vector<data> G[2][100009];
int dis[2][100009];
void djk(int st, int gi, int ind) {
  for (int i = 0; i < 100009; i++) dis[ind][i] = (1 << 30);
  priority_queue<data> Q;
  Q.push({st, 0, 0});
  dis[ind][st] = 0;
  while (!Q.empty()) {
    assert((int)Q.size() < 100100);
    int u = Q.top().v;
    int w = Q.top().w;
    Q.pop();
    for (int i = 0; i < (int)G[gi][u].size(); i++) {
      int v = G[gi][u][i].v;
      int w = G[gi][u][i].w;
      if (dis[ind][u] + w < dis[ind][v]) {
        dis[ind][v] = dis[ind][u] + w;
        Q.push({v, dis[ind][v], 0});
      }
    }
  }
  return;
}
void buildGraph() {
  int u, j;
  for (u = 0; u < (100009); u++) {
    for (j = 0; j < ((int)G[0][u].size()); j++) {
      int v = G[0][u][j].v;
      int w = G[0][u][j].c;
      if (dis[0][u] + dis[1][v] + 1 == dis[0][n]) {
        G[1][u].push_back({v, !w, w});
        G[1][v].push_back({u, !w, w});
      }
    }
  }
}
int color[100009];
map<pair<int, int>, bool> M;
vector<data> Ans;
vector<data> para;
void dfs(int u, int len, int &flag, int cnt) {
  if (color[u]) return;
  color[u] = 1;
  assert(cnt < 1001000);
  if (u == n) {
    if (len == dis[0][n]) {
      flag = 1;
      for (int i = 0; i < (int)para.size(); i++) {
        int u = para[i].v;
        int v = para[i].w;
        int c = para[i].c;
        M[make_pair(min(u, v), max(u, v))] = true;
        if (c == 0) Ans.push_back({u, v, !c});
      }
    }
    return;
  }
  for (int i = 0; i < (int)G[1][u].size(); i++) {
    int v = G[1][u][i].v;
    int w = G[1][u][i].w;
    int c = G[1][u][i].c;
    if (dis[0][u] + w + dis[1][v] == dis[0][n]) {
      para.push_back({u, v, c});
      dfs(v, len + w, flag, cnt + 1);
      para.pop_back();
      if (flag) return;
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  int i, j;
  while (cin >> n >> m) {
    for (i = 0; i < (m); i++) {
      int u, v, c;
      cin >> u >> v >> c;
      G[0][u].push_back({v, 1, c});
      G[0][v].push_back({u, 1, c});
    }
    djk(1, 0, 0);
    djk(n, 0, 1);
    buildGraph();
    djk(1, 1, 0);
    djk(n, 1, 1);
    int flag = 0;
    dfs(1, 0, flag, 0);
    int u;
    for (u = 0; u < (100009); u++) {
      for (j = 0; j < ((int)G[0][u].size()); j++) {
        int v = G[0][u][j].v;
        int c = G[0][u][j].c;
        if (M.find(make_pair(min(u, v), max(u, v))) == M.end()) {
          if (c == 1) {
            Ans.push_back({u, v, !c});
          }
          M[make_pair(min(u, v), max(u, v))] = true;
        }
      }
    }
    cout << (int)Ans.size() << endl;
    for (i = 0; i < ((int)Ans.size()); i++)
      cout << Ans[i].v << " " << Ans[i].w << " " << Ans[i].c << endl;
  }
}
