Problem:
E: 敵襲から守れ
問題
島が $V$ 島あり、それぞれ $0, 1, ..., V-1$ と番号がついている。橋が $E$ 本あり、それぞれ $0, 1, ..., E-1$ と番号がついている。 $i$ 番目の橋は島 $s_i$ と島 $t_i$ にかかってあり、幅は $c_i$ である。
島 $0$ に基地があるAORイカちゃん軍団 (通称イカ団) は規模が弱小であるため、島 $V-1$ にあるSosu-Usa軍団 (通称そすうさ団) にいつもやられっぱなしである。ある日、イカ団は「そすうさ団が明日攻めてくる」との情報を得た。そすうさ団の基地から大人数のそすうさ団の部下が橋を渡って島を移動し、部下が一人でもイカ団の基地にたどり着かれるとイカ団は滅びてしまう……。
そこでイカ団は橋に通行止めテープを張ることで橋を通れないようにし、危機を免れようとした。使うテープの長さは通行止めにした橋の幅の総和である。また、そすうさ団の部下全員が必ず
ある一本の幅 $1$ の橋
を通る場合、イカ団がそこで待ち伏せすることで、そすうさ団を通れなくすることができる。
保持しているテープの長さは $10^4$ である。今後のことも考え、消費するテープの量はなるべく少なくしたい。そすうさ団の部下がイカ団の基地にたどり着けないようにするために使うテープの長さの最小値を求めよ。ただし、テープの長さが足りずどうしても攻められてしまう合は
    $-1$ を出力せよ。
制約
$2 \le V \le 5 \times 10^3$
$1 \le E \le min(5 \times 10^3, V(V-1)/2)$
$1 \le c_i \le 5 \times 10^3$
$0 \le s_i, t_i \lt V$
与えられるグラフは連結かつ単純である。
入力は全て整数で与えらえる。
入力形式
入力は以下の形式で与えられる。
$V \ E$
$s_0 \ t_0 \ c_0$
$s_1 \ t_1 \ c_1$
$\vdots$
$s_{E-1} \ t_{E-1} \ c_{E-1}$
出力
そすうさ団の部下がイカ団の基地にたどり着けないようにするために使うテープの長さの最小値を出力せよ。ただし、テープの長さが足りずどうしても攻められてしまう場合は $-1$ を出力せよ。また、末尾に改行も出力せよ。
サンプル
サンプル入力 1
4 4
0 1 3
0 2 4
1 3 1
2 3 5
サンプル出力 1
4
イカ団は $2$ 番目の橋で待ち伏せし、$1$ 番の橋にテープを貼ることで、そすうさ団を止められる。
サンプル入力 2
2 1
0 1 100
サンプル出力 2
100
$0$ 番目の橋にテープを貼ることで、そすうさ団を止められる。 橋の幅が $1$ でないため、待ち伏せはできない。
サンプル入力 3
5 6
0 1 5000
0 2 5000
0 3 5000
1 4 5000
2 4 5000
3 4 5000
サンプル出力 3
-1
テープが足りないため、どのようにテープを貼ってもそうすさ団は止められない。

Submitted solutions:

code_snippet: // BEGIN: main.cpp
#line 1 "main.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2835"

// BEGIN: my_template.hpp
#line 1 "my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else
#if defined(__GNUC__)
#include <bits/allocator.h>
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,popcnt")
#endif
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'010'000'000;
template <>
constexpr ll infty<ll> = 2'020'000'000'000'000'000;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * 2'000'000'000'000'000'000;
template <>
constexpr double infty<double> = numeric_limits<double>::infinity();
template <>
constexpr long double infty<long double> =
    numeric_limits<long double>::infinity();

using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using pq_max = priority_queue<T>;
template <class T>
using pq_min = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a) - 1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a) - 1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b) - 1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define all(x) (x).begin(), (x).end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_sgn(int x) { return (__builtin_parity(unsigned(x)) & 1 ? -1 : 1); }
int popcnt_sgn(u32 x) { return (__builtin_parity(x) & 1 ? -1 : 1); }
int popcnt_sgn(ll x) { return (__builtin_parityll(x) & 1 ? -1 : 1); }
int popcnt_sgn(u64 x) { return (__builtin_parityll(x) & 1 ? -1 : 1); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T kth_bit(int k) {
  return T(1) << k;
}
template <typename T>
bool has_kth_bit(T x, int k) {
  return x >> k & 1;
}

template <typename UINT>
struct all_bit {
  struct iter {
    UINT s;
    iter(UINT s) : s(s) {}
    int operator*() const { return lowbit(s); }
    iter &operator++() {
      s &= s - 1;
      return *this;
    }
    bool operator!=(const iter) const { return s != 0; }
  };
  UINT s;
  all_bit(UINT s) : s(s) {}
  iter begin() const { return iter(s); }
  iter end() const { return iter(0); }
};

template <typename UINT>
struct all_subset {
  static_assert(is_unsigned<UINT>::value);
  struct iter {
    UINT s, t;
    bool ed;
    iter(UINT s) : s(s), t(s), ed(0) {}
    UINT operator*() const { return s ^ t; }
    iter &operator++() {
      (t == 0 ? ed = 1 : t = (t - 1) & s);
      return *this;
    }
    bool operator!=(const iter) const { return !ed; }
  };
  UINT s;
  all_subset(UINT s) : s(s) {}
  iter begin() const { return iter(s); }
  iter end() const { return iter(0); }
};

template <typename T>
T floor(T a, T b) {
  return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
  return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
  return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

constexpr ll TEN[] = {
    1LL,
    10LL,
    100LL,
    1000LL,
    10000LL,
    100000LL,
    1000000LL,
    10000000LL,
    100000000LL,
    1000000000LL,
    10000000000LL,
    100000000000LL,
    1000000000000LL,
    10000000000000LL,
    100000000000000LL,
    1000000000000000LL,
    10000000000000000LL,
    100000000000000000LL,
    1000000000000000000LL,
};

template <typename T, typename U>
T SUM(const U &A) {
  return std::accumulate(A.begin(), A.end(), T{});
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
template <class C, class T>
inline long long LB(const C &c, const T &x) {
  return lower_bound(c.begin(), c.end(), x) - c.begin();
}
template <class C, class T>
inline long long UB(const C &c, const T &x) {
  return upper_bound(c.begin(), c.end(), x) - c.begin();
}
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <class T, class Container, class Compare>
T POP(priority_queue<T, Container, Compare> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (llabs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    (check(x) ? ok : ng) = x;
  }
  return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    (check(x) ? ok : ng) = x;
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vc<T> cumsum(const vc<U> &A, int off = 1) {
  int N = A.size();
  vc<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vc<int> argsort(const vc<T> &A) {
  vc<int> ids(len(A));
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  vc<T> B(len(I));
  FOR(i, len(I)) B[i] = A[I[i]];
  return B;
}

template <typename T, typename... Vectors>
void concat(vc<T> &first, const Vectors &...others) {
  vc<T> &res = first;
  (res.insert(res.end(), others.begin(), others.end()), ...);
}
#endif
// END: my_template.hpp
#line 4 "main.cpp"
// BEGIN: other/io.hpp
#line 1 "other/io.hpp"
#define FASTIO

// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
  char num[10000][4];
  constexpr Pre() : num() {
    for (int i = 0; i < 10000; i++) {
      int n = i;
      for (int j = 3; j >= 0; j--) {
        num[i][j] = n % 10 | '0';
        n /= 10;
      }
    }
  }
} constexpr pre;

inline void load() {
  memmove(ibuf, ibuf + pil, pir - pil);
  pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
  pil = 0;
  if (pir < SZ) ibuf[pir++] = '\n';
}

inline void flush() {
  fwrite(obuf, 1, por, stdout);
  por = 0;
}

void rd(char &c) {
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
}

void rd(string &x) {
  x.clear();
  char c;
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
  do {
    x += c;
    if (pil == pir) load();
    c = ibuf[pil++];
  } while (!isspace(c));
}

template <typename T>
void rd_real(T &x) {
  string s;
  rd(s);
  x = stod(s);
}

template <typename T>
void rd_integer(T &x) {
  if (pil + 100 > pir) load();
  char c;
  do c = ibuf[pil++];
  while (c < '-');
  bool minus = 0;
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (c == '-') {
      minus = 1, c = ibuf[pil++];
    }
  }
  x = 0;
  while ('0' <= c) {
    x = x * 10 + (c & 15), c = ibuf[pil++];
  }
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (minus) x = -x;
  }
}

template <class T>
enable_if_t<is_integral_v<T> || is_same_v<T, i128> || is_same_v<T, u128>> rd(
    T &x) {
  rd_integer(x);
}

template <class T>
enable_if_t<is_floating_point_v<T> || is_same_v<T, f128>> rd(T &x) {
  rd_real(x);
}

template <class T, class U>
void rd(pair<T, U> &p) {
  rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
  if constexpr (N < tuple_size<T>::value) {
    auto &x = get<N>(t);
    rd(x);
    rd_tuple<N + 1>(t);
  }
}
template <class... T>
void rd(tuple<T...> &tpl) {
  rd_tuple(tpl);
}

template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
  for (auto &d : x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
  for (auto &d : x) rd(d);
}

void read() {}
template <class H, class... T>
void read(H &h, T &...t) {
  rd(h), read(t...);
}

// 先に用意（既出なら不要）
inline void wt_range(const char *s, size_t n) {
  size_t i = 0;
  while (i < n) {
    if (por == SZ) flush();
    size_t chunk = min(n - i, (size_t)(SZ - por));
    memcpy(obuf + por, s + i, chunk);
    por += chunk;
    i += chunk;
  }
}

void wt(const char c) {
  if (por == SZ) flush();
  obuf[por++] = c;
}
void wt(const char *s) { wt_range(s, strlen(s)); }
void wt(const string &s) { wt_range(s.data(), s.size()); }

template <typename T>
void wt_integer(T x) {
  if (por > SZ - 100) flush();
  if (x < 0) {
    obuf[por++] = '-', x = -x;
  }
  int outi;
  for (outi = 96; x >= 10000; outi -= 4) {
    memcpy(out + outi, pre.num[x % 10000], 4);
    x /= 10000;
  }
  if (x >= 1000) {
    memcpy(obuf + por, pre.num[x], 4);
    por += 4;
  } else if (x >= 100) {
    memcpy(obuf + por, pre.num[x] + 1, 3);
    por += 3;
  } else if (x >= 10) {
    int q = (x * 103) >> 10;
    obuf[por] = q | '0';
    obuf[por + 1] = (x - q * 10) | '0';
    por += 2;
  } else
    obuf[por++] = x | '0';
  memcpy(obuf + por, out + outi + 4, 96 - outi);
  por += 96 - outi;
}

template <typename T>
inline void wt_real(T x) {
  char buf[64];
  // 有効数字 15 桁、通常/指数を自動選択（printf("%.15g") 相当）
  int n = std::snprintf(buf, sizeof(buf), "%.15g", (double)x);

  // （任意）-0 を 0 に正規化
  if (n == 2 && buf[0] == '-' && buf[1] == '0') {
    buf[0] = '0';
    n = 1;
  }
  wt_range(buf, (size_t)n);
}

template <class T>
enable_if_t<is_integral_v<T> || is_same_v<T, i128> || is_same_v<T, u128>> wt(
    T x) {
  wt_integer(x);
}

template <class T>
enable_if_t<is_floating_point_v<T> || is_same_v<T, f128>> wt(T x) {
  wt_real(x);
}

inline void wt(bool b) { wt(static_cast<char>('0' + (b ? 1 : 0))); }

template <class T, class U>
void wt(const pair<T, U> &val) {
  wt(val.first);
  wt(' ');
  wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T &t) {
  if constexpr (N < tuple_size<T>::value) {
    if constexpr (N > 0) wt(' ');
    wt(get<N>(t));
    wt_tuple<N + 1>(t);
  }
}
template <class... T>
void wt(const tuple<T...> &tpl) {
  wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> &val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}
template <class T>
void wt(const vector<T> &val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}

void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&...tail) {
  wt(head);
  if (sizeof...(Tail)) wt(' ');
  print(forward<Tail>(tail)...);
}

// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
}  // namespace fastio
using fastio::flush;
using fastio::print;
using fastio::read;

#if defined(LOCAL)
#define HDR "[DEBUG:", __func__, __LINE__, "]"
#define SHOW(...)                                                         \
  SHOW_IMPL(__VA_ARGS__, SHOW8, SHOW7, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, \
            SHOW1)                                                        \
  (__VA_ARGS__)
#define SHOW_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME
#define SHOW1(x) print(HDR, #x, "=", (x)), flush()
#define SHOW2(x, y) print(HDR, #x, "=", (x), #y, "=", (y)), flush()
#define SHOW3(x, y, z) \
  print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z)), flush()
#define SHOW4(x, y, z, w) \
  print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w)), flush()
#define SHOW5(x, y, z, w, v)                                                  \
  print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \
        (v)),                                                                 \
      flush()
#define SHOW6(x, y, z, w, v, u)                                               \
  print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \
        (v), #u, "=", (u)),                                                   \
      flush()
#define SHOW7(x, y, z, w, v, u, t)                                            \
  print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \
        (v), #u, "=", (u), #t, "=", (t)),                                     \
      flush()
