#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#define show(x) cerr << #x << " = " << x << endl
using namespace std;
template <typename S, typename T>
ostream& operator<<(ostream& os, const pair<S, T>& p)
{
    os << "<" << p.first << "," << p.second
       << ">";
    return os;
}
class DisjointSets
{
public:
    DisjointSets(const int v) : parent(v), rank(v, 0), size(v, 1) { iota(parent.begin(), parent.end(), 0); }
    bool same(const int a, const int b) { return find(a) == find(b); }
    int find(const int a) { return parent[a] == a ? a : parent[a] = find(parent[a]); }
    void unite(int a, int b)
    {
        a = find(a);
        b = find(b);
        if (a == b) {
            return;
        }
        if (rank[a] < rank[b]) {
            swap(a, b);
        }
        rank[a] += rank[b];
        size[a] += size[b];
        parent[b] = a;
    }
    int getSize(const int i) { return size[find(i)]; }

private:
    vector<int> parent;
    vector<int> rank;
    vector<int> size;
};
struct Edge {
    Edge(const int u, const int v, const int w, const char l) : u{u}, v{v}, w{w}, A{(int)(l == 'A')} {}
    int u;
    int v;
    int w;
    int A;
    bool operator<(const Edge& e) const
    {
        return w != e.w ? w < e.w : A > e.A;
    }
};
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    while (true) {
        constexpr int MAX = 1000;
        int N, M, K;
        cin >> N >> M >> K;
        if (N == 0 and M == 0 and K == 0) {
            break;
        }
        vector<Edge> e;
        DisjointSets UF(N);
        for (int i = 0; i < M; i++) {
            int u, v, w;
            char l;
            cin >> u >> v >> w >> l;
            u--, v--;
            e.push_back(Edge(u, v, w, l));
            UF.unite(u, v);
        }
        if (UF.getSize(0) < N) {
            cout << -1 << endl;
            continue;
        }
        if (K == 0 or K == N - 1) {
            const int a = K == N - 1;
            sort(e.begin(), e.end());
            DisjointSets uf(N);
            int sum = 0;
            for (int i = 0; i < M; i++) {
                if (e[i].A != a) {
                    continue;
                }
                const int u = e[i].u;
                const int v = e[i].v;
                if (not uf.same(u, v)) {
                    uf.unite(u, v);
                    sum += e[i].w;
                }
            }
            cout << sum << endl;
        } else {
            auto check = [&](const int c) {
                vector<Edge> E = e;
                for (int i = 0; i < M; i++) {
                    if (E[i].A == 1) {
                        E[i].w = e[i].w + c;
                    }
                }
                sort(E.begin(), E.end());
                DisjointSets uf(N);
                int sum = 0;
                int a = 0;
                for (int i = 0; i < M; i++) {
                    const int u = E[i].u;
                    const int v = E[i].v;
                    if (not uf.same(u, v)) {
                        sum += E[i].w;
                        a += E[i].A;
                        uf.unite(u, v);
                    }
                }
                return a >= K;
            };
            int c = -MAX;
            for (; c <= MAX; c++) {
                if (not check(c)) {
                    break;
                }
            }
            c--;
            for (int i = 0; i < M; i++) {
                if (e[i].A == 1) {
                    e[i].w += c;
                }
            }
            sort(e.begin(), e.end());
            DisjointSets uf(N);
            int sum = 0;
            for (int i = 0; i < M; i++) {
                const int u = e[i].u;
                const int v = e[i].v;
                if (not uf.same(u, v)) {
                    uf.unite(u, v);
                    sum += e[i].w;
                }
            }
            cout << (c <= -MAX or c >= MAX - 1 ? -1 : sum - K * c) << endl;
        }
    }
    return 0;
}



Measured memory_bytes: 3144