#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int v, u;
  long long cap, flow = 0;
  Edge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
  void augment(long long new_flow) { flow += new_flow; }
  long long residual_cap() { return cap - flow; }
};
struct Dinic {
  int n, s, t, e = 0;
  queue<int> q;
  vector<Edge> edges;
  vector<int> level, ptr;
  vector<vector<int>> G;
  Dinic(int n, int s, int t) : n(n), s(s), t(t) {
    level.resize(n + 1);
    ptr.resize(n + 1);
    G.resize(n + 1);
  }
  void add_edge(int v, int u, long long cap) {
    edges.emplace_back(v, u, cap);
    edges.emplace_back(u, v, 0);
    G[v].push_back(e++);
    G[u].push_back(e++);
  }
  bool BFS() {
    while (!q.empty()) {
      int v = q.front();
      q.pop();
      for (int edge_id : G[v]) {
        Edge &E = edges[edge_id];
        if (E.residual_cap() > 0 && level[E.u] == -1) {
          q.push(E.u);
          level[E.u] = level[v] + 1;
        }
      }
    }
    return level[t] != -1;
  }
  long long DFS(int v, long long flow) {
    if (!flow || v == t) {
      return flow;
    }
    for (int &i = ptr[v]; i < G[v].size(); i++) {
      int edge_id = G[v][i];
      Edge &E = edges[edge_id];
      Edge &E_rev = edges[edge_id ^ 1];
      if (E.residual_cap() > 0 && level[E.u] == level[v] + 1) {
        long long new_flow = DFS(E.u, min(flow, E.residual_cap()));
        if (!new_flow) continue;
        E.augment(new_flow);
        E_rev.augment(-new_flow);
        return new_flow;
      }
    }
    return 0;
  }
  long long MaxFlow() {
    long long max_flow = 0;
    while (true) {
      fill(level.begin(), level.end(), -1);
      q.push(s);
      level[s] = 0;
      if (!BFS()) break;
      fill(ptr.begin(), ptr.end(), 0);
      long long flow = 0;
      while (flow = DFS(s, INT_MAX)) {
        max_flow += flow;
      }
    }
    return max_flow;
  }
};
int n, m;
vector<pair<int, int>> G[10001];
bool check(long long d) {
  int N = 2 * n + 2, S = 0, T = 2 * n + 1;
  Dinic solver(N, S, T);
  for (int i = 1; i <= n; i++) {
    solver.add_edge(S, i, 1);
  }
  for (int v = 1; v <= n; v++) {
    for (auto u : G[v]) {
      if (u.second <= d) {
        solver.add_edge(v, n + u.first, INT_MAX);
      }
    }
  }
  for (int i = n + 1; i <= 2 * n; i++) {
    solver.add_edge(i, T, 1);
  }
  return solver.MaxFlow() == n;
}
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int v, u, d;
    cin >> v >> u >> d;
    G[v].emplace_back(u, d);
  }
  long long L = 0, R = INT_MAX;
  while (L < R) {
    long long mid = (L + R) / 2;
    if (check(mid)) {
      R = mid;
    } else {
      L = mid + 1;
    }
  }
  cout << (L == INT_MAX ? -1 : L);
  return 0;
}
