#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int MAXN = 2e4 + 100;
const int MAXM = 4e5 + 10;
namespace MaxFlow {
struct Edge {
  int v, rev, f;
};
int n, s, t;
int cur[MAXM], dep[MAXN], gap[MAXN];
int flow;
std::vector<Edge> G[MAXN];
void add_edge(int u, int v, int f) {
  G[u].push_back({v, (int)G[v].size(), f});
  G[v].push_back({u, (int)G[u].size() - 1, 0});
}
int dfs(int u, int lim) {
  if (u == t) return lim;
  int num = 0, f;
  for (int &i = cur[u], v; i < (int)G[u].size(); ++i) {
    if (dep[v = G[u][i].v] == dep[u] - 1 && (f = G[u][i].f))
      if (G[u][i].f -= (f = dfs(v, std::min(lim - num, f))),
          G[v][G[u][i].rev].f += f, (num += f) == lim)
        return num;
  }
  if (!--gap[dep[u]++]) dep[s] = n + 1;
  return ++gap[dep[u]], cur[u] = 0, num;
}
void init(int _n) {
  n = _n;
  for (int i = 0; i <= n; ++i) G[i].clear();
}
void solve(int _s, int _t) {
  s = _s, t = _t, flow = 0;
  for (int i = 0; i <= n; ++i) cur[i] = dep[i] = gap[i] = 0;
  for (gap[0] = n; dep[s] <= n; flow += dfs(s, INF))
    ;
}
}  // namespace MaxFlow
using MaxFlow::add_edge;
int n, m, s, t;
vector<pair<pair<int, int>, int> > vc;
bool check(int x) {
  MaxFlow::init(n + n + 2);
  for (int i = 0; i < m; i++) {
    if (vc[i].second <= x) {
      add_edge(vc[i].first.first, vc[i].first.second + n, vc[i].second);
    }
  }
  for (int i = 1; i <= n; i++) {
    add_edge(s, i, 1);
    add_edge(i + n, t, 1);
  }
  MaxFlow::solve(s, t);
  return MaxFlow::flow == n;
}
int main() {
  scanf("%d%d", &n, &m);
  s = n + n + 1, t = n + n + 2;
  MaxFlow::init(n + n + 2);
  for (int i = 0, x, y, w; i < m; ++i) {
    scanf("%d%d%d", &x, &y, &w);
    vc.push_back({{x, y}, w});
  }
  int l = 0, r = INF;
  while (l < r) {
    int mid = (l + r) / 2;
    if (check(mid))
      r = mid;
    else
      l = mid + 1;
  }
  if (l == INF)
    printf("-1");
  else
    printf("%d", l);
  return 0;
}
