#include<stdio.h>
#include<string.h>
#define N_MAX 1024
#define M_MAX 1024*16
int n, m, sursa, dest, flux;
int list[M_MAX][2], start[N_MAX], stop[N_MAX], poz=0; //pentru memorat muchiile
int cap[N_MAX][N_MAX]; //pentru memorat capacitatile
int best[N_MAX], last[N_MAX], cd[M_MAX*16];
char sel[N_MAX];
void add(int a, int b, int c)
{
cap[a][b]=c;
++poz;
list[poz][0]=b;
list[poz][1]=0; //NULL
if (!stop[a])
start[a]=stop[a]=poz;
else
{
list[stop[a]][1]=poz;
stop[a]=poz;
}
}
inline int min(int a, int b)
{
if (a<=b) return a;
return b;
}
int drum_crestere()
{
int i, nr, p, ca;
nr=1;
cd[1]=sursa;
memset(best, 0, sizeof(best));
memset(last, 0, sizeof(last));
for (i=1; i<=nr; i++)
{
p=start[cd[i]];
while(p)
{
if ((list[p][0]!=last[cd[i]])&&(cap[ cd[i] ][ list[p][0] ]>0))
{
ca=best[ cd[i] ];
if (cd[i]==sursa)
ca=cap[ cd[i] ][ list[p][0] ];
ca=min(ca, cap[ cd[i] ][ list[p][0] ] );
if (best[ list[p][0] ] < ca )
{
best[ list[p][0] ] = ca;
last[ list[p][0] ] = cd[i];
if (!sel[ list[p][0] ])
{
sel[ list[p][0] ]=1;
++nr;
cd[nr]=list[p][0];
}
}
}
p=list[p][1];
}
sel[cd[i]]=0;
}
p=dest;
while (p>sursa)
{
cap[ last[p]][ p ]-=best[dest];
cap[ p ][ last[p] ]+=best[dest];
p=last[p];
}
return best[dest];
}
int main()
{
freopen("flux_alg.in", "r", stdin);
freopen("flux_alg.out", "w", stdout);
int i, a, b, c, f=1;
scanf("%d %d", &n, &m);
sursa=1;
dest=n;
//scanf("%d %d %d %d", &n, &m, &sursa, &dest);
for (i=1; i<=m; i++)
{
scanf("%d %d %d", &a, &b, &c);
add(a, b, c);
add(b, a, 0); //muchia speciala va avea initial capacitatea 0
}
while(f)
{
f=0;
f=drum_crestere();
flux+=f;
}
printf("%d", flux);
fclose(stdout);
return 0;
}