Problem: Example

Input

4 4
1 2 3
1 3 3
2 3 3
2 4 3


Output

1 3

Solution (in CPP):

Solution:
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <tuple>

using Bool = bool;
using Int = long long int;
template <class T, class U>
using Pair = std::pair<T, U>;
template <class T>
using Vector = std::vector<T>;

template <class Cost = Int>
struct Edge {
    Int src, dst;
    Cost cost;
    Edge(Int src = -1, Int dst = -1, Cost cost = 1)
        : src(src), dst(dst), cost(cost){};

    bool operator<(const Edge<Cost>& e) const { return this->cost < e.cost; }
    bool operator>(const Edge<Cost>& e) const { return this->cost > e.cost; }
};
template <class Cost = Int>
using Edges = Vector<Edge<Cost>>;

struct UnionFind {
    Vector<Int> par;

    void init() {
        std::iota(par.begin(), par.end(), 0);
    }

    UnionFind(Int n) : par(n) { init(); }

    Int find(Int v) {
        return v == par[v] ? v : par[v] = find(par[v]);
    }

    void unite(Int u, Int v) {
        u = find(u), v = find(v);
        par[v] = u;
    }

    Bool same(Int u, Int v) { return find(u) == find(v); }
};

int main() {
    Int n, m;
    std::cin >> n >> m;

    Edges<Int> edges(m);
    for (auto& e : edges) {
        std::cin >> e.src >> e.dst >> e.cost;
        --e.src, --e.dst;
    }
    std::sort(edges.begin(), edges.end());

    auto build = [&](Int skip) {
        UnionFind uf(n);
        Vector<Int> mst;
        Int cost = 0;

        for (Int i = 0; i < m; ++i) {
            const auto& e = edges[i];
            if (i == skip || uf.same(e.src, e.dst)) continue;

            uf.unite(e.src, e.dst);
            cost += e.cost;
            mst.push_back(i);
        }

        return std::make_pair(cost, mst);
    };

    Int mincost;
    Vector<Int> minmst;
    std::tie(mincost, minmst) = build(-1);

    Int num = 0, costsum = 0;
    for (auto t : minmst) {
        Int cost;
        Vector<Int> mst;
        std::tie(cost, mst) = build(t);

        if (mst.size() < n - 1 || cost > mincost) {
            ++num;
            costsum += edges[t].cost;
        }
    }

    std::cout << num << ' ' << costsum << std::endl;
    return 0;
}