#include <bits/stdc++.h>
const int max_N = 102401;
int n, m, R, B, ans, bX[max_N], bY[max_N], X[max_N], Y[max_N];
int bucx[max_N], bucy[max_N], minx[max_N], miny[max_N];
bool flip;
int read() {
  char c = getchar();
  int ans = 0;
  bool flag = true;
  while (!isdigit(c)) flag &= (c != '-'), c = getchar();
  while (isdigit(c)) ans = ans * 10 + c - '0', c = getchar();
  return flag ? ans : -ans;
}
void Write(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x < 10)
    putchar(x + '0');
  else
    Write(x / 10), putchar(x % 10 + '0');
}
int min(int x, int y) { return x < y ? x : y; }
int max(int x, int y) { return x > y ? x : y; }
void _min(int &x, int y) {
  if (x > y) x = y;
}
void _max(int &x, int y) {
  if (x < y) x = y;
}
void fail() { putchar('-'), putchar('1'), exit(0); }
namespace maxflow {
const int max_N = 2 * ::max_N, max_E = 5 * ::max_N, INF = 2e9;
int nxt[2 * max_E], head[max_N], to[2 * max_E], cap[2 * max_E], tot;
int dist[max_N], _head[max_N], n, S, T;
void init(int _n, int _S, int _T) {
  n = _n, S = _S, T = _T, tot = 1;
  std::fill(head + 1, head + n + 1, 0);
}
void add_edge(int u, int v, int w) {
  nxt[++tot] = head[u], head[u] = tot, to[tot] = v, cap[tot] = w;
  nxt[++tot] = head[v], head[v] = tot, to[tot] = u, cap[tot] = 0;
}
bool BFS() {
  std::fill(dist + 1, dist + n + 1, INF);
  std::queue<int> Q;
  Q.push(S);
  dist[S] = 0;
  while (!Q.empty()) {
    int cur = Q.front();
    Q.pop();
    for (int i = head[cur]; i; i = nxt[i])
      if (cap[i] > 0 && dist[to[i]] == INF)
        dist[to[i]] = dist[cur] + 1, Q.push(to[i]);
  }
  return dist[T] < INF;
}
int dfs(int x, int low) {
  if (x == T) return low;
  int used = 0, tmp;
  for (int &i = _head[x]; i; i = nxt[i])
    if (cap[i] > 0 && dist[to[i]] == dist[x] + 1) {
      tmp = dfs(to[i], min(low - used, cap[i]));
      if (tmp > 0) used += tmp, cap[i] -= tmp, cap[i ^ 1] += tmp;
      if (used == low) break;
    }
  return used;
}
int solve() {
  int ans = 0;
  while (BFS())
    std::copy(head + 1, head + n + 1, _head + 1), ans += dfs(S, INF);
  return ans;
}
}  // namespace maxflow
namespace bounded_maxflow {
int n, S, T, deg[maxflow::max_N];
void init(int _n, int _S, int _T) {
  n = _n, S = _S, T = _T;
  maxflow::init(n + 2, n + 1, n + 2);
}
void add_edge(int u, int v, int l, int r) {
  deg[u] -= l, deg[v] += l, maxflow::add_edge(u, v, r - l);
}
int solve() {
  int sum = 0;
  for (int i = 1; i <= n; i++)
    if (deg[i] > 0)
      maxflow::add_edge(n + 1, i, deg[i]), sum += deg[i];
    else if (deg[i] < 0)
      maxflow::add_edge(i, n + 2, -deg[i]);
  maxflow::add_edge(T, S, maxflow::INF);
  if (maxflow::solve() != sum) return -1;
  for (int i = 1; i <= n; i++)
    for (int &j = maxflow::head[i]; maxflow::to[j] > n; j = maxflow::nxt[j])
      ;
  return maxflow::S = S, maxflow::T = T, maxflow::solve();
}
}  // namespace bounded_maxflow
int main() {
  n = read(), m = read(), R = read(), B = read();
  if (R > B) std::swap(R, B), flip = true;
  for (int i = 1; i <= n; i++)
    X[i] = read(), Y[i] = read(), bX[++*bX] = X[i], bY[++*bY] = Y[i];
  std::sort(bX + 1, bX + *bX + 1),
      *bX = std::unique(bX + 1, bX + *bX + 1) - (bX + 1);
  std::sort(bY + 1, bY + *bY + 1),
      *bY = std::unique(bY + 1, bY + *bY + 1) - (bY + 1);
  for (int i = 1; i <= n; i++)
    X[i] = std::lower_bound(bX + 1, bX + *bX + 1, X[i]) - bX,
    Y[i] = std::lower_bound(bY + 1, bY + *bY + 1, Y[i]) - bY;
  bounded_maxflow::init(*bX + *bY + 2, *bX + *bY + 1, *bX + *bY + 2);
  for (int i = 1; i <= n; i++)
    bounded_maxflow::add_edge(X[i], Y[i] + *bX, 0, 1), bucx[X[i]]++,
        bucy[Y[i]]++;
  for (int i = 1; i <= *bX; i++) minx[i] = bucx[i];
  for (int i = 1; i <= *bY; i++) miny[i] = bucy[i];
  for (int _ = 1, l, d; _ <= m; _++)
    if (read() == 1) {
      l = read(), d = read();
      if (l <= bX[*bX] && l == *std::lower_bound(bX + 1, bX + *bX + 1, l))
        _min(minx[std::lower_bound(bX + 1, bX + *bX + 1, l) - bX], d);
    } else {
      l = read(), d = read();
      if (l <= bY[*bY] && l == *std::lower_bound(bY + 1, bY + *bY + 1, l))
        _min(miny[std::lower_bound(bY + 1, bY + *bY + 1, l) - bY], d);
    }
  for (int i = 1; i <= *bX; i++)
    if ((bucx[i] & 1) && !minx[i]) fail();
  for (int i = 1; i <= *bY; i++)
    if ((bucy[i] & 1) && !miny[i]) fail();
  for (int i = 1, l, r; i <= *bX; i++)
    l = (bucx[i] - minx[i] + 1) / 2, r = (bucx[i] + minx[i]) / 2,
    bounded_maxflow::add_edge(bounded_maxflow::S, i, l, r);
  for (int i = 1, l, r; i <= *bY; i++)
    l = (bucy[i] - miny[i] + 1) / 2, r = (bucy[i] + miny[i]) / 2,
    bounded_maxflow::add_edge(i + *bX, bounded_maxflow::T, l, r);
  if ((ans = bounded_maxflow::solve()) == -1) fail();
  Write((long long)ans * R + (long long)(n - ans) * B), putchar('\n');
  for (int i = 1; i <= n; i++)
    putchar((maxflow::cap[i * 2] ^ flip) ? 'b' : 'r');
  return 0;
}
