#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;   }