#include "bits/stdc++.h"
//#define int long long
#define range(i, a, b) for(int i = (a); i < (b); i++)
#define rep(i, a) range(i, 0, a)
#define all(a) (a).begin(),(a).end()
using namespace std;
const int INF = sizeof(int) == sizeof(long long) ? 1000000000000000000LL : 1000000000;
const int MOD = 1000000007;
const long double EPS = 1e-8;
using vi = vector <int>;
using vvi = vector <vi>;

class unionFindTree {
private:
	vector <int> tree;
	vector <int> rank;

public:
	unionFindTree() {}

	unionFindTree(int sz) {
		tree = vector <int> (sz);
		rank = vector <int> (sz, 0);
		for(int i = 0; i < tree.size(); i++)
			tree[i] = i;
	}

	unionFindTree(const unionFindTree &o) {
		tree = o.tree;
		rank = o.rank;
	}

	unionFindTree &operator=(const unionFindTree &o) {
		tree = o.tree;
		rank = o.rank;
		return (*this);
	};

	int root(int x) {
		return tree[x] == x ? x : tree[x] = root(tree[x]);
	}

	bool same(int a, int b) {
		return root(a) == root(b);
	}

	void unite(int a, int b) {
		a = root(a);
		b = root(b);
		if(a == b)return;

		if(rank[a] < rank[b]) swap(a, b);

		tree[b] = a;
		rank[a] += rank[a] == rank[b];
	}

	int size() {
		return tree.size();
	}
};


class Kruskal : public unionFindTree{
	private:
		struct edge {
			int u, v, cost;
			bool operator< (const edge& e) const {
				return cost < e.cost;
			}
		};
		vector <edge> es;
		int V;

	public:
		Kruskal(int v, int e) : unionFindTree(v){
			V = v;
			es = vector <edge> (e);
		}

		void addEdge(int start, int end, int cost) {
			es.push_back({start, end, cost});
		}

		int execute() {
			sort(es.begin(), es.end());
			int res = 0;
			for(int i = 0; i < es.size(); i++) {
				edge e = es[i];
				if(!same(e.u, e.v)) {
					unite(e.u, e.v);
					res += e.cost;
				}
			}
			return res;
		}
};


signed main() {
	int n, m;
	while (cin >> n >> m, n) {
		Kruskal pear(n, m);
		rep (i, m) {
			int a, b, d;
			scanf("%d, %d, %d", &a, &b, &d);
			d -= 100;
			pear.addEdge(a, b, d);
		}
		cout << pear.execute() / 100 << endl;
	}
	return 0;
}
