#include <bits/stdc++.h>
using namespace std;
const int MAX = 2005;
int from[MAX], to[MAX], cap[MAX], ptr[MAX], prv[MAX], head[MAX], g[MAX],
    ansf[MAX], ansc[MAX], ecnt;
void add_edge(int u, int v, int uv, int vu, int gg) {
  from[ecnt] = u, to[ecnt] = v, cap[ecnt] = uv, g[ecnt] = gg,
  prv[ecnt] = head[u];
  head[u] = ecnt++;
  from[ecnt] = v, to[ecnt] = u, cap[ecnt] = vu, g[ecnt] = -1,
  prv[ecnt] = head[v];
  head[v] = ecnt++;
}
int d[MAX], q[MAX], par[MAX];
bool bfs(int source, int sink) {
  memset(d, 63, sizeof(d));
  int h = 0, t = 0;
  d[sink] = 0;
  q[t++] = sink;
  while (h < t) {
    int v = q[h++];
    for (int i = head[v]; i != -1; i = prv[i])
      if (cap[i ^ 1] > 0 && d[to[i]] > d[v] + 1) {
        d[to[i]] = d[v] + 1;
        q[t++] = to[i];
      }
  }
  return (d[source] < MAX);
}
int dfs_f(int v, int sink, int flow = 2147483647) {
  if (v == sink) return flow;
  int ans = 0;
  for (; ptr[v] != -1; ptr[v] = prv[ptr[v]])
    if (cap[ptr[v]] && d[v] == d[to[ptr[v]]] + 1) {
      int x = dfs_f(to[ptr[v]], sink, min(flow, cap[ptr[v]]));
      flow -= x;
      ans += x;
      cap[ptr[v]] -= x;
      cap[ptr[v] ^ 1] += x;
      if (flow == 0) break;
    }
  return ans;
}
long long max_flow(int source, int sink) {
  long long ans = 0;
  while (bfs(source, sink)) {
    memcpy(ptr, head, sizeof(head));
    ans += dfs_f(source, sink);
  }
  return ans;
}
bool mark[MAX];
void dfs(int v) {
  mark[v] = true;
  for (int i = head[v]; i != -1; i = prv[i])
    if (!mark[to[i]] && g[i] == 1) {
      par[to[i]] = i;
      dfs(to[i]);
    }
}
bool inc(int x, int y) {
  memset(mark, 0, sizeof(mark));
  dfs(x);
  if (!mark[y]) return false;
  while (y != x) {
    ansf[par[y]]++;
    y = from[par[y]];
  }
  return true;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  memset(head, -1, sizeof(head));
  int n, m, s, t;
  cin >> n >> m >> s >> t;
  s--, t--;
  for (int i = 0; i < m; i++) {
    int u, v, gg;
    cin >> u >> v >> gg;
    u--;
    v--;
    if (gg)
      add_edge(u, v, 1, MAX, gg);
    else
      add_edge(u, v, MAX, 0, gg);
  }
  int ans = max_flow(s, t);
  for (int i = 0; i < 2 * m; i += 2)
    if (g[i] == 1) {
      ansf[i]++;
      if (!inc(to[i], from[i])) {
        inc(s, from[i]);
        inc(to[i], t);
      }
    }
  for (int i = 0; i < 2 * m; i += 2)
    if (g[i] == 1) {
      if (d[from[i]] > MAX && d[to[i]] < MAX)
        ansc[i] = ansf[i];
      else
        ansc[i] = ansf[i] + 1;
    } else
      ansc[i] = 1;
  cout << ans << "\n";
  for (int i = 0; i < 2 * m; i += 2) cout << ansf[i] << " " << ansc[i] << "\n";
  return 0;
}
