#include<bits/stdc++.h>
using namespace std;
#define ll long long
bool bfs(int **residualcapacity,int source,int sink,int n,int *parent)
{
bool visited[n];
memset(visited,0,sizeof(visited));
queue que;
//mark source as visited
visited[source]=true;
que.push(source);
bool foundaugumentedpath=false;
while(!que.empty())
{
int u=que.front();
que.pop();
for(int v=0;v<n;v++)
{
if(visited[v]==false and residualcapacity[u][v]>0)
{
parent[v]=u;
visited[v]=true;
que.push(v);
if(v==sink)
{
foundaugumentedpath=true;
break;
}
}
}
}
return foundaugumentedpath;
}
void printaugumentedpaths(vector<vector> augumentedpaths)
{
for(int i=0;i<augumentedpaths.size();i++)
{
for(int j=0;j<augumentedpaths[i].size();j++)
{
cout<<augumentedpaths[i][j]<<",";
}
cout<<endl;
}
}
int maxflow(int **capacity,int source,int sink,int v)
{
int *residualcapacity=new int[v];
for(int i=0;i<v;i++)
{
residualcapacity[i]=new int[v];
}
for(int i=0;i<v;i++)
{
for(int j=0;j<v;j++)
{
residualcapacity[i][j]=capacity[i][j];
}
}
int *parent=new int[1000];
vector<vector<int>> augumentedpaths;
int maxflow=0;
while(bfs(residualcapacity,source,sink,v,parent))
{
vector<int> currentaugumentedpath;
int flow=INT_MAX;
int v=sink;
while(v!=source)
{
currentaugumentedpath.push_back(v);
int u=parent[v];
if(flow>residualcapacity[u][v])
{
flow=residualcapacity[u][v];
}
v=u;
}
currentaugumentedpath.push_back(source);
std::reverse(currentaugumentedpath.begin(),currentaugumentedpath.end());
augumentedpaths.push_back(currentaugumentedpath);
maxflow+=flow;
v=sink;
while(v!=source)
{
int u=parent[v];
residualcapacity[u][v]-=flow;
residualcapacity[v][u]+=flow;
v=u;
}
}
printaugumentedpaths(augumentedpaths);
return maxflow;
}
int main()
{
int v,e;
cin>>v>>e;
//prepare adjacency matrix that denote our graph
int **capacity=new int*[v];
for(int i=0;i<v;i++)
{
capacity[i]=new int[v];
}
for(int i=0;i<e;i++)
{
int u,v,c;
cin>>u>>v>>c;
capacity[u][v]=c;
}
cout<<maxflow(capacity,0,1,v);
}