#include <bits/stdc++.h>
using namespace std;
struct flow_graph {
  int V, E, s, t;
  int *flow, *low, *cap, *to, *next, *last, *delta;
  int *dist, *q, *now, head, tail;
  flow_graph() {}
  flow_graph(int V, int E) {
    (*this).V = V;
    (*this).E = 0;
    int TE = 2 * (E + V + 1);
    flow = new int[TE];
    low = new int[TE];
    cap = new int[TE];
    to = new int[TE];
    next = new int[TE];
    last = new int[V + 2];
    delta = new int[V];
    dist = new int[V + 2];
    q = new int[V + 2];
    now = new int[V + 2];
  }
  void clear(int V) {
    (*this).V = V;
    (*this).E = 0;
    fill(last, last + V, -1);
  }
  void add_edge(int a, int b, int l, int u) {
    to[E] = b;
    low[E] = l;
    cap[E] = u;
    flow[E] = 0;
    next[E] = last[a];
    last[a] = E++;
    to[E] = a;
    low[E] = 0;
    cap[E] = 0;
    flow[E] = 0;
    next[E] = last[b];
    last[b] = E++;
  }
  bool bfs() {
    fill(dist, dist + V + 2, -1);
    head = tail = 0;
    q[tail] = t;
    ++tail;
    dist[t] = 0;
    while (head < tail) {
      int v = q[head];
      ++head;
      for (int e = last[v]; e != -1; e = next[e]) {
        if (cap[e ^ 1] > flow[e ^ 1] && dist[to[e]] == -1) {
          q[tail] = to[e];
          ++tail;
          dist[to[e]] = dist[v] + 1;
        }
      }
    }
    return dist[s] != -1;
  }
  int dfs(int v, int f) {
    if (v == t) return f;
    for (int &e = now[v]; e != -1; e = next[e]) {
      if (cap[e] > flow[e] && dist[to[e]] == dist[v] - 1) {
        int ret = dfs(to[e], min(f, cap[e] - flow[e]));
        if (ret > 0) {
          flow[e] += ret;
          flow[e ^ 1] -= ret;
          return ret;
        }
      }
    }
    return 0;
  }
  int max_flow(int source, int sink) {
    fill(delta, delta + V, 0);
    for (int e = 0; e < E; e += 2) {
      delta[to[e ^ 1]] -= low[e];
      delta[to[e]] += low[e];
      cap[e] -= low[e];
    }
    last[V] = last[V + 1] = -1;
    int sum = 0;
    for (int i = 0; i < V; ++i) {
      if (delta[i] > 0) {
        add_edge(V, i, 0, delta[i]);
        sum += delta[i];
      }
      if (delta[i] < 0) add_edge(i, V + 1, 0, -delta[i]);
    }
    add_edge(sink, source, 0, INT_MAX);
    s = V;
    t = V + 1;
    int f = 0, df;
    fill(flow, flow + E, 0);
    while (bfs()) {
      for (int i = V + 1; i >= 0; --i) now[i] = last[i];
      while (true) {
        df = dfs(s, INT_MAX);
        if (df == 0) break;
        f += df;
      }
    }
    if (f != sum) return -1;
    for (int e = 0; e < E; e += 2) {
      cap[e] += low[e];
      flow[e] += low[e];
      flow[e ^ 1] -= low[e];
      cap[e ^ 1] -= low[e];
    }
    s = source;
    t = sink;
    last[s] = next[last[s]];
    last[t] = next[last[t]];
    E -= 2;
    while (bfs()) {
      for (int i = V - 1; i >= 0; --i) now[i] = last[i];
      while (true) {
        df = dfs(s, INT_MAX);
        if (df == 0) break;
        f += df;
      }
    }
    return f;
  }
};
const int N = 100005;
pair<int, int> arr[N];
int xs[N], ys[N];
int dx[N], dy[N];
int qntx[N], qnty[N];
int pnt_id[N];
char ans[N];
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  int r, b;
  scanf("%d %d", &r, &b);
  char cheap = 'r', expensive = 'b';
  if (r > b) {
    swap(cheap, expensive);
    swap(r, b);
  }
  for (int i = 0; i < n; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    arr[i] = pair<int, int>(x, y);
    xs[i] = x;
    ys[i] = y;
  }
  sort(xs, xs + n);
  int xssz = unique(xs, xs + n) - xs;
  sort(ys, ys + n);
  int yssz = unique(ys, ys + n) - ys;
  for (int i = 0; i < n; ++i) {
    arr[i].first = lower_bound(xs, xs + xssz, arr[i].first) - xs;
    arr[i].second = lower_bound(ys, ys + yssz, arr[i].second) - ys;
    ++qntx[arr[i].first];
    ++qnty[arr[i].second];
    ++dx[arr[i].first];
    ++dy[arr[i].second];
  }
  for (int i = 0; i < m; ++i) {
    int t, l, d;
    scanf("%d %d %d", &t, &l, &d);
    if (t == 1) {
      int k = lower_bound(xs, xs + xssz, l) - xs;
      if (xs[k] == l) {
        dx[k] = min(dx[k], d);
      }
    } else {
      int k = lower_bound(ys, ys + yssz, l) - ys;
      if (ys[k] == l) {
        dy[k] = min(dy[k], d);
      }
    }
  }
  flow_graph fg = flow_graph(xssz + yssz + 2, n + xssz + yssz);
  fg.clear(xssz + yssz + 2);
  int source = xssz + yssz, sink = source + 1;
  for (int i = 0; i < xssz; ++i) {
    int l = (qntx[i] - dx[i] + 1) / 2;
    int r = (qntx[i] + dx[i]) / 2;
    if (l > r) {
      puts("-1");
      return 0;
    }
    fg.add_edge(source, i, l, r);
  }
  for (int i = 0; i < n; ++i) {
    pnt_id[i] = fg.E;
    fg.add_edge(arr[i].first, arr[i].second + xssz, 0, 1);
  }
  for (int i = 0; i < yssz; ++i) {
    int l = (qnty[i] - dy[i] + 1) / 2;
    int r = (qnty[i] + dy[i]) / 2;
    if (l > r) {
      puts("-1");
      return 0;
    }
    fg.add_edge(i + xssz, sink, l, r);
  }
  if (fg.max_flow(source, sink) < 0) {
    puts("-1");
    return 0;
  }
  long long qnt = 0;
  for (int i = 0; i < n; ++i) {
    int id = pnt_id[i];
    if (fg.flow[id] > 0)
      ans[i] = cheap, ++qnt;
    else
      ans[i] = expensive;
  }
  printf("%lld\n", qnt * r + (n - qnt) * b);
  printf("%s\n", ans);
  return 0;
}
