#include <iostream>
#include <set>
#include <vector>
#include <deque>
#include <map>
#include <cmath>
#include <random>
#include <algorithm>

#define se second
#define fi first
#define mp make_pair
#define pb push_back

typedef long long ll;
typedef long double ld;

using namespace std;

vector<int> p, w;

int get_root(int x) {
    if (p[x] == x) return x;
    return p[x] = get_root(p[x]);
}

bool is_equal(int x, int y) {
    return get_root(x) == get_root(y);
}

void unite(int x, int y) {
    x = get_root(x);
    y = get_root(y);
    if (w[x] > w[y]) swap(x, y);
    p[x] = y;
    w[y] += w[x];
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<pair<int, pair<int, int>>> a; ///{вес ребра, {x, y}}
    for (int i = 0; i < m; i++) {
        int x, y, w;
        cin >> x >> y >> w;
        x--, y--;
        a.push_back({w, {x, y}});
    }
    sort(a.begin(), a.end());
    vector<pair<int, int>> ostov;
    int answ = 0;
    p.resize(n);
    for (int i = 0; i < n; i++) {
        p[i] = i;
    }
    w.assign(n, 1);
    for (auto e : a) {
        if (!is_equal(e.se.fi, e.se.se)) {
            answ += e.fi;
            ostov.push_back(e.se);
            unite(e.se.fi, e.se.se);
        }
    }
    cout << answ << '\n';
    for (auto e : ostov) {
        cout << e.fi + 1 << ' ' << e.se + 1 << '\n';
    }
    return 0;
}