#include <queue>
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define DBG printf("this is a input\n")
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a % b);
}
ll lcm(ll a, ll b) {
return a / gcd(a, b) * b;
}
queue<int>q;
int n, m, cnt, ans, st ,ed;
int head[205],level[205];
struct e
{
int to;
int next;
int c;
}edge[205*2];
void add(int f ,int t, int w)
{
edge[cnt].to = t;
edge[cnt].c = w;
edge[cnt].next = head[f];
head[f] = cnt ++;
}
bool DinicBfs(int s, int e)
{
mem(level,0);
while(!q.empty())
q.pop();
q.push(s);
level[s] = 1;
while(!q.empty())
{
int root = q.front();
q.pop();
for(int i = head[root] ; i != 0 ; i = edge[i].next)
{
int v = edge[i].to;
if(!level[v] && edge[i].c > 0)
{
level[v] = level[root] + 1;
q.push(v);
}
}
}
return level[e] != 0;
}
int DinicDfs(int root, int flow)
{
if(root == ed)
return flow;
int newflow;
for(int i = head[root] ; i != 0 ; i = edge[i].next)
{
if(edge[i].c > 0 && level[edge[i].to] == level[root] + 1 && (newflow = DinicDfs(edge[i].to,min(edge[i].c,flow))))
{
edge[i].c -= newflow;
edge[i^1].c += newflow;
return newflow;
}
}
return 0;
}
void Dinic()
{
ans = 0;
while(DinicBfs(st,ed))
{
while(int add = DinicDfs(1,INF)) {
ans += add;
}
}
}
int main(void)
{
while(scanf("%d %d",&m , &n)!=EOF)
{
mem(head,0);
cnt = 1;
for(int i = 1 ; i <= m ; i ++)
{
int f ,t ,w;
scanf("%d %d %d",&f ,&t, &w);
add(f,t,w);
add(t,f,0);
}
st = 1;
ed = n;
Dinic();
printf("%d\n",ans);
}
}