Problem:
F: 風呂がオーバーフロー - Overflow of Furo -
物語
温泉宿・パロは自慢の温泉に全ての情熱を注いでおり、風呂のプロフェッショナルを集めている。
風呂のプロたちは主に温泉の配管を管理しており、複数の源泉から1つの大浴場へと繋がる、複雑に入り組んだ配管網を管理・調整している。
配管網の管理・調整業務もなかなかに大変なのだが、風呂のプロたちはその合間を縫って、さらに多くの湯を浴槽へと供給できるよう日々努力を積み重ねていた。
結果、風呂のプロたちは「1本だけ配管をオーバーフローさせることができる」という荒技を習得した。
すなわち、自由に配管1本を選び、その配管の湯量の制限をなくすことができるようになったのだ。
今まで最大湯量を実現する配管網の設定をあなたのプログラムに依存していた風呂のプロたちは、この技術を使ってさらに浴槽への供給湯量を増やすにはどうすればよいか、あなたに再びプログラムを書くよう依頼してきた。
問題
1
つの浴槽、
K
個の源泉、
N
個の結合点を含む配管網がある。
配管網は
M
本の配管からなり、配管1つ1つは流すことのできる湯量の制限を持つ。
配管それぞれは湯を流す方向が決められていないので、自由に決めて使ってよい。
N
個の結合点では何本かの配管から流れてきた湯をそれ以外の何本かの配管へと自由な配分で流すことができる。
すべての源泉、および浴槽は一部の配管の端点になっており、源泉からの湯量、および結合点での湯量を調整することで源泉から浴槽へと湯を供給している。
M
個の配管のうち1本だけオーバーフローさせる、すなわち流せる湯量を無限に増やすことで浴槽に供給できるようになる最大湯量はいくらか。
ただし、最大供給湯量を無限に増やすことができる場合も考えられるが、その場合は風呂がオーバーフローしてしまうので、"overfuro"と出力すること。
入力形式
入力は以下の形式で与えられる。
K
N
M
a_1
b_1
c_1
...
a_M
b_M
c_M
入力は全て整数からなる。
最初の行では源泉の数
K
、結合点の数
N
、配管の数
M
が与えられる。
続く
M
行のうち
i
行目には、
i
番目の配管の情報を表す3つの整数
a_i
,
b_i
,
c_i
が与えられる。
これは
i
番目の配管の両端点がそれぞれ
a_i
と
b_i
であり、湯量の制限が
c_i
であることを示す。
ここで、配管の端点
x
が
0
のときは大浴場、
1
から
K
までのときは
x
番目の源泉、
K+1
から
K+N
までのときは
x − K
番目の結合点であることを表す。
制約
1 ≤ K
0 ≤ N
N+K ≤ 100
1 ≤ M ≤ (N+K+1)(N+K)
/
2
0 ≤ a_i, b_i ≤ K+N
a_i ≠ b_i
1 ≤ c_i ≤ 5{,}000
同じ2端点を持つ配管は2つ以上存在しないことが保証される。
与えられる配管網は、配管をオーバーフローさせることなく最低1以上の湯を源泉から浴槽に供給できることが保証される。
出力形式
1本だけ配管をオーバーフローさせて源泉から浴槽への供給湯量を最大化するときの最大供給湯量を1行に出力せよ。
ただし、最大湯量を無限に増やせるときは、"overfuro"と1行に出力せよ。
入力例1
2 2 4
1 3 4
2 4 2
0 3 3
4 0 5
出力例1
8
入力例2
2 3 7
1 0 8
2 0 9
3 0 3
0 4 5
5 0 2
1 3 2
2 4 9
出力例2
overfuro
入力例3
1 1 2
0 2 1
1 2 1
出力例3
1
入力例4
5 0 5
0 1 1
0 2 1
0 3 1
0 4 1
0 5 1
出力例4
overfuro

Submitted solutions:

code_snippet: #include <iostream>
#include <queue>
#include <vector>
using namespace std;

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

class MaxFlow {
public:
	vector<Edge> G[109];
	int Dist[109];
	bool Used[109];

	void add_edge(int u, int v, int c) {
		G[u].push_back(Edge{ v, c, (int)G[v].size() });
		G[v].push_back(Edge{ u, 0, (int)G[u].size() - 1 });
	}

	void shortest(int u) {
		queue<int> Q;
		for (int i = 0; i < 109; i++) Dist[i] = 1000000000;
		Dist[u] = 0;
		Q.push(u);

		// BFS Start
		while (!Q.empty()) {
			int pos = Q.front(); Q.pop();
			for (int i = 0; i < G[pos].size(); i++) {
				if (G[pos][i].cap == 0) continue;
				if (Dist[G[pos][i].to] != 1000000000) continue;
				Dist[G[pos][i].to] = Dist[pos] + 1;
				Q.push(G[pos][i].to);
			}
		}
	}

	int dfs(int pos, int goal, int f) {
		if (pos == goal) return f;
		Used[pos] = true;

		// Brute Force
		for (int i = 0; i < G[pos].size(); i++) {
			if (G[pos][i].cap == 0) continue;
			if (Used[G[pos][i].to] == true) continue;
			if (Dist[pos] >= Dist[G[pos][i].to]) continue;
			int F = dfs(G[pos][i].to, goal, min(f, G[pos][i].cap));
			if (F == 0) continue;
			G[pos][i].cap -= F;
			G[G[pos][i].to][G[pos][i].rev].cap += F;
			return F;
		}
		return 0;
	}

	int max_flow(int u, int v) {
		int F = 0;
		while (true) {
			shortest(u);
			for (int i = 0; i < 109; i++) Used[i] = false;
			int res = dfs(u, v, 100000000);
			if (res == 0) break;
			F += res;
		}
		return F;
	}
};

int K;
int N;
int M, A[1 << 18], B[1 << 18], C[1 << 18];
int S[1 << 18];
int T[1 << 18];
MaxFlow Z;

int main() {
	// Step 1. Input
	cin >> K >> N >> M;
	for (int i = 1; i <= M; i++) cin >> A[i] >> B[i] >> C[i];
	
	// Step 2. Max Flow
	for (int i = 1; i <= K; i++) Z.add_edge(K + N + 1, i, 100000000);
	for (int i = 1; i <= M; i++) Z.add_edge(A[i], B[i], C[i]);
	for (int i = 1; i <= M; i++) Z.add_edge(B[i], A[i], C[i]);
	int First = Z.max_flow(K + N + 1, 0);

	// Step 3. Get S & T
	for (int i = 1; i <= K + N; i++) {
		MaxFlow Z2 = Z, Z3 = Z;
		S[i] = Z2.max_flow(K + N + 1, i);
		T[i] = Z3.max_flow(i, 0);
	}
	T[0] = 100000000;

	// Step 4. Get Answer
	int Answer = 0;
	for (int i = 1; i <= M; i++) {
		Answer = max(Answer, min(S[A[i]], T[B[i]]));
		Answer = max(Answer, min(S[B[i]], T[A[i]]));
	}
	if (Answer >= 10000000) cout << "overfuro" << endl;
	else cout << First + Answer << endl;
	return 0;
}
accuracy: 1
time_ms: 780
memory_kb: 6136
final_rank: 14

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()

/* do your best */

// verified : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A
// O(E V^2)

// [使い方]
// add_edge(from, to, cap) :  from から to へ 容量 cap の辺を貼る
// max_flow(s, t) :  s から t への最大フローを返す

template< typename T >
struct Dinic{
    const T inf;

    struct edge{
        int to;
        T cap;
        int rev;
        bool isrev;
    };

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

    Dinic(int V) : inf(numeric_limits<T>::max()), g(V){}


    // 0-indexed
    void add_edge(int from, int to, T cap){
        g[from].emplace_back((edge){to, cap, (int)g[to].size(), false});
        g[to].emplace_back((edge){from, 0, (int)g[from].size() - 1, true});
    }

