1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cstring>
5 #include <queue>
6 #include <stack>
7 #define rep(i,l,r) for(int i=l; i<=r; i++)
8 #define clr(x,y) memset(x,y,sizeof(x))
9 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
10 using namespace std;
11 const int INF = 0x7fffffff;
12 const int maxn = 4010;
13 struct Edge{
14 Edge *pre,*rev; int from,to; int cost;
15 }edge[120010];
16 Edge *last[maxn],*cur[maxn],*pt;
17 int n,m,x,y,z,S,T,ans=0,dfsclock=0,scc=0,d[maxn],dfn[maxn],low[maxn],belong[maxn];
18 bool isin[maxn];
19 queue <int> q;
20 stack <int> s;
21 inline int read(){
22 int ans = 0, f = 1;
23 char c = getchar();
24 while (!isdigit(c)){
25 if (c == ‘-‘) f = -1;
26 c = getchar();
27 }
28 while (isdigit(c)){
29 ans = ans * 10 + c - ‘0‘;
30 c = getchar();
31 }
32 return ans * f;
33 }
34 inline void addedge(int x,int y,int z){
35 pt->pre = last[x]; pt->from = x; pt->to = y; pt->cost = z; last[x] = pt++;
36 }
37 inline void add(int x,int y,int z){
38 addedge(x,y,z); addedge(y,x,0); last[x]->rev = last[y]; last[y]->rev = last[x];
39 }
40 bool bfs(){
41 while (!q.empty()) q.pop();
42 clr(d,-1); d[S] = 0; q.push(S);
43 while (!q.empty()){
44 int now = q.front(); q.pop();
45 travel(now){
46 if (d[p->to] == -1 && p->cost > 0){
47 d[p->to] = d[now] + 1;
48 q.push(p->to);
49 if (p->to == T) return 1;
50 }
51 }
52 }
53 return 0;
54 }
55 int dfs(int x,int flow){
56 if (x == T || (!flow)) return flow; int w = 0;
57 for(Edge *p=cur[x]; p && w < flow; p=p->pre){
58 if (d[p->to] == d[x] + 1 && p->cost > 0){
59 int delta = dfs(p->to,min(p->cost,flow-w));
60 p->cost -= delta;
61 p->rev->cost += delta;
62 w += delta;
63 if (p->cost) cur[x] = p;
64 }
65 }
66 if (w < flow) d[x] = -1;
67 return w;
68 }
69 void tarjan(int x){
70 dfn[x] = low[x] = ++dfsclock;
71 isin[x] = 1; s.push(x);
72 travel(x) if (p->cost){
73 if (!dfn[p->to]){
74 tarjan(p->to);
75 low[x] = min(low[x],low[p->to]);
76 }
77 else if (isin[p->to]) low[x] = min(low[x],dfn[p->to]);
78 }
79 if (low[x] == dfn[x]){
80 scc++;
81 while (s.top() != x){
82 isin[s.top()] = 0;
83 belong[s.top()] = scc;
84 s.pop();
85 }
86 isin[x] = 0; belong[x] = scc; s.pop();
87 }
88 }
89 int main(){
90 n = read(); m = read(); S = read(); T = read();
91 clr(last,0); pt = edge;
92 rep(i,1,m){
93 x = read(); y = read(); z = read();
94 add(x,y,z);
95 }
96 while (bfs()){
97 rep(i,1,n) cur[i] = last[i];
98 dfs(S,INF);
99 }
100 clr(dfn,0); clr(isin,0); rep(i,1,n) if (!dfn[i]) tarjan(i);
101 for (Edge *p=edge; p<=pt-2; p += 2){
102 if (p->cost) printf("0 0\n");
103 else{
104 if (belong[p->from] != belong[p->to]) printf("1 ");
105 else printf("0 ");
106 if (belong[p->from] == belong[S] && belong[p->to] == belong[T])
107 printf("1\n"); else printf("0\n");
108 }
109 }
110 return 0;
111 }