#define SHOW8(x, y, z, w, v, u, t, s)                                         \
  print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \
        (v), #u, "=", (u), #t, "=", (t), #s, "=", (s)),                       \
      flush()
#else
#define SHOW(...)
#endif

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define U32(...)   \
  u32 __VA_ARGS__; \
  read(__VA_ARGS__)
#define U64(...)   \
  u64 __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)   \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
void YA(bool t = 1) { print(t ? "YA" : "TIDAK"); }
void TIDAK(bool t = 1) { YA(!t); }
// END: other/io.hpp
#line 5 "main.cpp"

// BEGIN: flow/maxflow.hpp
#line 1 "flow/maxflow.hpp"
template <typename Cap>
struct MaxFlow {
  struct Edge {
    int to, rev;
    Cap cap;
  };

  vc<Edge> edges;
  vc<int> indptr, level;
  vc<Cap> init_cap;
  vc<tuple<int, int, Cap, Cap>> edge_pool;

  const int N, source, sink;
  bool calculated;
  Cap flow_ans;
  vc<int> pos;

  MaxFlow(int N, int source, int sink)
      : N(N), source(source), sink(sink), calculated(0), flow_ans(0) {}

  void add(int frm, int to, Cap cap, Cap rev_cap = 0) {
    calculated = 0;
    assert(0 <= frm && frm < N);
    assert(0 <= to && to < N);
    assert(Cap(0) <= cap);
    edge_pool.eb(frm, to, cap, rev_cap);
  }

  void build_csr() {
    int M = len(edge_pool);
    indptr.assign(N + 1, 0);
    for (auto [a, b, c, d] : edge_pool) indptr[a + 1]++, indptr[b + 1]++;
    FOR(i, N) indptr[i + 1] += indptr[i];
    vc<int> prog = indptr;
    edges.resize(2 * M);
    init_cap.resize(2 * M);
    for (auto [a, b, c, d] : edge_pool) {
      int I1 = prog[a], I2 = prog[b];
      edges[I1] = Edge{b, I2, c}, init_cap[I1] = c, prog[a]++;
      edges[I2] = Edge{a, I1, d}, init_cap[I2] = d, prog[b]++;
      pos.eb(I1);
    }
  }

  Cap flow() {
    if (calculated) return flow_ans;
    calculated = true;
    if (len(edges) != 2 * len(edge_pool)) build_csr();
    vc<int> prog = indptr;
    level.resize(N);
    vc<int> que(N);
    auto bfs = [&]() -> void {
      fill(all(level), -1);
      int ql = 0, qr = 0;
      level[source] = 0, que[qr++] = source;
      while (ql < qr) {
        int v = que[ql++];
        FOR(i, indptr[v], indptr[v + 1]) {
          Edge& e = edges[i];
          if (e.cap > 0 && level[e.to] == -1) {
            level[e.to] = level[v] + 1;
            que[qr++] = e.to;
            if (e.to == sink) return;
          }
        }
      }
    };

    // ACL 参考. v までいくつ流してくるという方式.
    // source-sink上にあるところだけ探索するのでこちらの方が高速ということだと思う.
    auto dfs = [&](auto& dfs, int v, Cap lim) -> Cap {
      if (v == source) return lim;
      Cap res = 0;
      int nxt_lv = level[v] - 1;
      for (int& i = prog[v]; i < indptr[v + 1]; ++i) {
        auto& e = edges[i];
        if (level[e.to] != nxt_lv || edges[e.rev].cap == 0) continue;
        Cap a = dfs(dfs, e.to, min(lim - res, edges[e.rev].cap));
        if (a <= 0) continue;
        e.cap += a, edges[e.rev].cap -= a, res += a;
        if (res == lim) return res;
      }
      level[v] = N;
      return res;
    };
    while (1) {
      bfs();
      if (level[sink] == -1) break;
      copy(all(indptr), prog.begin());
      Cap x = dfs(dfs, sink, infty<Cap>);
      flow_ans += x;
      if (flow_ans >= infty<Cap>) return infty<Cap>;
    }
    return flow_ans;
  }

  void change_capacity(int i, Cap after) {
    i = pos[i];
    auto& e = edges[i];
    Cap before = init_cap[i];
    Cap f = before - e.cap;
    init_cap[i] = after;
    if (before < after) {
      calculated = (e.cap > 0);
      e.cap += after - before;
      return;
    }
    e.cap = after - f;
    // 差分を押し戻す処理発生
    if (e.cap < 0) flow_push_back(e);
  }

  void flow_push_back(Edge& e0) {
    auto& re0 = edges[e0.rev];
    int a = re0.to;
    int b = e0.to;
    /*
    辺 e0 の容量が正になるように戻す
    path-cycle 分解を考えれば、
    - uv 辺を含むサイクルを消す
    - suvt パスを消す
    前者は残余グラフで ab パス（flow_ans が変わらない）
    後者は残余グラフで tb, as パス
    */

    vc<int> prog(N + 1);
    auto find_path = [&](int s, int t, Cap lim) -> Cap {
      vc<bool> vis(N);
      copy(all(indptr), prog.begin());
      auto dfs = [&](auto& dfs, int v, Cap f) -> Cap {
        if (v == t) return f;
        for (int& i = prog[v]; i < indptr[v + 1]; ++i) {
          auto& e = edges[i];
          if (vis[e.to] || e.cap <= Cap(0)) continue;
          vis[e.to] = 1;
          Cap a = dfs(dfs, e.to, min(f, e.cap));
          assert(a >= 0);
          if (a == Cap(0)) continue;
          e.cap -= a, edges[e.rev].cap += a;
          return a;
        }
        return 0;
      };
      return dfs(dfs, s, lim);
    };

    while (e0.cap < 0) {
      Cap x = find_path(a, b, -e0.cap);
      if (x == Cap(0)) break;
      e0.cap += x, re0.cap -= x;
    }
    Cap c = -e0.cap;
    while (c > 0 && a != source) {
      Cap x = find_path(a, source, c);
      assert(x > 0);
      c -= x;
    }
    c = -e0.cap;
    while (c > 0 && b != sink) {
      Cap x = find_path(sink, b, c);
      assert(x > 0);
      c -= x;
    }
    c = -e0.cap;
    e0.cap += c, re0.cap -= c;
    flow_ans -= c;
  }

  // frm, to, flow
  vc<tuple<int, int, Cap>> get_flow_edges() {
    vc<tuple<int, int, Cap>> res;
    FOR(v, N) {
      FOR(i, indptr[v], indptr[v + 1]) {
        Edge& e = edges[i];
        Cap f = init_cap[i] - e.cap;
        if (f > 0) res.eb(v, e.to, f);
      }
    }
    return res;
  }

  // 最小カットの値および、カットを表す 01 列を返す
  pair<Cap, vc<int>> cut() {
    flow();
    vc<int> res(N);
    FOR(v, N) res[v] = (level[v] >= 0 ? 0 : 1);
    return {flow_ans, res};
  }

  // O(F(N+M)) くらい使って経路復元
  // simple path になる
  vvc<int> path_decomposition() {
    flow();
    auto edges = get_flow_edges();
    vvc<int> TO(N);
    for (auto&& [frm, to, flow] : edges) {
      FOR(flow) TO[frm].eb(to);
    }
    vvc<int> res;
    vc<int> vis(N);

    FOR(flow_ans) {
      vc<int> path = {source};
      vis[source] = 1;
      while (path.back() != sink) {
        int to = POP(TO[path.back()]);
        while (vis[to]) {
          vis[POP(path)] = 0;
        }
        path.eb(to), vis[to] = 1;
      }
      for (auto&& v : path) vis[v] = 0;
      res.eb(path);
    }
    return res;
  }

  void debug() {
    print("source", source);
    print("sink", sink);
    print("edges (frm, to, cap, flow)");
    FOR(v, N) {
      FOR(i, indptr[v], indptr[v + 1]) {
        Edge& e = edges[i];
        Cap f = init_cap[i] - e.cap;
        SHOW(i, v, e.to, e.cap, f);
      }
    }
  }
};
// END: flow/maxflow.hpp
#line 7 "main.cpp"

void solve() {
  LL(N, M);
  using T = tuple<int, int, int>;
  VEC(T, dat, M);
  MaxFlow<int> G(N, 0, N - 1);
  FOR(i, M) {
    auto [a, b, c] = dat[i];
    G.add(a, b, c);
    G.add(b, a, c);
  }
  int ans = G.flow();
  int LIM = 10'000;
  if (ans > LIM + 1) return print(-1);
  ll base = G.flow();
  FOR(i, M) {
    auto [a, b, c] = dat[i];
    if (c == 1) {
      G.change_capacity(2 * i + 0, 0);
      G.change_capacity(2 * i + 1, 0);
      chmin(ans, G.flow());
      G.change_capacity(2 * i + 0, 1);
      G.change_capacity(2 * i + 1, 1);
      assert(G.flow() == base);
    }
  }
  if (ans > LIM) return print(-1);
  print(ans);
}

signed main() {
  solve();
  return 0;
}// END: main.cpp
accuracy: 1
time_ms: 740
memory_kb: 4048
final_rank: 8

code_snippet: #include<iostream>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cassert>
#include<cstring>
#include<climits>
#include<sstream>
#include<deque>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
#include<bitset>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

const int MAX_V = 10000;
const int IINF = INT_MAX;
typedef pair<int,int> ii;

map<ii,int> mp; /////////

struct Edge{ int to,cap,rev; };

vector<Edge> G[MAX_V];
bool used[MAX_V];

void add_edge(int from,int to,int cap){
  assert( mp.count(ii(from,to)) == 0 );
  mp[ii(from,to)] = (int)G[from].size();
  G[from].push_back((Edge){to,cap,(int)G[to].size()});
  G[to].push_back((Edge){from,0,(int)G[from].size()-1});
}