    bool bfs(int s, int t) {
        min_cost.assign(g.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 : g[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;
    }
    
    T dfs(int idx, const int t, T flow){
        if(idx == t) return flow;
        for(int &i = iter[idx]; i < g[idx].size(); i++){
            edge &e = g[idx][i];
            if(e.cap > 0 && min_cost[idx] < min_cost[e.to]){
                T d = dfs(e.to, t, min(flow, e.cap));
                if(d > 0){
                    e.cap -= d;
                    g[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    // 0-indexed
    T max_flow(int s, int t){
        T flow = 0;
        while(bfs(s, t)){
            iter.assign(g.size(), 0);
            T f = 0;
            while((f = dfs(s, t, inf)) > 0) flow += f;
        }

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

int main() {

  int k, n, m; cin >> k >> n >> m;
  int source = n + k + 1;
  int sink = 0;

  // 0 と (1 ~ k) が直接繋がっていたら，overfuro

  Dinic<lint> dc(n + k + 2);
  bool overfuro = false;
  for (int i = 0; i < m; i++) {
    lint a, b, c; cin >> a >> b >> c;
    if (a > b) swap(a, b);
    if (a == sink and 1 <= b and b <= k) {
      overfuro = true;
    }
    dc.add_edge(a, b, c);
    dc.add_edge(b, a, c);
  }

  if (overfuro) {
    cout << "overfuro" << endl;
    return 0;
  }

  for (int i = 1; i <= k; i++) {
    dc.add_edge(source, i, INF);
  }

  lint ans = dc.max_flow(source, sink);

  lint add = 0;
  for(int i = 0; i < dc.g.size(); i++) {
    for(auto &e : dc.g[i]) {
      if(e.isrev) continue;
      auto &rev_e = dc.g[e.to][e.rev];
      if (rev_e.cap == e.cap + rev_e.cap) {
        auto extra = dc;
        extra.add_edge(i, e.to, INF);
        lint tmp = extra.max_flow(source, sink);
        add = max(add, tmp);
      }
      // cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
    }
  }

  cout << ans + add << endl;
  return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 3992
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll,ll> mp;
typedef pair<mp,ll> mmp;

#define INF 1e9
struct edge{
    ll to,rev;
    ll cap,cost;
    edge(ll to, ll cap ,ll rev):to(to),cap(cap),rev(rev){}
    edge(ll to, ll cap,ll cost,ll rev):to(to),cap(cap),cost(cost),rev(rev){}
};
typedef vector<vector<edge> > graph;
struct Flow{
	graph g;
	ll MAXC = 1<<30;
	ll n;
	vector<bool> used;
	vector<ll> prevv,preve,dist;
	Flow() {} 
	Flow(ll _n) : g(_n),n(_n),used(_n,false),prevv(_n),preve(_n),dist(_n,MAXC){}
	// G[e.to][e.rev] で逆辺を操作できる
	void add_edge(ll from , ll to , ll cap){
	    g[from].push_back( edge(to,cap,g[to].size() ) );
	    g[to].push_back( edge(from,0,g[from].size()-1) );
	}
	void add_edge(ll from, ll to, ll cap,ll cost){
	    g[from].push_back( edge(to,cap,cost,g[to].size() ) );
	    g[to].push_back( edge(from, 0,-cost,g[from].size()-1) );
	}
	// Ford-Fulkerson 法による 最大流 O( F |E| )
	// Bellman-Ford 法による 最小費用流 O( F |V| |E| )
	// Verified: AOJ GRL_6_A (Maximum Flow)
	// 行き先と容量と逆辺のインデックスを記録する構造体
	// 通常のグラフの辺の構造体と異なるため注意
	// 最小費用流はもう少し速くできるので、改良しましょう
	// → ダイクストラが使えるようにポテンシャルを導入しよう
	ll dfs(ll v,ll t , ll f){
	    if( v== t)return f;
	    used[v] = true;
	    for(int i=0;i< g[v].size();i++){
		edge &e = g[v][i];
		if(!used[e.to] && e.cap > 0){
		    ll 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;
	}
	ll max_flow(ll s,ll t){
	    ll flow = 0;
	    while(1){
		fill(used.begin(),used.end(),false);
		ll f = dfs(s,t,INF);
		if( f== 0) return flow;
		flow += f;
	    }
	}
	ll mincost_flow(ll s,ll t,ll f){
	    ll res = 0;
	    ll M = MAXC ;
	    while(f>0){
		fill(dist.begin(),dist.end(), M);
		dist[s] = 0;
		bool update = true;
		while(update){
		    update = false;
		    for(ll i=0;i<n;i++){
			if(dist[i] == M) continue;
			for(ll j=0;j<g[i].size();j++){
			    edge &e = g[i][j];
			    if(e.cap > 0 && dist[e.to] > dist[i] + e.cost){
				dist[e.to] = dist[i] + e.cost;
				prevv[e.to] = i;
				preve[e.to] = j;
				update = true;
			    }
			}
		    }
		}
		if( dist[t] == M) return -1;
		ll d = f;
		for(ll i= t ; i!=s; i=prevv[i] ) d = min(d,g[ prevv[i] ][ preve[i] ].cap );
		f -= d;
		res += d*dist[t];
		for(ll i= t ; i!=s; i=prevv[i] ){
		    edge &e = g[prevv[i] ][preve[i]];
		    e.cap -= d;
		    g[i][e.rev].cap += d;
		}
	    }
	    return res;
	}
	 // ポテンシャルの導入により、ダイクストラ法で最小費用流を解く
	 // [仮定している条件]
	 //     1. グラフに負の閉路が存在しない (流量の 0 初期化のため)
	 //        もし存在するならベルマンフォードで負の閉路を見つけ
	 //        そこに流せるだけ流してスタート
	 //     2. グラフに負の辺が存在しない (pot_0 の計算可能性)
	 //     もし存在する場合は最初のみベルマンフォードを使う必要あり
	ll fast_mincost_flow(ll s,ll t,ll f){
	    ll res = 0, M = MAXC;
	    vector<ll> pot(n);
	    while( f > 0 ){
		priority_queue<mp,vector<mp>,greater<mp> > q;
		fill(dist.begin(),dist.end(),M);
		dist[s] = 0;
		q.push( mp(0,s) );
		while(!q.empty()){
		    mp now = q.top();
		    q.pop();
		    ll v = now.second;
		    ll cost = now.first;
		    if( dist[v] < cost ) continue;
		    for(ll i=0;i<g[v].size();i++){
			edge &e = g[v][i];
			if( e.cap > 0 && dist[e.to] > dist[v] + e.cost + pot[v] - pot[e.to] ){
			    dist[e.to] = dist[v] + e.cost + pot[v] - pot[e.to];
			    prevv[e.to] = v;
			    preve[e.to] = i;
			    q.push( mp(dist[e.to],e.to) );
			}
		    }
		}
		if( dist[t] == M ) return -1;
		for(ll i = 0; i< n;i++)pot[i] += dist[i];
		ll d = f;
		for(ll i = t; i!=s; i= prevv[i] ) d = min(d,g[prevv[i]][preve[i]].cap);
		f-=d;
		res += d*pot[t];
		for(ll i = t; i!=s; i=prevv[i] ){
		    edge &e = g[prevv[i] ][preve[i]];
		    e.cap -= d;
		    g[i][e.rev].cap += d;
		}
	    }
	    return res;
	}
};

int main(){
  ll k,n,m;
  cin>>k>>n>>m;
  vector< vector<mp> > g(n+k+2);
  vector<mmp>  ed(m);

  for(int i=0;i<m;i++){
   ll a,b,c;
   cin>>a>>b>>c;
   if( a > b ){
    swap(a,b);
   }
   if( a== 0 ){
    if( b <= k ){
     cout<<"overfuro"<<endl;
     return 0;
    }
   }
   ed[i] = mmp( mp(a,b), c );
   if( a == 0 ){
    g[b].push_back( mp(a,c) );
    continue;
   }
   g[a].push_back( mp(b,c) );
   if( k+1 <= a ) g[b].push_back( mp(a,c) );
  }

 // cout<<"OK"<<endl;

  ll ans = 0;
  for(int i=0;i<m;i++){
   Flow f(n+k+2);
   for(int j=1;j<=k;j++){
    f.add_edge( n + k + 1 , j , INF );
   }
   for(int j=0;j<n+k+2;j++){
    for(int l=0;l<g[j].size();l++) 
     f.add_edge( j , g[j][l].first , g[j][l].second );
   }
   
   f.add_edge( ed[i].first.first , ed[i].first.second , INF );
   if( k+1 <= ed[i].first.first ) f.add_edge( ed[i].first.second , ed[i].first.first, INF ); 

   
  
   ans = max(ans , f.max_flow( n+k+1 , 0 ) );
  }


  cout<<ans<<endl;




  return 0;
}
accuracy: 0.08333333333333333
time_ms: 540
memory_kb: 3176
final_rank: 20

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld =long double;
const ld eps = 1e-9;


//namespace cent {
//
//	struct Edge {
//		int src;
//		int dst;
//		long long int cost;
//	};
//	using Graph = vector<vector<Edge>>;
//
//	class Centroid {
//	private:
//		int dfs(const Graph&g, const int now, const int from, vector<int>&ch_nums, const vector<int>&oks) {
//			int sum = 1;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					sum += dfs(g, e.dst, e.src, ch_nums, oks);
//				}
//			}
//			return ch_nums[now] = sum;
//		}
//
//		int find_centroid(const int asize, const vector<vector<Edge>>&graph, const int pre_root, const int pre_from, const vector<int>&ch_nums, const vector<int>&oks) {
//			for (auto&& e : graph[pre_root]) {
//				if (e.dst == pre_from)continue;
//				if (oks[e.dst] != -1)continue;
//				if (ch_nums[e.dst]>asize / 2)return find_centroid(asize, graph, e.dst, e.src, ch_nums, oks);
//			}
//			return pre_root;
//		}
//
//		void dfs2(const Graph&g, const int root,const int now, const int from, const vector<int>&oks,int depth) {
//			mp[make_pair(root,now)]=depth;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					dfs2(g,root,e.dst,e.src,oks,depth+1);
//				}
//			}
//		};
//
//
//		void cent(const vector<vector<Edge>>&graph, vector<int>&oks, const int root, const int from, vector<vector<int>>&centroid_edges, int& fst_centroid, int depth, vector<int>&ch_nums) {
//			dfs(graph, root, from, ch_nums, oks);
//
//			int cent_id = find_centroid(ch_nums[root], graph, root, from, ch_nums, oks);
//
//
//			dfs2(graph,cent_id,cent_id,-1,oks,0);
//			lens1[cent_id][make_pair(0,0)]--;
//			lens2[cent_id][0]--;
//
//
//			oks[cent_id] = depth;
//
//			//for (auto&& e : graph[cent_id]) {
//			//	if (e.dst == from)continue;
//			//	if (oks[e.dst] != -1)continue;
//
//			//	dfs2(graph, e.dst, e.dst, e.src, oks,e.cost%mod,e.cost%mod,1);
//
//			//	for (auto&& l1 : lens1[e.dst]) {
//			//		int keta = l1.first.second;
//			//		long long int num = l1.first.first;
//
//			//		long long int need = (mod - num) / mod_pow(10, keta);
//			//		need%=mod;
//			//		auto it = lens2[e.dst].find(need);
//			//		if (it != lens2[e.dst].end()) {
//			//			ans -= l1.second*it->second;
//			//		}
//			//	}
//			//	lens1[e.dst].clear();
//			//	lens2[e.dst].clear();
//			//}
//
//			if (from != -1) {
//				centroid_edges[from].push_back(cent_id);
//			}
//			else {
//				fst_centroid = cent_id;
//			}
//			for (auto&& e : graph[cent_id]) {
//				if (e.dst == from)continue;
//				if (oks[e.dst] != -1)continue;
//				cent(graph, oks, e.dst, e.src, centroid_edges, fst_centroid, depth + 1, ch_nums);
//			}
//		}
//
//	public:
//
//		map<pair<int,int>,int>mp;
//
//		vector<map<pair<long long int,int>, long long int>>lens1;
//		vector<map<long long int, long long int>>lens2;
//		vector<vector<int>> centroid_graph;
//		vector<int>ts;
//		vector<int>parents;
//		vector<int>oks;
//		vector<int>anss;
//
//		//fst:root  snd:centroid_graph
//		void init(const Graph&g) {
//			lens1.resize(g.size());
//			lens2.resize(g.size());
//			oks = vector<int>(g.size(), -1);
//			int root = -1;
//			centroid_graph.resize(g.size());
//			parents = vector<int>(g.size(), -1);
//			ts=vector<int>(g.size(),-1);
//			anss=vector<int>(g.size(),100000);
//
//			vector<int>ch_nums(g.size());
//			cent(g, oks, 0, -1, centroid_graph, root, 0, ch_nums);
//
//			for (int i = 0; i < centroid_graph.size(); ++i) {
//				for (auto&& e : centroid_graph[i]) {
//					parents[e] = i;
//				}
//			}
//			return ;
//		}
//	}centroid;
//
//
//	void addEdge(Graph& g, int a, int b, long long int c) {
//		g[a].push_back(Edge{ a,b,c });
//		g[b].push_back(Edge{ b,a,c });
//	}
//}


//const int mod = 1000000007;
//struct Mod {
//public:
//	int num;
//	Mod() : Mod(0) { ; }
//	Mod(long long int n) : num((n % mod + mod) % mod) {
//		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
//	}
//	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
//	operator int() { return num; }
//};
//
//Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
//Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
//Mod operator+(const Mod a, const long long int  b) { return b + a; }
//Mod operator++(Mod &a) { return a + Mod(1); }
//Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
//Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
//Mod operator--(Mod &a) { return a - Mod(1); }
//Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
//Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
//Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
//Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
//Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
//Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
//Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
//Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
//Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
//Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
//Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
//Mod operator^(const Mod a, const int n) {
//	if (n == 0) return Mod(1);
//	Mod res = (a * a) ^ (n / 2);
//	if (n % 2) res = res * a;
//	return res;
//}
//Mod mod_pow(const Mod a, const long long  int n) {
//	if (n == 0) return Mod(1);
//	Mod res = mod_pow((a * a), (n / 2));
//	if (n % 2) res = res * a;
//	return res;
//}
//
////mod が素数の場合のみ　違う場合はextend euclid を用いる。
//Mod inv(const Mod a) { return a ^ (mod - 2); }
//Mod operator/(const Mod a, const Mod b) {
//	assert(b.num != 0);
//	return a * inv(b);
//}
//Mod operator/(const long long int a, const Mod b) {
//	return Mod(a) / b;
//}
//Mod operator/=(Mod &a, const Mod b) {
//	return a = a / b;
//}
//
//#define MAX_MOD_N 1024000
//
//Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
//void init(const int amax = MAX_MOD_N) {
//	fact[0] = Mod(1); factinv[0] = 1;
//	for (int i = 0; i < amax - 1; ++i) {
//		fact[i + 1] = fact[i] * Mod(i + 1);
//		factinv[i + 1] = factinv[i] / Mod(i + 1);
//	}
//}
//Mod comb(const int a, const int b) {
//	return fact[a] * factinv[b] * factinv[a - b];
//}
//
//vector<int>primes;
//void hurui(const int amax=3500) {
//	static bool flag = false;
//	if (flag)return;
//	vector<int>sos;
//	sos = vector<int>(amax + 1, true);
//	sos[0] = false; sos[1] = false;
//	for (int i = 2; i <= amax; ++i) {
//		if (sos[i]) {
//			for (int j = 2 * i; j <= amax; j += i)sos[j] = false;
//		}
//	}
//	for (int i = 0; i <= amax; ++i) {
//		if (sos[i]) {
//			primes.push_back(i);
//		}
//	}
//	flag = true;
//}
//
//
//struct query {
//	int u;
//	int v;
//	map<int,int>mp;
//};
//
//map<int, int>mk_mp(const int a) {
//	int rest(a);
//	map<int,int>as;
//	for (auto pr : primes) {
//		while (rest%pr == 0) {
//			as[pr]++;
//			rest /= pr;
//		}
//	}
//	if (rest!=1)as[rest]++;
//	return as;
//}
//
//#define Seg_Max_N (1<<18) 
//
//class Tree {
//public:
//	Tree(int V, int root) : V(V), root(root), cnum(V), place(V), id(V) {
//		T.resize(V);
//		for (int i = 0; i < MAXLOGV; i++) {
//			parent[i].resize(V);
//		}
//		depth.resize(V);
//	}
//	// uとvをつなぐ
//	// lcaを求めることが主目的なので無向グラフとしている
//	void unite(int u, int v) {
//		T[u].push_back(v);
//		T[v].push_back(u);
//	}
//	void unite(vector<vector<int>>&e) {
//		T = e;
//	}
//	// initする
//	// コンストラクタだけじゃなくてこれも呼ばないとlcaが求められないぞ
//	void init() {
//		dfs(root, 0, 0);
//		int id = 0;
//		getid(root, 0, id);
//	}
//	// uとvのlcaを求める
//	int lca(int u, int v) const {
//		if (depth[u] > depth[v]) swap(u, v);
//		for (int k = 0; k < MAXLOGV; k++) {
//			if ((depth[v] - depth[u]) >> k & 1) {
//				v = parent[k][v];
//			}
//		}
//		if (u == v) return u;
//		for (int k = MAXLOGV - 1; k >= 0; k--) {
//			if (parent[k][u] != parent[k][v]) {
//				u = parent[k][u];
//				v = parent[k][v];
//			}
//		}
//		return parent[0][u];
//	}
//	// uとvの距離を求める
//	// edgeを定義しないといけない時はこれじゃダメ
//	int dist(int u, int v) const {
//		int p = lca(u, v);
//		return (depth[u] - depth[p]) + (depth[v] - depth[p]);
//	}
//	int dfs(int v, int p, int d) {
//		parent[0][v] = p;
//		depth[v] = d;
//		cnum[v] = 0;
//		for (int i = 1; i < MAXLOGV; i++) {
//			parent[i][v] = parent[i - 1][parent[i - 1][v]];
//		}
//		for (int next : T[v]) {
//			if (next != p) cnum[v] += dfs(next, v, d + 1);
//		}
//		return cnum[v] + 1;
//	}
//
//	void dfs2(int v, int p, vector<vector<int>>&doubles, const vector<int>&nums) {
//		for (int next : T[v]) {
//			if (next != p) dfs2(next, v, doubles, nums);
//		}
//		doubles[0][v] = nums[v];
//		for (int j = 1; j < MAXLOGV; ++j) {
//			doubles[j][v] = min(doubles[j][v], doubles[j - 1][v]);
//		}
//		for (int j = 0; j < MAXLOGV - 1; ++j) {
//			doubles[j + 1][parent[j][v]] = min(doubles[j + 1][parent[j][v]], doubles[j][v]);
//		}
//	}
//	//ここでは親から距離2^iの部分木の最小値を求めている
//	vector<vector<int>>get_doubles(const vector<int>&nums) {
//		vector<vector<int>>doubles(MAXLOGV, vector<int>(V, 1e9));
//		dfs2(root, -1, doubles, nums);
//		return doubles;
//	}
//
//	void getid(const int v, const int p, int &nplace) {
//		place[v] = nplace;
//		id[nplace] = v;
//		nplace++;
//		for (int next : T[v]) {
//			if (next != p) getid(next, v, nplace);
//		}
//	}
//	static const int MAXLOGV = 25;
//	// グラフの隣接リスト表現
//	vector<vector<int> > T;
//	// 頂点の数
//	int V;
//	// 根ノードの番号
//	int root;
//
//	// 親ノード
//	vector<int> parent[MAXLOGV];
//	// 根からの深さ
//	vector<int> depth;
//
//	//子の数
//	vector<int>cnum;
//
//	//変換
//	vector<int>place;
//	vector<int>id;
//
//};
//
//vector<int>pas;
//void adfs(vector<pair<int, int>>&lrs, vector<int>&tos,const vector<vector<int>>&edges, const int now, const int from,int &id) {
//	tos[now]=id;
//	lrs[tos[now]].first=id++;
//	for (auto e : edges[now]) {
//		if (e == from) {
//			pas[now] = from;
//			continue;
//		}
//		adfs(lrs,tos,edges,e,now,id);
//	}
//	lrs[tos[now]].second=id;
//}
//
//vector<pair<int, int>>get_lrs(vector<int>&tos,const vector<vector<int>>&edges, const int root) {
//	pas.resize(tos.size());pas[0]=-1;
//	vector<pair<int,int>>lrs(edges.size());
//	int id=0;
//	adfs(lrs,tos,edges,0,-1,id);
//	return lrs;
//}



#define _GLIBCXX_DEBUG

using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(auto i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()


//const int INF = 2147483647;
//const long long int L_INF = 9223372036854775807;

typedef int Weight;

const Weight INF = 1e9;
const Weight ZERO = 0;
struct Edge {
	int src, dst;
	Weight weight;
	int id;
	Edge(int src_, int dst_, Weight weight_, const int id_) :
		src(src_), dst(dst_), weight(weight_), id(id_) { }
	Edge(int src, int dst, Weight weight) :
		src(src), dst(dst), weight(weight) { }
	Edge() :src(0), dst(0), weight(0) {

	}
};
bool operator < (const Edge &e, const Edge &f) {
	return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
	e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;
#define RESIDUE(s,t) (capacity[s][t]-flow[s][t])

int flow_try(const Graph&g, int s, int t, Matrix&flow, Matrix&capacity) {
	Weight total = ZERO;
	while (1) {
		queue<int> Q; Q.push(s);
		vector<int> prev(g.size(), -1); prev[s] = s;
		while (!Q.empty() && prev[t] < 0) {
			int u = Q.front(); Q.pop();
			FOR(e, g[u]) if (prev[e->dst] < 0 && RESIDUE(u, e->dst) > ZERO) {
				prev[e->dst] = u;
				Q.push(e->dst);
			}
		}
		if (prev[t] < 0)break; // prev[x] == -1 <=> t-side
		Weight inc = INF;
		for (int j = t; prev[j] != j; j = prev[j]) {
			auto v(RESIDUE(prev[j], j));
			if (inc > v) {
				inc = v;
			}
		}
		for (int j = t; prev[j] != j; j = prev[j])
			flow[prev[j]][j] = flow[prev[j]][j] + inc, flow[j][prev[j]] = flow[j][prev[j]] - inc;;
		total += inc;
	}
	return total;
}

//流量0の逆辺も張らないと正しく求まらないので注意
Weight maximumFlow(const Graph &ag, int s, int t) {

	Graph g(ag);
	for (int i = 0; i < ag.size(); ++i) {
		for (int j = 0; j < ag[i].size(); ++j) {
			int d = ag[i][j].dst;
			int s = ag[i][j].src;

			bool ok = false;
			for (int k = 0; k < ag[d].size(); ++k) {
				if (ag[d][k].dst == s) {
					ok = true;
					break;
				}
			}
			if (!ok) {
				g[d].push_back(Edge(d, s, ZERO));
			}
		}
	}
	int n = g.size();
	Matrix flow(n, Array(n,ZERO)), capacity(n, Array(n,ZERO));
	REP(u, n) FOR(e, g[u]) capacity[e->src][e->dst] =capacity[e->src][e->dst]+ e->weight;


	Weight total = flow_try(g,s,t,flow,capacity);

	vector<int>ss(g.size()),ts(g.size());

	for (int at = 0; at < g.size(); ++at) {
		int as=0;
		if(as==at)ss[at]=1e9;
		else {
			Matrix aflow(flow);
			Matrix acap(capacity);
			ss[at]=flow_try(g,as,at,aflow,acap);
		}
	}
	for (int as = 0; as < g.size(); ++as) {
		int at = g.size()-1;
		if (as == at)ts[as]=1e9;
		else {
			Matrix aflow(flow);
			Matrix acap(capacity);
			ts[as] = flow_try(g, as, at, aflow, acap);
		}
	}

	int plus=0;
	for (int i = 0; i < g.size(); ++i) {
		for (auto e : g[i]) {
			int nplus=min(ss[e.src],ts[e.dst]);
			
			plus=max(plus,nplus);
		}
	}

	return total+plus;
}



int main()
{
	int K,N,M;cin>>K>>N>>M;

	const int start=0;
	const int gensen=1;
	const int connection=gensen+K;
	const int goal=connection+N;

	Graph g(goal+1);
	for (int i = 0; i < M; ++i) {
		int a,b,c;
		cin>>a>>b>>c;
		g[a].push_back(Edge(a,b,c));
		g[b].push_back(Edge(b,a,c));
	}

	for (int i = 0; i < K; ++i) {
		bool flag=false;
		for (auto&e : g[goal]) {
			if (e.dst == gensen + i) {
				e.weight=1e9;
				flag=true;
			}
		}
		for (auto&e : g[gensen+i]) {
			if (e.dst == goal) {
				e.weight = 1e9;
			}
		}
		if (!flag) {

			g[goal].push_back(Edge(goal, gensen + i, 1e9));
			g[gensen + i].push_back(Edge(gensen + i, goal, 1e9));
		}
	}

	auto f=maximumFlow(g,start,goal);

	if (f >= 1e9-1e8) {
		cout<<"overfuro"<<endl;
	}
	else {


		cout << f << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3568
final_rank: 11

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 120

enum Type{
	BASE,
	TMP,
};


//辺を表す構造体(行先、容量、逆辺のインデックス)
struct Edge{
	Edge(int arg_to,int arg_capacity,int arg_rev_index){
		to = arg_to;
		capacity = arg_capacity;
		rev_index = arg_rev_index;
	}
	int to,capacity,rev_index;
};

int V;
int K,N,E;
vector<Edge> G[2][NUM]; //グラフの隣接リスト表現
int dist[2][NUM]; //sourceからの距離
int cheked_index[2][NUM]; //どこまで調べ終わったか
int table[NUM];
bool can_visit[NUM];

//fromからtoへ向かう容量capacityの辺をグラフに追加する
void add_edge(int from,int to,int capacity){
	G[BASE][from].push_back(Edge(to,capacity,G[BASE][to].size())); //★逆辺はそれぞれ張る★
	G[BASE][to].push_back(Edge(from,0,G[BASE][from].size()-1)); //逆辺の、初期容量は0
}

//sourceからの最短距離をBFSで計算する
void bfs(Type type,int source){
	for(int i = 0; i < V; i++)dist[type][i] = -1;
	queue<int> Q;
	dist[type][source] = 0;
	Q.push(source);

	while(!Q.empty()){
		int node_id = Q.front();
		Q.pop();

		for(int i = 0; i < G[type][node_id].size(); i++){
			Edge &e = G[type][node_id][i];
			if(e.capacity > 0 && dist[type][e.to] < 0){ //辺の容量が正で、かつエッジの行先に未訪問の場合
				dist[type][e.to] = dist[type][node_id]+1;
				Q.push(e.to);
			}
		}
	}
}

//増加パスをDFSで探す
int dfs(Type type,int node_id,int sink,int flow){
	if(node_id == sink)return flow; //終点についたらflowをreturn

	for(int &i = cheked_index[type][node_id]; i < G[type][node_id].size(); i++){ //node_idから出ているエッジを調査
		Edge &e = G[type][node_id][i];
		if(e.capacity > 0 && dist[type][node_id] < dist[type][e.to]){ //流せる余裕があり、かつsourceからの距離が増加する方法である場合
			int tmp_flow = dfs(type,e.to,sink,min(flow,e.capacity)); //流せるだけ流す
			if(tmp_flow > 0){ //流せた場合
				e.capacity -= tmp_flow; //流した分、エッジの容量を削減する
				G[type][e.to][e.rev_index].capacity += tmp_flow; //逆辺の容量を、流した分だけ増加させる
				return tmp_flow;
			}
		}
	}
	return 0;
}

//sourceからsinkへの最大流を求める
int max_flow(Type type,int source,int sink){ //source:始点 sink:終点
	int flow = 0,add;
	while(true){ //増加パスが存在する限り、流量を追加し続ける
		bfs(type,source);
		if(dist[type][sink] < 0)break; //sourceからsinkへと辿り着く残余グラフがない、つまり増加パスが無くなった場合、break
		for(int i = 0; i < V; i++)cheked_index[type][i] = 0;
		while((add = dfs(type,source,sink,BIG_NUM)) > 0){ //増加パスが見つかる間、加算
			flow += add;
		}
	}
	return flow;
}

//sourceから行けるノードを探す
void visit_check(int node_id){
	can_visit[node_id] = true;

	for(int i = 0; i < G[BASE][node_id].size(); i++){
		if(can_visit[G[BASE][node_id][i].to] == true || G[BASE][node_id][i].capacity == 0)continue;
		visit_check(G[BASE][node_id][i].to);
	}
}


int main(){

	scanf("%d %d %d",&K,&N,&E);

	int from,to,capacity;
	for(int loop = 0; loop < E; loop++){
		scanf("%d %d %d",&from,&to,&capacity);
		add_edge(from,to,capacity);
		add_edge(to,from,capacity);
	}

	int source = K+N+1,sink = 0; //浴槽をsinkとする

	for(int i = 1; i <= K; i++){
		add_edge(source,i,BIG_NUM);
	}

	//一回流す
	V = K+N+2;
	int base_flow = max_flow(BASE,source,sink);

	//sourceから行けるノードを探す
	for(int i = 0; i < V; i++)can_visit[i] = false;
	visit_check(source);

	int ans = 0;

	//残余グラフ上でボトルネックを走査(ボトルネック辺はcapacityが0になっているはず)
	//ループの際、sourceとsinkは除く
	table[source] = BIG_NUM;
	table[sink] = BIG_NUM;
	for(int i = 1; i < V-1; i++){
		for(int k = 0; k < NUM; k++){
			G[TMP][k] = G[BASE][k];
		}
		if(can_visit[i]){
			table[i] = max_flow(TMP,source,i);
		}else{
			table[i] = max_flow(TMP,i,sink);
		}
	}

	for(int i = 0; i < V; i++){
		if(!can_visit[i])continue;
		for(int k = 0; k < G[BASE][i].size(); k++){
			if(can_visit[G[BASE][i][k].to])continue;
			ans = max(ans,min(table[i],table[G[BASE][i][k].to]));
		}
	}

	ans += base_flow;

	if(ans >= BIG_NUM){
		printf("overfuro\n");
	}else{
		printf("%d\n",ans);
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3576
final_rank: 8

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 120

enum Type{
	BASE,
	TMP,
};


//辺を表す構造体(行先、容量、逆辺のインデックス)
struct Edge{
	Edge(int arg_to,int arg_capacity,int arg_rev_index){
		to = arg_to;
		capacity = arg_capacity;
		rev_index = arg_rev_index;
	}
	int to,capacity,rev_index;
};

int V;
int K,N,E;
vector<Edge> G[2][NUM]; //グラフの隣接リスト表現
int dist[2][NUM]; //sourceからの距離
int cheked_index[2][NUM]; //どこまで調べ終わったか
int table[NUM];
bool can_visit[NUM];

//fromからtoへ向かう容量capacityの辺をグラフに追加する
void add_edge(int from,int to,int capacity){
	G[BASE][from].push_back(Edge(to,capacity,G[BASE][to].size())); //★逆辺はそれぞれ張る★
	G[BASE][to].push_back(Edge(from,0,G[BASE][from].size()-1)); //逆辺の、初期容量は0
}

//sourceからの最短距離をBFSで計算する
void bfs(Type type,int source){
	for(int i = 0; i < V; i++)dist[type][i] = -1;
	queue<int> Q;
	dist[type][source] = 0;
	Q.push(source);

	int debug = 0;
	while(!Q.empty()){
		int node_id = Q.front();
		Q.pop();
		debug++;
		if(debug == 100){
			printf("LOOP!!\n");
			return;
		}

		for(int i = 0; i < G[type][node_id].size(); i++){
			Edge &e = G[type][node_id][i];
			if(e.capacity > 0 && dist[type][e.to] < 0){ //辺の容量が正で、かつエッジの行先に未訪問の場合
				dist[type][e.to] = dist[type][node_id]+1;
				Q.push(e.to);
			}
		}
	}
}

//増加パスをDFSで探す
int dfs(Type type,int node_id,int sink,int flow){
	if(node_id == sink)return flow; //終点についたらflowをreturn

	for(int &i = cheked_index[type][node_id]; i < G[type][node_id].size(); i++){ //node_idから出ているエッジを調査
		Edge &e = G[type][node_id][i];
		if(e.capacity > 0 && dist[type][node_id] < dist[type][e.to]){ //流せる余裕があり、かつsourceからの距離が増加する方法である場合
			int tmp_flow = dfs(type,e.to,sink,min(flow,e.capacity)); //流せるだけ流す
			if(tmp_flow > 0){ //流せた場合
				e.capacity -= tmp_flow; //流した分、エッジの容量を削減する
				G[type][e.to][e.rev_index].capacity += tmp_flow; //逆辺の容量を、流した分だけ増加させる
				return tmp_flow;
			}
		}
	}
	return 0;
}

//sourceからsinkへの最大流を求める
int max_flow(Type type,int source,int sink){ //source:始点 sink:終点
	int flow = 0,add;
	while(true){ //増加パスが存在する限り、流量を追加し続ける
		bfs(type,source);
		if(dist[type][sink] < 0)break; //sourceからsinkへと辿り着く残余グラフがない、つまり増加パスが無くなった場合、break
		for(int i = 0; i < V; i++)cheked_index[type][i] = 0;
		while((add = dfs(type,source,sink,BIG_NUM)) > 0){ //増加パスが見つかる間、加算
			flow += add;
		}
	}
	return flow;
}

//sourceから行けるノードを探す
void visit_check(int node_id){
	can_visit[node_id] = true;

	for(int i = 0; i < G[BASE][node_id].size(); i++){
		if(can_visit[G[BASE][node_id][i].to] == true || G[BASE][node_id][i].capacity == 0)continue;
		visit_check(G[BASE][node_id][i].to);
	}
}


int main(){

	scanf("%d %d %d",&K,&N,&E);

	int from,to,capacity;
	for(int loop = 0; loop < E; loop++){
		scanf("%d %d %d",&from,&to,&capacity);
		add_edge(from,to,capacity);
		add_edge(to,from,capacity);
	}

	int source = K+N+1,sink = 0; //浴槽をsinkとする

	for(int i = 1; i <= K; i++){
		add_edge(source,i,BIG_NUM);
	}

	//一回流す
	V = K+N+2;
	int base_flow = max_flow(BASE,source,sink);

	//sourceから行けるノードを探す
	for(int i = 0; i < V; i++)can_visit[i] = false;
	visit_check(source);

	int ans = 0;

	//残余グラフ上でボトルネックを走査(ボトルネック辺はcapacityが0になっているはず)
	//ループの際、sourceとsinkは除く
	table[source] = BIG_NUM;
	table[sink] = BIG_NUM;
	for(int i = 1; i < V-1; i++){
		for(int k = 0; k < NUM; k++){
			G[TMP][k] = G[BASE][k];
		}
		if(can_visit[i]){
			table[i] = max_flow(TMP,source,i);
		}else{
			table[i] = max_flow(TMP,i,sink);
		}
	}

	for(int i = 0; i < V; i++){
		if(!can_visit[i])continue;
		for(int k = 0; k < G[BASE][i].size(); k++){
			if(can_visit[G[BASE][i][k].to])continue;
			ans = max(ans,min(table[i],table[G[BASE][i][k].to]));
		}
	}

	ans += base_flow;

	if(ans >= BIG_NUM){
		printf("overfuro\n");
	}else{
		printf("%d\n",ans);
	}

	return 0;
}
accuracy: 0.125
time_ms: 30
memory_kb: 3452
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)   FOR(i,0,n)
#define pb emplace_back
typedef long long ll;
typedef pair<ll,ll> pint;

const int INF=1000100010;
const int MAX_N=102;
struct edge{
    int to,cap,rev;
    edge(int to,int cap,int rev):
    to(to),cap(cap),rev(rev){}
    };

vector<edge> g[MAX_N];
int dist[MAX_N];
int used[MAX_N];
void add_edge(int src,int dst,int cap){
    g[src].pb(edge(dst,cap,g[dst].size()));
    g[dst].pb(edge(src,cap,g[src].size()-1));
}
void bfs(int s){
    memset(dist,-1,sizeof(dist));
    queue<int> q;
    dist[s]=0;
    q.push(s);
    while(!q.empty()){
        int v=q.front();q.pop();
        rep(i,g[v].size()){
            edge &e=g[v][i];
            if(e.cap>0&&dist[e.to]<0){
                dist[e.to]=dist[v]+1;
                q.push(e.to);
            }
        }
    }
}
int dfs(int v,int t,int f){
    if(v==t) return f;
    used[v]=true;
    rep(i,g[v].size()){
        edge &e=g[v][i];
        if(e.cap>0&&dist[v]<dist[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;
}
int max_flow(int s,int t){
    int flow=0;
    while(1){
        bfs(s);
        if(dist[t]<0) return flow;
        memset(used,0,sizeof(used));
        int f;
        while((f=dfs(s,t,INF))>0){
            flow+=f;
        }
    }
}
vector<edge> g2[MAX_N];
int main(){
    int k,n,m;
    int a,b,c;
    cin>>k>>n>>m;
    bool flag=false;
    rep(i,m){
        cin>>a>>b>>c;
        add_edge(a,b,c);
        if(a==0&&b<=k||b==0&&a<=k) flag=true;
    }
    if(flag){
        cout<<"overfuro"<<endl;
        return 0;
    }
    int s=n+k+1;
    FOR(i,1,k+1){
        add_edge(s,i,INF);
    }
    int cur=max_flow(s,0);
    //cout<<cur<<endl;
    int mx=0;
    rep(i,s+1) g2[i]=g[i];
    rep(i,s+1){
        rep(j,g[i].size()){
            if(g[i][j].cap==0){
                g[i][j].cap=INF;
                mx=max(mx,max_flow(s,0));
                rep(l,s+1) g[l]=g2[l];
            }
        }
    }
    if(cur+mx>=INF) cout<<"overfuro"<<endl;
    else cout<<cur+mx<<endl;
    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 3288
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using pi = pair<int,int>;

// (?????????,??????,??????)
struct edge{ int to,cap,rev; };

const int MAX_V = 111; // TODO:initialize
const int F_INF = 99999999; // TODO:initialize
vector<edge> G[MAX_V],z[MAX_V];
int level[MAX_V]; // s??????????????¢
int iter[MAX_V]; // ???????????§??????????????£??????

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

void dinic_bfs(int s){
    memset(level,-1,sizeof(level));
    queue<int> que;
    level[s]=0;
    que.push(s);
    while(!que.empty()){
        int v = que.front();
        que.pop();
        rep(i,G[v].size()){
            edge &e = G[v][i];
            if(e.cap>0 && level[e.to]<0){
                level[e.to] = level[v]+1;
                que.push(e.to);
            }
        }
    }
}

// ?¢?????????????dfs??§??¢???
int dinic_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 = dinic_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;
}

// s??????t???????????§???
int max_flow(int s, int t){
    int flow = 0;
    while(1){
        dinic_bfs(s);
        if(level[t]<0) return flow;
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dinic_dfs(s,t,F_INF))>0) flow+=f;
    }
}

const int INF=5555555;
int ff[MAX_V][2]={};

void solve()
{
    bool direct = false;
    int K,N,M;
    cin >>K >>N >>M;
    vector<int> a(M),b(M),c(M);
    rep(i,M)
    {
        cin >>a[i] >>b[i] >>c[i];
        if(a[i]>b[i]) swap(a[i],b[i]);
        add_edge(a[i],b[i],c[i]);
        direct|=(a[i]==0 && 1<=b[i] && b[i]<=K);
    }

    if(direct)
    {
        cout << "overfuro" << endl;
        return;
    }

    int S=K+N+1,T=0;
    for(int i=1; i<=K; ++i) add_edge(S,i,INF);

    int F = max_flow(S,T);

    rep(i,MAX_V) z[i]=G[i];

    ff[S][0]=INF;
    rep(i,S)
    {
        rep(j,MAX_V) G[j]=z[j];
        ff[i][0] = max_flow(S,i);
    }
    ff[0][1]=INF;
    for(int i=1; i<=S; ++i)
    {
        rep(j,MAX_V) G[j]=z[j];
        ff[i][1] = max_flow(i,T);
    }

    int add = 0;
    rep(i,M)
    {
        int u=a[i], v=b[i];
        add = max(add,min(ff[u][0],ff[v][1]));
        add = max(add,min(ff[v][0],ff[u][1]));
    }

    cout << F+add << endl;
}

int main()
{
    solve();
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3324
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repl(i,0,n)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__",", __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 100000000

template<typename T>
class MaximumFlow{
public:
  struct edge{int to; T cap; int rev;};
  vector<vector<edge> > Graph;
  vector<int> level, iter; //s??????????????¢,???????????§????????????
  void bfs(int s){
    fill(all(level), -1);
    queue<int> q;
    level[s]=0;
    q.push(s);
    while(!q.empty()){
      int v=q.front(); q.pop();
      for(auto e : Graph[v]){
        if(e.cap>0 && level[e.to]<0){
          level[e.to] = level[v]+1;
          q.push(e.to);
        }
      }
    }
  }
  T dfs(int v, int t, T f){
    if(v==t) return f;
    for(int &i=iter[v]; i<(int)Graph[v].size(); i++){
      auto &e = Graph[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;
          Graph[e.to][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0;
  }
  MaximumFlow(int n){
    Graph = vector<vector<edge> >(n, vector<edge>());
    level = vector<int>(n);
    iter = vector<int>(n);
  }
  T max_flow(int s, int t){
    T flow=0;
    while(true){
      bfs(s);
      if(level[t] < 0) break;
      fill(all(iter), 0);
      T f;
      while( (f=dfs(s,t,INF)) > 0){
        flow += f;
      }
    }
    return flow;
  }
  void add_edge(int from, int to, T cap){
    int tos = Graph[to].size(), froms = Graph[from].size();
    Graph[from].pb(((edge){to, cap, tos}));
    Graph[to].pb(((edge){from, cap, froms}));
  }
}; // END class MaximumFlow

int main(){
  int k,n,m;
  cin>>k>>n>>m;
  MaximumFlow<int> flow(k+n+2);
  // 0: sink
  // 1-k: gensen
  // k+1 - k+n: vertex
  // k+n+1: source
  rep(i,k) flow.add_edge(k+n+1, i+1, INF);

  bool ov = false;
  rep(i,m){
    int a,b,c;
    cin>>a>>b>>c;
    if(1<=a && a<=k && 1<=b && b<=k) continue;
    flow.add_edge(a, b, c);
    if(a*b==0 && ((1<=a && a<=k) || (1<=b && b<=k)) ) ov = true;
  }
  if(ov){ cout << "overfuro" << endl; return 0; }

  int f = flow.max_flow(k+n+1, 0);

  // source??????bfs??????????????????????£????????????¢???
  auto g = flow.Graph;
  vector<int> u,v;
  queue<int> q;
  vector<bool> visited(k+n+2);
  q.push(k+n+1);
  visited[k+n+1]=true;
  while(!q.empty()){
    int d = q.front(); q.pop();
    for(auto to : g[d]) if(!visited[to.to]){
      if(to.cap==0){u.pb(d); v.pb(to.to);}
      else{
        q.push(to.to);
        visited[to.to] = true;
      }
    }
  }
  // dbg(u);
  // dbg(v);

  vector<int> uu(k+n+2, -1), vv(k+n+2, -1);
  int ans = f;
  rep(i,u.size()){
    if(uu[u[i]]==-1 || vv[v[i]]==-1){
      flow.Graph = g;
      if(uu[u[i]]==-1){
        if(1<=u[i] && u[i]<=k) uu[u[i]] = INF;
        else uu[u[i]] = flow.max_flow(k+n+1, u[i]);
      }
      if(vv[v[i]]==-1){
        if(v[i]==0) vv[v[i]] = INF;
        else vv[v[i]] = flow.max_flow(v[i], 0);
      }
    }
//    dbg(uu[u[i]],vv[v[i]]);
    ans = max(ans, f + min(uu[u[i]], vv[v[i]]) );
  }
  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3340
final_rank: 3

code_snippet: #include<bits/stdc++.h>
#define rep(i,a) for(int i=0;i<(int)(a);i++)
#define pb push_back
#define sz size()
using namespace std;
typedef vector<int> vi;

const int INF = 1e8;

struct edge{
  int from,to,cap,rev;
  edge(int a,int b,int c,int e)
    :from(a),to(b),cap(c),rev(e){}
};

struct dinic{
  int n;
  vector< vector<edge> > graph;
  vi level,iter;

  dinic(int a=0):n(a){graph.resize(a);}

  void AddEdge(int s,int g,int p){
    graph[s].pb( edge(s,g,p,graph[g].sz) );
    graph[g].pb( edge(g,s,0,graph[s].sz-1) );
  }

  void bfs(int s){
    level = vi(n,-1);
    level[s] = 0;
    queue<int> q; q.push(s);
    while(q.sz){
      int v = q.front(); q.pop();
      for(edge e: graph[v]){
	if(e.cap > 0 && level[e.to] < 0){
	  level[e.to] = level[v] + 1;
	  q.push(e.to);
	}
      }
    }
  }
  
  int dfs(int v, int t, int f){
    if(v==t)return f;
    for(int &i = iter[v];i<(int)graph[v].sz;i++){
      edge &e = graph[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;
	  graph[e.to][e.rev].cap += d;
	  return d;
	}
      }
    }
    return 0;
  }
  
  int max_flow(int s, int t){
    int res = 0;
    for(;;){
      bfs(s);
      if(level[t]<0)return res;
      iter = vi(n,0);
      int f;
      while((f=dfs(s,t,INF))>0)res += f;
    }
  }
};

int main(){
  int k,n,m;
  cin >> k >> n >> m;

  int v = k+n+2;
  dinic mf(v);
  rep(i,k) mf.AddEdge(v-1,i+1,INF);

  vector<int> a(m), b(m), c(m);
  rep(i,m){
    cin >> a[i] >> b[i] >> c[i];
    mf.AddEdge(a[i], b[i], c[i]);
    mf.AddEdge(b[i], a[i], c[i]);
  }

  //check overfuro
  rep(i,m){
    if(a[i] > b[i]) swap(a[i], b[i]);
    if( a[i] == 0 && (1 <= b[i] && b[i] <= k) ){
      cout << "overfuro" << endl;
      return 0;
    }
  }

  int ans = mf.max_flow(v-1,0);

  vi from_s(v,-1), to_t(v,-1);
  rep(i,v){
    dinic red(v);
    red.graph = mf.graph;
    from_s[i] = i==v-1 ? INF : red.max_flow(v-1,i);

    red.graph = mf.graph;
    to_t[i] = i==0 ? INF : red.max_flow(i,0);
  }

  int over = 0;
  rep(i,m){
    over = max( over, min(from_s[a[i]], to_t[b[i]]) );
    over = max( over, min(from_s[b[i]], to_t[a[i]]) );
  }

  cout << ans + over << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3636
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX 105
#define INF (1e8)
int K,N,M;
int T;
  
bool g[MAX][MAX];
int G[MAX][MAX];
int C[MAX];
int tmp[MAX][MAX];
  
bool visited[MAX];
bool used[MAX];
  
void copyA(){
  for(int i=0;i<MAX;i++)
    for(int j=0;j<MAX;j++)
      tmp[i][j]=G[i][j];
}
void copyB(){
  for(int i=0;i<MAX;i++)
    for(int j=0;j<MAX;j++)
      G[i][j]=tmp[i][j];
}
  
  
  
int dfs(int pos,int ti,int f){
  if(pos==ti)return f;
  visited[pos]=true;
  for(int tt=0;tt<=T;tt++){
    int to=tt;
    if(to==-1)to=T;
      
    if(visited[to])continue;
    if(G[pos][to]==0)continue;
      
    int k=dfs(to,ti, min(f,G[pos][to]) );
    if(k>0){
      G[pos][to]-=k;
      G[to][pos]+=k;
      return k;
    }
  }
  return 0;
}
  
int maxFlow(int si,int ti){
  if(si==ti)return INF;
  int res=0;
  while(1){
    memset(visited,false,sizeof(visited));
    int f=dfs(si,ti,INF);
    if(f==0)break;
    res+=f;
  
  }
  return res;
}
int calcC(int id){
  if(C[id]!=-1)return C[id];
  copyA();
  if(used[id]){
    C[id]=maxFlow(T,id);
  }else{
    C[id]=maxFlow(id,0);
  }
  copyB();
  return C[id];
}
  
int main(){
  memset(C,-1,sizeof(C));
    
  bool isOverfuro=false;
  cin>>K>>N>>M;
  T=N+K+1;
  for(int i=0;i<M;i++){
    int a,b,c;
    cin>>a>>b>>c;
    if(a==0&&1<=b&&b<=K){
      isOverfuro=true;
    }
    if(b==0&&1<=a&&a<=K){
      isOverfuro=true;
    }
    G[a][b]+=c;
    G[b][a]+=c;
    g[a][b]=true;
    g[b][a]=true;
  }
    
  for(int i=1;i<=K;i++){
    G[T][i]=INF;
  }
  
  if(isOverfuro){
    cout<<"overfuro"<<endl;
    return 0;
  }
  
  int F=maxFlow(T,0);
  assert(F>0);
    
  memset(visited,false,sizeof(visited));
  dfs(T,0,INF);
    
  for(int i=0;i<=T;i++){
    used[i]=visited[i];
  }
  
  C[0]=INF;
    
  int ans=0;
  for(int i=0;i<T;i++){
    for(int j=0;j<T;j++){
      if(i==j)continue;
      if(G[i][j]==0&&g[i][j]==true && used[i]==true && used[j]==false ){
        calcC(i);
        calcC(j);
        ans=max(ans, min(C[i],C[j]) );
      }
    }
  }
  cout<<F+ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 1120
memory_kb: 3192
final_rank: 13

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define all(a)  (a).begin(),(a).end()
#define pb push_back
#define INF (1e9+1)
//#define INF (1LL<<59)
 
 
#define MAX_V 110
 
struct edge{int to,cap,rev;};
 
vector<edge> G[MAX_V];  //???°???????????????
int level[MAX_V];       //??§???????????????????¢
int iter[MAX_V];        //????????????§????????????
 
// from??????to?????????????????????cap????????????°?????????????????????
void add_edge(int from,int to,int cap){
    G[from].push_back(  (edge){ to  ,cap,(int)G[to  ].size()   }  );
    G[to  ].push_back(  (edge){ from,0  ,(int)G[from].size()-1 }  );
}
 
// s?????????????????????¢???BFS???§??¨??????????
void bfs(int s){
    rep(i,MAX_V)level[i]=-1;
    queue<int> que;
    level[s]=0;
    que.push(s);
    while(!que.empty()){
        int v=que.front();que.pop();
         
        rep(i,G[v].size()){
            edge &e=G[v][i];
            if(e.cap>0 && level[e.to]<0){
                level[e.to]=level[v]+1;
                que.push(e.to);
            }
        }
    }
}
 
//??¢?????????????DFS???§???¢???
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;
}
 
// s??????t????????????§????????±???????
int max_flow(int s,int t){
    if(s==t)return INF;
    int flow=0;
    for(;;){
        bfs(s);
        if(level[t]<0)return flow;
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,INF))>0){
            flow+=f;
        }
    }
}
 
void isUsedDfs(int s,int t,bool used[MAX_V]){
    if(s==t)return ;
    for(auto &e:G[s]){
        if(!used[e.to]&&e.cap>0){
            used[e.to]=true;
            isUsedDfs(e.to,t,used);
        }
    }
}
 
 
int main(){
    int k,n,m;
    cin>>k>>n>>m;
    int s = 1+k+n;
    int t = 0;
    int v = s+1;
     
    rep(i,m){
        int a,b,c;
        cin>>a>>b>>c;
        add_edge(a,b,c);
        add_edge(b,a,c);
    }
     
    rep(i,k)add_edge(s,i+1,INF);
     
    int res = max_flow(s,t);
    vector<edge> Greg[MAX_V];
    rep(i,v)Greg[i] = G[i];
     
     
    bool used[MAX_V]={};
    used[s]=true;
    isUsedDfs(s,t,used);
     
    int ans = 0;
    vector<int> sflow(v,-1),tflow(v,-1);
    rep(i,v){
        for(auto e:Greg[i]){
            if(used[i]&&!used[e.to]){
                rep(i,v)G[i] = Greg[i];
                if(sflow[i]==-1) sflow[i] = max_flow(s,i);
                if(tflow[e.to]==-1)tflow[e.to] = max_flow(e.to,t);
                ans = max( ans , res + min(sflow[i],tflow[e.to]) );
            }
        }
    }
    if(ans>=INF)cout<<"overfuro"<<endl;
    else cout<<ans<<endl;
     
}
accuracy: 1
time_ms: 30
memory_kb: 3592
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define INF 1<<28
#define MAX_V 105
#define ll int
struct edge{
  ll to,cap,rev;
  edge(ll to ,ll cap,ll rev):to(to),cap(cap),rev(rev){}
};
vector<edge> G[MAX_V];
vector<edge> G2[MAX_V];
bool used[MAX_V];
int level[MAX_V];
int iter[MAX_V];


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

void bfs(int s){
  memset(level,-1,sizeof(level));
  queue<int> que;
  level[s]=0;
  que.push(s);
  while(!que.empty()){
    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;
}

void bfs2(int s){
  memset(level,-1,sizeof(level));
  queue<int> que;
  level[s]=0;
  que.push(s);
  while(!que.empty()){
    int v=que.front();que.pop();
    for(int i=0;i<G2[v].size();i++){
      edge &e = G2[v][i];
      if(e.cap>0&&level[e.to]<0){
	level[e.to]=level[v]+1;
	que.push(e.to);
      }
    }
  }
}

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

int flow=0;
int max_flow(int s,int t){
  for(;;){
    bfs(s);
    if(level[t]<0) return flow;
    memset(iter,0,sizeof(iter));
    int f;
    while((f=dfs(s,t,INF))>0){
      flow+=f;
    }
  }
}

int max_flow2(int s,int t){
  int flow2=0;
  for(;;){
    bfs2(s);
    if(level[t]<0) return flow2;
    memset(iter,0,sizeof(iter));
    int f;
    while((f=dfs2(s,t,INF))>0){
      flow2+=f;
    }
  }
}

signed main(){
  ll k,n,m,i,j,a,b,c,x,y;
  cin >> k >> n >> m;
  ll s=MAX_V-1,t=0;
  for(i=0;i<m;i++){
    cin >> a >> b >> c;
    add_edge(a,b,c);
  }
  for(i=1;i<=k;i++){
    add_edge(s,i,INF);
  }
  ll ans=max_flow(s,t);
  for(i=1;i<MAX_V-1;i++){
    for(j=0;j<G[i].size();j++){
      if(G[i][j].cap!=0) continue;
      for(x=0;x<MAX_V;x++) G2[x]=G[x];
      G2[i][j].cap=INF;
      ans=max(ans,flow+max_flow2(s,t));
      if(ans>=INF) break;
    }
  } if(ans>=INF) cout << "overfuro" << endl;
  else cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3264
final_rank: 4

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#include <string>
#define repd(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repd(i,0,n)
#define all(x) (x).begin(),(x).end()
#define mod 1000000007
#define inf 1000000007
#define mp make_pair
#define pb push_back
typedef long long ll;
using namespace std;
template <typename T>
inline void output(T a, int p = 0) {
    if(p) cout << fixed << setprecision(p)  << a << "\n";
    else cout << a << "\n";
}
// end of template
// goal, capacity, index of reverse edge
struct edge {
    int to, cap, rev;
};

struct ftc{
    int from, to, cap;
};

// O(EV^2)
class Dinic{
public:
    int V;
    vector<vector<edge>> G;
    vector<int> L;
    vector<int> I;
    vector<int> vis;
    
    Dinic(int v){
        G.resize(v), L.resize(v), I.resize(v), vis.assign(v, 0);
        V = v;
    }
    
    // add edge
    void add(int from, int to, int cap){
        G[from].push_back((edge){to, cap, (int)G[to].size()});
        G[to].push_back((edge){from, 0, (int)G[from].size() - 1});
    }
    
    // label dist from s
    void bfs(int s){
        L.assign(V, -1);
        queue<int> q;
        L[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            rep(i, G[v].size()){
                edge &e = G[v][i];
                if (e.cap > 0 && L[e.to] < 0) {
                    L[e.to] = L[v] + 1;
                    q.push(e.to);
                }
            }
        }
    }
    
    // search positive path
    int dfs(int v, int t, int f){
        if (v == t) return f;
        for (int &i = I[v]; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && L[v] < L[e.to]) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    // calc max flow
    int max_flow(int s, int t){
        int flow = 0;
        for (;;) {
            bfs(s);
            if (L[t] < 0) return flow;
            I.assign(V, 0);
            int f;
            while ((f = dfs(s, t, inf)) > 0) {
                flow += f;
            }
        }
    }
    
    vector<ftc> pipe;
    vector<int> ofuro;
    vector<int> neck;
    void dfs_cut(int s){
        if(vis[s] == 1){
            return;
        }
        vis[s] = 1;
        rep(i, G[s].size()){
            
                if(G[s][i].cap > 0){
                    dfs_cut(G[s][i].to);
                }
                else ofuro.pb(s), neck.pb(G[s][i].to), pipe.pb({s, G[s][i].to, G[s][i].cap});
        }
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    // source code
    int K, N, M;
    cin >> K >> N >> M;
    
    Dinic mf(K + N + 2);
    vector<ftc> E;
    // source: K + N + 1
    // sink: 0
    // spring: 1 ~ K
    // joint: K + 1 ~ K + N
    rep(i, K){
        E.pb({K + N + 1, i + 1, inf});
        mf.add(K + N + 1, i + 1, inf);
    }
    
    rep(i, M){
        int a, b, c;
        cin >> a >> b >> c;
        if(a != 0 && !(b >= 1 && b <= K)) mf.add(a, b, c), E.pb({a, b, c});
        if(!(a >= 1 && a <= K) && b != 0) mf.add(b, a, c), E.pb({b, a, c});
    }
    auto D = mf;
    int mfmf = mf.max_flow(K + N + 1, 0);
    
    mf.dfs_cut(K + N + 1);
    
    int ret = 0;
    vector<int> source(K + N + 2, 0), sink(K + N + 2, 0);
    
    for(int f: mf.ofuro){
        auto d = D;
        if(K + N + 1 == f) {
            source[f] = inf;
            continue;
        }
        source[f] = d.max_flow(K + N + 1, f);
    }
    
    for(int f: mf.neck){
        auto d = D;
        if(f == 0) {
            sink[f] = inf;
            continue;
        }
        sink[f] = d.max_flow(f, 0);
    }
    
    rep(i, D.G.size()){
        for(edge e: D.G[i]){
            if(source[i] > 0 && sink[e.to] > 0){
//                cout << source[i] << ", " << sink[e.to] << ", " << e.cap << endl;
                ret = max(ret, mfmf + min(source[i], sink[e.to]) - e.cap);
                if(min(source[i], sink[e.to]) == inf){
                    output("overfuro");
                    return 0;
                }
            }
        }
    }
    
    
    
    
//    if(ret >= inf){
//        output("overfuro");
//    }
//    else{
        output(ret);
//    }
    
    
    return 0;
}
accuracy: 0.14583333333333334
time_ms: 180
memory_kb: 3300
final_rank: 18

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#include <string>
#define repd(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repd(i,0,n)
#define all(x) (x).begin(),(x).end()
#define mod 1000000007
#define inf 1000000007
#define mp make_pair
#define pb push_back
typedef long long ll;
using namespace std;
template <typename T>
inline void output(T a, int p = 0) {
    if(p) cout << fixed << setprecision(p)  << a << "\n";
    else cout << a << "\n";
}
// end of template
// goal, capacity, index of reverse edge
struct edge {
    int to, cap, rev;
};

struct ftc{
    int from, to, cap;
};

// O(EV^2)
class Dinic{
public:
    int V;
    vector<vector<edge>> G;
    vector<int> L;
    vector<int> I;
    vector<int> vis;
    
    Dinic(int v){
        G.resize(v), L.resize(v), I.resize(v), vis.assign(v, 0);
        V = v;
    }
    
    // add edge
    void add(int from, int to, int cap){
        G[from].push_back((edge){to, cap, (int)G[to].size()});
        G[to].push_back((edge){from, 0, (int)G[from].size() - 1});
    }
    
    // label dist from s
    void bfs(int s){
        L.assign(V, -1);
        queue<int> q;
        L[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            rep(i, G[v].size()){
                edge &e = G[v][i];
                if (e.cap > 0 && L[e.to] < 0) {
                    L[e.to] = L[v] + 1;
                    q.push(e.to);
                }
            }
        }
    }
    
    // search positive path
    int dfs(int v, int t, int f){
        if (v == t) return f;
        for (int &i = I[v]; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && L[v] < L[e.to]) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    // calc max flow
    int max_flow(int s, int t){
        int flow = 0;
        for (;;) {
            bfs(s);
            if (L[t] < 0) return flow;
            I.assign(V, 0);
            int f;
            while ((f = dfs(s, t, inf)) > 0) {
                flow += f;
            }
        }
    }
    
    vector<ftc> pipe;
    vector<int> ofuro;
    vector<int> neck;
    void dfs_cut(int s){
        if(vis[s] == 1){
            return;
        }
        vis[s] = 1;
        rep(i, G[s].size()){
            
                if(G[s][i].cap > 0){
                    dfs_cut(G[s][i].to);
                }
                else ofuro.pb(s), neck.pb(G[s][i].to), pipe.pb({s, G[s][i].to, G[s][i].cap});
        }
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    // source code
    int K, N, M;
    cin >> K >> N >> M;
    
    Dinic mf(K + N + 2);
    vector<ftc> E;
    // source: K + N + 1
    // sink: 0
    // spring: 1 ~ K
    // joint: K + 1 ~ K + N
    rep(i, K){
        E.pb({K + N + 1, i + 1, inf});
        mf.add(K + N + 1, i + 1, inf);
    }
    
    rep(i, M){
        int a, b, c;
        cin >> a >> b >> c;
        if(a != 0 && !(b >= 1 && b <= K)) mf.add(a, b, c), E.pb({a, b, c});
        if(!(a >= 1 && a <= K) && b != 0) mf.add(b, a, c), E.pb({b, a, c});
    }
    auto D = mf;
    int mfmf = mf.max_flow(K + N + 1, 0);
    
    mf.dfs_cut(K + N + 1);
    
    int ret = 0;
    vector<int> source(K + N + 2, 0), sink(K + N + 2, 0);
    
    for(int f: mf.ofuro){
        auto d = D;
        if(K + N + 1 == f) {
            source[f] = inf;
            continue;
        }
        source[f] = d.max_flow(K + N + 1, f);
    }
    
    for(int f: mf.neck){
        auto d = D;
        if(f == 0) {
            sink[f] = inf;
            continue;
        }
        sink[f] = d.max_flow(f, 0);
    }
    
    rep(i, D.G.size()){
        for(edge e: D.G[i]){
            if(source[i] && sink[e.to]){
//                cout << source[i] << ", " << sink[e.to] << ", " << e.cap << endl;
                ret = max(ret, mfmf + min(source[i], sink[e.to]) - e.cap);
                if(min(source[i], sink[e.to]) == inf){
                    output("overfuro");
                    return 0;
                }
            }
        }
    }
    
    
    
    
//    if(ret >= inf){
//        output("overfuro");
//    }
//    else{
        output(ret);
//    }
    
    
    return 0;
}
accuracy: 0.14583333333333334
time_ms: 150
memory_kb: 3296
final_rank: 15

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#include <string>
#define repd(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repd(i,0,n)
#define all(x) (x).begin(),(x).end()
#define mod 1000000007
#define inf 1000000007
#define mp make_pair
#define pb push_back
typedef long long ll;
using namespace std;
template <typename T>
inline void output(T a, int p = 0) {
    if(p) cout << fixed << setprecision(p)  << a << "\n";
    else cout << a << "\n";
}
// end of template
// goal, capacity, index of reverse edge
struct edge {
    int to, cap, rev;
};

struct ftc{
    int from, to, cap;
};

// O(EV^2)
class Dinic{
public:
    int V;
    vector<vector<edge>> G;
    vector<int> L;
    vector<int> I;
    vector<int> vis;
    
    Dinic(int v){
        G.resize(v), L.resize(v), I.resize(v), vis.assign(v, 0);
        V = v;
    }
    
    // add edge
    void add(int from, int to, int cap){
        G[from].push_back((edge){to, cap, (int)G[to].size()});
        G[to].push_back((edge){from, 0, (int)G[from].size() - 1});
    }
    
    // label dist from s
    void bfs(int s){
        L.assign(V, -1);
        queue<int> q;
        L[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            rep(i, G[v].size()){
                edge &e = G[v][i];
                if (e.cap > 0 && L[e.to] < 0) {
                    L[e.to] = L[v] + 1;
                    q.push(e.to);
                }
            }
        }
    }
    
    // search positive path
    int dfs(int v, int t, int f){
        if (v == t) return f;
        for (int &i = I[v]; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && L[v] < L[e.to]) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    // calc max flow
    int max_flow(int s, int t){
        int flow = 0;
        for (;;) {
            bfs(s);
            if (L[t] < 0) return flow;
            I.assign(V, 0);
            int f;
            while ((f = dfs(s, t, inf)) > 0) {
                flow += f;
            }
        }
    }
    
    vector<ftc> pipe;
    vector<int> ofuro;
    vector<int> neck;
    void dfs_cut(int s){
        if(vis[s] == 1){
            return;
        }
        vis[s] = 1;
        rep(i, G[s].size()){
            
                if(G[s][i].cap > 0){
                    dfs_cut(G[s][i].to);
                }
                else ofuro.pb(s), neck.pb(G[s][i].to), pipe.pb({s, G[s][i].to, G[s][i].cap});
        }
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    // source code
    int K, N, M;
    cin >> K >> N >> M;
    
    Dinic mf(K + N + 2);
    vector<ftc> E;
    // source: K + N + 1
    // sink: 0
    // spring: 1 ~ K
    // joint: K + 1 ~ K + N
    rep(i, K){
        E.pb({K + N + 1, i + 1, inf});
        mf.add(K + N + 1, i + 1, inf);
    }
    
    rep(i, M){
        int a, b, c;
        cin >> a >> b >> c;
        if(a != 0 && !(b >= 1 && b <= K)) mf.add(a, b, c), E.pb({a, b, c});
        if(!(a >= 1 && a <= K) && b != 0) mf.add(b, a, c), E.pb({b, a, c});
    }
    auto D = mf;
    int mfmf = mf.max_flow(K + N + 1, 0);
    
    mf.dfs_cut(K + N + 1);
    
    int ret = 0;
    vector<int> source(K + N + 2, 0), sink(K + N + 2, 0);
    
    for(int f: mf.ofuro){
        auto d = D;
        if(K + N + 1 == f) {
            source[f] = inf;
            continue;
        }
        source[f] = d.max_flow(K + N + 1, f);
    }
    
    for(int f: mf.neck){
        auto d = D;
        if(f == 0) {
            sink[f] = inf;
            continue;
        }
        sink[f] = d.max_flow(f, 0);
    }
    
    rep(i, D.G.size()){
        for(edge e: D.G[i]){
            if(source[i] && sink[e.to]){
                ret = max(ret, mfmf + min(source[i], sink[e.to]) - e.cap);
            }
        }
    }
    
    
    
    
    if(ret >= inf){
        output("overfuro");
    }
    else{
        output(ret);
    }
    
    
    return 0;
}
accuracy: 0.14583333333333334
time_ms: 170
memory_kb: 3300
final_rank: 17

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#include <string>
#define repd(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repd(i,0,n)
#define all(x) (x).begin(),(x).end()
#define mod 1000000007
#define inf 20000000
#define mp make_pair
#define pb push_back
typedef long long ll;
using namespace std;
template <typename T>
inline void output(T a, int p = 0) {
    if(p) cout << fixed << setprecision(p)  << a << "\n";
    else cout << a << "\n";
}
// end of template
// goal, capacity, index of reverse edge
struct edge {
    int to, cap, rev;
};

struct ftc{
    int from, to, cap;
};

// O(EV^2)
class Dinic{
public:
    int V;
    vector<vector<edge>> G;
    vector<int> L;
    vector<int> I;
    vector<int> vis;
    
    Dinic(int v){
        G.resize(v), L.resize(v), I.resize(v), vis.assign(v, 0);
        V = v;
    }
    
    // add edge
    void add(int from, int to, int cap){
        G[from].push_back((edge){to, cap, (int)G[to].size()});
        G[to].push_back((edge){from, 0, (int)G[from].size() - 1});
    }
    
    // label dist from s
    void bfs(int s){
        L.assign(V, -1);
        queue<int> q;
        L[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            rep(i, G[v].size()){
                edge &e = G[v][i];
                if (e.cap > 0 && L[e.to] < 0) {
                    L[e.to] = L[v] + 1;
                    q.push(e.to);
                }
            }
        }
    }
    
    // search positive path
    int dfs(int v, int t, int f){
        if (v == t) return f;
        for (int &i = I[v]; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && L[v] < L[e.to]) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    // calc max flow
    int max_flow(int s, int t){
        int flow = 0;
        for (;;) {
            bfs(s);
            if (L[t] < 0) return flow;
            I.assign(V, 0);
            int f;
            while ((f = dfs(s, t, inf)) > 0) {
                flow += f;
            }
        }
    }
    
    vector<ftc> pipe;
    vector<int> ofuro;
    vector<int> neck;
    void dfs_cut(int s){
        if(vis[s] == 1){
            return;
        }
        vis[s] = 1;
        rep(i, G[s].size()){
            
                if(G[s][i].cap > 0){
                    dfs_cut(G[s][i].to);
                }
                else ofuro.pb(s), neck.pb(G[s][i].to), pipe.pb({s, G[s][i].to, G[s][i].cap});
        }
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    // source code
    int K, N, M;
    cin >> K >> N >> M;
    
    Dinic mf(K + N + 2);
    vector<ftc> E;
    // source: K + N + 1
    // sink: 0
    // spring: 1 ~ K
    // joint: K + 1 ~ K + N
    rep(i, K){
        E.pb({K + N + 1, i + 1, inf});
        mf.add(K + N + 1, i + 1, inf);
    }
    
    rep(i, M){
        int a, b, c;
        cin >> a >> b >> c;
        if(a != 0 && !(b >= 1 && b <= K)) mf.add(a, b, c), E.pb({a, b, c});
        if(!(a >= 1 && a <= K) && b != 0) mf.add(b, a, c), E.pb({b, a, c});
    }
    auto D = mf;
    int mfmf = mf.max_flow(K + N + 1, 0);
    
    mf.dfs_cut(K + N + 1);
    
    int ret = 0;
    vector<int> source(K + N + 2, 0), sink(K + N + 2, 0);
    
    for(int f: mf.ofuro){
        auto d = D;
        if(K + N + 1 == f) {
            source[f] = inf;
            continue;
        }
        source[f] = d.max_flow(K + N + 1, f);
    }
    
    for(int f: mf.neck){
        auto d = D;
        if(f == 0) {
            sink[f] = inf;
            continue;
        }
        sink[f] = d.max_flow(f, 0);
    }
    
    rep(i, D.G.size()){
        for(edge e: D.G[i]){
            if(source[i] && sink[e.to]){
                ret = max(ret, mfmf + min(source[i], sink[e.to]) - e.cap);
            }
        }
    }
    
    
    
    
    if(ret >= inf){
        output("overfuro");
    }
    else{
        output(ret);
    }
    
    
    return 0;
}
accuracy: 0.14583333333333334
time_ms: 170
memory_kb: 3288
final_rank: 16

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define all(a)  (a).begin(),(a).end()
#define pb push_back
#define INF (1e9+1)
//#define INF (1LL<<59)


#define MAX_V 110

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

vector<edge> G[MAX_V];  //??°???????????????
int level[MAX_V];       //?§??????????????????¢
int iter[MAX_V];        //???????????§????????????

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

// s????????????????????¢???BFS??§?¨??????????
void bfs(int s){
	rep(i,MAX_V)level[i]=-1;
	queue<int> que;
	level[s]=0;
	que.push(s);
	while(!que.empty()){
		int v=que.front();que.pop();
		
		rep(i,G[v].size()){
			edge &e=G[v][i];
			if(e.cap>0 && level[e.to]<0){
				level[e.to]=level[v]+1;
				que.push(e.to);
			}
		}
	}
}

//?¢?????????????DFS??§??¢???
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;
}

// s??????t???????????§???????±???????
int max_flow(int s,int t){
	if(s==t)return INF;
	int flow=0;
	for(;;){
		bfs(s);
		if(level[t]<0)return flow;
		memset(iter,0,sizeof(iter));
		int f;
		while((f=dfs(s,t,INF))>0){
			flow+=f;
		}
	}
}

void isUsedDfs(int s,int t,bool used[MAX_V]){
	if(s==t)return ;
	for(auto &e:G[s]){
		if(!used[e.to]&&e.cap>0){
			used[e.to]=true;
			isUsedDfs(e.to,t,used);
		}
	}
}


int main(){
	int k,n,m;
	cin>>k>>n>>m;
	int s = 1+k+n;
	int t = 0;
	int v = s+1;
	
	rep(i,m){
		int a,b,c;
		cin>>a>>b>>c;
		add_edge(a,b,c);
		add_edge(b,a,c);
	}
	
	rep(i,k)add_edge(s,i+1,INF);
	
	int res = max_flow(s,t);
	vector<edge> Greg[MAX_V];
	rep(i,v)Greg[i] = G[i];
	
	
	bool used[MAX_V]={};
	used[s]=true;
	isUsedDfs(s,t,used);
	
	int ans = 0;
	vector<int> sflow(v,-1),tflow(v,-1);
	rep(i,v){
		for(auto e:Greg[i]){
			if(used[i]&&!used[e.to]){
				rep(i,v)G[i] = Greg[i];
				if(sflow[i]==-1) sflow[i] = max_flow(s,i);
				if(tflow[e.to]==-1)tflow[e.to] = max_flow(e.to,t);
				ans = max( ans , res + min(sflow[i],tflow[e.to]) );
			}
		}
	}
	if(ans>=INF)cout<<"overfuro"<<endl;
	else cout<<ans<<endl;
	
}
accuracy: 1
time_ms: 30
memory_kb: 3580
final_rank: 5

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

#define rep(i,n) for (int i=0;i<(n);i++)
#define rep2(i,a,b) for (int i=(a);i<(b);i++)
#define rrep(i,n) for (int i=(n)-1;i>=0;i--)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define printV(v) for(auto&& x : v){cout << x << " ";} cout << endl
#define printVV(vv) for(auto&& v : vv){for(auto&& x : v){cout << x << " ";}cout << endl;}
#define printP(p) cout << p.first << " " << p.second << endl
#define printVP(vp) for(auto&& p : vp) printP(p);

struct edge { int to, cap, rev; };
using Graph = vector<vector<edge>>;

const int inf = 1e9;
const int MAX_V = 110;
int level[MAX_V];
int iter[MAX_V];
bool reachable[MAX_V]; // ????????°?????????????????????S????????°???????????????

void add_edge(Graph& G, 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});
}

void bfs(Graph& G, int s) {
    memset(level, -1, sizeof(level));
    queue<int> que;
    level[s] = 0;
    que.push(s);
    while (!que.empty()) {
        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(Graph& G, 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(G, 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(Graph& G, int s, int t) {
    int flow = 0;
    for (;;) {
        bfs(G, s);
        if (level[t] < 0) return flow;
        memset(iter, 0, sizeof(iter));
        int f;
        while ((f = dfs(G, s, t, inf)) > 0) {
            flow += f;
        }
    }
}

// Graph????????§??§?????????
int max_flow_2(Graph G, int s, int t) {
    int flow = 0;
    for (;;) {
        bfs(G, s);
        if (level[t] < 0) return flow;
        memset(iter, 0, sizeof(iter));
        int f;
        while ((f = dfs(G, s, t, inf)) > 0) {
            flow += f;
        }
    }
}

void my_dfs (Graph& G, int v) {
    if (reachable[v]) return; // ??¢?????\?????????
    reachable[v] = true;
    for (auto e : G[v]) {
        if (e.cap > 0) {
            my_dfs(G, e.to);
        }
    }
}

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

    int K, N, M;
    cin >> K >> N >> M;

    Graph G_ori(MAX_V);
    const int s = K + N + 1, t = 0;
    const int V = s + 1;
    rep(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
        add_edge(G_ori, a, b, c);
        add_edge(G_ori, b, a, c);
    }
    rep(i, K) {
        add_edge(G_ori, s, i + 1, inf);
    }

    Graph G_flow = G_ori;
    int flow = max_flow(G_flow, s, t);
    my_dfs(G_flow, s);

    vector<int> f1(V), f2(V); // s->i, i->t
    f1[s] = inf; f2[t] = inf;
    rep2(i, 1, K + N + 1) {
        Graph G_tmp = G_flow;
        if (reachable[i]) {
            f1[i] = max_flow(G_tmp, s, i);
        } else {
            f2[i] = max_flow(G_tmp, i, t);
        }
    }

    int ans = -1;
    rep(v, V) {
        for (auto e : G_ori[v]) {
            int u = e.to;
            if (reachable[v] && !reachable[u]) {
                ans = max(ans, flow + min(f1[v], f2[u]));
            }
        }
    }

    if (ans >= inf) {
        cout << "overfuro" << endl;
    } else {
        cout << ans << endl;
    }

}
accuracy: 1
time_ms: 30
memory_kb: 3708
final_rank: 10

code_snippet: #define _USE_MATH_DEFINES
#include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <complex>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <limits>
#include <climits>
#include <cfloat>
#include <functional>
using namespace std;

class Edge
{
public:
    int to, cap, rev;
    Edge(){};
    Edge(int to0, int cap0){to = to0; cap = cap0;}
    Edge(int to0, int cap0, int rev0){to = to0; cap = cap0; rev = rev0;}
};

int maxFlow(const vector<vector<Edge> >& edges0, int source, int sink, vector<vector<Edge> >& edgesOut)
{
    static vector<vector<Edge> > edges;
    static vector<unsigned> index;
    static vector<int> level;
    static int n;

    class Func{
    public:
        static void bfs(int s){
            level.assign(n, -1);
            queue<int> q;
            level[s] = 0;
            q.push(s);
            while(!q.empty()){
                int v = q.front();
                q.pop();
                for(unsigned i=0; i<edges[v].size(); ++i){
                    Edge& e = edges[v][i];
                    if(e.cap > 0 && level[e.to] < 0){
                        level[e.to] = level[v] + 1;
                        q.push(e.to);
                    }
                }
            }
        }
        static int dfs(int s, int t, int f){
            if(s == t)
                return f;
            for(unsigned& i=index[s]; i<edges[s].size(); ++i){
                Edge& e = edges[s][i];
                if(e.cap > 0 && level[s] < level[e.to]){
                    int g = dfs(e.to, t, min(f, e.cap));
                    if(g > 0){
                        e.cap -= g;
                        edges[e.to][e.rev].cap += g;
                        return g;
                    }
                }
            }
            return 0;
        }
    };

    if(source == sink){
        edgesOut = edges;
        return INT_MAX;
    }

    n = edges0.size();
    edges = edges0;

    int ret = 0;
    for(;;){
        Func::bfs(source);
        if(level[sink] < 0){
            edgesOut.swap(edges);
            return ret;
        }
        index.assign(n, 0);
        int f;
        while((f = Func::dfs(source, sink, INT_MAX)) > 0)
            ret += f;
    }
}

const int INF = INT_MAX / 2;

int main()
{
    int k, n, m;
    cin >> k >> n >> m;

    vector<vector<Edge> > edges(n+k+2);
    int source = n + k + 1;
    int sink = 0;
    for(int i=1; i<=k; ++ i){
        edges[source].push_back(Edge(i, INF, edges[i].size()));
        edges[i].push_back(Edge(source, INF, edges[source].size()-1));
    }
    for(int i=0; i<m; ++i){
        int a, b, c;
        cin >> a >> b >> c;
        if(a == 0 || b == 0){
            if(1 <= a + b && a + b <= k){
                cout << "overfuro" << endl;
                return 0;
            }
        }
        edges[a].push_back(Edge(b, c, edges[b].size()));
        edges[b].push_back(Edge(a, c, edges[a].size()-1));
    }

    vector<vector<Edge> > edges2;
    int flow = maxFlow(edges, source, sink, edges2);
    vector<bool> check(n+k+2, false);
    queue<int> q;
    check[source] = true;
    q.push(source);
    while(!q.empty()){
        int pos = q.front();
        q.pop();
        for(const Edge& e : edges2[pos]){
            if(e.cap > 0 && !check[e.to]){
                check[e.to] = true;
                q.push(e.to);
            }
        }
    }

    vector<int> addFlow(n+k+2);
    for(int i=0; i<n+k+2; ++i){
        vector<vector<Edge> > edges3;
        if(check[i])
            addFlow[i] = maxFlow(edges2, source, i, edges3);
        else
            addFlow[i] = maxFlow(edges2, i, sink, edges3);
    }

    int ans = flow;
    for(int i=0; i<n+k+2; ++i){
        for(const Edge& e : edges2[i]){
            if(check[i] ^ check[e.to])
                ans = max(ans, flow + min(addFlow[i], addFlow[e.to]));
        }
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3312
final_rank: 2