#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int f[305][305], fat[305], n, m, u, v, c;
bool vis[305];
int ans = 0;
struct node
{
int to, w;
bool operator<(const node &b) const
{
return w > b.w;
}
};
void prim()
{
priority_queue<node> p;
p.push({1, 0});
while (!p.empty())
{
node u = p.top();
p.pop();
if (vis[u.to])
continue;
vis[u.to] = true;
if (fat[u.to] != u.to)
ans = max(ans, f[fat[u.to]][u.to]);
for (int i = 1; i <= n; i++)
{
if (!vis[i] && f[u.to][i] < f[0][0])
{
p.push({i, f[u.to][i]});
if (f[u.to][i] < f[fat[i]][i])
fat[i] = u.to;
}
}
}
}
int main()
{
memset(f, 0x3f, sizeof(f));
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
cin >> u >> v >> c;
f[u][v] = f[v][u] = c;
}
for (int i = 1; i <= n; i++)
fat[i] = i;
prim();
cout << n - 1 << " " << ans;
return 0;
}