#include <bits/stdc++.h>
using namespace std;
template <class T>
bool uin(T& a, T b) {
  return a > b ? (a = b, true) : false;
}
template <class T>
bool uax(T& a, T b) {
  return a < b ? (a = b, true) : false;
}
struct dsu {
  vector<int> e;
  dsu(int n) : e(n, -1) {}
  int size(int x) { return -e[get(x)]; }
  bool same_set(int a, int b) { return get(a) == get(b); }
  int get(int x) { return e[x] < 0 ? x : e[x] = get(e[x]); }
  bool unite(int a, int b) {
    a = get(a);
    b = get(b);
    if (a == b) return false;
    if (e[a] > e[b]) swap(a, b);
    e[a] += e[b];
    e[b] = a;
    return true;
  }
};
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int N, M;
  cin >> N >> M;
  vector<tuple<int, int, int>> edges;
  for (int i = 0; i < M; ++i) {
    int u, v, w;
    cin >> u >> v >> w;
    --u, --v;
    edges.emplace_back(w, u, v);
  }
  int s = get<1>(edges[0]);
  int d = get<2>(edges[0]);
  sort(edges.begin() + 1, edges.end());
  priority_queue<pair<int, int>> heap;
  for (int i = 1; i < M; ++i) heap.emplace(-get<0>(edges[i]), i);
  dsu uf(N);
  int ans = 1e9;
  while (!heap.empty()) {
    int id = heap.top().second;
    heap.pop();
    auto [w, u, v] = edges[id];
    uf.unite(u, v);
    if (uf.same_set(s, d)) {
      uin(ans, w);
      break;
    }
  }
  cout << ans << '\n';
}
