#include <bits/stdc++.h>   #pragma GCC optimize(2)   using namespace std;   const int INF = 0x3f3f3f3f;   const int GRAPH_SIZE = 20010;   int pin[GRAPH_SIZE], dep[GRAPH_SIZE], s = 0, t = GRAPH_SIZE - 1;   struct EDGE {     int u, v, c;   };   vector<EDGE> e;   vector<int> each[GRAPH_SIZE];   bool bfs() {     queue<int> Q;     Q.push(s);     while (!Q.empty()) {       int now = Q.front();       Q.pop();       for (auto it : each[now]) {         int next = e[it].v;         if (e[it].c)           if (dep[next] > dep[now] + 1) {             dep[next] = dep[now] + 1;             Q.push(next);           }       }     }     return dep[t] != INF;   }   int dfs(int now, int flow) {     if (now == t) {       return flow;     }     for (int& i = pin[now]; i < each[now].size(); i++) {       int it = each[now][i];       if (e[it].c && dep[e[it].v] == dep[now] + 1) {         int tmp;         if (tmp = dfs(e[it].v, min(flow, e[it].c))) {           e[it].c -= tmp;           e[it ^ 1].c += tmp;           return tmp;         }       }     }     return 0;   }   int Dinic() {     int max_flow = 0;     for (int i = 0; i < GRAPH_SIZE; ++i) {       dep[i] = INF;     }     dep[s] = 0;     while (bfs()) {       for (int i = 0; i < GRAPH_SIZE; ++i) {         pin[i] = 0;       }       int tmp;       while (tmp = dfs(s, INF)) {         max_flow += tmp;       }       for (int i = 0; i < GRAPH_SIZE; ++i) {         dep[i] = INF;       }       dep[s] = 0;     }     return max_flow;   }   void make_edge(int U, int V, int C) {     EDGE tmp;     tmp.u = U;     tmp.v = V;     tmp.c = C;     e.push_back(tmp);     each[U].push_back(e.size() - 1);     swap(tmp.u, tmp.v);     tmp.c = 0;     e.push_back(tmp);     each[V].push_back(e.size() - 1);   }   void init() {     e.clear();     for (int i = 0; i < GRAPH_SIZE; ++i) {       each[i].clear();     }   }   vector<pair<int, pair<int, int> > > edges;   int n;   int m;   bool check(int x) {     init();     for (int i = 1; i <= n; ++i) make_edge(s, i, 1);     for (int i = 1; i <= n; ++i) make_edge(i + n, t, 1);     for (int i = 0; i < x; ++i) {       make_edge(edges[i].second.first, edges[i].second.second + n, 1);     }     if (Dinic() == n) return true;     return false;   }   int main() {     ios::sync_with_stdio(false);     cin >> n >> m;     for (int i = 1; i <= m; ++i) {       int u, v, d;       cin >> u >> v >> d;       edges.push_back(make_pair(d, make_pair(u, v)));     }     sort(edges.begin(), edges.end());     if (!check(m)) {       cout << -1 << endl;       return 0;     }     int l = 1, r = m;     while (l < r) {       int mid = (l + r) >> 1;       if (check(mid)) {         r = mid;       } else {         l = mid + 1;       }     }     cout << edges[l - 1].first << endl;     return 0;   }   