#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 100;
const int MAXM = 1000;
typedef struct MF {
  int n, m;
  char name;
  vector<int> ghead, flow, back;
  vector<int> id, cap, gto, gnxt;
  queue<int> q;
  void init(int _n, char _name) {
    n = _n;
    name = _name;
    ghead = vector<int>(n, -1);
    flow = vector<int>(n, 0);
    back = vector<int>(n, -1);
  }
  void addedge(int a, int b, int c, int _id) {
    gnxt.push_back(ghead[a]), ghead[a] = m, gto.push_back(b), id.push_back(_id),
                              cap.push_back(c);
    ++m;
    gnxt.push_back(ghead[b]), ghead[b] = m, gto.push_back(a), id.push_back(-1),
                              cap.push_back(0);
    ++m;
  }
  int maxflow(int s, int t) {
    int ret = 0;
    while (true) {
      for (int i = (0); i < (n); ++i) flow[i] = 0, back[i] = -1;
      flow[s] = INT_MAX, back[s] = -2, q.push(s);
      while (!q.empty()) {
        int at = q.front();
        q.pop();
        for (int x = ghead[at]; x != -1; x = gnxt[x]) {
          int to = gto[x];
          if (cap[x] == 0 || flow[to] != 0) continue;
          flow[to] = min(flow[at], cap[x]), back[to] = x ^ 1, q.push(to);
        }
      }
      if (flow[t] == 0) return ret;
      ret += flow[t];
      for (int at = t; at != s; at = gto[back[at]]) {
        cap[back[at]] += flow[t];
        cap[back[at] ^ 1] -= flow[t];
      }
    }
  }
} MF;
int n, m, s, t;
int u[MAXM], v[MAXM], used[MAXM];
MF a, b;
int bal[MAXN];
int f[MAXM], c[MAXM];
void run() {
  scanf("%d%d%d%d", &n, &m, &s, &t);
  --s, --t;
  for (int i = (0); i < (m); ++i)
    scanf("%d%d%d", &u[i], &v[i], &used[i]), --u[i], --v[i];
  a.init(n, 'A');
  for (int i = (0); i < (m); ++i)
    if (!used[i])
      a.addedge(u[i], v[i], m + 1, -1);
    else
      a.addedge(u[i], v[i], 1, i), a.addedge(v[i], u[i], m + 1, -1);
  a.maxflow(s, t);
  for (int i = (0); i < (n); ++i) bal[i] = 0;
  for (int i = (0); i < (m); ++i)
    if (used[i]) --bal[u[i]], ++bal[v[i]];
  b.init(n + 2, 'B');
  int ss = n, tt = n + 1;
  for (int i = (0); i < (m); ++i)
    if (used[i]) b.addedge(u[i], v[i], m, i);
  for (int i = (0); i < (n); ++i)
    if (bal[i] > 0) b.addedge(ss, i, bal[i], -1);
  for (int i = (0); i < (n); ++i)
    if (bal[i] < 0) b.addedge(i, tt, -bal[i], -1);
  b.addedge(t, s, m, -1);
  b.maxflow(ss, tt);
  for (int i = (0); i < (m); ++i) f[i] = used[i];
  for (int i = (0); i < (b.m); ++i)
    if (b.id[i] != -1) f[b.id[i]] += b.cap[i ^ 1];
  for (int i = (0); i < (m); ++i) c[i] = f[i] + 1;
  int nsat = 0;
  for (int i = (0); i < (a.m); ++i)
    if (a.id[i] != -1 && a.flow[a.gto[i ^ 1]] != 0 && a.flow[a.gto[i]] == 0)
      c[a.id[i]] = f[a.id[i]], ++nsat;
  printf("%d\n", nsat);
  for (int i = (0); i < (m); ++i) printf("%d %d\n", f[i], c[i]);
}
int main() {
  run();
  return 0;
}
