#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;     }   }