#include <bits/stdc++.h>
using namespace std;
#define BRANCO 0
#define CINZA 1
#define PRETO 2
typedef pair<int, pair<int, int> > ip;
vector<ip> MST;
vector<ip> arestas;
vector<ip> outMST;
vector<int> graph[502];
int pai[502], peso[502], cor[502], firstRead, cost1, cost2 = -1;
int v, e, x, y, w;
bool trouve;
void dfs(int vertice)
{
cor[vertice] = CINZA;
for (int i = 0; i < graph[vertice].size(); i++) {
if (cor[graph[vertice][i]] == BRANCO)
dfs(graph[vertice][i]);
}
}
bool DFS()
{
for (int i = 1; i <= v; i++) {
if (cor[i] == BRANCO) {
if (i > 1)
return false;
dfs(i);
}
}
return true;
}
int FIND_SET(int v)
{
if (pai[v] != v)
pai[v] = FIND_SET(pai[v]);
return pai[v];
}
void UNION(int v, int u)
{
v = FIND_SET(v);
u = FIND_SET(u);
if (u == v)
return;
if (peso[u] > peso[v])
pai[v] = u;
else if (peso[v] > peso[u])
pai[u] = v;
else {
pai[v] = u;
peso[u]++;
}
}
int main()
{
scanf("%d%d", &v, &e);
for (int i = 1; i <= v; i++) {
pai[i] = i;
cor[i] = BRANCO;
}
ip aresta;
for (int i = 1; i <= e; i++) {
scanf("%d%d%d", &x, &y, &w);
aresta = make_pair(w, make_pair(x, y));
arestas.push_back(aresta);
}
stable_sort(arestas.begin(), arestas.end());
int v1, v2;
for (int i = 0; i < arestas.size(); i++) {
v1 = arestas[i].second.first;
v2 = arestas[i].second.second;
if (FIND_SET(v1) != FIND_SET(v2)) {
MST.push_back(arestas[i]);
UNION(v1, v2);
}
else
outMST.push_back(arestas[i]);
}
for (int i = 0; i < MST.size(); i++) {
cost1 += MST[i].first;
graph[MST[i].second.first].push_back(MST[i].second.second);
graph[MST[i].second.second].push_back(MST[i].second.first);
}
for (int i = MST.size() - 1; i >= 0; i--) {
for (int j = 0; j < graph[MST[i].second.first].size(); j++) {
if (graph[MST[i].second.first][j] == MST[i].second.second) {
graph[MST[i].second.first].erase(graph[MST[i].second.first].begin() + j);
break;
}
}
for (int j = 0; j < graph[MST[i].second.second].size(); j++) {
if (graph[MST[i].second.second][j] == MST[i].second.first) {
graph[MST[i].second.second].erase(graph[MST[i].second.second].begin() + j);
break;
}
}
int ind = lower_bound(outMST.begin(), outMST.end(), MST[i]) - outMST.begin();
for (int j = ind; j < outMST.size(); j++) {
graph[outMST[j].second.first].push_back(outMST[j].second.second);
graph[outMST[j].second.second].push_back(outMST[j].second.first);
if (DFS()) {
cost2 = cost1 + outMST[j].first - MST[i].first;
trouve = true;
goto fin;
}
else {
for (int z = 1; z <= v; z++)
cor[z] = BRANCO;
graph[outMST[j].second.first].pop_back();
graph[outMST[j].second.second].pop_back();
}
}
graph[MST[i].second.first].push_back(MST[i].second.second);
graph[MST[i].second.second].push_back(MST[i].second.first);
}
fin:
if (!trouve) {
for (int j = 0; j < outMST.size(); j++) {
graph[outMST[j].second.first].push_back(outMST[j].second.second);
graph[outMST[j].second.second].push_back(outMST[j].second.first);
if (DFS())
cost2 = cost1 + outMST[j].first;
else {
for (int z = 1; z <= v; z++)
cor[z] = BRANCO;
graph[outMST[j].second.first].pop_back();
graph[outMST[j].second.second].pop_back();
}
}
}
printf("Cost: %d\n", cost1);
printf("Cost: %d\n", cost2);
return 0;
}