#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
const ll INF = 9e18;
class edge{
public:
int to,rev;
ll c;
//u->to 的反向边 to->u 是 adj[to][rev]
edge(int _to,int _rev,ll _c):to(_to),rev(_rev),c(_c){};
};
void solve(){
int n,m,s,t;
cin >> n >> m >> s >> t;
vector<vector<edge>> adj(n+1);
for (int i=0;i<m;i++){
int u,v;
ll c;
cin >> u >> v >> c;
adj[u].emplace_back(v,0,c);
adj[v].emplace_back(u,0,0);
adj[u].back().rev = adj[v].size()-1;
adj[v].back().rev = adj[u].size()-1;
}
//不需要初始化,每轮都会重置
vector<int> cur,level;
auto bfs = [&](){
level = vector<int>(n+1,-1);
queue<int> q;
q.push(s);
level[s] = 0;
while (!q.empty()){
int u = q.front();
q.pop();
for (auto& [v,rev,c]:adj[u]){
if (level[v]!=-1 || c==0) continue;
level[v] = level[u]+1;
q.push(v);
if (v==t) return true;
}
}
return false;
};
function<ll(int,ll)> dfs = [&](int u,ll mf){
if (u==t) return mf;
ll sum = 0;
int len = adj[u].size();
//当前弧优化
for (int& i=cur[u];i<len;i++){
auto& [v,rev,c] = adj[u][i];
if (level[v]!=level[u]+1 || c<=0) continue;
ll f = dfs(v,min(mf,c));
c -= f;
adj[v][rev].c += f;
sum += f;
mf -= f;
//剩余流量优化
if (mf==0) break;
}
//残枝优化
if (sum==0){
level[u] = -1;
}
return sum;
};
ll res = 0;
while (bfs()){
cur = vector<int>(n+1,0);
res += dfs(s,INF);
}
cout << res << '\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t = 1;
// cin >> t;
while (t--) solve();
return 0;
}