#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
const int maxn = (int)2e5 + 5;
template <typename T>
struct dinic {
  struct edge {
    int src, dst;
    T cap, flow;
    int rev;
  };
  int n;
  vector<vector<edge>> adj;
  dinic(int n) : n(n), adj(n) {}
  void add_edge(int src, int dst, T cap) {
    adj[src].push_back({src, dst, cap, 0, (int)adj[dst].size()});
    if (src == dst) adj[src].back().rev++;
    adj[dst].push_back({dst, src, 0, 0, (int)adj[src].size() - 1});
  }
  vector<int> level, iter;
  T augment(int u, int t, T cur) {
    if (u == t) return cur;
    for (int &i = iter[u]; i < (int)adj[u].size(); ++i) {
      edge &e = adj[u][i];
      if (e.cap - e.flow > 0 && level[u] > level[e.dst]) {
        T f = augment(e.dst, t, min(cur, e.cap - e.flow));
        if (f > 0) {
          e.flow += f;
          adj[e.dst][e.rev].flow -= f;
          return f;
        }
      }
    }
    return 0;
  }
  int bfs(int s, int t) {
    level.assign(n, n);
    level[t] = 0;
    queue<int> Q;
    for (Q.push(t); !Q.empty(); Q.pop()) {
      int u = Q.front();
      if (u == s) break;
      for (int i = 0; i < (int)adj[u].size(); ++i) {
        edge &e = adj[u][i];
        edge &erev = adj[e.dst][e.rev];
        if (erev.cap - erev.flow > 0 && level[e.dst] > level[u] + 1) {
          Q.push(e.dst);
          level[e.dst] = level[u] + 1;
        }
      }
    }
    return level[s];
  }
  const T oo = numeric_limits<T>::max();
  T max_flow(int s, int t) {
    for (int u = 0; u < n; ++u)
      for (int i = 0; i < (int)adj[u].size(); ++i) {
        edge &e = adj[u][i];
        e.flow = 0;
      }
    T flow = 0;
    while (bfs(s, t) < n) {
      iter.assign(n, 0);
      for (T f; (f = augment(s, t, oo)) > 0;) flow += f;
    }
    return flow;
  }
};
vector<array<int, 3>> E;
int n;
bool can(int mid) {
  dinic<int> G(2 * n + 2);
  for (int i = 1; i <= n; i++) G.add_edge(0, i, 1);
  for (int i = 1; i <= n; i++) G.add_edge(n + i, 2 * n + 1, 1);
  for (auto i : E)
    if (i[2] <= mid) G.add_edge(i[0], i[1] + n, 1);
  if (G.max_flow(0, 2 * n + 1) == n) return 1;
  return 0;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(0);
  int m, l = 1000000000, r = -1000000000;
  cin >> n >> m;
  E.resize(m);
  for (auto &i : E) {
    cin >> i[0] >> i[1] >> i[2];
    l = min(l, i[2]);
    r = max(r, i[2]);
  }
  while (l < r) {
    int mid = (l + r) >> 1;
    if (can(mid))
      r = mid;
    else
      l = mid + 1;
  }
  if (can(l))
    cout << l;
  else
    cout << -1;
  return 0;
}
