#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ull unsigned long long
#define ld long double
#define chad char
#define mod 1'000'000'007
#define dim 100005
#define lim 1000000
#define BASE 31
#define NMAX 21'005
#define FOR(i,a,b) for(int i=(a); i<=(b); i++)
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define nr_biti __builtin_popcount
using namespace __gnu_pbds;
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
int t=1;
int n,m;
vector<int> g[1005];
int cap[1005][1005];
int ans;
int dist[1005];
int fq[1005];
void bfs()
{
for(int i=1; i<=n; i++)
{
dist[i]=0;
fq[i]=0;
}
dist[1]=1;
queue<int> q;
q.push(1);
while(q.size())
{
int nod=q.front();
q.pop();
for(auto it:g[nod])
{
if(cap[nod][it]>0 && dist[it]==0)
{
dist[it]=1+dist[nod];
q.push(it);
}
}
}
}
int dfs(int nod,int mn)
{
if(nod==n || mn==0)
return mn;
while(fq[nod]<(int)g[nod].size())
{
int vec=g[nod][fq[nod]];
if(dist[vec]==dist[nod]+1 && cap[nod][vec]>0)
{
int u=dfs(vec,min(mn,cap[nod][vec]));
if(u)
{
cap[nod][vec]-=u;
cap[vec][nod]+=u;
return u;
}
else
fq[nod]++;
}
else
fq[nod]++;
}
return 0;
}
bool flux()
{
bfs();
if(dist[n]==0)
return 0;
int add=0;
for(;;)
{
int u=dfs(1,INT_MAX);
if(u)
add+=u;
else
break;
}
ans+=add;
return add!=0;
}
void solve()
{
fin >> n >> m;
for(int i=1; i<=m; i++)
{
int x,y,c;
fin >> x >> y >> c;
cap[x][y]=c;
// cap[y][x]=0
g[x].pb(y);
g[y].pb(x);
}
while(flux());
fout << ans;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
//cin >> t;
while(t--)
solve();
return 0;
}