#include <bits/stdc++.h>
using namespace std;
const int N(200009);
struct LnkNode {
  int v, w, nxt;
} edge[N << 3];
int etot = 1, fst[N], cur[N];
void addedge_(int u, int v, int w) {
  ++etot;
  edge[etot].v = v;
  edge[etot].w = w;
  edge[etot].nxt = fst[u];
  fst[u] = etot;
}
void addedge(int u, int v, int w) { addedge_(u, v, w), addedge_(v, u, 0); }
void deledge_(int u) { fst[u] = edge[fst[u]].nxt; }
int n, m, r, b, x[N], y[N], cntx[N], cnty[N], x_[N], y_[N], limx[N], limy[N],
    dt[N], mf, d[N], q[N], Head, Tail;
bool bfs(int s, int t) {
  memset(d + 1, 0x3f, ((n << 1) + 4) << 2);
  Head = Tail = 0;
  d[q[Tail++] = s] = 0;
  while (Head ^ Tail) {
    int &x = q[Head++];
    for (int i = fst[x]; i; i = edge[i].nxt) {
      int &y = edge[i].v, &w = edge[i].w;
      if (w && d[y] > d[x] + 1) d[q[Tail++] = y] = d[x] + 1;
    }
  }
  return d[t] != 0x3f3f3f3f;
}
int dfs(int x, int t, int f) {
  if (x == t) return f;
  int r = f;
  for (int &i = cur[x]; i; i = edge[i].nxt) {
    int &y = edge[i].v, &w = edge[i].w;
    if (w && d[y] == d[x] + 1) {
      int k = dfs(y, t, min(r, w));
      w -= k, edge[i ^ 1].w += k;
      if (!(r -= k)) break;
    }
  }
  return f - r;
}
char res[N];
int main() {
  scanf("%d%d%d%d", &n, &m, &r, &b);
  for (int i = 1; i <= n; ++i) scanf("%d%d", x + i, y + i);
  memcpy(x_ + 1, x + 1, n << 2);
  sort(x_ + 1, x_ + 1 + n);
  memcpy(y_ + 1, y + 1, n << 2);
  sort(y_ + 1, y_ + 1 + n);
  for (int i = 1; i <= n; ++i) {
    ++cntx[x[i] = lower_bound(x_ + 1, x_ + 1 + n, x[i]) - x_];
    ++cnty[y[i] = lower_bound(y_ + 1, y_ + 1 + n, y[i]) - y_];
    addedge(x[i], n + y[i], 1);
  }
  for (int i = 1; i <= n; ++i) limx[i] = limy[i] = n;
  int t, l, d;
  while (m--) {
    scanf("%d%d%d", &t, &l, &d);
    switch (t) {
      case 1: {
        int t_ = lower_bound(x_ + 1, x_ + 1 + n, l) - x_;
        if (t_ <= n && x_[t_] == l && limx[t_] > d) limx[t_] = d;
        break;
      }
      case 2: {
        int t_ = lower_bound(y_ + 1, y_ + 1 + n, l) - y_;
        if (t_ <= n && y_[t_] == l && limy[t_] > d) limy[t_] = d;
        break;
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (cntx[i]) {
      int lb = (cntx[i] > limx[i]
                    ? (((cntx[i] - limx[i]) >> 1) + ((cntx[i] - limx[i]) & 1))
                    : 0),
          rb = (cntx[i] + limx[i]) >> 1;
      if (lb > rb) return puts("-1"), 0;
      dt[(n << 1) + 1] -= lb, dt[i] += lb, addedge((n << 1) + 1, i, rb - lb);
    }
    if (cnty[i]) {
      int lb = (cnty[i] > limy[i]
                    ? (((cnty[i] - limy[i]) >> 1) + ((cnty[i] - limy[i]) & 1))
                    : 0),
          rb = (cnty[i] + limy[i]) >> 1;
      if (lb > rb) return puts("-1"), 0;
      dt[n + i] -= lb, dt[(n << 1) + 2] += lb,
          addedge(n + i, (n << 1) + 2, rb - lb);
    }
  }
  for (int i = 1; i <= (n << 1) + 2; ++i) {
    if (dt[i] > 0)
      addedge((n << 1) + 3, i, dt[i]);
    else if (dt[i] < 0)
      addedge(i, (n << 1) + 4, -dt[i]);
  }
  addedge((n << 1) + 2, (n << 1) + 1, 0x7fffffff);
  int f;
  while (bfs((n << 1) + 3, (n << 1) + 4)) {
    memcpy(cur + 1, fst + 1, ((n << 1) + 4) << 2);
    while (dfs((n << 1) + 3, (n << 1) + 4, 0x7fffffff))
      ;
  }
  for (int i = fst[(n << 1) + 3]; i; i = edge[i].nxt)
    if (edge[i].w) return puts("-1"), 0;
  mf += edge[etot].w;
  deledge_((n << 1) + 1), deledge_((n << 1) + 2);
  while (bfs((n << 1) + 1, (n << 1) + 2)) {
    memcpy(cur + 1, fst + 1, ((n << 1) + 4) << 2);
    while ((f = dfs((n << 1) + 1, (n << 1) + 2, 0x7fffffff))) mf += f;
  }
  printf("%lld\n", (long long)mf * min(r, b) + (long long)(n - mf) * max(r, b));
  for (int i = 1; i <= n; ++i) putchar((edge[i << 1].w ^ (r < b)) ? 'r' : 'b');
  putchar(10);
  return 0;
}
