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>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repr(i, n) for (int i = (n); i >= 0; --i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define FORR(i, m, n) for (int i = (m); i >= (n); --i)
#define equals(a, b) (fabs((a) - (b)) < EPS)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ll mod = 1000000007;
//const ll mod = 998244353;
const int inf = 1e9 + 10;
const ll INF = 1e18;
const ld EPS = 1e-10;
const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

struct UnionFind {
  vector<ll> par; 
  vector<ll> siz; 

    
  UnionFind(ll sz_): par(sz_), siz(sz_, 1) {
    for (ll i = 0; i < sz_; ++i) par[i] = i; 
  }
  void init(ll sz_) {
    par.clear();
    par.resize(sz_);
    siz.clear();
    siz.resize(sz_, 1);
    for (ll i = 0; i < sz_; ++i) par[i] = i;
  }

  ll root(ll x) { 
    while (par[x] != x) {
      x = par[x] = par[par[x]];
    }
    return x;
  }

  bool merge(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (siz[x] < siz[y]) swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(ll x, ll y) {
    return root(x) == root(y);
  }

  ll size(ll x) {
    return siz[root(x)];
  }
};

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(25);

  int n, m;
  cin >> n >> m;
  vector<array<int, 3>> G(m);
  rep(i, m) {
    cin >> G[i][1] >> G[i][2] >> G[i][0];
    G[i][1]--, G[i][2]--;
  }

  sort(G.begin(), G.end());
  UnionFind uf(n);
  vector<bool> used(m, false);
  int cost = 0;
  rep(i, m) {
    if (uf.merge(G[i][1], G[i][2])) {
      used[i] = true;
      cost += G[i][0];
    }
  }
  vector<int> ans(2, 0);
  rep(i, m) {
    if (!used[i]) continue;
    uf.init(n);
    int cost2 = 0;
    rep(j, m) {
      if (i != j && uf.merge(G[j][1], G[j][2])) {
        cost2 += G[j][0];
      }
    }
    if (uf.size(0) != n || cost2 != cost) {
      ans[0]++;
      ans[1] += G[i][0];
    }
    //cout << cost2 << '\n';
  }
  cout << ans[0] << ' ' << ans[1] << '\n';

  




  
  return 0;
}