int dfs(int v,int t,int f){
  if( v == t ) return f;
  used[v] = true;
  for(int i=0;i<(int)G[v].size();i++){
    Edge &e = G[v][i];
    if( !used[e.to] && e.cap > 0 ){
      int d = dfs(e.to,t,min(f,e.cap));
      if( d > 0 ){
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s,int t){
  int flow = 0;
  for(;;){
    memset(used,0,sizeof(used));
    int f = dfs(s,t,IINF);
    if( f == 0 ) return flow;
    flow += f;
  }
}

void init(int _size=MAX_V){ rep(i,_size) G[i].clear(); }

int V,E,Q;


inline void remove_edge(int u,int v){
  G[u][mp[ii(u,v)]].cap = 0;
  G[v][G[u][mp[ii(u,v)]].rev].cap = 0;
  G[v][mp[ii(v,u)]].cap = 0;
  G[u][G[v][mp[ii(v,u)]].rev].cap = 0;
}

inline bool remove(int u,int v,int source,int sink){
  Back:;
  if( G[u][mp[ii(u,v)]].cap == 1 && G[v][mp[ii(v,u)]].cap == 1 ) {
    remove_edge(u,v);
    return false;
  }

  if( G[u][mp[ii(u,v)]].cap == 0 && G[v][mp[ii(v,u)]].cap == 0 ){
    G[u][mp[ii(u,v)]].cap = 1;
    G[v][G[u][mp[ii(u,v)]].rev].cap = 0;
    G[v][mp[ii(v,u)]].cap = 1;
    G[u][G[v][mp[ii(v,u)]].rev].cap = 0;
    goto Back;
  }


  if( G[u][mp[ii(u,v)]].cap == 1 ) swap(u,v);
  memset(used,false,sizeof(used));
  int tmp = dfs(u,v,IINF);
  bool ret = false;
  if( tmp == 0 ) {
    memset(used,false,sizeof(used));
    tmp = dfs(sink,source,1);
    memset(used,false,sizeof(used));
    tmp = dfs(u,v,1);
    assert(tmp);
    ret = true;
  } 
  remove_edge(u,v);
  return ret;
}

int main(){

  set<ii> S;
  scanf("%d %d",&V,&E);
  vector<ii> es;
  rep(i,E){
    int F,T,C;
    scanf("%d %d %d",&F,&T,&C);
    add_edge(F,T,C);
    add_edge(T,F,C);
    if( F > T ) swap(F,T);
    if( C == 1 ) es.push_back(ii(F,T));
    S.insert(ii(F,T));
  }
  int source = 0, sink = V-1;
  int cur_flow = max_flow(source,sink);

  int mini = cur_flow;

  rep(_,(int)es.size()){
    //cout << "query : " << _ << " ";
    int A = es[_].first, B = es[_].second;
    if( A > B ) swap(A,B);

    bool res = remove(A,B,source,sink); //| remove(B,A,source,sink);
    if( res ) cur_flow--;
    mini = min(mini,cur_flow);
    int F = A, T = B;
    if( S.count(ii(F,T)) ) {
      int pos = IINF;
      G[A][mp[ii(A,B)]].cap = 1;
      G[B][G[A][mp[ii(A,B)]].rev].cap = 0;
      G[B][mp[ii(B,A)]].cap = 1;
      G[A][G[B][mp[ii(B,A)]].rev].cap = 0;
    } else {
      add_edge(A,B,1);
      add_edge(B,A,1);
      S.insert(ii(F,T));
    }
    memset(used,false,sizeof(used));
    cur_flow += dfs(source,sink,IINF);
  }
  if( mini <= 10000 ) {
    cout << mini << endl;
  } else {
    puts("-1");
  }
  return 0;
}
accuracy: 1
time_ms: 660
memory_kb: 5180
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int N = 5e3 + 5;

int a[N][N], used[N], n, m;
vector<int> g[N];
array<int, 3> e[N];

void add_edge(int u, int v, int f) {
    g[u].push_back(v);
    g[v].push_back(u);
    a[u][v] = a[v][u] = f;
}

int dfs(int v, int t, int f) {
    if (v == t)return f;
    used[v] = 1;
    for (auto x : g[v]) {
        if (used[x] || !a[v][x])continue;
        int d = dfs(x, t, min(f, a[v][x]));
        if (d) {
            a[v][x] -= d;
            a[x][v] += d;
            return d;
        }
    }
    return 0;
}

int ford(int s, int t, int nd) {
    int ans = 0;
    while (1) {
        memset(used, 0, sizeof(used));
        int f = dfs(s, t, nd);
        if (!f)return ans;
        ans += f;
        nd -= f;
    }
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        cin >> e[i][0] >> e[i][1] >> e[i][2];
        add_edge(e[i][0], e[i][1], e[i][2]);
    }
    int fl = ford(0, n - 1, 1e4 + 2);
    if (fl == 1e4 + 2) {
        cout << -1 << '\n';
        return 0;
    }
    for (int i = 0; i < m; i++) {
        if (e[i][2] != 1)continue;
        int s = e[i][0];
        int t = e[i][1];
        if (a[s][t] == 1) continue;
        if (!a[s][t])swap(s, t);
        int x = ford(t, s, 1);
        if (!x) {
            fl--;
            cout << fl << '\n';
            return 0;
        }
    }
    if (fl != 1e4 + 1) {
        cout << fl << '\n';
        return 0;
    }
    cout << -1 << '\n';
}
accuracy: 1
time_ms: 200
memory_kb: 99284
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int N = 5e3 + 5;

int a[N][N], used[N], n, m;
vector<int> g[N];
array<int, 3> e[N];

void add_edge(int u, int v, int f) {
    g[u].push_back(v);
    g[v].push_back(u);
    a[u][v] = a[v][u] = f;
}

int dfs(int v, int t, int f) {
    if (v == t)return f;
    used[v] = 1;
    for (auto x : g[v]) {
        if (used[x] || !a[v][x])continue;
        int d = dfs(x, t, min(f, a[v][x]));
        if (d) {
            a[v][x] -= d;
            a[x][v] += d;
            return d;
        }
    }
    return 0;
}

int ford(int s, int t, int nd) {
    int ans = 0;
    while (1) {
        memset(used, 0, sizeof(used));
        int f = dfs(s, t, nd);
        if (!f)return ans;
        ans += f;
        nd -= f;
    }
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        cin >> e[i][0] >> e[i][1] >> e[i][2];
        add_edge(e[i][0], e[i][1], e[i][2]);
    }
    int fl = ford(0, n - 1, 1e4 + 2);
    if (fl == 1e4 + 2) {
        cout << -1 << '\n';
        return 0;
    }
    for (int i = 0; i < m; i++) {
        if (e[i][2] != 1)continue;
        int s = e[i][0];
        int t = e[i][1];
        if (a[s][t] == 1) continue;
        fl--;
        cout << fl << '\n';
        return 0;
    }
    if (fl != 1e4 + 1) {
        cout << fl << '\n';
        return 0;
    }
    cout << -1 << '\n';
}
accuracy: 0.9659090909090909
time_ms: 60
memory_kb: 99280
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int N = 5e3 + 5;

int a[N][N], used[N], n, m;
vector<int> g[N];
array<int, 3> e[N];

void add_edge(int u, int v, int f) {
    g[u].push_back(v);
    g[v].push_back(u);
    a[u][v] = a[v][u] = f;
}

int dfs(int v, int t, int f) {
    if (v == t)return f;
    used[v] = 1;
    for (auto x : g[v]) {
        if (used[x] || !a[v][x])continue;
        int d = dfs(x, t, min(f, a[v][x]));
        if (d) {
            a[v][x] -= d;
            a[x][v] += d;
            return d;
        }
    }
    return 0;
}

int ford(int s, int t, int nd) {
    int ans = 0;
    while (1) {
        memset(used, 0, sizeof(used));
        int f = dfs(s, t, nd);
        if (!f)return ans;
        ans += f;
        nd -= f;
    }
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        cin >> e[i][0] >> e[i][1] >> e[i][2];
        add_edge(e[i][0], e[i][1], e[i][2]);
    }
    int fl = ford(0, n - 1, 1e4 + 2);
    if (fl == 1e4 + 2) {
        cout << -1 << '\n';
        return 0;
    }
    for (int i = 0; i < m; i++) {
        if (e[i][2] != 1)continue;
        int s = e[i][0];
        int t = e[i][1];
        if (!a[s][t])swap(s, t);
        if (!a[t][s]) {
            int x = ford(t, s, 1);
            if (!x) {
                fl--;
                cout << fl << '\n';
                return 0;
            }
        }
    }
    if (fl != 1e4 + 1) {
        cout << fl << '\n';
        return 0;
    }
    cout << -1 << '\n';
}
accuracy: 1
time_ms: 210
memory_kb: 99236
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int N = 5e3 + 5;

int a[N][N], used[N], n, m;
vector<int> g[N];
array<int, 3> e[N];

void add_edge(int u, int v, int f) {
    g[u].push_back(v);
    g[v].push_back(u);
    a[u][v] = a[v][u] += f;
}

int dfs(int v, int t, int f) {
    if (v == t)return f;
    used[v] = 1;
    for (auto x : g[v]) {
        if (used[x] || !a[v][x])continue;
        int d = dfs(x, t, min(f, a[v][x]));
        if (d) {
            a[v][x] -= d;
            a[x][v] += d;
            return d;
        }
    }
    return 0;
}

int ford(int s, int t, int nd) {
    int ans = 0;
    while (1) {
        memset(used, 0, sizeof(used));
        int f = dfs(s, t, nd);
        if (!f)return ans;
        ans += f;
        nd -= f;
    }
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        cin >> e[i][0] >> e[i][1] >> e[i][2];
        add_edge(e[i][0], e[i][1], e[i][2]);
    }
    int fl = ford(0, n - 1, 1e4 + 2);
    if (fl == 1e4 + 2) {
        cout << -1 << '\n';
        return 0;
    }

    for (int i = 0; i < m; i++) {
        if (e[i][2] != 1)continue;
        int s = e[i][0];
        int t = e[i][1];
        if (a[t][s] == 2)swap(s, t);
        if (a[s][t] == 2) {
            int x = ford(t, s, 1);
            if (!x) {
                ford(n - 1, 0, 1);
                ford(t, s, 1);
                fl--;
                cout << fl << '\n';
                return 0;
            }
        }
    }
    if (fl == 1e4 + 1) {
        cout << -1 << '\n';
        return 0;
    }
    cout << fl << '\n';
}
accuracy: 1
time_ms: 190
memory_kb: 99348
final_rank: 12

code_snippet: #line 1 "main.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2835"

#line 1 "library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else

// https://codeforces.com/blog/entry/96344
#pragma GCC optimize("Ofast,unroll-loops")
// いまの CF だとこれ入れると動かない？
// #pragma GCC target("avx2,popcnt")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'000'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;

using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define FOR_subset(t, s) \
  for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_mod_2(int x) { return __builtin_parity(x); }
int popcnt_mod_2(u32 x) { return __builtin_parity(x); }
int popcnt_mod_2(ll x) { return __builtin_parityll(x); }
int popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T floor(T a, T b) {
  return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
  return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
  return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template <typename T, typename U>
T SUM(const vector<U> &A) {
  T sm = 0;
  for (auto &&a: A) sm += a;
  return sm;
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <typename T>
T POP(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(pqg<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    (check(x) ? ok : ng) = x;
  }
  return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    (check(x) ? ok : ng) = x;
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
  vector<int> ids(len(A));
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  vc<T> B(len(I));
  FOR(i, len(I)) B[i] = A[I[i]];
  return B;
}
#endif
#line 1 "library/other/io.hpp"
#define FASTIO
#include <unistd.h>

// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
  char num[10000][4];
  constexpr Pre() : num() {
    for (int i = 0; i < 10000; i++) {
      int n = i;
      for (int j = 3; j >= 0; j--) {
        num[i][j] = n % 10 | '0';
        n /= 10;
      }
    }
  }
} constexpr pre;

inline void load() {
  memcpy(ibuf, ibuf + pil, pir - pil);
  pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
  pil = 0;
  if (pir < SZ) ibuf[pir++] = '\n';
}

inline void flush() {
  fwrite(obuf, 1, por, stdout);
  por = 0;
}

void rd(char &c) {
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
}

void rd(string &x) {
  x.clear();
  char c;
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
  do {
    x += c;
    if (pil == pir) load();
    c = ibuf[pil++];
  } while (!isspace(c));
}

template <typename T>
void rd_real(T &x) {
  string s;
  rd(s);
  x = stod(s);
}

template <typename T>
void rd_integer(T &x) {
  if (pil + 100 > pir) load();
  char c;
  do
    c = ibuf[pil++];
  while (c < '-');
  bool minus = 0;
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (c == '-') { minus = 1, c = ibuf[pil++]; }
  }
  x = 0;
  while ('0' <= c) { x = x * 10 + (c & 15), c = ibuf[pil++]; }
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (minus) x = -x;
  }
}

void rd(int &x) { rd_integer(x); }
void rd(ll &x) { rd_integer(x); }
void rd(i128 &x) { rd_integer(x); }
void rd(u32 &x) { rd_integer(x); }
void rd(u64 &x) { rd_integer(x); }
void rd(u128 &x) { rd_integer(x); }
void rd(double &x) { rd_real(x); }
void rd(long double &x) { rd_real(x); }
void rd(f128 &x) { rd_real(x); }

template <class T, class U>
void rd(pair<T, U> &p) {
  return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
  if constexpr (N < std::tuple_size<T>::value) {
    auto &x = std::get<N>(t);
    rd(x);
    rd_tuple<N + 1>(t);
  }
}
template <class... T>
void rd(tuple<T...> &tpl) {
  rd_tuple(tpl);
}

template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
  for (auto &d: x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
  for (auto &d: x) rd(d);
}

void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
  rd(h), read(t...);
}

void wt(const char c) {
  if (por == SZ) flush();
  obuf[por++] = c;
}
void wt(const string s) {
  for (char c: s) wt(c);
}
void wt(const char *s) {
  size_t len = strlen(s);
  for (size_t i = 0; i < len; i++) wt(s[i]);
}

template <typename T>
void wt_integer(T x) {
  if (por > SZ - 100) flush();
  if (x < 0) { obuf[por++] = '-', x = -x; }
  int outi;
  for (outi = 96; x >= 10000; outi -= 4) {
    memcpy(out + outi, pre.num[x % 10000], 4);
    x /= 10000;
  }
  if (x >= 1000) {
    memcpy(obuf + por, pre.num[x], 4);
    por += 4;
  } else if (x >= 100) {
    memcpy(obuf + por, pre.num[x] + 1, 3);
    por += 3;
  } else if (x >= 10) {
    int q = (x * 103) >> 10;
    obuf[por] = q | '0';
    obuf[por + 1] = (x - q * 10) | '0';
    por += 2;
  } else
    obuf[por++] = x | '0';
  memcpy(obuf + por, out + outi + 4, 96 - outi);
  por += 96 - outi;
}

template <typename T>
void wt_real(T x) {
  ostringstream oss;
  oss << fixed << setprecision(15) << double(x);
  string s = oss.str();
  wt(s);
}

void wt(int x) { wt_integer(x); }
void wt(ll x) { wt_integer(x); }
void wt(i128 x) { wt_integer(x); }
void wt(u32 x) { wt_integer(x); }
void wt(u64 x) { wt_integer(x); }
void wt(u128 x) { wt_integer(x); }
void wt(double x) { wt_real(x); }
void wt(long double x) { wt_real(x); }
void wt(f128 x) { wt_real(x); }

template <class T, class U>
void wt(const pair<T, U> val) {
  wt(val.first);
  wt(' ');
  wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
  if constexpr (N < std::tuple_size<T>::value) {
    if constexpr (N > 0) { wt(' '); }
    const auto x = std::get<N>(t);
    wt(x);
    wt_tuple<N + 1>(t);
  }
}
template <class... T>
void wt(tuple<T...> tpl) {
  wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}
template <class T>
void wt(const vector<T> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}

void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  wt(head);
  if (sizeof...(Tail)) wt(' ');
  print(forward<Tail>(tail)...);
}

// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::read;
using fastio::print;
using fastio::flush;

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define U32(...)   \
  u32 __VA_ARGS__; \
  read(__VA_ARGS__)
#define U64(...)   \
  u64 __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)   \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 5 "main.cpp"

#line 1 "library/flow/maxflow.hpp"
// incremental に辺を追加してよい
// 辺の容量の変更が可能
// 変更する capacity が F のとき、O((N+M)|F|) 時間で更新
template <typename Cap>
struct MaxFlow {
  struct Edge {
    int to, rev;
    Cap cap; // 残っている容量. したがって cap+flow が定数.
    Cap flow = 0;
  };

