// Arup Guha
// 6/14/2026
// Solution to Kattis Problem: Minimum Soanning Tree
// https://open.kattis.com/problems/minspantree

using namespace std;

#include <bits/stdc++.h>

struct edge {

    int u;
    int v;
    int w;

    // Here, we define less than, which the priority queue uses.
    // pq's are max queues in c++, so this is pretty weird.
    bool operator<(const edge& other) const {
        return w >= other.w;
    }
};

vector<pair<int,int>> prims(vector<vector<edge>>& g, int v, int& weight);

int main() {

    // Get number of vertices and edges.
    int n, e;
    cin >> n >> e;

    while (n != 0) {

        // Make the graph.
        vector<vector<edge>> graph(n);

        // Add each edge into the graph.
        for (int i=0; i<e; i++) {

            // Read in, is already 0 based.
            struct edge e1, e2;
            cin >> e1.u >> e1.v >> e1.w;

            // Add both edges.
            e2.u = e1.v; e2.v = e1.u; e2.w = e1.w;
            graph[e1.u].push_back(e1);
            graph[e2.u].push_back(e2);
        }

        // Run Prim's.
        int mst = 0;
        vector<pair<int,int>> res = prims(graph, 0, mst);

        // Get rid of this case.
        if (res.size() < n-1)
            cout << "Impossible\n";

        // Regular case.
        else {

            // Sort edges first.
            sort(res.begin(), res.end());

            // Output for the case.
            cout << mst << endl;
            for (int i=0; i<res.size(); i++)
                cout << res[i].first << " " << res[i].second << endl;
        }
        // Get next case.
        cin >> n >> e;
    }

    return 0;
}

// Returns the MST of the graph g, starting Prim's algorithm at vertex v.
vector<pair<int,int>> prims(vector<vector<edge>>& g, int v, int& weight) {

    // Set up prims.
    int n = g.size();

    // Store vertices connected.
    vector<bool> used(n, false);

    // Store mst here.
    vector<pair<int,int>> res;

    // Priority Queue of edges to consider, put in edges from v.
    priority_queue<edge> pq;
    used[v] = true;
    for (auto e: g[v])
        pq.push(e);

    // Bookkeeping.
    int numE = 0;
    int cost = 0;

    // We'll handle the disconnected case in the loop.
    while (numE < n-1) {

        // Indicates no MST (not connected).
        if (pq.size() == 0) break;

        // Get the next edge.
        edge cur = pq.top(); pq.pop();

        // Doesn't help us get anywhere new.
        if (used[cur.u] && used[cur.v]) continue;

        // Added vertex.
        int nV = !used[cur.u] ? cur.u : cur.v;
        numE++;
        used[nV] = true;
        cost += cur.w;
        res.push_back({min(cur.u, cur.v), max(cur.u, cur.v)});

        // Add edges from this vertex.
        for (auto e: g[nV])
            pq.push(e);
    }

    // Ta da!
    weight = cost;
    return res;
}
