#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 200005;

ifstream fin("apm.in");
ofstream fout("apm.out");

vector<int> t;

int find(int x)
{
    if (t[x] == 0)
        return x;
    t[x] = find(t[x]);
    return t[x];
}

void unite(int x, int y)
{
    int tx = find(x);
    int ty = find(y);
    t[tx] = ty;
}

int main()
{
    int n, m;
    fin >> n >> m;


    vector< pair<int, pair<int, int>> > muchii;
    muchii.resize(m);
    t.resize(n + 1);
    for (int i = 0; i < m; i++)
    {
        int c, x, y;
        fin >> x >> y >> c;
        muchii[i] = { c, {x, y} };
    }

    sort(muchii.begin(), muchii.end());

    int costArb = 0;
    vector<pair<int, int>> arbore;
    for (auto muchie : muchii)
    {
        int x = muchie.second.first;
        int y = muchie.second.second;
        int cost = muchie.first;

        if (find(x) != find(y))
        {
            arbore.push_back({ x, y });
            costArb += cost;

            unite(x, y);
        }
    }

    fout << costArb << '\n' << arbore.size() << '\n';
    for (auto muchie : arbore)
        fout << muchie.first << ' ' << muchie.second << '\n';

    return 0;
}