  const int N, source, sink;
  vvc<Edge> edges;
  vc<pair<int, int>> pos;
  vc<int> prog, level;
  vc<int> que;
  bool calculated;

  MaxFlow(int N, int source, int sink)
      : N(N),
        source(source),
        sink(sink),
        edges(N),
        calculated(0),
        flow_ans(0) {}

  void add(int frm, int to, Cap cap, Cap rev_cap = 0) {
    calculated = 0;
    assert(0 <= frm && frm < N);
    assert(0 <= to && to < N);
    assert(frm != to);
    assert(Cap(0) <= cap);
    if (frm == to) return;
    int a = len(edges[frm]);
    int b = len(edges[to]);
    pos.eb(frm, a);
    edges[frm].eb(Edge{to, b, cap, 0});
    edges[to].eb(Edge{frm, a, rev_cap, 0});
  }

  void change_capacity(int i, Cap before, Cap after) {
    if (before == after) return;
    auto [frm, idx] = pos[i];
    auto& e = edges[frm][idx];
    assert(e.cap + e.flow == before);
    if (before < after) {
      calculated = (e.cap > 0);
      e.cap += after - before;
      return;
    }
    e.cap = after - e.flow;
    // 差分を押し戻す処理発生
    if (e.cap < 0) flow_push_back(e);
  }

  void flow_push_back(Edge& e0) {
    auto& re0 = edges[e0.to][e0.rev];
    int a = re0.to;
    int b = e0.to;
    /*
    辺 e0 の容量が正になるように戻す
    path-cycle 分解を考えれば、
    - uv 辺を含むサイクルを消す
    - suvt パスを消す
    前者は残余グラフで ab パス（flow_ans が変わらない）
    後者は残余グラフで tb, as パス
    */

    auto find_path = [&](int s, int t, Cap lim) -> Cap {
      vc<bool> vis(N);
      prog.assign(N, 0);
      auto dfs = [&](auto& dfs, int v, Cap f) -> Cap {
        if (v == t) return f;
        for (int& i = prog[v]; i < len(edges[v]); ++i) {
          auto& e = edges[v][i];
          if (vis[e.to] || e.cap <= Cap(0)) continue;
          vis[e.to] = 1;
          Cap a = dfs(dfs, e.to, min(f, e.cap));
          assert(a >= 0);
          if (a == Cap(0)) continue;
          e.cap -= a, e.flow += a;
          edges[e.to][e.rev].cap += a, edges[e.to][e.rev].flow -= a;
          return a;
        }
        return 0;
      };
      return dfs(dfs, s, lim);
    };

    while (e0.cap < 0) {
      Cap x = find_path(a, b, -e0.cap);
      if (x == Cap(0)) break;
      e0.cap += x, e0.flow -= x;
      re0.cap -= x, re0.flow += x;
    }
    Cap c = -e0.cap;
    while (c > 0 && a != source) {
      Cap x = find_path(a, source, c);
      assert(x > 0);
      c -= x;
    }
    c = -e0.cap;
    while (c > 0 && b != sink) {
      Cap x = find_path(sink, b, c);
      assert(x > 0);
      c -= x;
    }
    c = -e0.cap;
    e0.cap += c, e0.flow -= c;
    re0.cap -= c, re0.flow += c;
    flow_ans -= c;
  }

  // frm, to, flow
  vc<tuple<int, int, Cap>> get_flow_edges() {
    vc<tuple<int, int, Cap>> res;
    FOR(frm, N) {
      for (auto&& e: edges[frm]) {
        if (e.flow <= 0) continue;
        res.eb(frm, e.to, e.flow);
      }
    }
    return res;
  }

  // 差分ではなくこれまでの総量
  Cap flow() {
    if (calculated) return flow_ans;
    calculated = true;
    while (set_level()) {
      prog.assign(N, 0);
      while (1) {
        Cap x = flow_dfs(source, infty<Cap>);
        if (x == 0) break;
        flow_ans += x;
        chmin(flow_ans, infty<Cap>);
        if (flow_ans == infty<Cap>) return flow_ans;
      }
    }
    return flow_ans;
  }

  // 最小カットの値および、カットを表す 01 列を返す
  pair<Cap, vc<int>> cut() {
    flow();
    vc<int> res(N);
    FOR(v, N) res[v] = (level[v] >= 0 ? 0 : 1);
    return {flow_ans, res};
  }

  // O(F(N+M)) くらい使って経路復元
  // simple path になる
  vvc<int> path_decomposition() {
    flow();
    auto edges = get_flow_edges();
    vvc<int> TO(N);
    for (auto&& [frm, to, flow]: edges) { FOR(flow) TO[frm].eb(to); }
    vvc<int> res;
    vc<int> vis(N);

    FOR(flow_ans) {
      vc<int> path = {source};
      vis[source] = 1;
      while (path.back() != sink) {
        int to = POP(TO[path.back()]);
        while (vis[to]) { vis[POP(path)] = 0; }
        path.eb(to), vis[to] = 1;
      }
      for (auto&& v: path) vis[v] = 0;
      res.eb(path);
    }
    return res;
  }

  void debug() {
    print("source", source);
    print("sink", sink);
    print("edges (frm, to, cap, flow)");
    FOR(v, N) {
      for (auto& e: edges[v]) {
        if (e.cap == 0 && e.flow == 0) continue;
        print(v, e.to, e.cap, e.flow);
      }
    }
  }

private:
  Cap flow_ans;

  bool set_level() {
    que.resize(N);
    level.assign(N, -1);
    level[source] = 0;
    int l = 0, r = 0;
    que[r++] = source;
    while (l < r) {
      int v = que[l++];
      for (auto&& e: edges[v]) {
        if (e.cap > 0 && level[e.to] == -1) {
          level[e.to] = level[v] + 1;
          if (e.to == sink) return true;
          que[r++] = e.to;
        }
      }
    }
    return false;
  }

  Cap flow_dfs(int v, Cap lim) {
    if (v == sink) return lim;
    Cap res = 0;
    for (int& i = prog[v]; i < len(edges[v]); ++i) {
      auto& e = edges[v][i];
      if (e.cap > 0 && level[e.to] == level[v] + 1) {
        Cap a = flow_dfs(e.to, min(lim, e.cap));
        if (a > 0) {
          e.cap -= a, e.flow += a;
          edges[e.to][e.rev].cap += a, edges[e.to][e.rev].flow -= a;
          res += a;
          lim -= a;
          if (lim == 0) break;
        }
      }
    }
    return res;
  }
};
#line 7 "main.cpp"

void solve() {
  LL(N, M);
  using T = tuple<int, int, int>;
  VEC(T, dat, M);
  MaxFlow<int> G(N, 0, N - 1);
  FOR(i, M) {
    auto [a, b, c] = dat[i];
    G.add(a, b, c);
    G.add(b, a, c);
  }
  int ans = G.flow();
  int LIM = 10'000;
  if (ans > LIM + 1) return print(-1);

  FOR(i, M) {
    auto [a, b, c] = dat[i];
    if (c == 1) {
      G.change_capacity(2 * i + 0, 1, 0);
      G.change_capacity(2 * i + 1, 1, 0);
      chmin(ans, G.flow());
      G.change_capacity(2 * i + 0, 0, 1);
      G.change_capacity(2 * i + 1, 0, 1);
    }
  }
  if (ans > LIM) return print(-1);
  print(ans);
}

signed main() {
  solve();
  return 0;
}
accuracy: 1
time_ms: 650
memory_kb: 4240
final_rank: 5

code_snippet: #line 1 "library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else

// https://codeforces.com/blog/entry/96344
#pragma GCC optimize("Ofast,unroll-loops")
// いまの CF だとこれ入れると動かない？
// #pragma GCC target("avx2,popcnt")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'000'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;

using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define FOR_subset(t, s) \
  for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_mod_2(int x) { return __builtin_parity(x); }
int popcnt_mod_2(u32 x) { return __builtin_parity(x); }
int popcnt_mod_2(ll x) { return __builtin_parityll(x); }
int popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T floor(T a, T b) {
  return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
  return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
  return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template <typename T, typename U>
T SUM(const vector<U> &A) {
  T sm = 0;
  for (auto &&a: A) sm += a;
  return sm;
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <typename T>
T POP(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(pqg<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    (check(x) ? ok : ng) = x;
  }
  return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    (check(x) ? ok : ng) = x;
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
  vector<int> ids(len(A));
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  vc<T> B(len(I));
  FOR(i, len(I)) B[i] = A[I[i]];
  return B;
}
#endif
#line 1 "library/other/io.hpp"
#define FASTIO
#include <unistd.h>

// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
  char num[10000][4];
  constexpr Pre() : num() {
    for (int i = 0; i < 10000; i++) {
      int n = i;
      for (int j = 3; j >= 0; j--) {
        num[i][j] = n % 10 | '0';
        n /= 10;
      }
    }
  }
} constexpr pre;

inline void load() {
  memcpy(ibuf, ibuf + pil, pir - pil);
  pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
  pil = 0;
  if (pir < SZ) ibuf[pir++] = '\n';
}

inline void flush() {
  fwrite(obuf, 1, por, stdout);
  por = 0;
}

void rd(char &c) {
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
}

void rd(string &x) {
  x.clear();
  char c;
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
  do {
    x += c;
    if (pil == pir) load();
    c = ibuf[pil++];
  } while (!isspace(c));
}

template <typename T>
void rd_real(T &x) {
  string s;
  rd(s);
  x = stod(s);
}

template <typename T>
void rd_integer(T &x) {
  if (pil + 100 > pir) load();
  char c;
  do
    c = ibuf[pil++];
  while (c < '-');
  bool minus = 0;
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (c == '-') { minus = 1, c = ibuf[pil++]; }
  }
  x = 0;
  while ('0' <= c) { x = x * 10 + (c & 15), c = ibuf[pil++]; }
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (minus) x = -x;
  }
}

void rd(int &x) { rd_integer(x); }
void rd(ll &x) { rd_integer(x); }
void rd(i128 &x) { rd_integer(x); }
void rd(u32 &x) { rd_integer(x); }
void rd(u64 &x) { rd_integer(x); }
void rd(u128 &x) { rd_integer(x); }
void rd(double &x) { rd_real(x); }
void rd(long double &x) { rd_real(x); }
void rd(f128 &x) { rd_real(x); }

template <class T, class U>
void rd(pair<T, U> &p) {
  return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
  if constexpr (N < std::tuple_size<T>::value) {
    auto &x = std::get<N>(t);
    rd(x);
    rd_tuple<N + 1>(t);
  }
}
template <class... T>
void rd(tuple<T...> &tpl) {
  rd_tuple(tpl);
}

template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
  for (auto &d: x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
  for (auto &d: x) rd(d);
}

void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
  rd(h), read(t...);
}

void wt(const char c) {
  if (por == SZ) flush();
  obuf[por++] = c;
}
void wt(const string s) {
  for (char c: s) wt(c);
}
void wt(const char *s) {
  size_t len = strlen(s);
  for (size_t i = 0; i < len; i++) wt(s[i]);
}

template <typename T>
void wt_integer(T x) {
  if (por > SZ - 100) flush();
  if (x < 0) { obuf[por++] = '-', x = -x; }
  int outi;
  for (outi = 96; x >= 10000; outi -= 4) {
    memcpy(out + outi, pre.num[x % 10000], 4);
    x /= 10000;
  }
  if (x >= 1000) {
    memcpy(obuf + por, pre.num[x], 4);
    por += 4;
  } else if (x >= 100) {
    memcpy(obuf + por, pre.num[x] + 1, 3);
    por += 3;
  } else if (x >= 10) {
    int q = (x * 103) >> 10;
    obuf[por] = q | '0';
    obuf[por + 1] = (x - q * 10) | '0';
    por += 2;
  } else
    obuf[por++] = x | '0';
  memcpy(obuf + por, out + outi + 4, 96 - outi);
  por += 96 - outi;
}

template <typename T>
void wt_real(T x) {
  ostringstream oss;
  oss << fixed << setprecision(15) << double(x);
  string s = oss.str();
  wt(s);
}

void wt(int x) { wt_integer(x); }
void wt(ll x) { wt_integer(x); }
void wt(i128 x) { wt_integer(x); }
void wt(u32 x) { wt_integer(x); }
void wt(u64 x) { wt_integer(x); }
void wt(u128 x) { wt_integer(x); }
void wt(double x) { wt_real(x); }
void wt(long double x) { wt_real(x); }
void wt(f128 x) { wt_real(x); }

template <class T, class U>
void wt(const pair<T, U> val) {
  wt(val.first);
  wt(' ');
  wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
  if constexpr (N < std::tuple_size<T>::value) {
    if constexpr (N > 0) { wt(' '); }
    const auto x = std::get<N>(t);
    wt(x);
    wt_tuple<N + 1>(t);
  }
}
template <class... T>
void wt(tuple<T...> tpl) {
  wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}
template <class T>
void wt(const vector<T> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}

void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  wt(head);
  if (sizeof...(Tail)) wt(' ');
  print(forward<Tail>(tail)...);
}

// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::read;
using fastio::print;
using fastio::flush;

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define U32(...)   \
  u32 __VA_ARGS__; \
  read(__VA_ARGS__)
#define U64(...)   \
  u64 __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)   \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 3 "main.cpp"

