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<bits/stdc++.h>
using namespace std;

typedef long long lint;
typedef long double ldouble;
#define REP(i, x, n) for(int i = x ; i < n ; i++)
#define rep(i, n) REP(i, 0, n)
#define repr(i, n) for(int i = n - 1 ; i >= 0 ; i--)
#define SORT(c) sort((c).begin(), (c).end())

const int IINF = 1e9 + 10;
const lint LLINF = 1e18;
const lint MOD = 1e9 + 7;
const lint inv = MOD - 2;

struct unionFind{

    vector<int> par, rank;

    void init(int n){
        par.resize(n);
        rank.resize(n, 0);
        rep(i, n){
            par[i] = i;
        }
        return;
    }

    int root(int x){
        if(par[x] == x){
            return x;
        }else{
            par[x] = root(par[x]);
            return par[x];
        }
    }

    bool unite(int x, int y){
        int rx = root(x);
        int ry = root(y);
        if(rx == ry){
            return false;
        }
        if(rank[rx] < rank[ry]){
            par[rx] = ry;
        }else if(rank[rx] == rank[ry]){
            par[rx] = ry;
            rank[ry]++;
        }else{
            par[ry] = rx;
        }
        return true;
    }

    bool same(int x, int y){
        return root(x) == root(y);
    }

};

struct edge{
    int from, to;
    lint cost;
    int id;

    bool operator<(const edge & right) const {
        return cost < right.cost;
    }
};

int main(){
    int n, m;
    cin >> n >> m;
    vector<edge> edges;
    rep(i, m){
        edge e;
        cin >> e.from >> e.to >> e.cost;
        e.from--;
        e.to--;
        e.id = i;
        edges.push_back(e);
    }
    sort(edges.begin(), edges.end());
    vector<edge> MST;
    lint sum = 0;
    unionFind uf;
    uf.init(n);
    rep(i, m){
        edge e = edges[i];
        if(uf.unite(e.from, e.to)){
            MST.push_back(e);
            sum += e.cost;
        }
    }
    pair<int, lint> ans;
    ans.first = 0;
    ans.second = 0;
    rep(i, MST.size()){
        lint tmp = 0;
        uf.init(n);
        rep(j, m){
            edge e = edges[j];
            if(!uf.same(e.from, e.to) && e.id != MST[i].id){
                uf.unite(e.from, e.to);
                tmp += e.cost;
            }
        }
        if(sum != tmp){
            ans.first++;
            ans.second += MST[i].cost;
        }
    }
    cout << ans.first << " " << ans.second << endl;
    return 0;
}