1 program rrr(input,output);
2 const
3 inf=123456789;
4 type
5 pointer=^nodetype;
6 nodetype=record
7 t,c:longint;
8 next,rev:pointer;
9 end;
10 var
11 a,cur:array[0..10010]of pointer;
12 d,q:array[0..10010]of longint;
13 p:pointer;
14 i,n,m,s,t,c,x,y,ans:longint;
15 function min(a,b:longint):longint;
16 begin
17 if a<b then exit(a) else exit(b);
18 end;
19 procedure add(x,y,c:longint);
20 begin
21 new(p);p^.t:=y;p^.c:=c;p^.next:=a[x];a[x]:=p;
22 end;
23 procedure bfs;
24 var
25 h,t:longint;
26 begin
27 for i:=1 to n do d[i]:=-1;
28 h:=1;t:=1;q[1]:=s;d[s]:=0;
29 while h<=t do
30 begin
31 p:=a[q[h]];
32 while p<>nil do
33 begin
34 if (d[p^.t]=-1) and (p^.c>0) then
35 begin
36 d[p^.t]:=d[q[h]]+1;
37 inc(t);q[t]:=p^.t;
38 end;
39 p:=p^.next;
40 end;
41 inc(h);
42 end;
43 end;
44 function dfs(k,f:longint):longint;
45 var
46 ans,r:longint;
47 p:pointer;
48 begin
49 if (k=t) or (f=0) then exit(f);
50 ans:=0;
51 p:=cur[k];
52 while p<>nil do
53 begin
54 if (d[p^.t]=d[k]+1) and (p^.c>0) then
55 begin
56 r:=dfs(p^.t,min(f,p^.c));
57 p^.c:=p^.c-r;
58 p^.rev^.c:=p^.rev^.c+r;
59 f:=f-r;
60 ans:=ans+r;
61 if f=0 then break;
62 end;
63 p:=p^.next;
64 cur[k]:=p;
65 end;
66 if f>0 then d[k]:=-1;
67 exit(ans);
68 end;
69 begin
70 assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
71 readln(n,m,s,t);
72 for i:=1 to n do a[i]:=nil;
73 for i:=1 to m do
74 begin
75 readln(x,y,c);
76 if x=y then continue;
77 add(x,y,c);add(y,x,0);
78 a[x]^.rev:=a[y];a[y]^.rev:=a[x];
79 end;
80 ans:=0;
81 while true do
82 begin
83 bfs;
84 if d[t]=-1 then break;
85 for i:=1 to n do cur[i]:=a[i];
86 ans:=ans+dfs(s,inf);
87 end;
88 write(ans);
89 close(input);close(output);
90 end.