// 辺の容量の変更が可能
// 変更する capacity が F のとき、O((N+M)|F|) 時間で更新
template <typename Cap>
struct MaxFlow_Difference_Update {
  struct Edge {
    int to, rev;
    Cap cap; // 残っている容量. したがって cap+flow が定数.
    Cap flow = 0;
  };

  const int N, source, sink;
  vvc<Edge> edges;
  vc<pair<int, int>> pos;
  vc<int> prog, level;
  vc<int> que;
  bool calculated;

  MaxFlow_Difference_Update(int N, int source, int sink)
      : N(N),
        source(source),
        sink(sink),
        edges(N),
        calculated(0),
        flow_ans(0) {}

  void add(int frm, int to, Cap cap, Cap rev_cap = 0) {
    calculated = 0;
    assert(0 <= frm && frm < N);
    assert(0 <= to && to < N);
    assert(frm != to);
    assert(Cap(0) <= cap);
    if (frm == to) return;
    int a = len(edges[frm]);
    int b = len(edges[to]);
    pos.eb(frm, a);
    edges[frm].eb(Edge{to, b, cap, 0});
    edges[to].eb(Edge{frm, a, rev_cap, 0});
  }

  void change_capacity(int i, Cap before, Cap after) {
    if (before == after) return;
    auto [frm, idx] = pos[i];
    auto& e = edges[frm][idx];
    assert(e.cap + e.flow == before);
    if (before < after) {
      calculated = (e.cap > 0);
      e.cap += after - before;
      return;
    }
    e.cap = after - e.flow;
    // 差分を押し戻す処理発生
    if (e.cap < 0) flow_push_back(e);
  }

  void flow_push_back(Edge& e0) {
    auto& re0 = edges[e0.to][e0.rev];
    int a = re0.to;
    int b = e0.to;
    /*
    辺 e0 の容量が正になるように戻す
    path-cycle 分解を考えれば、
    - uv 辺を含むサイクルを消す
    - suvt パスを消す
    前者は残余グラフで ab パス（flow_ans が変わらない）
    後者は残余グラフで tb, as パス
    */

    auto find_path = [&](int s, int t, Cap lim) -> Cap {
      vc<bool> vis(N);
      prog.assign(N, 0);
      auto dfs = [&](auto& dfs, int v, Cap f) -> Cap {
        if (v == t) return f;
        for (int& i = prog[v]; i < len(edges[v]); ++i) {
          auto& e = edges[v][i];
          if (vis[e.to] || e.cap <= Cap(0)) continue;
          vis[e.to] = 1;
          Cap a = dfs(dfs, e.to, min(f, e.cap));
          assert(a >= 0);
          if (a == Cap(0)) continue;
          e.cap -= a, e.flow += a;
          edges[e.to][e.rev].cap += a, edges[e.to][e.rev].flow -= a;
          return a;
        }
        return 0;
      };
      return dfs(dfs, s, lim);
    };

    while (e0.cap < 0) {
      Cap x = find_path(a, b, -e0.cap);
      if (x == Cap(0)) break;
      e0.cap += x, e0.flow -= x;
      re0.cap -= x, re0.flow += x;
    }
    Cap c = -e0.cap;
    while (c > 0 && a != source) {
      Cap x = find_path(a, source, c);
      assert(x > 0);
      c -= x;
    }
    c = -e0.cap;
    while (c > 0 && b != sink) {
      Cap x = find_path(sink, b, c);
      assert(x > 0);
      c -= x;
    }
    c = -e0.cap;
    e0.cap += c, e0.flow -= c;
    re0.cap -= c, re0.flow += c;
    flow_ans -= c;
  }

  // frm, to, flow
  vc<tuple<int, int, Cap>> get_flow_edges() {
    vc<tuple<int, int, Cap>> res;
    FOR(frm, N) {
      for (auto&& e: edges[frm]) {
        if (e.flow <= 0) continue;
        res.eb(frm, e.to, e.flow);
      }
    }
    return res;
  }

  // 差分ではなくこれまでの総量
  Cap flow() {
    if (calculated) return flow_ans;
    calculated = true;
    while (set_level()) {
      prog.assign(N, 0);
      while (1) {
        Cap x = flow_dfs(source, infty<Cap>);
        if (x == 0) break;
        flow_ans += x;
        chmin(flow_ans, infty<Cap>);
        if (flow_ans == infty<Cap>) return flow_ans;
      }
    }
    return flow_ans;
  }

  // 最小カットの値および、カットを表す 01 列を返す
  pair<Cap, vc<int>> cut() {
    flow();
    vc<int> res(N);
    FOR(v, N) res[v] = (level[v] >= 0 ? 0 : 1);
    return {flow_ans, res};
  }

  // O(F(N+M)) くらい使って経路復元
  // simple path になる
  vvc<int> path_decomposition() {
    flow();
    auto edges = get_flow_edges();
    vvc<int> TO(N);
    for (auto&& [frm, to, flow]: edges) { FOR(flow) TO[frm].eb(to); }
    vvc<int> res;
    vc<int> vis(N);

    FOR(flow_ans) {
      vc<int> path = {source};
      vis[source] = 1;
      while (path.back() != sink) {
        int to = POP(TO[path.back()]);
        while (vis[to]) { vis[POP(path)] = 0; }
        path.eb(to), vis[to] = 1;
      }
      for (auto&& v: path) vis[v] = 0;
      res.eb(path);
    }
    return res;
  }

  void debug() {
    print("source", source);
    print("sink", sink);
    print("edges (frm, to, cap, flow)");
    FOR(v, N) {
      for (auto& e: edges[v]) {
        if (e.cap == 0 && e.flow == 0) continue;
        print(v, e.to, e.cap, e.flow);
      }
    }
  }

private:
  Cap flow_ans;

  bool set_level() {
    que.resize(N);
    level.assign(N, -1);
    level[source] = 0;
    int l = 0, r = 0;
    que[r++] = source;
    while (l < r) {
      int v = que[l++];
      for (auto&& e: edges[v]) {
        if (e.cap > 0 && level[e.to] == -1) {
          level[e.to] = level[v] + 1;
          if (e.to == sink) return true;
          que[r++] = e.to;
        }
      }
    }
    return false;
  }

  Cap flow_dfs(int v, Cap lim) {
    if (v == sink) return lim;
    Cap res = 0;
    for (int& i = prog[v]; i < len(edges[v]); ++i) {
      auto& e = edges[v][i];
      if (e.cap > 0 && level[e.to] == level[v] + 1) {
        Cap a = flow_dfs(e.to, min(lim, e.cap));
        if (a > 0) {
          e.cap -= a, e.flow += a;
          edges[e.to][e.rev].cap += a, edges[e.to][e.rev].flow -= a;
          res += a;
          lim -= a;
          if (lim == 0) break;
        }
      }
    }
    return res;
  }
};

void solve() {
  LL(N, M);
  using T = tuple<int, int, int>;
  VEC(T, dat, M);
  MaxFlow_Difference_Update<int> G(N, 0, N - 1);
  FOR(i, M) {
    auto [a, b, c] = dat[i];
    G.add(a, b, c);
    G.add(b, a, c);
  }
  int ans = G.flow();
  int LIM = 10'000;
  if (ans > LIM + 1) return print(-1);

  FOR(i, M) {
    auto [a, b, c] = dat[i];
    if (c == 1) {
      G.change_capacity(2 * i + 0, 1, 0);
      G.change_capacity(2 * i + 1, 1, 0);
      chmin(ans, G.flow());
      G.change_capacity(2 * i + 0, 0, 1);
      G.change_capacity(2 * i + 1, 0, 1);
    }
  }
  if (ans > LIM) return print(-1);
  print(ans);
}

signed main() {
  solve();
  return 0;
}
accuracy: 1
time_ms: 660
memory_kb: 4480
final_rank: 6

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
#pragma endregion

const int MAX = 10000;

/**
 * @brief Ford Fulkerson
 * @docs docs/flow/FordFulkerson.md
 */
