#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

// const int mod = 998244353;
int mod;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

// ----------------------------------------

const int maxn = 80, maxx = 100, maxm = 320;

int n, x[maxn], y[maxn];
li v[maxn];

int m;
char type[maxm];
int a[maxm], b[maxm];

int min_x[maxx + 1], max_x[maxx + 1], min_y[maxx + 1], max_y[maxx + 1];

namespace mcf {
  const int maxn = 204;
  const int maxm = 1e6;
  const int inf = ~0U >> 1;
  const li infl = ~0LLU >> 2;

  int n, m, s, t;
  vector<int> g[maxn];
  int enter[maxn];
  li basic_cost;

  struct Edge {
    int v, cap;
    li cost;
  } edge[maxm];

  void AddSimple(int u, int v, int cap, li cost) {
    g[u].push_back(m);
    edge[m++] = {v, cap, cost};
    g[v].push_back(m);
    edge[m++] = {u, 0, -cost};
  }

  void AddEdge(int u, int v, int l, int r, li cost) {
    basic_cost += cost * l;
    enter[v] += l;
    enter[u] -= l;
    if (l < r) {
      AddSimple(u, v, r - l, cost);
    }
  }

  void Init(int _n) {
    n = _n + 2;
    s = _n, t = s + 1;
    m = 0;
    for (int i = 0; i < n; ++i) {
      g[i].clear();
      enter[i] = 0;
    }
    basic_cost = 0;
  }

  li h[maxn], dist[maxn];
  int prev[maxn];

  struct Node {
    int u;
    li d;
    bool operator < (const Node &b) const {
      return d > b.d;
    }
  };

  bool Dijkstra(void) {
    for (int i = 0; i < n; ++i) {
      dist[i] = infl;
    }
    dist[s] = 0;
    priority_queue<Node> que;
    que.push({s, 0});
    while (!que.empty()) {
      int u = que.top().u;
      li d = que.top().d;
      que.pop();
      if (d != dist[u]) continue;
      for (int i = 0; i < g[u].size(); ++i) {
        Edge &e = edge[g[u][i]];
        if (e.cap == 0) continue;
        li newd = d + e.cost + h[u] - h[e.v];
        if (newd < dist[e.v]) {
          dist[e.v] = newd;
          que.push({e.v, newd});
          prev[e.v] = g[u][i];
        }
      }
    }
    return dist[t] < infl;
  }

  pair<bool, li> Solve(void) {
    int should = 0;
    for (int i = 0; i < n; ++i) {
      if (enter[i] > 0) {
        should += enter[i];
        AddSimple(s, i, enter[i], 0);
      } else {
        AddSimple(i, t, -enter[i], 0);
      }
      h[i] = 0;
    }
    int flow = 0;
    li cost = basic_cost;
    while (Dijkstra()) {
      for (int i = 0; i < n; ++i) {
        h[i] = min(h[i] + dist[i], infl);
      }
      int now = inf;
      for (int x = t; x != s; x = edge[prev[x] ^ 1].v) {
        Min(now, edge[prev[x]].cap);
      }
      flow += now;
      cost += now * h[t];
      for (int x = t; x != s; x = edge[prev[x] ^ 1].v) {
        edge[prev[x]].cap -= now;
        edge[prev[x] ^ 1].cap += now;
      }
    }
    return {flow == should, cost};
  }
}

int main(void) {
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%d%d%lld", x + i, y + i, v + i);
    --x[i]; --y[i];
  }
  scanf("%d", &m);
  for (int i = 0; i < m; ++i) {
    char buf[2];
    scanf("%s%d%d", buf, a + i, b + i);
    --a[i];
    type[i] = buf[0];
  }

  li ans = 0;
  for (int total = 1; total <= n; ++total) {
    for (int i = 0; i <= maxx; ++i) {
      min_x[i] = min_y[i] = 0;
      max_x[i] = max_y[i] = n;
    }
    for (int i = 0; i < m; ++i) {
      switch (type[i]) {
      case 'L':
        Min(max_x[a[i] + 1], b[i]);
        break;
      case 'R':
        Max(min_x[a[i]], total - b[i]);
        break;
      case 'D':
        Min(max_y[a[i] + 1], b[i]);
        break;
      case 'U':
        Max(min_y[a[i]], total - b[i]);
        break;
      }
    }

    mcf::Init(maxx + 1 << 1);
    int mid = maxx + 1;
    for (int i = 0; i < maxx; ++i) {
      mcf::AddEdge(i + 1, i, min_x[i + 1], max_x[i + 1], 0);
      mcf::AddEdge(mid + i, mid + i + 1, min_y[i + 1], max_y[i + 1], 0);
    }
    mcf::AddEdge(mid + maxx, maxx, total, total, 0);
    for (int i = 0; i < n; ++i) {
      mcf::AddEdge(x[i], mid + y[i], 1, 1, -v[i]);
      mcf::AddEdge(mid + y[i], x[i], 0, 1, v[i]);
    }
    auto res = mcf::Solve();
    if (res.first) {
      li cost = res.second;
      Max(ans, -cost);
    }
  }

  printf("%lld\n", ans);
  return 0;
}
