#include <bits/stdc++.h>
using namespace std;
const long long INF = 0x3f3f3f3f3f3f3f3fLL;
const int inf = 0x3f3f3f3f;
const int maxn = 2e4 + 10;
const int mod = 1e9 + 7;
const double eps = 1e-6;
int di[8][2] = {{-1, 0},  {1, 0},  {0, -1}, {0, 1},
                {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
clock_t _st = clock();
inline double now_time() { return (double)(clock() - _st) / CLOCKS_PER_SEC; }
inline long long rd() {
  long long x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 3) + (x << 1) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
int n, m;
struct node {
  int x, y, w;
  bool friend operator<(const node& n1, const node& n2) { return n1.w < n2.w; }
} aa[maxn * 10];
int maxflow;
int deep[maxn];
struct Edge {
  int next, to, dis;
} edge[maxn * 20];
int num_edge = -1, head[maxn], cur[maxn];
queue<int> qu;
void add_edge(int from, int to, int dis) {
  edge[++num_edge].next = head[from];
  edge[num_edge].to = to;
  edge[num_edge].dis = dis;
  head[from] = num_edge;
}
void add(int from, int to, int dis) {
  add_edge(from, to, dis);
  add_edge(to, from, 0);
}
void init() {
  num_edge = -1;
  memset(head, -1, sizeof(int) * (n + 10));
}
bool bfs(int s, int t) {
  memset(deep, 0x7f, sizeof(deep));
  while (!qu.empty()) qu.pop();
  for (int i = 0; i <= n + 1; i++) cur[i] = head[i];
  deep[s] = 0;
  qu.push(s);
  while (!qu.empty()) {
    int now = qu.front();
    qu.pop();
    for (int i = head[now]; i != -1; i = edge[i].next) {
      if (deep[edge[i].to] > inf && edge[i].dis) {
        deep[edge[i].to] = deep[now] + 1;
        qu.push(edge[i].to);
      }
    }
  }
  if (deep[t] < inf) return 1;
  return 0;
}
int dfs(int now, int t, int limit) {
  if (!limit || now == t) return limit;
  int flow = 0, f;
  for (int i = cur[now]; i != -1; i = edge[i].next) {
    cur[now] = i;
    if (deep[edge[i].to] == deep[now] + 1 &&
        (f = dfs(edge[i].to, t, min(limit, edge[i].dis)))) {
      flow += f;
      limit -= f;
      edge[i].dis -= f;
      edge[i ^ 1].dis += f;
      if (!limit) break;
    }
  }
  return flow;
}
int Dinic(int s, int t) {
  maxflow = 0;
  while (bfs(s, t)) maxflow += dfs(s, t, inf);
  return maxflow;
}
bool check(int x) {
  init();
  for (int i = 1; i <= m; i++) {
    if (aa[i].w > x) break;
    int a = aa[i].x, b = aa[i].y;
    add(a, b, 1);
  }
  for (int i = 1; i <= n / 2; i++) {
    add(0, i, 1);
  }
  for (int i = n / 2 + 1; i <= n; i++) add(i, n + 1, 1);
  return Dinic(0, n + 1) == n / 2;
}
int main() {
  n = rd(), m = rd();
  for (int i = 1; i <= m; i++) {
    aa[i].x = rd(), aa[i].y = rd() + n, aa[i].w = rd();
  }
  n *= 2;
  sort(aa + 1, aa + 1 + m);
  int l = 1, r = inf;
  int ans = -1;
  while (l <= r) {
    int mid = l + r >> 1;
    if (check(mid)) {
      ans = mid;
      r = mid - 1;
    } else
      l = mid + 1;
  }
  printf("%d\n", ans);
}
