← Home
#include <bits/stdc++.h>
 
using namespace std;
using ll = long long;
 
struct RollbackUF {
    vector<int> e;
    vector<pair<int, int>> st;
    RollbackUF(int n) : e(n, -1) {}
    int size(int x) { return -e[find(x)]; }
    int find(int x) {
        return e[x] < 0 ? x : find(e[x]);
    }
    int time() { return (int)st.size(); }
    void rollback(int t) {
        for (int i = time(); i-- > t;) {
            e[st[i].first] = st[i].second;
        }
        st.resize(t);
    }
    bool join(int a, int b) {
        a = find(a);
        b = find(b);
        if (a == b) return false;
        if (e[a] > e[b]) swap(a, b);
        st.push_back({a, e[a]});
        st.push_back({b, e[b]});
        e[a] += e[b];
        e[b] = a;
        return true;
    }
};
struct Edge {
    int a, b, id;
    ll w;
};
struct Node {
    Edge key;
    Node *l = nullptr, *r = nullptr;
    ll delta = 0;
    void prop() {
        key.w += delta;
        if (l) l->delta += delta;
        if (r) r->delta += delta;
        delta = 0;
    }
    Edge top() {
        prop();
        return key;
    }
};
Node* merge(Node* a, Node* b) {
    if (!a || !b) return a ? a : b;
    a->prop();
    b->prop();
    if (a->key.w > b->key.w) swap(a, b);
    swap(a->l, (a->r = merge(b, a->r)));
    return a;
}
void pop(Node*& a) {
    a->prop();
    a = merge(a->l, a->r);
}
pair<ll, vector<int>> dmst(int n, int r, vector<Edge>& g) {
    RollbackUF uf(n);
    vector<Node*> heap(n, nullptr);
    for (const Edge& e : g) {
        heap[e.b] = merge(heap[e.b], new Node{e});
    }
    ll res = 0;
    vector<int> seen(n, -1), path(n), par(n);
    seen[r] = r;
    vector<Edge> Q(n), in(n, {-1, -1, -1, 0});
    deque<tuple<int, int, vector<Edge>>> cycs;
    for (int s = 0; s < n; ++s) {
        int u = s, qi = 0, w;
        while (seen[u] < 0) {
            if (!heap[u]) return {-1, {}};
            Edge e = heap[u]->top();
            heap[u]->delta -= e.w;
            pop(heap[u]);
            Q[qi] = e;
            path[qi++] = u;
            seen[u] = s;
            res += e.w;
            u = uf.find(e.a);
            if (seen[u] == s) {
                Node* cyc = nullptr;
                int end = qi, time_now = uf.time();
                do {
                    w = path[--qi];
                    cyc = merge(cyc, heap[w]);
                } while (uf.join(u, w));
                u = uf.find(u);
                heap[u] = cyc;
                seen[u] = -1;
                
                vector<Edge> component_edges;
                for(int i = qi; i < end; ++i) component_edges.push_back(Q[i]);
                cycs.push_front({u, time_now, component_edges});
            }
        }
        for (int i = 0; i < qi; ++i) {
            in[uf.find(Q[i].b)] = Q[i];
        }
    }
    for (auto& [u, t, comp] : cycs) {
        uf.rollback(t);
        Edge inEdge = in[u];
        for (auto& e : comp) {
            in[uf.find(e.b)] = e;
        }
        in[uf.find(inEdge.b)] = inEdge;
    }
    vector<int> edges_res(n);
    for (int i = 0; i < n; ++i) {
        edges_res[i] = in[i].id;
    }
    return {res, edges_res};
}
 
int main() {
    cin.tie(0) -> sync_with_stdio(0);
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n, m;
    cin >> n >> m;
    vector<Edge> eds(m);
    for(int i = 0;i < m;i++) {
        int u, v, w;
        cin >> u >> v >> w;
        --u, --v;
        eds[i] = {u, v, w ? i + 1 : -1, w};
    }
    auto [c, p] = dmst(n, 0, eds);
    cout << c << '\n';
    if(c <= 0) return 0;
    for(auto id : p) {
        if(id == -1) continue;
        cout << id << ' ';
    }
    cout << '\n';
}