#include <bits/stdc++.h>
using namespace std;
int n, m;
const int MAXN = 100000 + 10;
const int INF = 0x3f3f3f3f;
vector<int> G[MAXN];
vector<int> D[MAXN];
int Mx[MAXN], My[MAXN];
int dx[MAXN], dy[MAXN];
int dis, mid;
bool used[MAXN];
bool SearchP() {
  queue<int> Q;
  dis = INF;
  memset(dx, -1, sizeof(dx));
  memset(dy, -1, sizeof(dy));
  for (int i = 0; i < n; ++i)
    if (Mx[i] == -1) {
      Q.push(i);
      dx[i] = 0;
    }
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    if (dx[u] > dis) break;
    int sz = G[u].size();
    for (int i = 0; i < sz; ++i) {
      int v = G[u][i];
      if (D[u][i] > mid) continue;
      if (dy[v] == -1) {
        dy[v] = dx[u] + 1;
        if (My[v] == -1)
          dis = dy[v];
        else {
          dx[My[v]] = dy[v] + 1;
          Q.push(My[v]);
        }
      }
    }
  }
  return dis != INF;
}
bool DFS(int u) {
  int sz = G[u].size();
  for (int i = 0; i < sz; ++i) {
    int v = G[u][i];
    if (D[u][i] > mid) continue;
    if (!used[v] && dy[v] == dx[u] + 1) {
      used[v] = true;
      if (My[v] != -1 && dy[v] == dis) continue;
      if (My[v] == -1 || DFS(My[v])) {
        My[v] = u;
        Mx[u] = v;
        return true;
      }
    }
  }
  return false;
}
int MaxMatch() {
  int res = 0;
  memset(Mx, -1, sizeof(Mx));
  memset(My, -1, sizeof(My));
  while (SearchP()) {
    memset(used, false, sizeof(used));
    for (int i = 0; i < n; ++i)
      if (Mx[i] == -1 && DFS(i)) res++;
  }
  return res;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0, u, v, d; i < m; ++i) {
    scanf("%d%d%d", &u, &v, &d);
    --u, --v;
    G[u].push_back(v + n);
    G[v + n].push_back(u);
    D[u].push_back(d), D[v + n].push_back(d);
  }
  int l = 1, r = 1000000000 + 1;
  int ans = -1;
  while (l < r) {
    mid = l + (r - l) / 2;
    if (MaxMatch() == n)
      ans = mid, r = mid;
    else
      l = mid + 1;
  }
  cout << ans << endl;
  return 0;
}
