#include <bits/stdc++.h>
using namespace std;
long long modpow(long long b, long long e, long long mod) {
  long long ans = 1;
  for (; e; b = b * b % mod, e /= 2)
    if (e & 1) ans = ans * b % mod;
  return ans;
}
const int N = 100005;
const int inf = (int)1e9;
struct Dinic {
  Dinic() = default;
  struct Edge {
    int to, rev;
    long long c, oc;
    long long flow() { return max(oc - c, 0LL); }
  };
  vector<int> lvl, ptr, q;
  vector<vector<Edge>> adj;
  Dinic(int n) : lvl(n), ptr(n), q(n), adj(n) {}
  int addEdge(int a, int b, long long c, int rcap = 0) {
    int p = (int)(adj[a]).size();
    adj[a].push_back({b, (int)(adj[b]).size(), c, c});
    adj[b].push_back({a, (int)(adj[a]).size() - 1, rcap, rcap});
    return p;
  }
  long long dfs(int v, int t, long long f) {
    if (v == t || !f) return f;
    for (int& i = ptr[v]; i < (int)(adj[v]).size(); i++) {
      Edge& e = adj[v][i];
      if (lvl[e.to] == lvl[v] + 1)
        if (long long p = dfs(e.to, t, min(f, e.c))) {
          e.c -= p, adj[e.to][e.rev].c += p;
          return p;
        }
    }
    return 0;
  }
  long long calc(int s, int t) {
    long long flow = 0;
    q[0] = s;
    for (int L = 0; L < (31); ++L) do {
        lvl = ptr = vector<int>((int)(q).size());
        int qi = 0, qe = lvl[s] = 1;
        while (qi < qe && !lvl[t]) {
          int v = q[qi++];
          for (auto& e : adj[v])
            if (!lvl[e.to] && e.c >> (30 - L))
              q[qe++] = e.to, lvl[e.to] = lvl[v] + 1;
        }
        while (long long p = dfs(s, t, LLONG_MAX)) flow += p;
      } while (lvl[t]);
    return flow;
  }
  bool leftOfMinCut(int a) { return lvl[a] != 0; }
};
class Demands {
 public:
  Demands(int n) {
    this->n = n;
    source = n + 1, sink = n + 2;
    h = vector<int>(n + 3, 0);
    flow = Dinic(n + 3);
  }
  int addEdge(int a, int b, int c, int d) {
    h[a] -= c;
    h[b] += c;
    return flow.addEdge(a, b, d - c);
  }
  int solve() {
    int dx = 0, sx = 0;
    flow.addEdge(n, n - 1, inf);
    for (int i = 0; i <= n; i++) {
      if (h[i] < 0) {
        flow.addEdge(i, sink, -h[i]);
        sx += -h[i];
      } else if (h[i] > 0) {
        flow.addEdge(source, i, h[i]);
        dx += h[i];
      }
    }
    int p = 0;
    if ((p = flow.calc(source, sink)) != sx || sx != dx) {
      return -1;
    }
    p = flow.calc(n - 1, n);
    return p;
  }
  vector<int> h;
  Dinic flow;
  int source, sink, n;
};
int X[N], Y[N], cX[N], cY[N], dX[N], dY[N], id[N];
int32_t main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int r, b;
  cin >> r >> b;
  vector<int> x, y;
  for (int i = 1; i < (n + 1); ++i)
    cin >> X[i] >> Y[i], x.push_back(X[i]), y.push_back(Y[i]);
  sort(begin(x), end(x)), sort(begin(y), end(y));
  x.resize(unique(begin(x), end(x)) - begin(x)),
      y.resize(unique(begin(y), end(y)) - begin(y));
  for (int i = 1; i < (n + 1); ++i)
    X[i] = lower_bound(begin(x), end(x), X[i]) - begin(x),
    Y[i] = lower_bound(begin(y), end(y), Y[i]) - begin(y), dX[X[i]]++,
    dY[Y[i]]++;
  for (int i = 0; i < (N); ++i) cX[i] = dX[i], cY[i] = dY[i];
  for (int i = 1; i < (m + 1); ++i) {
    int t, l, d;
    cin >> t >> l >> d;
    if (t == 1) {
      int j = lower_bound(begin(x), end(x), l) - begin(x);
      if (j < (int)(x).size() && x[j] == l) {
        cX[j] = min(cX[j], d);
      }
    } else {
      int j = lower_bound(begin(y), end(y), l) - begin(y);
      if (j < (int)(y).size() && y[j] == l) {
        cY[j] = min(cY[j], d);
      }
    }
  }
  int source = (int)(x).size() + (int)(y).size(), sink = source + 1;
  Demands flow(sink);
  for (int i = 1; i < (n + 1); ++i) {
    id[i] = flow.addEdge(X[i], Y[i] + (int)(x).size(), 0, 1);
  }
  for (int i = 0; i < ((int)(x).size()); ++i) {
    int L = 0, R = dX[i];
    L = (dX[i] - cX[i] + 1) / 2;
    R = (dX[i] + cX[i]) / 2;
    if (L > R) {
      cout << -1 << endl;
      return 0;
    }
    flow.addEdge(source, i, L, R);
  }
  for (int i = 0; i < ((int)(y).size()); ++i) {
    int L = 0, R = dY[i];
    L = (dY[i] - cY[i] + 1) / 2;
    R = (dY[i] + cY[i]) / 2;
    if (L > R) {
      cout << -1 << endl;
      return 0;
    }
    flow.addEdge(i + (int)(x).size(), sink, L, R);
  }
  int p = flow.solve();
  bool swapped = 0;
  if (r < b) swap(r, b), swapped ^= 1;
  if (p == -1) {
    cout << p << endl;
    return 0;
  }
  long long cost = 1ll * r * (n - p) + 1ll * b * p;
  cout << cost << endl;
  for (int i = 1; i < (n + 1); ++i) {
    if (flow.flow.adj[X[i]][id[i]].flow()) {
      cout << (swapped ? 'r' : 'b');
    } else
      cout << (swapped ? 'b' : 'r');
  }
}
