#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10, M = 2e5 + 10, inf = 0x3f3f3f3f;
int n, m, cnt, s, t, l, r, ans = -1, u[M], v[M], c[M], head[2 * N], dep[2 * N],
                           now[2 * N];
struct Edge {
  int nxt;
  int to;
  int flow;
};
Edge edge[M << 1];
inline void add_edge(int u, int v, int c) {
  edge[cnt] = (Edge){head[u], v, c};
  head[u] = cnt++;
  edge[cnt] = (Edge){head[v], u, 0};
  head[v] = cnt++;
}
inline void build(int k) {
  cnt = 0;
  memset(head, -1, sizeof(head));
  for (int i = (1), iend = (m); i <= iend; i++)
    if (c[i] <= k) add_edge(u[i], n + v[i], 1);
  for (int i = (1), iend = (n); i <= iend; i++) {
    add_edge(s, i, 1);
    add_edge(i + n, t, 1);
  }
}
inline int bfs() {
  memset(dep, 0, sizeof(dep));
  memcpy(now, head, sizeof(now));
  queue<int> q;
  q.push(s);
  dep[s] = 1;
  while (q.size()) {
    int u = q.front();
    q.pop();
    for (int i = head[u]; ~i; i = edge[i].nxt) {
      int v = edge[i].to;
      if (!dep[v] && edge[i].flow) {
        dep[v] = dep[u] + 1;
        q.push(v);
        if (v == t) return 1;
      }
    }
  }
  return 0;
}
int dfs(int u, int sum) {
  if (u == t) return sum;
  int rest = sum;
  for (int &i = now[u]; ~i; i = edge[i].nxt) {
    int v = edge[i].to, k;
    if (dep[v] == dep[u] + 1 && edge[i].flow &&
        (k = dfs(v, min(rest, edge[i].flow)))) {
      edge[i].flow -= k;
      edge[i ^ 1].flow += k;
      rest -= k;
      if (!rest) break;
    }
  }
  return sum - rest;
}
int dinic() {
  int res = 0;
  while (bfs()) res += dfs(s, inf);
  return res;
}
int main() {
  scanf("%d%d", &n, &m);
  s = 0;
  t = 2 * n + 1;
  for (int i = (1), iend = (m); i <= iend; i++) {
    scanf("%d%d%d", &u[i], &v[i], &c[i]);
    r = max(r, c[i]);
  }
  l = 1;
  while (l < r) {
    int mid = (l + r) >> 1;
    build(mid);
    if (dinic() == n) {
      ans = mid;
      r = mid;
    } else
      l = mid + 1;
  }
  printf("%d", ans);
  return 0;
}
