#include <bits/stdc++.h>
using namespace std;
const int maxn = 210000;
const int inf = 0x3f3f3f3f;
const int maxm = maxn * 20;
struct edge {
  int to, cap, next;
} E[maxm];
int limitx[maxn], limity[maxn], cntx[maxn], cnty[maxn];
pair<int, int> A[maxn];
int head[maxn], si, level[maxn];
int start[maxn], node_cnt, now_level;
void add_edge(int u, int v, int cap) {
  if (cap == 0) return;
  E[si].to = v;
  E[si].next = head[u];
  E[si].cap = cap;
  head[u] = si++;
  E[si].to = u;
  E[si].next = head[v];
  E[si].cap = 0;
  head[v] = si++;
}
bool bfs(int s, int t) {
  memset(level, -1, sizeof(int) * node_cnt);
  queue<int> que;
  level[s] = 0;
  que.push(s);
  while (!que.empty() && level[t] == -1) {
    int v = que.front();
    que.pop();
    for (int i = head[v]; ~i; i = E[i].next) {
      int u = E[i].to;
      if (u < node_cnt && level[u] == -1 && E[i].cap > 0) {
        level[u] = level[v] + 1;
        que.push(u);
      }
    }
  }
  return level[t] != -1;
}
int dfs(int v, int t, int f) {
  if (v == t) {
    return f;
  }
  int w = 0;
  for (int &i = start[v]; ~i; i = E[i].next) {
    int u = E[i].to;
    if (E[i].cap > 0 && level[u] == level[v] + 1) {
      int d = dfs(u, t, min(f - w, E[i].cap));
      w += d;
      E[i].cap -= d;
      E[i ^ 1].cap += d;
      if (f == w) {
        return w;
      }
    }
  }
  level[v] = -1;
  return w;
}
int max_flow(int s, int t) {
  int flow = 0;
  while (bfs(s, t)) {
    memcpy(start, head, sizeof(*head) * node_cnt);
    flow += dfs(s, t, INT_MAX);
  }
  return flow;
}
char C[maxn];
int used[maxn];
int main() {
  int n, m, red, blue;
  scanf("%d%d%d%d", &n, &m, &red, &blue);
  bool is_swap = false;
  if (red < blue) {
    swap(red, blue);
    is_swap = true;
  }
  vector<int> X, Y;
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &A[i].first, &A[i].second);
    X.push_back(A[i].first);
    Y.push_back(A[i].second);
  }
  sort(X.begin(), X.end());
  X.erase(unique(X.begin(), X.end()), X.end());
  sort(Y.begin(), Y.end());
  Y.erase(unique(Y.begin(), Y.end()), Y.end());
  memset(head, -1, sizeof head);
  si = 0;
  add_edge(2 * n + 1, 0, n);
  for (int i = 1; i <= n; i++) {
    int x = lower_bound(X.begin(), X.end(), A[i].first) - X.begin() + 1;
    int y = lower_bound(Y.begin(), Y.end(), A[i].second) - Y.begin() + 1;
    add_edge(x, y + n, 1);
    cntx[x]++;
    cnty[y]++;
  }
  for (int i = 1; i <= n; i++) {
    limitx[i] = cntx[i];
    limity[i] = cnty[i];
  }
  for (int i = 1, t, d, l; i <= m; i++) {
    scanf("%d%d%d", &t, &l, &d);
    if (t == 1) {
      int pos = lower_bound(X.begin(), X.end(), l) - X.begin();
      if (pos < X.size() && X[pos] == l) {
        pos++;
        limitx[pos] = min(limitx[pos], d);
      }
    } else {
      int pos = lower_bound(Y.begin(), Y.end(), l) - Y.begin();
      if (pos < Y.size() && Y[pos] == l) {
        pos++;
        limity[pos] = min(limity[pos], d);
      }
    }
  }
  int res = 0;
  int S = 2 * n + 2, T = 2 * n + 3;
  int flowS = 0, flowT = 0;
  node_cnt = 2 * n + 4;
  int nx = X.size(), ny = Y.size();
  for (int i = 1; i <= nx; i++) {
    int r = (cntx[i] + limitx[i]) / 2;
    int l = (cntx[i] - limitx[i] + 1) / 2;
    if (l > r) {
      printf("-1\n");
      return 0;
    }
    if (l < 0) l = 0;
    add_edge(0, i, r - l);
    add_edge(S, i, l);
    add_edge(0, T, l);
  }
  for (int i = 1; i <= ny; i++) {
    int r = (cnty[i] + limity[i]) / 2;
    int l = (cnty[i] - limity[i] + 1) / 2;
    if (l > r) {
      printf("-1\n");
      return 0;
    }
    if (l < 0) l = 0;
    add_edge(i + n, 2 * n + 1, r - l);
    add_edge(i + n, T, l);
    add_edge(S, 2 * n + 1, l);
  }
  assert(si < maxm);
  max_flow(S, T);
  for (int i = head[S]; ~i; i = E[i].next) {
    if (E[i].cap > 0) {
      puts("-1");
      return 0;
    }
  }
  long long ans = 0;
  E[1].cap = E[0].cap = 0;
  node_cnt -= 2;
  max_flow(0, 2 * n + 1);
  for (int i = head[0]; ~i; i = E[i].next) {
    if (E[i ^ 1].cap > 0) {
      ans += E[i ^ 1].cap;
    }
  }
  ans = red * 1LL * n + ans * (blue - red);
  cout << ans << endl;
  for (int i = 0; i < n; i++) {
    C[i] = 'r';
    if (E[i * 2 + 2].cap == 0) {
      C[i] = 'b';
    }
  }
  C[n] = '\0';
  if (is_swap) {
    for (int i = 0; i < n; i++) {
      if (C[i] == 'r')
        C[i] = 'b';
      else
        C[i] = 'r';
    }
  }
  printf("%s\n", C);
  return 0;
}
