#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int M = 5000;
struct Edge {
  int v, c, nxt;
} e[20010];
int tot = 1;
int first[210];
void build(int u, int v, int c) {
  e[++tot] = (Edge){v, c, first[u]};
  first[u] = tot;
  return;
}
void adde(int u, int v, int c) {
  build(u, v, c);
  build(v, u, 0);
  return;
}
int S, T;
int dep[210];
queue<int> q;
bool bfs() {
  memset(dep, 0, sizeof(dep));
  q.push(S);
  dep[S] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = first[u]; i; i = e[i].nxt)
      if (e[i].c && !dep[e[i].v]) {
        dep[e[i].v] = dep[u] + 1;
        q.push(e[i].v);
      }
  }
  if (dep[T]) return true;
  return false;
}
int cur[110];
int dfs(int u, int flow) {
  if (u == T) return flow;
  int used = 0;
  for (int &i = cur[u]; i; i = e[i].nxt)
    if (e[i].c && dep[u] + 1 == dep[e[i].v]) {
      int d = dfs(e[i].v, min(flow - used, e[i].c));
      if (d) {
        e[i].c -= d;
        e[i ^ 1].c += d;
        used += d;
      }
    }
  return used;
}
int n, m;
int dinic() {
  int ans = 0;
  while (bfs()) {
    for (int i = 1; i <= n + 2; i++) cur[i] = first[i];
    int d;
    while (d = dfs(S, INF)) ans += d;
  }
  return ans;
}
int U[1010], V[1010], G[1010];
int id[1010];
bool v[210];
int d[210];
int main() {
  int s, t;
  scanf("%d %d %d %d", &n, &m, &s, &t);
  S = s;
  T = t;
  for (int i = 1; i <= m; i++) {
    scanf("%d %d %d", &U[i], &V[i], &G[i]);
    if (!G[i])
      adde(U[i], V[i], INF);
    else {
      adde(U[i], V[i], 1);
      adde(V[i], U[i], INF);
    }
  }
  int ans = dinic();
  printf("%d\n", ans);
  for (int i = 1; i <= n; i++)
    if (!dep[i]) v[i] = true;
  memset(first, 0, sizeof(first));
  tot = 1;
  S = n + 1;
  T = n + 2;
  for (int i = 1; i <= m; i++) {
    if (!G[i]) continue;
    id[i] = tot + 1;
    adde(U[i], V[i], M);
    d[V[i]]++;
    d[U[i]]--;
  }
  adde(t, s, INF);
  for (int i = 1; i <= n; i++)
    if (d[i] > 0)
      adde(S, i, d[i]);
    else
      adde(i, T, -d[i]);
  dinic();
  for (int i = 1; i <= m; i++) {
    if (!G[i])
      printf("0 1\n");
    else {
      int f = M - e[id[i]].c + 1;
      if (!v[U[i]] && v[V[i]])
        printf("%d %d\n", f, f);
      else
        printf("%d %d\n", f, f + 1);
    }
  }
  return 0;
}
