#include<bits/stdc++.h>
#define pb push_back
#define Nmax 100100
using namespace std;
typedef long long ll;
struct Edge {
int u, v;
ll cap, flow;
Edge() {}
Edge(int u, int v, ll cap): u(u), v(v), cap(cap), flow(0) {}
};
int N;
vector<Edge> E;
vector<int> g[Nmax]; //edge indices
vector<int> d, pt;
void AddEdge(int u, int v, ll cap) {
if (u != v) {
E.pb(Edge(u, v, cap));
g[u].pb(E.size() - 1);
E.pb(Edge(v, u, 0));
g[v].pb(E.size() - 1);
}
}
int BFS(int S, int T) {
queue<int> q;
q.push(S);
fill(d.begin(), d.end(), N + 1);
d[S] = 0;
while(!q.empty()) {
int u = q.front(); q.pop();
if (u == T) break;
for (int k: g[u]) {
Edge &e = E[k];
if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
d[e.v] = d[e.u] + 1;
q.push(e.v);
}
}
}
return d[T] != N + 1;
}
ll DFS(int u, int T, ll flow = -1) {
if (u == T || flow == 0) return flow;
for (int i = pt[u]; i < g[u].size(); ++i) {
Edge &e = E[g[u][i]];
Edge &oe = E[g[u][i]^1];
if (d[e.v] == d[e.u] + 1) {
ll amt = e.cap - e.flow;
if (flow != -1 && amt > flow) amt = flow;
if (ll pushed = DFS(e.v, T, amt)) {
e.flow += pushed;
oe.flow -= pushed;
return pushed;
}
}
}
return 0;
}
ll MaxFlow(int S, int T) {
ll total = 0;
pt.resize(N);
d.resize(N);
while (BFS(S, T)) {
fill(pt.begin(), pt.end(), 0);
while (ll flow = DFS(S, T)) {
total += flow;
}
}
return total;
}
int main() {
freopen("maxflow.in","r",stdin);
freopen("maxflow.out","w",stdout);
int E;
scanf("%d%d", &N, &E);
for(int i = 0; i < E; ++i) {
int u, v;
ll cap;
scanf("%d%d%lld", &u, &v, &cap);
AddEdge(u - 1, v - 1, cap);
AddEdge(v - 1, u - 1, 0);
}
printf("%lld\n", MaxFlow(0, N - 1));
return 0;
}