#include <bits/stdc++.h>
using namespace std;
void err(istream_iterator<string> it) { cout << endl; }
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << " ";
  err(++it, args...);
}
template <typename T>
inline void read(T& x) {
  x = 0;
  T f = 1;
  char ch = getchar();
  while (!isdigit(ch)) f = (ch == '-') ? -1 : 1, ch = getchar();
  while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
  x *= f;
}
template <typename T, typename... Args>
inline void read(T& x, Args&... args) {
  read(x), read(args...);
}
constexpr int MAXN = 1e4 + 4, MOD = 1e9 + 7, INF = 1e9 + 7;
struct Edge {
  Edge() = default;
  Edge(int _to, int _c, int _next) : to(_to), c(_c), next(_next) {}
  int to = 0, c = 0, next = 0;
};
vector<Edge> edge;
int n, m, s, t;
array<int, MAXN * 2> head, curv, depth;
inline void addEdge(int from, int to, int c) {
  edge.emplace_back(to, c, head[from]), head[from] = edge.size() - 1;
  edge.emplace_back(from, 0, head[to]), head[to] = edge.size() - 1;
}
inline bool bfs() {
  fill(depth.begin(), depth.end(), 0);
  copy(head.begin(), head.end(), curv.begin());
  queue<int> q;
  q.push(s), depth[s] = 1;
  while (!q.empty()) {
    int cur = q.front();
    q.pop();
    for (int i = head[cur]; ~i; i = edge[i].next) {
      int to = edge[i].to;
      if (!edge[i].c || depth[to]) continue;
      depth[to] = depth[cur] + 1;
      q.push(to);
      if (to == t) return true;
    }
  }
  return false;
}
int dfs(int cur, int limit) {
  if (!limit || cur == t) return limit;
  int flow(0);
  for (int i = curv[cur]; ~i; i = edge[i].next) {
    curv[cur] = i;
    int to = edge[i].to;
    if (edge[i].c && depth[to] == depth[cur] + 1) {
      int k = dfs(to, min(edge[i].c, limit));
      edge[i].c -= k, edge[i ^ 1].c += k;
      limit -= k, flow += k;
      if (flow == limit) break;
    }
  }
  if (!flow) depth[cur] = 0;
  return flow;
}
inline int dinic(int maxFlow = 0) {
  while (bfs()) {
    int tmp;
    while (tmp = dfs(s, INF)) maxFlow += tmp;
  }
  return maxFlow;
}
array<int, MAXN * 10> u, v, day;
bool check(int mid) {
  edge.clear();
  s = 0, t = 2 * n + 1;
  fill(head.begin(), head.end(), -1);
  for (int i = 1; i <= m; i++)
    if (day[i] <= mid) addEdge(u[i], v[i] + n, 1);
  for (int i = 1; i <= n; i++) addEdge(0, i, 1), addEdge(i + n, 2 * n + 1, 1);
  return dinic() >= n;
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  ;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) cin >> u[i] >> v[i] >> day[i];
  int l = 1, r = 1e9, ans = 0;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      r = mid - 1, ans = mid;
    else
      l = mid + 1;
  }
  if (!ans) ans = -1;
  cout << ans << "\n";
  return 0;
}
