#include <bits/stdc++.h>
using namespace std;
/*struct Dinic
{
struct Edge
{
int from, to, cap, ult;
};
int n;
vector<int> dist, last;
vector<Edge> edges;
queue<int> coada;
Dinic(int cn)
{
n = cn;
last.assign(n + 1, -1);
}
void baga(int from, int to, int cap)
{
edges.push_back({from, to, cap, last[from]});
last[from] = edges.size() - 1;
edges.push_back({to, from, 0, last[to]});
last[to] = edges.size() - 1;
}
bool bfs(int source, int sink)
{
dist.assign(n + 1, 1e9);
coada.push(source);
dist[source] = 0;
while(!coada.empty())
{
int x = coada.front();
coada.pop();
for(int y = last[x]; y != -1; y = edges[y].ult)
{
if(edges[y].cap > 0 && dist[edges[y].to] == 1e9)
{
dist[edges[y].to] = dist[x] + 1;
coada.push(edges[y].to);
}
}
}
return dist[sink] != 1e9;
}
int dfs(int source, int sink, int flow)
{
if(source == sink)
return flow;
int ans = 0;
for(int y = last[source]; y != -1; y = edges[y].ult)
{
if(edges[y].cap > 0 && dist[edges[y].to] == dist[edges[y].from] + 1)
{
int trimis = dfs(edges[y].to, sink, min(flow, edges[y].cap));
ans += trimis;
flow -= trimis;
edges[y].cap -= trimis;
edges[y ^ 1].cap += trimis;
}
}
return ans;
}
int MaxFlow(int source, int sink)
{
int ans = 0;
while(bfs(source, sink))
{
int x;
do
{
int x = dfs(source, sink, 1e9);
ans += x;
}
while(x > 0);
}
return ans;
}
};
*/
struct Dinic
{
int n;
struct Edge
{
int from, to, cap, ult;
};
vector<Edge> edges;
vector<int> dist, last;
queue<int> q;
Dinic(int sz)
{
n = sz;
dist.resize(n + 1, 0);
last.resize(n + 1, -1);
}
void baga(int from, int to, int cap)
{
edges.push_back({from, to, cap, last[from]});
last[from] = edges.size() - 1;
edges.push_back({to, from, 0, last[to]});
last[to] = edges.size() - 1;
}
bool bfs(int source, int sink)
{
q.push(source);
dist.assign(n + 1, 1e9);
dist[source] = 0;
while(!q.empty())
{
int nod = q.front();
q.pop();
for(int i = last[nod]; i != -1; i = edges[i].ult)
{
if(edges[i].cap > 0 && dist[edges[i].to] == 1e9)
{
dist[edges[i].to] = dist[nod] + 1;
q.push(edges[i].to);
}
}
}
return dist[sink] != 1e9;
}
int dfs(int nod, int sink, int pushed)
{
if(nod == sink)
return pushed;
int ans = 0;
for(int i = last[nod]; i != -1; i = edges[i].ult)
{
if(edges[i].cap > 0 && dist[edges[i].to] > dist[nod] && pushed > 0)
{
int x = dfs(edges[i].to, sink, min(pushed, edges[i].cap));
edges[i].cap -= x;
edges[i ^ 1].cap += x;
ans += x;
pushed -= x;
}
}
return ans;
}
int MaxFlow(int source, int sink)
{
int ans = 0;
while(bfs(source, sink))
{
int x;
do
{
x = dfs(source, sink, 1e9);
ans += x;
}
while(x)
}
return ans;
}
};
int main()
{
ifstream cin("maxflow.in");
ofstream cout("maxflow.out");
int n, m;
cin >> n >> m;
Dinic flux(n);
for(int i = 1; i <= m; i ++)
{
int a, b, c;
cin >> a >> b >> c;
flux.baga(a, b, c);
}
cout << flux.MaxFlow(1, n);
}