template <typename Cap, bool directed> struct FordFulkerson {
    struct edge {
        int to;
        Cap cap;
        int rev;
        edge(int to, Cap cap, int rev) : to(to), cap(cap), rev(rev) {}
    };
    vector<vector<edge>> G;
    vector<pair<int, int>> pos;
    vector<int> used;
    FordFulkerson(int n) : G(n), used(n) {}
    int add_edge(int from, int to, Cap cap) {
        pos.emplace_back(from, G[from].size());
        G[from].emplace_back(to, cap, G[to].size());
        G[to].emplace_back(from, directed ? 0 : cap, G[from].size() - 1);
        return pos.size() - 1;
    }
    tuple<int, int, Cap, Cap> get_edge(int i) {
        auto e = G[pos[i].first][pos[i].second];
        auto re = G[e.to][e.rev];
        return {pos[i].first, e.to, e.cap + re.cap, re.cap};
    }
    vector<tuple<int, int, Cap, Cap>> edges() {
        vector<tuple<int, int, Cap, Cap>> res;
        for (size_t i = 0; i < pos.size(); i++) res.emplace_back(get_edge(i));
        return res;
    }
    void change_edge(int i, Cap new_cap, Cap new_flow) {
        assert(0 <= i && i < (int)pos.size());
        assert(0 <= new_flow && new_flow <= new_cap);
        auto& e = G[pos[i].first][pos[i].second];
        auto& re = G[e.to][e.rev];
        e.cap = new_cap - new_flow;
        re.cap = (directed ? new_flow : new_cap + new_flow);
    }
    Cap dfs(int v, int t, Cap f) {
        if (v == t) return f;
        used[v] = true;
        for (auto& e : G[v]) {
            if (!used[e.to] && e.cap > 0) {
                Cap d = dfs(e.to, t, min(f, e.cap));
                if (d <= 0) continue;
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
        return 0;
    }
    Cap max_flow(int s, int t, Cap lim) {
        Cap flow = 0;
        while (lim > 0) {
            fill(used.begin(), used.end(), 0);
            Cap f = dfs(s, t, lim);
            if (f == 0) break;
            flow += f;
            if (flow > 2 * MAX) return -1;
            lim -= f;
        }
        return flow;
    }
    Cap max_flow(int s, int t) { return max_flow(s, t, numeric_limits<Cap>::max()); }
};

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int V, E;
    cin >> V >> E;
    vector<int> s(E), t(E), c(E);
    for (int i = 0; i < E; i++) cin >> s[i] >> t[i] >> c[i];

    FordFulkerson<int, false> FF(V);
    for (int i = 0; i < E; i++) FF.add_edge(s[i], t[i], c[i]);
    int S = 0, T = V - 1;
    int cur = FF.max_flow(S, T);
    if (cur == -1) {
        cout << -1 << '\n';
        return 0;
    }
    int ans = cur;
    for (int i = 0; i < E; i++) {
        if (c[i] != 1) continue;
        auto e = FF.get_edge(i);
        int u = get<0>(e), v = get<1>(e), f = get<3>(e);
        FF.change_edge(i, 0, 0);
        if (f != 1) {
            if (f < 1) swap(u, v);
            if (!FF.max_flow(u, v, 1)) {
                FF.max_flow(T, v, 1);
                FF.max_flow(u, S, 1);
                --cur;
            }
        }
        chmin(ans, cur);
        FF.change_edge(i, 1, 0);
        cur += FF.max_flow(S, T);
    };
    cout << (ans <= MAX ? ans : -1) << '\n';
    return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 3896
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define inf (int)(1e4 + 1)
using namespace std;

template <class T>
struct Dinic {
  struct edge {
    int to;
    T cap;
    int rev;
    edge(int t = 0, T c = 0, int r = -1) : to(t), cap(c), rev(r) {}
  };
  int n;
  T finf;
  vector<vector<edge>> g;
  vector<int> id;
  vector<int> d;
  Dinic(int _n = 1, T _finf = (int)(2e9))
      : n(_n), finf(_finf), g(n, vector<edge>()), id(n), d(n) {}

  int add(int start, int goal, T capacity) {
    g[start].emplace_back(goal, capacity, (int)g[goal].size());
    g[goal].emplace_back(start, 0, (int)g[start].size() - 1);
    return (int)g[start].size() - 1;
  }

  int change(int x, int idx, T newf, int s, int t) {
    int y = g[x][idx].to, ridx = g[x][idx].rev;
    newf -= g[x][idx].cap + g[y][ridx].cap;
    if (newf > 0) {
      g[x][idx].cap += newf;
      return solve(s, t);
    } else if (newf < 0) {
      g[x][idx].cap += newf;
      if (g[x][idx].cap >= 0) return 0;
      swap(newf = 0, g[x][idx].cap);
      g[y][ridx].cap += newf;
      newf += solve(x, y, -newf);
      if (-newf) {
        solve(x, s, -newf);
        solve(t, y, -newf);
      }
      return newf;
    }
    return 0;
  }

  void bfs(int st) {
    d.assign(n, -1);
    queue<int> qu;
    d[st] = 0;
    qu.push(st);
    while (qu.size()) {
      int now = qu.front();
      qu.pop();
      for (auto e : g[now])
        if (e.cap > 0 && d[e.to] < 0) {
          d[e.to] = d[now] + 1;
          qu.push(e.to);
        }
    }
  }
  T pathdfs(int now, int goal, T nf) {
    if (now == goal) return nf;
    int len = g[now].size();
    for (int& i = id[now]; i < len; ++i) {
      edge* e = &g[now][i];
      if (e->cap > 0 && d[now] < d[e->to]) {
        T res = pathdfs(e->to, goal, min(nf, e->cap));
        if (res > 0) {
          e->cap -= res;
          g[e->to][e->rev].cap += res;
          return res;
        }
      }
    }
    return 0;
  }
  T solve(int start, int goal, T flimit = 0) {
    if (!flimit) flimit = finf;
    T res = 0, nf = 0;
    while (flimit - res) {
      bfs(start);
      if (d[goal] < 0) return res;
      id.assign(n, 0);
      while ((nf = pathdfs(start, goal, flimit - res)) > 0) res += nf;
    }
    return res;
  }
};

struct edge {
  int s, t, c, id1, id2;
};

int n, m;
vector<edge> e;
Dinic<int> din(n);

int solve();

int main() {
  cin >> n >> m;
  din = Dinic<int>(n);
  e.resize(m);
  for (auto& [s, t, c, id1, id2] : e) {
    cin >> s >> t >> c;
    id1 = din.add(s, t, c), id2 = din.add(t, s, c);
  }
  cout << solve() << endl;
  return 0;
}

int solve() {
  int res = inf;
  int nf = din.solve(0, n - 1);
  res = min(res, nf);
  for (auto& [s, t, c, id1, id2] : e)
    if (c == 1) {
      nf += din.change(s, id1, 0, 0, n - 1);
      nf += din.change(t, id2, 0, 0, n - 1);
      if (res > nf) return nf;
      nf += din.change(s, id1, 1, 0, n - 1);
      nf += din.change(t, id2, 1, 0, n - 1);
    }
  if (res == inf) return -1;
  return res;
}
accuracy: 1
time_ms: 810
memory_kb: 4208
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define inf (int)(1e4 + 1)
using namespace std;

template <class T>
struct Dinic {
  struct edge {
    int to;
    T cap;
    int rev;
    edge(int t = 0, T c = 0, int r = -1) : to(t), cap(c), rev(r) {}
  };
  int n;
  T finf;
  vector<vector<edge>> g;
  vector<int> id;
  vector<int> d;
  Dinic(int _n = 1, T _finf = (int)(2e9))
      : n(_n), finf(_finf), g(n, vector<edge>()), id(n), d(n) {}

  int add(int start, int goal, T capacity) {
    g[start].emplace_back(goal, capacity, (int)g[goal].size());
    g[goal].emplace_back(start, 0, (int)g[start].size() - 1);
    return (int)g[start].size() - 1;
  }

  int change(int x, int idx, T newf, int s, int t) {
    int y = g[x][idx].to, ridx = g[x][idx].rev;
    newf -= g[x][idx].cap + g[y][ridx].cap;
    if (newf > 0) {
      g[x][idx].cap += newf;
      return solve(s, t);
    } else if (newf < 0) {
      g[x][idx].cap += newf;
      if (g[x][idx].cap >= 0) return 0;
      swap(newf = 0, g[x][idx].cap);
      g[y][ridx].cap += newf;
      newf += solve(x, y, -newf);
      if (-newf) {
        solve(x, s, -newf);
        solve(t, y, -newf);
      }
      return newf;
    }
    return 0;
  }

  void bfs(int st) {
    d.assign(n, -1);
    queue<int> qu;
    d[st] = 0;
    qu.push(st);
    while (qu.size()) {
      int now = qu.front();
      qu.pop();
      for (auto e : g[now])
        if (e.cap > 0 && d[e.to] < 0) {
          d[e.to] = d[now] + 1;
          qu.push(e.to);
        }
    }
  }
  T pathdfs(int now, int goal, T nf) {
    if (now == goal) return nf;
    int len = g[now].size();
    for (int& i = id[now]; i < len; ++i) {
      edge* e = &g[now][i];
      if (e->cap > 0 && d[now] < d[e->to]) {
        T res = pathdfs(e->to, goal, min(nf, e->cap));
        if (res > 0) {
          e->cap -= res;
          g[e->to][e->rev].cap += res;
          return res;
        }
      }
    }
    return 0;
  }
  T solve(int start, int goal, T flimit = 0) {
    if (!flimit) flimit = finf;
    T res = 0, nf = 0;
    while (flimit - res) {
      bfs(start);
      if (d[goal] < 0) return res;
      id.assign(n, 0);
      while ((nf = pathdfs(start, goal, flimit - res)) > 0) res += nf;
    }
    return res;
  }
};

struct edge {
  int s, t, c, id1, id2;
};

int n, m;
vector<edge> e;
Dinic<int> din(n);

int solve();

int main() {
  cin >> n >> m;
  din = Dinic<int>(n);
  e.resize(m);
  for (auto& [s, t, c, id1, id2] : e) {
    cin >> s >> t >> c;
    id1 = din.add(s, t, c), id2 = din.add(t, s, c);
  }
  cout << solve() << endl;
  return 0;
}

int solve() {
  int res = inf;
  int nf = din.solve(0, n - 1);
  res = min(res, nf);
  for (auto& [s, t, c, id1, id2] : e)
    if (c == 1) {
      int bf = nf;
      nf += din.change(s, id1, 0, 0, n - 1);
      nf += din.change(t, id2, 0, 0, n - 1);
      res = min(res, nf);
      if (bf > nf) return res;
      nf += din.change(s, id1, 1, 0, n - 1);
      nf += din.change(t, id2, 1, 0, n - 1);
    }
  if (res == inf) return -1;
  return res;
}
accuracy: 0.5
time_ms: 350
memory_kb: 4012
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using uint = unsigned;
using pcc = pair<char, char>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
using tuplis = array<ll, 3>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;
const ll LINF=0x1fffffffffffffff;
const ll MINF=0x7fffffffffff;
const int INF=0x3fffffff;
const int MOD=1000000007;
const int MODD=998244353;
const ld DINF=numeric_limits<ld>::infinity();
const ld EPS=1e-9;
const ld PI=3.1415926535897932;
const ll dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const ll dy[] = {1, 0, -1, 0, 1, 1, -1, -1};
#define overload4(_1,_2,_3,_4,name,...) name
#define overload3(_1,_2,_3,name,...) name
#define rep1(n) for(ll i=0;i<n;++i)
#define rep2(i,n) for(ll i=0;i<n;++i)
#define rep3(i,a,b) for(ll i=a;i<b;++i)
#define rep4(i,a,b,c) for(ll i=a;i<b;i+=c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i=n;i--;)
#define rrep2(i,n) for(ll i=n;i--;)
#define rrep3(i,a,b) for(ll i=b;i-->(a);)
#define rrep4(i,a,b,c) for(ll i=(a)+((b)-(a)-1)/(c)*(c);i>=(a);i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define each1(i,a) for(auto&&i:a)
#define each2(x,y,a) for(auto&&[x,y]:a)
#define each3(x,y,z,a) for(auto&&[x,y,z]:a)
#define each(...) overload4(__VA_ARGS__,each3,each2,each1)(__VA_ARGS__)
#define all1(i) begin(i),end(i)
#define all2(i,a) begin(i),begin(i)+a
#define all3(i,a,b) begin(i)+a,begin(i)+b
#define all(...) overload3(__VA_ARGS__,all3,all2,all1)(__VA_ARGS__)
#define rall1(i) (i).rbegin(),(i).rend()
#define rall2(i,k) (i).rbegin(),(i).rbegin()+k
#define rall3(i,a,b) (i).rbegin()+a,(i).rbegin()+b
#define rall(...) overload3(__VA_ARGS__,rall3,rall2,rall1)(__VA_ARGS__)
#define sum(...) accumulate(all(__VA_ARGS__),0LL)
#define dsum(...) accumulate(all(__VA_ARGS__),0.0L)
#define Msum(...) accumulate(all(__VA_ARGS__),0_M)
#define elif else if
#define unless(a) if(!(a))
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T> bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }
vector<ll> iota(ll n){ vector<ll> a(n); iota(a.begin(), a.end(), 0); return a; }
vector<pll> factor(ull x){ vector<pll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans.push_back({i, 1}); while((x /= i) % i == 0) ans.back().second++; } if(x != 1) ans.push_back({x, 1}); return ans; }
map<ll,ll> factor_map(ull x){ map<ll,ll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans[i] = 1; while((x /= i) % i == 0) ans[i]++; } if(x != 1) ans[x] = 1; return ans; }
vector<ll> divisor(ull x){ vector<ll> ans; for(ull i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); rrep(ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
template<class T> unordered_map<T, ll> press(vector<T> a){ Uniq(a); unordered_map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
template<class T> map<T, ll> press_map(vector<T> a){ Uniq(a); map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
int scan(){ return getchar(); }
void scan(int& a){ scanf("%d", &a); }
void scan(unsigned& a){ scanf("%u", &a); }
void scan(long& a){ scanf("%ld", &a); }
void scan(long long& a){ scanf("%lld", &a); }
void scan(unsigned long long& a){ scanf("%llu", &a); }
void scan(char& a){ do{ a = getchar(); }while(a == ' ' || a == '\n'); }
void scan(float& a){ scanf("%f", &a); }
void scan(double& a){ scanf("%lf", &a); }
void scan(long double& a){ scanf("%Lf", &a); }
void scan(vector<bool>& a){ for(unsigned i = 0; i < a.size(); i++){ int b; scan(b); a[i] = b; } }
void scan(char a[]){ scanf("%s", a); }
void scan(string& a){ cin >> a; }
template<class T> void scan(vector<T>&);
template<class T, size_t size> void scan(array<T, size>&);
template<class T, class L> void scan(pair<T, L>&);
template<class T, size_t size> void scan(T(&)[size]);
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
template<class T> void scan(deque<T>& a){ for(auto&& i : a) scan(i); }
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i); }
template<class T, class L> void scan(pair<T, L>& p){ scan(p.first); scan(p.second); }
template<class T, size_t size> void scan(T (&a)[size]){ for(auto&& i : a) scan(i); }
template<class T> void scan(T& a){ cin >> a; }
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){ scan(head); in(tail...); }
void print(){ putchar(' '); }
void print(bool a){ printf("%d", a); }
void print(int a){ printf("%d", a); }
void print(unsigned a){ printf("%u", a); }
void print(long a){ printf("%ld", a); }
void print(long long a){ printf("%lld", a); }
void print(unsigned long long a){ printf("%llu", a); }
void print(char a){ printf("%c", a); }
void print(char a[]){ printf("%s", a); }
void print(const char a[]){ printf("%s", a); }
void print(float a){ printf("%.15f", a); }
void print(double a){ printf("%.15f", a); }
void print(long double a){ printf("%.15Lf", a); }
void print(const string& a){ for(auto&& i : a) print(i); }
template<class T> void print(const complex<T>& a){ if(a.real() >= 0) print('+'); print(a.real()); if(a.imag() >= 0) print('+'); print(a.imag()); print('i'); }
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ print(p.first); putchar(' '); print(p.second); }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ putchar(' '); print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
#ifdef DEBUG
inline ll __lg(ull __n){ return sizeof(ull) * __CHAR_BIT__  - 1 - __builtin_clzll(__n); }
#define debug(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...) void(0)
#endif
int first(bool i = true){ return out(i?"first":"second"); }
int yes(bool i = true){ return out(i?"yes":"no"); }
int Yes(bool i = true){ return out(i?"Yes":"No"); }
int No(){ return out("No"); }
int YES(bool i = true){ return out(i?"YES":"NO"); }
int NO(){ return out("NO"); }
int Yay(bool i = true){ return out(i?"Yay!":":("); }
int possible(bool i = true){ return out(i?"possible":"impossible"); }
int Possible(bool i = true){ return out(i?"Possible":"Impossible"); }
int POSSIBLE(bool i = true){ return out(i?"POSSIBLE":"IMPOSSIBLE"); }
void Case(ll i){ printf("Case #%lld: ", i); }



template< typename flow_t >
struct Dinic {
  const flow_t INF;

  struct edge {
    int to;
    flow_t cap;
    int rev;
    bool isrev;
    int idx;
  };

  vector< vector< edge > > graph;
  vector< int > min_cost, iter;

  Dinic(int V) : INF(numeric_limits< flow_t >::max()), graph(V) {}

  void add_edge(int from, int to, flow_t cap, int idx = -1) {
    graph[from].emplace_back((edge) {to, cap, (int) graph[to].size(), false, idx});
    graph[to].emplace_back((edge) {from, cap, (int) graph[from].size() - 1, true, idx});
  }

  bool bfs(int s, int t) {
    min_cost.assign(graph.size(), -1);
    queue< int > que;
    min_cost[s] = 0;
    que.push(s);
    while(!que.empty() && min_cost[t] == -1) {
      int p = que.front();
      que.pop();
      for(auto &e : graph[p]) {
        if(e.cap > 0 && min_cost[e.to] == -1) {
          min_cost[e.to] = min_cost[p] + 1;
          que.push(e.to);
        }
      }
    }
    return min_cost[t] != -1;
  }

