import std.stdio;
import std.ascii;
import std.c.stdio;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.regex;
import std.typecons;

struct Edge {
    int from, to, cost;
}

class UnionFind {
    int[] parent;
    int rootCount;
    this(int N) {
        parent = new int[N];
        parent[] = -1;
        rootCount = N;
    }
    int root(int x) {
        if (parent[x] == -1) return x;
        return parent[x] = root(parent[x]);
    }
    bool query(int x, int y) {
        return root(x) == root(y);
    }
    void merge(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return;
        rootCount--;
        parent[y] = x;
    }
}

void main() {
    int N, M;
    Edge[] G;

    bool input() {
        scanf("%d %d\n", &N, &M);
        if (N == 0 && M == 0) return false;
        G.clear;
        foreach (i; 0 .. M) {
            int x, y, c;
            scanf("%d %d %d\n", &x, &y, &c);
            G ~= Edge(x, y, c);
        }
        return true;
    }

    void solve() {
        auto uf = new UnionFind(N);
        G.sort!"a.cost > b.cost";
        int Ans = reduce!"a + b.cost"(0, G);
        foreach (e; G) {
            if (e.cost <= 0) continue;
            if (uf.query(e.from, e.to)) {
                Ans -= e.cost;
            } else if (uf.rootCount > 2) {
                uf.merge(e.from, e.to);
                Ans -= e.cost;
            }
        }
        writeln(Ans);
    }

    while (input) solve;
}