#include <bits/stdc++.h>
// #define LOCAL
#define INF 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(false), cin.tie(0)
#define int long long
#define debug(a) cerr << #a << "=" << a << endl;
using namespace std;
const int N = 1e5 + 10, M = 2e4 + 10;
int n, m;
struct rec_{
int a, b, c;
}query[N];
int fa[M], d[M];
void init(){
for (int i = 1; i <= n; ++i)
fa[i] = i, d[i] = 0;
}
int find(int x){
if(x == fa[x])
return x;
int root = find(fa[x]);
d[x] ^= d[fa[x]];
return fa[x] = root;
}
bool check(int x){
init();
for (int i = 0; i < m; ++i){
auto t = query[i];
int a = find(t.a), b = find(t.b), c = t.c;
if(a == b){
//若c > x,那么两个节点之间边权不能为0.若c <= x,那么两个节点边权可以是1,也可以是0.
if(c > x && d[t.a] ^ d[t.b] == 0)
return false;
}
else if(c > x){
fa[a] = b;
d[a] = d[t.a] ^ d[t.b] ^ 1;
}
}
return true;
}
signed main(){
#ifdef LOCAL
freopen("input.in", "r", stdin);
freopen("output.out", "w", stdout);
#endif
IOS;
cin >> n >> m;
int maxc = 0;
for (int i = 0; i < m; ++i){
auto &t = query[i];
cin >> t.a >> t.b >> t.c;
maxc = max(maxc, t.c);
}
int lb = 0, rb = maxc, mb;
while(lb < rb){
mb = lb + rb >> 1;
if(check(mb))
rb = mb;
else
lb = mb + 1;
}
cout << lb << '\n';
}