#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int n, m, S, T, tot, cnt = 1, lim[N], h[N], lst[N], in[N], wid[N];
struct edge {
  int to, next, w;
} e[N * 20];
void addedge(int x, int y, int z) {
  e[++cnt] = (edge){y, h[x], z};
  h[x] = cnt;
}
void insert(int x, int y, int z) {
  addedge(x, y, z);
  addedge(y, x, 0);
}
map<int, int> Id;
vector<pair<int, int> > G[N];
vector<int> Idx, Idy;
int d[N];
bool bfs(int st, int ed) {
  memset(d, 0, sizeof(d));
  queue<int> Q;
  Q.push(st);
  d[st] = 1;
  while (Q.size()) {
    int x = Q.front();
    Q.pop();
    for (int i = h[x]; i; i = e[i].next) {
      int y = e[i].to;
      if (e[i].w && !d[y]) d[y] = d[x] + 1, Q.push(y);
    }
  }
  return d[ed] > 0;
}
int dfs(int x, int ed, int maxf) {
  if (x == ed || !maxf) return maxf;
  int flow = 0;
  for (int& i = lst[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (!e[i].w || d[y] != d[x] + 1) continue;
    int w = dfs(y, ed, min(maxf, e[i].w));
    flow += w;
    maxf -= w;
    e[i].w -= w;
    e[i ^ 1].w += w;
    if (!maxf) break;
  }
  return flow;
}
int dinic(int st, int ed) {
  int ans = 0;
  while (bfs(st, ed)) {
    memcpy(lst, h, sizeof(lst));
    ans += dfs(st, ed, 1e9);
  }
  return ans;
}
int main() {
  scanf("%d%d", &n, &m);
  int r, b;
  scanf("%d%d", &r, &b);
  for (int i = 1; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    y = -y;
    if (!Id.count(x)) Id[x] = ++tot, Idx.push_back(tot);
    if (!Id.count(y)) Id[y] = ++tot, Idy.push_back(tot);
    int idx = Id[x], idy = Id[y];
    G[idx].push_back(make_pair(idy, i));
    G[idy].push_back(make_pair(idx, i));
  }
  for (int i = 1; i <= tot; i++) lim[i] = 1e9;
  for (int i = 1; i <= m; i++) {
    int t, l, D;
    scanf("%d%d%d", &t, &l, &D);
    if (t == 1)
      lim[Id[l]] = min(lim[Id[l]], D);
    else
      lim[Id[-l]] = min(lim[Id[-l]], D);
  }
  S = 0;
  T = ++tot;
  for (int i = 0; i < Idx.size(); i++) {
    int id = Idx[i];
    lim[id] = min(lim[id], int(G[id].size()));
    int l = (int(G[id].size()) - lim[id] + 1) / 2,
        r = (G[id].size() + lim[id]) / 2;
    if (l > r) puts("-1"), exit(0);
    in[S] -= l;
    in[id] += l;
    insert(S, id, r - l);
    for (int j = 0; j < G[id].size(); j++) {
      insert(id, G[id][j].first, 1);
      wid[G[id][j].second] = cnt;
    }
  }
  for (int i = 0; i < Idy.size(); i++) {
    int id = Idy[i];
    lim[id] = min(lim[id], int(G[id].size()));
    int l = (G[id].size() - lim[id] + 1) / 2, r = (G[id].size() + lim[id]) / 2;
    if (l > r) puts("-1"), exit(0);
    in[id] -= l;
    in[T] += l;
    insert(id, T, r - l);
  }
  int st = ++tot, ed = ++tot, tmp = cnt;
  for (int i = 0; i <= tot - 2; i++)
    if (in[i] > 0)
      insert(st, i, in[i]);
    else if (in[i] < 0)
      insert(i, ed, -in[i]);
  insert(T, S, 1e9);
  int edge_id = cnt;
  dinic(st, ed);
  for (int i = h[st]; i; i = e[i].next)
    if (e[i].w) puts("-1"), exit(0);
  for (int i = h[ed]; i; i = e[i].next)
    if (e[i ^ 1].w) puts("-1"), exit(0);
  for (int x = 0; x <= tot; x++)
    while (h[x] > tmp) h[x] = e[h[x]].next;
  int ans = e[edge_id].w + dinic(S, T);
  cout << 1ll * ans * min(r, b) + 1ll * (n - ans) * max(r, b) << "\n";
  bool flag = (r > b);
  for (int i = 1; i <= n; i++) cout << ((e[wid[i]].w ^ flag) ? "r" : "b");
}
