#include <bits/stdc++.h>
using namespace std;
const int INF = 1e5;
const int N = 2010;
int rec[N], cr;
int d[N], vis[N], q[N], h, t;
int frS[N], frT[N];
int n, S, T;
int ex[N], ey[N], g[N];
int f[N][N];
int cut[N];
int ans;
struct node {
  int to, next, c, from;
};
node edge[N * 2];
int graph[N], tot;
vector<int> vec[N];
void addedge(int i, int x, int y, int c) {
  edge[i].to = y;
  edge[i].next = graph[x];
  graph[x] = i;
  edge[i].c = c;
  edge[i].from = x;
}
void add(int x, int y, int c) {
  tot++;
  addedge(tot, x, y, c);
  tot++;
  addedge(tot, y, x, 0);
}
bool bfs() {
  int i, x, y;
  for (i = 1; i <= n; i++) d[i] = -1;
  d[S] = 0;
  h = t = 0;
  q[++t] = S;
  while (h < t) {
    x = q[++h];
    for (i = graph[x]; i; i = edge[i].next) {
      y = edge[i].to;
      if (edge[i].c && d[y] == -1) {
        d[y] = d[x] + 1;
        q[++t] = y;
      }
    }
  }
  return d[T] != -1;
}
int find(int x, int low) {
  int i, y;
  int now, totflow = 0;
  if (x == T || !low) return low;
  for (i = graph[x]; i; i = edge[i].next) {
    y = edge[i].to;
    if (edge[i].c && d[y] == d[x] + 1) {
      now = find(y, min(low, edge[i].c));
      low -= now;
      totflow += now;
      edge[i].c -= now;
      edge[i ^ 1].c += now;
      if (!low) return totflow;
    }
  }
  if (low) d[x] = -1;
  return totflow;
}
void maxflow() {
  while (bfs()) ans += find(S, INF);
}
void bfs1() {
  int i, x, y;
  for (i = 1; i <= n; i++) vis[i] = 0;
  vis[S] = 1;
  h = t = 0;
  q[++t] = S;
  frS[S] = 0;
  while (h < t) {
    x = q[++h];
    for (i = 0; i <= (int)vec[x].size() - 1; i++) {
      y = vec[x][i];
      if (vis[y]) continue;
      vis[y] = 1;
      frS[y] = x;
      q[++t] = y;
    }
  }
}
void bfs2() {
  int i, x, y;
  for (i = 1; i <= n; i++) vis[i] = 0;
  vis[T] = 1;
  h = t = 0;
  q[++t] = T;
  frT[T] = 0;
  while (h < t) {
    x = q[++h];
    for (i = 0; i <= (int)vec[x].size() - 1; i++) {
      y = vec[x][i];
      if (vis[y]) continue;
      vis[y] = 1;
      frT[y] = x;
      q[++t] = y;
    }
  }
}
int main() {
  int m, i, x, j;
  tot = 1;
  scanf("%d%d%d%d", &n, &m, &S, &T);
  for (i = 1; i <= m; i++) scanf("%d%d%d", &ex[i], &ey[i], &g[i]);
  for (i = 1; i <= m; i++) {
    if (g[i]) {
      add(ex[i], ey[i], 1);
      add(ey[i], ex[i], INF);
    } else
      add(ex[i], ey[i], INF);
  }
  maxflow();
  bfs();
  for (i = 1; i <= m; i++)
    if (d[ex[i]] >= 0 && d[ey[i]] == -1) {
      cut[i] = 1;
    }
  for (i = 1; i <= m; i++)
    if (g[i]) vec[ex[i]].push_back(ey[i]);
  bfs1();
  for (i = 1; i <= n; i++) vec[i].clear();
  for (i = 1; i <= m; i++)
    if (g[i]) vec[ey[i]].push_back(ex[i]);
  bfs2();
  for (i = 1; i <= m; i++) {
    if (!g[i]) continue;
    f[ex[i]][ey[i]]++;
    x = ex[i];
    while (frS[x]) f[frS[x]][x]++, x = frS[x];
    x = ey[i];
    while (frT[x]) f[x][frT[x]]++, x = frT[x];
  }
  printf("%d\n", ans);
  for (i = 1; i <= m; i++) {
    if (cut[i])
      printf("%d %d\n", f[ex[i]][ey[i]], f[ex[i]][ey[i]]);
    else
      printf("%d %d\n", f[ex[i]][ey[i]], f[ex[i]][ey[i]] + 1);
  }
}