  flow_t dfs(int idx, const int t, flow_t flow) {
    if(idx == t) return flow;
    for(int &i = iter[idx]; i < graph[idx].size(); i++) {
      edge &e = graph[idx][i];
      if(e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
        flow_t d = dfs(e.to, t, min(flow, e.cap));
        if(d > 0) {
          e.cap -= d;
          graph[e.to][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0;
  }

  flow_t max_flow(int s, int t) {
    flow_t flow = 0;
    while(bfs(s, t)) {
      iter.assign(graph.size(), 0);
      flow_t f = 0;
      while((f = dfs(s, t, INF)) > 0) flow += f;
    }
    return flow;
  }

  void output() {
    for(int i = 0; i < graph.size(); i++) {
      for(auto &e : graph[i]) {
        if(e.isrev) continue;
        auto &rev_e = graph[e.to][e.rev];
        cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
      }
    }
  }
};

signed main(){
    LL(n,m);
    Dinic<ll>g(n);
    VEC(tuplis,edge,m);
    each(i,edge)g.add_edge(i[0],i[1],i[2]*10000-(i[2]==1));
    ll ans=g.max_flow(0,n-1);
    ans/=10000;
    if(ans>10000)ans=-1;
    out(ans);
}
accuracy: 1
time_ms: 90
memory_kb: 3828
final_rank: 1

code_snippet: #include <iostream>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <map>
#include <math.h>
#include <string.h>
#include <iomanip>
#include <numeric>
#include <cstdlib>
#include <cstdint>
#include <cmath>
#include <functional>
#include <limits>
#include <cassert>
#include <bitset>
#include <complex>
 
using namespace std;
 
/* template */
 
using ll = long long;
 
void debug_out() { std::cout << std::endl; }
 
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cout << H << " ";
  debug_out(T...);
}
 
#ifdef LOCAL
#define debug(...) cout << "debug: "; debug_out(__VA_ARGS__)
#else
#define debug(...) 
#endif
 
#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n-1)); i >= (int)(a); i--)
#define Rep(i, a, n) for (long long i = (long long)(a); i< (long long)(n); i++)
#define RRep(i, a, n) for (long long i = ((long long)(n-1ll)); i>=(long long)(a); i--)
#define all(v) (v).begin(),(v).end()
#define rall(v) (v).rbegin(),(v).rend()
 
template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}
 
struct Edge{
    int to;
    ll weight;
    Edge(int t, ll w) : to(t), weight(w){ }
};
 
struct edge{
    int from;
    int to;
    ll weight;
    edge(int f,int t,ll w) : from(f), to(t), weight(w){ }
};
 
using Graph = vector<vector<Edge>>;
using graph = vector<vector<int>>;
using edges = vector<edge>;
 
template <class T>
inline bool chmin(T &a, T b){
    if (a > b){
        a = b;
        return true;
    }
    return false;
}
 
template <class T>
inline bool chmax(T &a, T b){
    if (a < b){
        a = b;
        return true;
    }
    return false;
}
 
template <class T>
T lcm(T a, T b){
    return (a*b)/gcd(a,b);
}
 
ll ctoi(char c) {
	switch (c) {
	case '0': return 0; case '1': return 1; case '2': return 2;
	case '3': return 3; case '4': return 4; case '5': return 5;
	case '6': return 6; case '7': return 7; case '8': return 8;
	case '9': return 9;  default: return 0;
	}
}
 
constexpr ll LNF = 1LL<<50;
 
constexpr int INF = 1e9+7;
 
const long double PI=3.14159265358979323846;
 
vector<int> dx = {1,0,-1,1,-1,0};
vector<int> dy = {1,1,1,0,0,-1};
 
/* template */

struct Ford_Fulkerson{
private:
    struct edge{
        int to;
        int cap;
        int rev;
    };
    vector<vector<edge>> g;
    vector<int> seen;
    int v;
    int flow;

    int dfs(int from,int t, int f){
        if(from==t) return f;
        seen[from] = 1;
        for(auto &e: g[from]){
            if(seen[e.to]==0 && e.cap>0){
                int d = dfs(e.to, t, min(f,e.cap));
                if(d>0){
                    e.cap -= d;
                    g[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

public:
    Ford_Fulkerson(int v) : v(v) {
        g.resize(v);
        seen.assign(v,0);
    }

    void add_edge(int from, int to, int cap){
        g[from].emplace_back(edge{to,cap,(int)g[to].size()});
        g[to].emplace_back(edge{from, 0, (int)g[from].size()-1});
        return;
    }

    int max_flow(int s, int t){
        int flow = 0;
        int index = 0;
        while(true){
            seen.assign(v,0);
            int f = dfs(s,t,INF);
            if(f==0) return flow;
            flow += f;
            index++;
        }
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int v,e; cin >> v >> e;
    vector<int> a;
    vector<int> s(e),t(e),c(e);
    Ford_Fulkerson f(v),g(v);
    rep(i,0,e){
        cin >> s[i] >> t[i] >> c[i];
        if(c[i]!=1){
            g.add_edge(s[i],t[i],c[i]);
            g.add_edge(t[i],s[i],c[i]);
        }
        f.add_edge(s[i],t[i],c[i]);
        f.add_edge(t[i],s[i],c[i]);
    }
    auto x = f.max_flow(0,v-1);
    int ans = x;
    auto y = g.max_flow(0,v-1);
    if(y!=x){
        ans--;
    }
    if(ans<=1e4){
        cout << ans << endl;
    }
    else{
        cout << -1 << endl;
    }

}
accuracy: 0.9772727272727273
time_ms: 90
memory_kb: 3960
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<ll, ll>;
#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template<typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template<typename T> void chmax(T &a, const T &b) { a = max(a, b); }
struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio;
#ifdef DEBUG_ 
#include "../program_contest_library/memo/dump.hpp"
#else
#define dump(...)
#endif
const ll INF = 1LL<<60;

template<class T>
struct dinic {
    struct edge{
        int to;
        T cap;
        int rev;
        bool isrev;
    };

    vector<vector<edge>> G;
    vector<int> level, iter;

    void bfs(int s) {
        level.assign(G.size(), -1);
        queue<int> que;
        level[s] = 0;
        que.push(s);
        while(que.size()) {
            int v = que.front(); que.pop();
            for(auto i: G[v]) {
                if(i.cap > 0 && level[i.to] < 0) {
                    level[i.to] = level[v] + 1;
                    que.push(i.to);
                }
            }
        }
    }

    T dfs(int v, const int t, T f) {
        if(v == t) return f;
        for(int &i = iter[v]; i<(ll)G[v].size(); ++i) {
            edge &e = G[v][i];
            if(e.cap > 0 && level[v] < level[e.to]) {
                T d = dfs(e.to, t, min(f, e.cap));
                if(d > 0) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    dinic() {}
    dinic(int n) : G(n), level(n), iter(n) {}

    void add_edge(int from, int to, T cap) {
        G[from].push_back({to, cap, (int)G[to].size(), false});
        G[to].push_back({from, 0, (int)G[from].size()-1, true});
    }

    // sからtへ流量fを流す
    T maxflow(int s, int t, T f = 1LL<<30) {
        T flow = 0;
        while(1) {
            bfs(s);
            if(level[t] < 0) return flow;
            iter.assign(G.size(), 0);
            T tmp;
            while((tmp = dfs(s, t, f)) > 0) flow += tmp;
        }
    }

    // sからtへ1流す
    T flow(int s, int t) {
        bfs(s);
        if(level[t] < 0) return 0;
        iter.assign(G.size(), 0);
        return dfs(s, t, 1);
    }
    // 始点，終点tのフローで辺e=(from,to)の容量を1増やしたときの最大流の変化
    // 並列辺はたぶんバグる
    T add(int from, int to, int s, int t) {
        for(auto &e: G[from]) {
            if(e.to == to && !e.isrev) {
                e.cap++;
                break;
            }
        }
        return flow(s, t);
    }
    // 始点s，終点tのフローで辺e=(from,to)の容量を1減らしたときの最大流の変化
    // 並列辺はたぶんバグる
    T sub(int from, int to, int s, int t) {
        for(auto &e: G[from]) {
            if(e.to == to && !e.isrev) {
                T diff = 0;
                // 辺(from,to)で容量いっぱいに流れている
                if(e.cap == 0) {
                    // 残余グラフでfrom→toのパスがない
                    if(flow(from, to) == 0) {
                        flow(t, to);
                        flow(from, s);
                        diff = -1;
                    }
                    G[e.to][e.rev].cap--;
                } else {
                    e.cap--;
                }
                return diff;
            }
        }
        assert(false); // 存在しない辺を減らそうとした
    }

    friend ostream &operator <<(ostream& out, const dinic& a){
        out << endl;
        for(int i = 0; i < (int)a.G.size(); i++) {
            for(auto &e : a.G[i]) {
                if(e.isrev) continue;
                auto &rev_e = a.G[e.to][e.rev];
                out << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
            }
        }
        return out;
    }
};

int main(void) {
    ll n, m;
    cin >> n >> m;
    vector<ll> u(m), v(m), c(m);
    dinic<ll> flow(n);
    REP(i, m) {
        cin >> u[i] >> v[i] >> c[i];
        flow.add_edge(u[i], v[i], c[i]);
        flow.add_edge(v[i], u[i], c[i]);
    }

    ll ans = flow.maxflow(0, n-1);
    REP(i, m) {
        if(c[i] != 1) continue;
        ll diff = 0;
        diff += flow.sub(u[i], v[i], 0, n-1);
        diff += flow.sub(v[i], u[i], 0, n-1);
        if(diff < 0) {
            ans--;
            break;
        }
        flow.add(u[i], v[i], 0, n-1);
        flow.add(v[i], u[i], 0, n-1);
    }

    if(ans > 10000) ans = -1;
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 970
memory_kb: 3948
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<ll, ll>;
#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template<typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template<typename T> void chmax(T &a, const T &b) { a = max(a, b); }
struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio;
#ifdef DEBUG_ 
#include "../program_contest_library/memo/dump.hpp"
#else
#define dump(...)
#endif
const ll INF = 1LL<<60;

template<class T>
struct dinic {
    struct edge{
        int to;
        T cap;
        int rev;
        bool isrev;
    };

    T nowmaxflow;
    vector<vector<edge>> G;
    vector<int> level, iter;

    void bfs(int s) {
        level.assign(G.size(), -1);
        queue<int> que;
        level[s] = 0;
        que.push(s);
        while(que.size()) {
            int v = que.front(); que.pop();
            for(auto i: G[v]) {
                if(i.cap > 0 && level[i.to] < 0) {
                    level[i.to] = level[v] + 1;
                    que.push(i.to);
                }
            }
        }
    }

    T dfs(int v, const int t, T f) {
        if(v == t) return f;
        for(int &i = iter[v]; i<(ll)G[v].size(); ++i) {
            edge &e = G[v][i];
            if(e.cap > 0 && level[v] < level[e.to]) {
                T d = dfs(e.to, t, min(f, e.cap));
                if(d > 0) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    dinic() {}
    dinic(int n) : nowmaxflow(0), G(n), level(n), iter(n) {}

    void add_edge(int from, int to, T cap) {
        G[from].push_back({to, cap, (int)G[to].size(), false});
        G[to].push_back({from, 0, (int)G[from].size()-1, true});
    }

    // sからtへできるだけ流す
    T max_flow(int s, int t) {
        T flow = 0;
        while(1) {
            bfs(s);
            if(level[t] < 0) return nowmaxflow = flow;
            iter.assign(G.size(), 0);
            T f;
            while((f = dfs(s, t, INF)) > 0) flow += f;
        }
    }

    // sからtへ1流す
    T flow(int s, int t) {
        bfs(s);
        if(level[t] < 0) return 0;
        iter.assign(G.size(), 0);
        return dfs(s, t, 1);
    }
    // 始点，終点tのフローで辺e=(from,to)の容量を1増やしたときの最大流の変化
    // 並列辺はたぶんバグる
    T add(int from, int to, int s, int t) {
        for(auto &e : G[from]) {
            if(e.to == to && !e.isrev) {
                e.cap++;
                break;
            }
        }
        ll f = flow(s, t);
        nowmaxflow += f;
        return f;
    }
    // 始点s，終点tのフローで辺e=(from,to)の容量を1減らしたときの最大流の変化
    // 並列辺はたぶんバグる
    T sub(int from, int to, int s, int t) {
        for(auto &e : G[from]) {
            if(e.to == to && !e.isrev) {
                // e=(from,to) について f(e) <= c(e)-1 ならばそのままでok
                if(e.cap >= 1) return 0;
                // 残余グラフでfrom→toのパスを流して1流れればそれでok
                if(flow(from, to) == 1) return 0;
                // 存在しない場合t→toとfrom→sのパスに流して最大流が-1される
                flow(t, to);
                flow(from, s);
                nowmaxflow--;
                return -1;
            }
        }
        return 0;
    }

    friend ostream &operator <<(ostream& out, const dinic& a){
        out << endl;
        for(int i = 0; i < (int)a.G.size(); i++) {
            for(auto &e : a.G[i]) {
                if(e.isrev) continue;
                auto &rev_e = a.G[e.to][e.rev];
                out << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
            }
        }
        return out;
    }
};

int main(void) {
    ll n, m;
    cin >> n >> m;
    vector<ll> u(m), v(m), c(m);
    dinic<ll> flow(n);
    REP(i, m) {
        cin >> u[i] >> v[i] >> c[i];
        flow.add_edge(u[i], v[i], c[i]);
        flow.add_edge(v[i], u[i], c[i]);
    }

    ll ans = flow.max_flow(0, n-1);
    REP(i, m) {
        if(c[i] != 1) continue;
        flow.sub(u[i], v[i], 0, n-1);
        flow.sub(v[i], u[i], 0, n-1);
        if(ans > flow.nowmaxflow) {
            ans--;
            break;
        }
        flow.add(u[i], v[i], 0, n-1);
        flow.add(v[i], u[i], 0, n-1);
    }

    if(ans > 10000) ans = -1;
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 980
memory_kb: 3980
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define int long long
using namespace std;
#define REP(i, n) for (long long i = 0, max_i = (n); i < max_i; i++)
template <class T>
ostream& operator<<(ostream& s, vector<T>& d) {
    REP(i, d.size()) s << d[i] << (i == d.size() - 1 ? "" : " ");
    return s;
}
using Int = long long;

struct Dinic {
    struct edge {
        int to, cap, rev;
    };

    int n;
    vector<vector<edge>> G;
    vector<int> level;
    vector<int> iter;

    void bfs(int s) {
        level.assign(n, -1);
        queue<int> que;
        que.push(s);
        level[s] = 0;
        while (que.size()) {
            int v = que.front();
            que.pop();
            for (int i = 0; i < G[v].size(); i++) {
                edge& e = G[v][i];
                if (e.cap > 0 && level[e.to] < 0) {
                    level[e.to] = level[v] + 1;
                    que.push(e.to);
                }
            }
        }
    }

    int dfs(int v, int t, int f) {
        if (v == t) return f;
        for (int i = iter[v]; i < G[v].size(); i++) {
            edge& e = G[v][i];
            if (e.cap > 0 && level[v] < level[e.to]) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d > 0) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    Dinic(int n) : n(n), G(n), level(n), iter(n) {}

    void add_edge(int from, int to, int cap) {
        G[from].push_back({to, cap, (int)G[to].size()});
        G[to].push_back({from, 0, (int)G[from].size() - 1});
    }

    int max_flow(int s, int t) {
        int flow = 0;
        while (1) {
            bfs(s);
            if (level[t] < 0) return flow;
            iter.assign(n, 0);
            int f;
            while ((f = dfs(s, t, 1e9)) > 0) {
                flow += f;
            }
        }
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m;
    cin >> n >> m;

    Dinic hoge(n), fuga(n);

    for (int i = 0; i < m; i++) {
        int a, b, c;
        cin >> a >> b >> c;

        hoge.add_edge(a, b, 2 * c);
        hoge.add_edge(b, a, 2 * c);
        fuga.add_edge(a, b, c == 1 ? 1 : 2 * c);
        fuga.add_edge(b, a, c == 1 ? 1 : 2 * c);
    }

    int h = hoge.max_flow(0, n - 1);
    int f = fuga.max_flow(0, n - 1);
    int ans = h == f ? h / 2 : h / 2 - 1;
    if (ans > 10000) {
        cout << -1 << endl;
        return 0;
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 410
memory_kb: 4640
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;

const int INF = 1e9;

struct Fordfulkerson{
  const int INF = 1 << 28;
  struct edge{
    int to,cap,rev;
    edge(){}
    edge(int to,int cap,int rev):to(to),cap(cap),rev(rev){}
  };

  int n;
  vector<vector<edge> > G;
  vector<int> used;
  
  Fordfulkerson(){}
  Fordfulkerson(int sz):n(sz),G(n),used(n){}
  
  void add_edge(int from,int to,int cap){
    G[from].push_back(edge(to,cap,G[to].size()));
    // undirected
    G[to].push_back(edge(from,cap,G[from].size()-1));
    // directed
    G[to].push_back(edge(from,0,G[from].size()-1));
  }
 
  int dfs(int v,int t,int f){
    if(v==t) return f;
    used[v]=true;
    for(int i=0;i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(!used[e.to] && e.cap > 0 ){
        int d=dfs(e.to,t,min(f,e.cap));
        if(d>0){
          e.cap-=d;
          G[e.to][e.rev].cap+=d;
          return d;
        }
      } 
    }
    return 0;
  }
 
  int flow(int s,int t,int lim){
    int fl=0;
    for(;;){
      fill(used.begin(),used.end(),0);
      int f=dfs(s,t,lim);
      if(f==0) return fl;
      fl+=f;
      lim-=f;
    }
  }

  int flow(int s,int t){
    return flow(s,t,INF);
  }
  
};

struct Edge {
  int s, t, c;  
};

signed main() {
  int V, E;
  cin >> V >> E;

  vector<Edge> edges(E);
  Fordfulkerson F(V);  
  for ( int i = 0; i < E; i++ ) {
    int s, t, c;
    cin >> s >> t >> c;
    edges[i] = Edge{s, t, c};
    F.add_edge(s, t, c);    
  }

  int min_cut = F.flow(0, V-1);

  int cnt = 0;  
  for ( int j = 0; j < E; j++ ) {
    if ( edges[j].c != 1 ) continue;
    if ( cnt++ >= 1000 ) break;    
    Fordfulkerson G(V);  
    for ( int i = 0; i < E; i++ ) {
      int s, t, c;
      s = edges[i].s;
      t = edges[i].t;
      c = edges[i].c;
      if ( i == j ) {
	// dinic.add_edge(s, t, 100000);    
      } /*se if ( c == 1 ) {
	dinic.add_edge(s, t, 100000);	
	}*/ else {
	G.add_edge(s, t, c);    
      }
    }

    int min_cut2 = G.flow(0, V-1, 10001);
    if ( min_cut2 == min_cut-1 ) {
      min_cut--;
      break;      
    }
  }

  if ( min_cut <= 10000 ) {
    cout << min_cut << endl;    
  } else {
    cout << -1 << endl;    
  }

  
  return 0;  
}
accuracy: 0.20454545454545456
time_ms: 760
memory_kb: 3760
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;

const int INF = 1e9;

struct Fordfulkerson{
  const int INF = 1 << 28;
  struct edge{
    int to,cap,rev;
    edge(){}
    edge(int to,int cap,int rev):to(to),cap(cap),rev(rev){}
  };

  int n;
  vector<vector<edge> > G;
  vector<int> used;
  
  Fordfulkerson(){}
  Fordfulkerson(int sz):n(sz),G(n),used(n){}
  
  void add_edge(int from,int to,int cap){
    G[from].push_back(edge(to,cap,G[to].size()));
    // undirected
    G[to].push_back(edge(from,cap,G[from].size()-1));
    // directed
    G[to].push_back(edge(from,0,G[from].size()-1));
  }
 
  int dfs(int v,int t,int f){
    if(v==t) return f;
    used[v]=true;
    for(int i=0;i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(!used[e.to] && e.cap > 0 ){
        int d=dfs(e.to,t,min(f,e.cap));
        if(d>0){
          e.cap-=d;
          G[e.to][e.rev].cap+=d;
          return d;
        }
      } 
    }
    return 0;
  }
 
  int flow(int s,int t,int lim){
    int fl=0;
    for(;;){
      fill(used.begin(),used.end(),0);
      int f=dfs(s,t,lim);
      if(f==0) return fl;
      fl+=f;
      lim-=f;
    }
  }

  int flow(int s,int t){
    return flow(s,t,INF);
  }
  
};

struct Edge {
  int s, t, c;  
};

signed main() {
  int V, E;
  cin >> V >> E;

  vector<Edge> edges(E);
  Fordfulkerson F(V);  
  for ( int i = 0; i < E; i++ ) {
    int s, t, c;
    cin >> s >> t >> c;
    edges[i] = Edge{s, t, c};
    F.add_edge(s, t, c);    
  }

  int min_cut = F.flow(0, V-1);

  int cnt = 0;  
  for ( int j = 0; j < E; j++ ) {
    if ( edges[j].c != 1 ) continue;
    if ( cnt++ >= 500 ) break;    
    Fordfulkerson G(V);  
    for ( int i = 0; i < E; i++ ) {
      int s, t, c;
      s = edges[i].s;
      t = edges[i].t;
      c = edges[i].c;
      if ( i == j ) {
	// dinic.add_edge(s, t, 100000);    
      } /*se if ( c == 1 ) {
	dinic.add_edge(s, t, 100000);	
	}*/ else {
	G.add_edge(s, t, c);    
      }
    }

    int min_cut2 = G.flow(0, V-1, 10001);
    if ( min_cut2 == min_cut-1 ) {
      min_cut--;
      break;      
    }
  }

  if ( min_cut <= 10000 ) {
    cout << min_cut << endl;    
  } else {
    cout << -1 << endl;    
  }

  
  return 0;  
}
accuracy: 0.20454545454545456
time_ms: 380
memory_kb: 3836
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;

const int INF = 1e9;

struct Fordfulkerson{
  const int INF = 1 << 28;
  struct edge{
    int to,cap,rev;
    edge(){}
    edge(int to,int cap,int rev):to(to),cap(cap),rev(rev){}
  };

  int n;
  vector<vector<edge> > G;
  vector<int> used;
  
  Fordfulkerson(){}
  Fordfulkerson(int sz):n(sz),G(n),used(n){}
  
  void add_edge(int from,int to,int cap){
    G[from].push_back(edge(to,cap,G[to].size()));
    // undirected
    G[to].push_back(edge(from,cap,G[from].size()-1));
    // directed
    G[to].push_back(edge(from,0,G[from].size()-1));
  }
 
  int dfs(int v,int t,int f){
    if(v==t) return f;
    used[v]=true;
    for(int i=0;i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(!used[e.to] && e.cap > 0 ){
        int d=dfs(e.to,t,min(f,e.cap));
        if(d>0){
          e.cap-=d;
          G[e.to][e.rev].cap+=d;
          return d;
        }
      } 
    }
    return 0;
  }
 
  int flow(int s,int t,int lim){
    int fl=0;
    for(;;){
      fill(used.begin(),used.end(),0);
      int f=dfs(s,t,lim);
      if(f==0) return fl;
      fl+=f;
      lim-=f;
    }
  }

  int flow(int s,int t){
    return flow(s,t,INF);
  }
  
};

struct Edge {
  int s, t, c;  
};

signed main() {
  int V, E;
  cin >> V >> E;

  vector<Edge> edges(E);
  Fordfulkerson F(V);  
  for ( int i = 0; i < E; i++ ) {
    int s, t, c;
    cin >> s >> t >> c;
    edges[i] = Edge{s, t, c};
    F.add_edge(s, t, c);    
  }

  int min_cut = F.flow(0, V-1);

  int cnt = 0;  
  for ( int j = 0; j < E; j++ ) {
    if ( edges[j].c != 1 ) continue;
    if ( cnt++ >= 100 ) break;    
    Fordfulkerson G(V);  
    for ( int i = 0; i < E; i++ ) {
      int s, t, c;
      s = edges[i].s;
      t = edges[i].t;
      c = edges[i].c;
      if ( i == j ) {
	// dinic.add_edge(s, t, 100000);    
      } /*se if ( c == 1 ) {
	dinic.add_edge(s, t, 100000);	
	}*/ else {
	G.add_edge(s, t, c);    
      }
    }

    int min_cut2 = G.flow(0, V-1, 10001);
    if ( min_cut2 == min_cut-1 ) {
      min_cut--;
      break;      
    }
  }

  if ( min_cut <= 10000 ) {
    cout << min_cut << endl;    
  } else {
    cout << -1 << endl;    
  }

  
  return 0;  
}
accuracy: 0.18181818181818182
time_ms: 40
memory_kb: 3268
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
 
int n,E,Q;
int cap[5002][5002];
 
bool used[5550];
vector<int>G[5002];
 
void add_edge(int from,int to,int X){
    G[from].push_back(to);
    G[to].push_back(from);
    cap[from][to]=cap[to][from]+=X;
}
 
int dfs(int v,int t,int f){
    if(v==t)return f;
    used[v]=1;
    for(int i=0;i<G[v].size();i++){
        int e=G[v][i];
        if(!(!used[e]&&cap[v][e]>0))continue;
        int d=dfs(e,t,min(f,cap[v][e]));
        if(d){
            cap[v][e]-=d;
            cap[e][v]+=d;
            return d;
        }
    }
    return 0;
}
 
int flow(int s,int t,int lim){
    int fl=0;
    for(;;){
        memset(used,0,sizeof(used));
        int f=dfs(s,t,lim);
        if(!f)return fl;
        fl+=f;
        lim-=f;
    }
}

int A[10000];
int B[10000];
int C[10000];

int main(){
    cin>>n>>E;
    r(i,E){
        int s,t,z;
        cin>>s>>t>>z;
        A[i]=s;
        B[i]=t;
        C[i]=z;
        add_edge(s,t,z);
    }
    int ANS=flow(0,n-1,1e4+2);

    if(ANS==1e4+2){
        cout<<-1<<endl;
        return 0;
    }

    r(i,E){
        if(C[i]!=1)continue;
        int s=A[i];
        int t=B[i];
            if(cap[t][s]==2)swap(s,t);
            if(cap[s][t]==2){
                int x=flow(t,s,1);
                if(!x){
                    flow(n-1,0,1);
                    flow(t,s,1);
                    ANS--;
                    cout<<ANS<<endl;
                    return 0;
                }
            }
    }
    if(ANS==1e4+1){
        cout<<-1<<endl;
        return 0;
    }
    cout<<ANS<<endl;
}
accuracy: 1
time_ms: 230
memory_kb: 37888
final_rank: 4