#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5, INF = 1e18;
int n, m, a[N], in[N];
vector<pair<pair<int, int>, int>> g;
map<pair<pair<int, int>, int>, int> mst;
vector<pair<int, int>> f[N];
template<class Tp>
class Ufs {
private:
unordered_map<Tp, Tp> f;
unordered_map<Tp, int> s;
Tp root(Tp a) {
if(f[a] == a) return a;
f[a] = root(f[a]);
return f[a];
}
public:
void init(Tp *b, Tp *e) {
int z = 0;
for(Tp *i = b; i <= e; i++) f[*i] = *i;
}
bool same(Tp a, Tp b) {
Tp p = root(a), q = root(b);
return p == q;
}
void merge(Tp a, Tp b) {
Tp p = root(a), q = root(b);
if(p == q) return;
if(s[p] > s[q]) swap(p, q);
f[p] = q;
s[q] += s[p];
}
};
bool cmp(pair<pair<int, int>, int> x, pair<pair<int, int>, int> y) {
return x.second < y.second;
}
int Kruskal(int s) {
int ans = 0;
Ufs<int> u;
for(int i = 1; i <= n; i++) a[i] = i;
u.init(a + 1, a + n + 1);
sort(g.begin(), g.end(), cmp);
for(auto i : g) {
if(u.same(i.first.first, i.first.second)) continue;
mst[i] = 1;
f[i.first.first].push_back({i.first.second, i.second}); f[i.first.second].push_back({i.first.first, i.second});
ans += i.second;
u.merge(i.first.first, i.first.second);
}
if(mst.size() == n - 1) return ans;
else return -1;
}
int d[N], v[N];
pair<int, int> p[N];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
void Dijkstra(int s) {
for(int i = 1; i <= n; i++) d[i] = INF, p[i] = {-1, -1}, v[i] = 0;
d[s] = 0;
q.push({d[s], s});
while(!q.empty()) {
int i = q.top().second;
q.pop();
if(v[i]) continue;
v[i] = 1;
for(auto j : f[i]) {
int k = j.first, w = j.second;
if(d[k] > d[i] + w) {
d[k] = d[i] + w, p[k] = {i, w};
q.push({d[k], k});
}
}
}
}
int work(int u, int v) {
int r = -INF;
while(v != u) {
r = max(r, p[v].second);
v = p[v].first;
}
return r;
}
signed main() {
cin>>n>>m;
for(int i = 1; i <= m; i++) {
int u, v, w; cin>>u>>v>>w;
g.push_back({{u, v}, w}); g.push_back({{v, u}, w});
}
int len = Kruskal(1), ans = INF;
cout<<len<<" ";
for(auto i : g) if(mst[i]) {
int u = i.first.first, v = i.first.second, w = i.second;
Dijkstra(u);
ans = min(ans, len + w - work(u, v));
}
cout<<ans<<endl;
return 0;
}