#include using namespace std ; typedef long long ll ; typedef tuple TP ; #define rep(i,n) for(int i = 0 ; i < n ; i++) #define rrep(i,a,b) for(int i = a ; i < b ; i++) const int MAX_N = 101010 ; int n ; TP A[101010] ; template struct UnionFind { T par[MAX_N] ; //親 T lank[MAX_N] ; //木の深さ T volume[MAX_N] ; //木のサイズ UnionFind(T n){ //n要素で初期化 for(int i = 0 ; i < n ; i++){ par[i] = i ; lank[i] = 0 ; volume[i] = 1 ; } } //木の根を求める T root(T x){ if(par[x] == x){ return x ; } else{ return par[x] = root(par[x]) ; } } //xとyの属する集合を合併 void unite(T x , T y){ x = root(x); y = root(y) ; if(x == y) return ; if(lank[x] < lank[y]){ par[x] = y ; volume[y] += volume[x] ; } else { par[y] = x ; if(lank[x] == lank[y]) lank[x]++ ; volume[x] += volume[y] ; } } bool same(T x , T y){ return root(x) == root(y) ; } T size(T x){ return volume[root(x)] ; } } ; int main(){ cin >> n ; rep(i,n*(n-1)/2){ ll a , b ; double c ; cin >> a >> b >> c ; A[i] = {c,--a,--b} ; } sort(A,A+n) ; UnionFind UF(n) ; double res = -1e17 ; rep(i,n){ ll a , b ; double c ; tie(c,a,b) = A[i] ; if(UF.same(a,b)) continue ; UF.unite(a,b) ; res = max(res,c) ; } cout << res << endl ; }