#include
#include
#include
using namespace std;
const int maxn = 105;
int root[maxn], sz[maxn];
void init() {
for(int i = 0; i < maxn; i++) {
sz[i] = 1;
root[i] = i;
}
}
int find_root(int x) {
while(x != root[x]) {
root[x] = root[root[x]];
x = root[x];
}
return x;
}
bool check(int A, int B) {
return find_root(A) == find_root(B);
}
void unite(int A, int B) {
int a_root = find_root(A);
int b_root = find_root(B);
if(a_root != b_root) {
if(sz[a_root] > sz[b_root]) {
sz[a_root] += sz[b_root];
root[b_root] = root[a_root];
}
else {
sz[b_root] += sz[a_root];
root[a_root] = root[b_root];
}
}
}
int main() {
int n, m;
cin >> n >> m;
vector > > v;
for(int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c;
v.push_back(make_pair(c, make_pair(a, b)));
}
sort(v.begin(), v.end());
init();
int MST1 = 0;
vector > mst_edges;
for(int i = 0; i < m; i++) {
int a = v[i].second.first;
int b = v[i].second.second;
int c = v[i].first;
if(!check(a, b)) {
unite(a, b);
MST1 += c;
mst_edges.push_back(make_pair(a, b));
}
}
int MST2 = 1e9;
for(int i = 0; i < (int) mst_edges.size(); i++) {
init();
int tmp = 0;
int cnt = 0;
for(int j = 0; j < m; j++) {
int a = v[j].second.first;
int b = v[j].second.second;
int c = v[j].first;
if(a == mst_edges[i].first and b == mst_edges[i].second) continue;
if(!check(a, b)) {
unite(a, b);
tmp += c;
cnt++;
}
}
if(cnt == n - 1) {
MST2 = min(MST2, tmp);
}
}
cout << MST1 << " " << MST2 << endl;
return 0;
}