#include <bits/stdc++.h>

using namespace std;

using cap_t = int;
using cost_t = long long;

const cap_t cap_inf = 0x3f3f3f3f;
const cost_t cost_inf = 1ll << 60;

namespace flow {
struct edge {
  int to, rev;
  cost_t cost;
  cap_t cap;

  edge(int t, cap_t c, cost_t w, int r) {
    to = t;
    rev = r;
    cap = c;
    cost = w;
  }
};

vector<vector<edge>> adj;
vector<cost_t> dist;
int n, source, sink;
vector<bool> visit;
vector<int> cur;
cost_t res;
cap_t ans;

void init(int v, int s, int t) {
  n = v;
  ans = res = 0;
  source = s;
  sink = t;
  adj.clear();
  adj.resize(n);
  cur.resize(n);
  dist.resize(n);
  visit.resize(n);
}

void add(int x, int y, cap_t c, cost_t w) {
  adj[x].emplace_back(y, c, w, adj[y].size());
  adj[y].emplace_back(x, 0, -w, adj[x].size() - 1);
}

bool spfa() {
  queue<int> q;
  for (int i = 0; i < n; ++i) {
    dist[i] = cost_inf;
    visit[i] = false;
    cur[i] = 0;
  }
  dist[source] = 0;
  q.push(source);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    visit[x] = false;
    for (auto e : adj[x]) {
      if (e.cap && dist[e.to] > dist[x] + e.cost) {
        dist[e.to] = dist[x] + e.cost;
        if (!visit[e.to]) {
          visit[e.to] = true;
          q.push(e.to);
        }
      }
    }
  }
  return dist[sink] != cost_inf;
}

cap_t dfs(int x, cap_t f) {
  if (x == sink) {
    return f;
  }
  visit[x] = true;
  cap_t res = 0;
  for (int &i = cur[x]; i < (int) adj[x].size(); ++i) {
    edge &e = adj[x][i];
    if (e.cap && dist[e.to] == dist[x] + e.cost && !visit[e.to]) {
      cap_t w = dfs(e.to, min(e.cap, f - res));
      res += w;
      e.cap -= w;
      adj[e.to][e.rev].cap += w;
      if (res == f) {
        visit[x] = false;
        return res;
      }
    }
  }
  dist[x] = cost_inf;
  return res;
}

pair<cap_t, cost_t> min_cost_max_flow() {
  while (spfa()) {
    cap_t flow = dfs(source, cap_inf);
    ans += flow;
    res += flow * dist[sink];
  }
  return make_pair(ans, res);
}
}

using flow::source;
using flow::sink;
using flow::init;
using flow::add;
using flow::min_cost_max_flow;

const int MAX = 100;

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  vector<int> x(n), y(n);
  vector<long long> z(n);
  for (int i = 0; i < n; ++i) {
    cin >> x[i] >> y[i] >> z[i];
  }
  vector<int> l(MAX, n), r(MAX, n), d(MAX, n), u(MAX, n);
  int m;
  cin >> m;
  while (m--) {
    string type;
    int a, b;
    cin >> type >> a >> b;
    --a;
    if (type == "L") {
      l[a] = b;
    } else if (type == "R") {
      r[a] = b;
    } else if (type == "D") {
      d[a] = b;
    } else {
      u[a] = b;
    }
  }
  for (int i = MAX - 2; ~i; --i) {
    l[i] = min(l[i], l[i + 1]);
    d[i] = min(d[i], d[i + 1]);
  }
  for (int i = 1; i < MAX; ++i) {
    r[i] = min(r[i], r[i - 1]);
    u[i] = min(u[i], u[i - 1]);
  }
  long long ans = 0;
  auto solve = [&](int take) {
    init(MAX * 2 + 4, MAX * 2 + 2, MAX * 2 + 3);
    add(source, 0, take, 0);
    add(MAX + 1, sink, take, 0);
    int need = take;
    for (int i = 0; i < MAX; ++i) {
      int low = max(0, take - l[max(i - 1, 0)]);
      int high = r[i];
      if (low > high) {
        return;
      }
      add(i, i + 1, high - low, 0);
      add(source, i + 1, low, 0);
      add(i, sink, low, 0);
      need += low;
    }
    for (int i = 0; i < MAX; ++i) {
      int low = max(0, take - d[max(i - 1, 0)]);
      int high = u[i];
      if (low > high) {
        return;
      }
      add(MAX + i + 2, MAX + i + 1, high - low, 0);
      add(source, MAX + i + 1, low, 0);
      add(MAX + i + 2, sink, low, 0);
      need += low;
    }
    for (int i = 0; i < n; ++i) {
      add(x[i], MAX + y[i] + 1, 1, -z[i]);
    }
    pair<int, long long> res = min_cost_max_flow();
    if (res.first == need) {
      ans = max(ans, -res.second);
    }
  };
  for (int i = 1; i <= n; ++i) {
    solve(i);
  }
  cout << ans << "\n";
  return 0;
}


Measured memory_bytes: 384