#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200000;
const int MAXRN = 100000;
const int MAXM = 1500000;
const int INF = 0x3f3f3f3f;
struct node {
  int v, c;
  node *next, *back;
} Edges[MAXM * 2 + 10], *ecnt = Edges, *adj[MAXN + 10], *yadj[MAXN + 10],
                        *Fa[MAXN + 10];
void addedge(int u, int v, int c) {
  ++ecnt;
  ecnt->v = v;
  ecnt->c = c;
  ecnt->next = adj[u];
  ecnt->back = ecnt + 1;
  adj[u] = ecnt;
  ++ecnt;
  ecnt->v = u;
  ecnt->c = 0;
  ecnt->next = adj[v];
  ecnt->back = ecnt - 1;
  adj[v] = ecnt;
}
int node_cnt, S, T, dis[MAXN + 10], num[MAXN + 10];
void bfs(int u) {
  memset(num, 0, sizeof num);
  memset(dis, 0x3f, sizeof dis);
  queue<int> que;
  que.push(u);
  ++num[dis[u] = node_cnt = 0];
  ++node_cnt;
  while (!que.empty()) {
    u = que.front();
    que.pop();
    for (node *p = adj[u]; p; p = p->next) {
      if (dis[p->v] != INF) continue;
      ++num[dis[p->v] = dis[u] + 1];
      ++node_cnt;
      que.push(p->v);
    }
  }
}
int aug(int u, int augs) {
  if (u == T) return augs;
  int augc = 0, mind = node_cnt;
  for (node *p = adj[u]; p; p = p->next) {
    if (!p->c) continue;
    if (dis[p->v] + 1 == dis[u]) {
      int stre = min(p->c, augs - augc);
      stre = aug(p->v, stre);
      p->c -= stre;
      p->back->c += stre;
      augc += stre;
      if (dis[S] >= node_cnt || augs == augc) break;
    }
    mind = min(mind, dis[p->v]);
  }
  if (!augc) {
    if (!(--num[dis[u]])) dis[S] = node_cnt;
    ++num[dis[u] = mind + 1];
  }
  return augc;
}
int Aug(int s, int t) {
  int u = t, Mins = INF;
  while (u != s) {
    Mins = min(Mins, Fa[u]->c);
    u = Fa[u]->back->v;
  }
  u = t;
  while (u != s) {
    Fa[u]->c -= Mins;
    Fa[u]->back->c += Mins;
    u = Fa[u]->back->v;
  }
  return Mins;
}
int isap(int s, int t, int lim) {
  bfs(t);
  int x = s, ret = 0;
  while (dis[s] < node_cnt) {
    if (x == t) {
      ret += Aug(s, t);
      if (ret >= lim) return ret;
      x = s;
    }
    int ok = 0;
    for (node *p = adj[x]; p; p = p->next) {
      if (p->c && dis[p->v] + 1 == dis[x]) {
        ok = 1;
        Fa[p->v] = p;
        adj[x] = p;
        x = p->v;
        break;
      }
    }
    if (!ok) {
      int mind = node_cnt - 1;
      for (node *p = yadj[x]; p; p = p->next) {
        if (p->c) mind = min(mind, dis[p->v]);
      }
      if (!(--num[dis[x]])) break;
      num[dis[x] = mind + 1]++;
      adj[x] = yadj[x];
      if (x != s) x = Fa[x]->back->v;
    }
  }
  return ret;
}
int inq_x[MAXRN + 10], inq_y[MAXRN + 10], xcnt, ycnt, r, b;
int x[MAXRN + 10], y[MAXRN + 10], limx[MAXRN + 10], limy[MAXRN + 10];
int xs[MAXRN + 10], ys[MAXRN + 10], off[MAXN + 10];
void Del(int id) {
  for (node *p = adj[id]; p; p = p->next) {
    p->c = p->back->c = 0;
  }
}
int main() {
  int n, m, t, l, d;
  scanf("%d%d%d%d", &n, &m, &r, &b);
  int rev = 0;
  if (r < b) {
    swap(r, b);
    rev = 1;
  }
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &x[i], &y[i]);
    inq_x[++xcnt] = x[i];
    inq_y[++ycnt] = y[i];
  }
  sort(inq_x + 1, inq_x + 1 + xcnt);
  sort(inq_y + 1, inq_y + 1 + ycnt);
  int lenx = unique(inq_x + 1, inq_x + 1 + xcnt) - inq_x - 1;
  int leny = unique(inq_y + 1, inq_y + 1 + ycnt) - inq_y - 1;
  int ss = 0, tt = lenx + leny + 1, sus = lenx + leny + 2,
      sut = lenx + leny + 3;
  for (int i = 1; i <= n; i++) {
    x[i] = lower_bound(inq_x + 1, inq_x + 1 + lenx, x[i]) - inq_x;
    y[i] = lower_bound(inq_y + 1, inq_y + 1 + leny, y[i]) - inq_y;
    limx[x[i]]++, xs[x[i]]++;
    limy[y[i]]++, ys[y[i]]++;
  }
  int pre_l;
  while (m--) {
    scanf("%d%d%d", &t, &l, &d);
    pre_l = l;
    if (t == 1) {
      l = lower_bound(inq_x + 1, inq_x + 1 + lenx, l) - inq_x;
      if (inq_x[l] == pre_l) limx[l] = min(limx[l], d);
    } else {
      l = lower_bound(inq_y + 1, inq_y + 1 + leny, l) - inq_y;
      if (inq_y[l] == pre_l) limy[l] = min(limy[l], d);
    }
  }
  for (int i = 1; i <= n; i++) addedge(x[i], y[i] + lenx, 1);
  int bottom_val, top_val;
  for (int i = 1; i <= lenx; i++) {
    if ((xs[i] - limx[i]) & 1) {
      bottom_val = ((xs[i] - limx[i]) >> 1) + 1;
      top_val = bottom_val + limx[i] - 1;
    } else {
      bottom_val = (xs[i] - limx[i]) >> 1;
      top_val = bottom_val + limx[i];
    }
    if (bottom_val > top_val) {
      printf("-1\n");
      return 0;
    }
    off[ss] += bottom_val;
    off[i] -= bottom_val;
    addedge(ss, i, top_val - bottom_val);
  }
  for (int i = 1; i <= leny; i++) {
    if ((ys[i] - limy[i]) & 1) {
      bottom_val = ((ys[i] - limy[i]) >> 1) + 1;
      top_val = bottom_val + limy[i] - 1;
    } else {
      bottom_val = (ys[i] - limy[i]) >> 1;
      top_val = bottom_val + limy[i];
    }
    if (bottom_val > top_val) {
      printf("-1\n");
      return 0;
    }
    off[i + lenx] += bottom_val;
    off[tt] -= bottom_val;
    addedge(i + lenx, tt, top_val - bottom_val);
  }
  int sum = 0;
  for (int i = ss; i <= tt; i++) {
    if (off[i] > 0) {
      sum += off[i];
      addedge(i, sut, off[i]);
    } else
      addedge(sus, i, -off[i]);
  }
  addedge(tt, ss, INF);
  for (int i = ss; i <= sut; i++) yadj[i] = adj[i];
  if (isap(sus, sut, sum) != sum) {
    printf("-1\n");
    return 0;
  }
  ecnt->back->c = ecnt->c = 0;
  for (int i = ss; i <= sut; i++) adj[i] = yadj[i];
  isap(ss, tt, INF);
  long long val[2] = {r, b}, ans = 0;
  n <<= 1;
  for (int i = 2; i <= n; i += 2) ans += val[Edges[i].c];
  printf("%I64d\n", ans);
  char op[2] = {'r', 'b'};
  if (rev) swap(op[0], op[1]);
  for (int i = 2; i <= n; i += 2) printf("%c", op[Edges[i].c]);
  return 0;
}
