#include <bits/stdc++.h>

using namespace std;

#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define fst first
#define snd second
#define SZ(u) ((int) (u).size())
#define ALL(u) (u).begin(), (u).end()

inline void proc_status()
{
	ifstream t("/proc/self/status");
	cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
}

template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
template<typename T> inline T read()
{
	register T sum(0), fg(1);
	register char ch(getchar());
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') fg = -1;
	for(;  isdigit(ch); ch = getchar()) sum = sum * 10 - '0' + ch;
	return sum * fg;
}

typedef long long LL;
typedef pair<int, int> pii;

const int MAXN = 80, MAXM = 320;

struct point
{
	int x, y;
	LL w;

	point() { }
	point(int _x, int _y, LL _w): x(_x), y(_y), w(_w) { }
};

int n, m;

point A[MAXN + 5];

struct lim
{
	int l, r;

	lim() { }
	lim(int _l, int _r): l(_l), r(_r) { }
};

int l0[MAXN + 5], r0[MAXN + 5], l1[MAXN + 5], r1[MAXN + 5];

inline char safe_getchar()
{
	register char ch(getchar());
	while(!isupper(ch)) ch = getchar();
	return ch;
}

inline void input()
{
	n = read<int>();
	for(int i = 1; i <= n; ++i) A[i].x = read<int>(), A[i].y = read<int>(), A[i].w = read<LL>();

	m = read<int>();
	for(int i = 1; i <= n; ++i) l0[i] = l1[i] = 0, r0[i] = r1[i] = 101;
	for(int i = 1; i <= m; ++i)
	{
		char type = safe_getchar();
		int a = read<int>(), b = read<int>();
		if(type == 'L') chkmax(l0[b + 1], a);
		else if(type == 'R') chkmin(r0[b + 1], a);
		else if(type == 'D') chkmax(l1[b + 1], a);
		else if(type == 'U') chkmin(r1[b + 1], a);
		else assert(0);
	}
}

namespace FLOW
{
	const int MAXV = MAXN * 4 + 2;
	const int MAXE = MAXN * MAXN * 2 + MAXN * 3;

	struct edge
	{
		int adj, nxt, c;
		LL w;

		edge() { }
		edge(int _adj, int _nxt, int _c, LL _w): adj(_adj), nxt(_nxt), c(_c), w(_w) { }
	};

	edge e[MAXE * 2 + 5];
	int st[MAXV + 5], edge_cnt;

	inline void real_add_edge(int u, int v, int c, LL w, int type = 1)
	{
		e[edge_cnt] = edge(v, st[u], c, w), st[u] = edge_cnt++;
		if(type) real_add_edge(v, u, 0, -w, 0);
	}

	inline void init(int N)
	{
		for(int i = 1; i <= N; ++i) st[i] = -1;
		edge_cnt = 0;
	}

	namespace cache
	{
		struct EDGE
		{
			int u, v, c;
			LL w;

			EDGE() { }
			EDGE(int _u, int _v, int _c, LL _w): u(_u), v(_v), c(_c), w(_w) { }
		};

		EDGE stk[MAXE + 5];
		int top = 0;
	}

	inline void add_edge(int u, int v, int c, LL w)
	{
		using namespace cache;
		stk[++top] = EDGE(u, v, c, w);
	}

	inline void build_graph(int N)
	{
		init(N);
		using namespace cache;

		while(top > 0) real_add_edge(stk[top].u, stk[top].v, stk[top].c, stk[top].w), --top;
	}

	const LL INF = LLONG_MAX / 2;

	int cur[MAXV + 5];
	LL d[MAXV + 5];

	inline LL SPFA(int S, int T, int N)
	{
		static queue<int> q;
		static int inq[MAXV + 5];
		for(int i = 1; i <= N; ++i) inq[i] = 0, d[i] = -INF;

		d[S] = 0, q.push(S);
		while(!q.empty())
		{
			int u = q.front();
			inq[u] = 0, q.pop();
			cur[u] = st[u];

			for(int i = st[u]; ~i; i = e[i].nxt)
			{
				int v = e[i].adj;
				if(e[i].c > 0 && chkmax(d[v], d[u] + e[i].w) && !inq[v]) inq[v] = 1, q.push(v);
			}
		}

		return d[T];
	}

	int vis[MAXV + 5];

	inline int dfs(int u, int T, int low)
	{
		if(u == T) return low;

		vis[u] = 1;
		int sum = 0;
		for(int k, &i = cur[u]; ~i; i = e[i].nxt)
		{
			int v = e[i].adj;
			if(!vis[v] && d[v] == d[u] + e[i].w && e[i].c > 0 && (k = dfs(v, T, min(low, e[i].c))) > 0)
			{
				e[i].c -= k;
				e[i ^ 1].c += k;
				low -= k;
				sum += k;
				if(low == 0) { vis[u] = 0; return sum; }
			}
		}
		vis[u] = 0;
		return sum;
	}

	inline pair<int, LL> solve(int S, int T, int N)
	{
		build_graph(N);

		int flow = 0;
		LL sum = 0;
		for(LL cost; (cost = SPFA(S, T, N)) != -INF; )
			for(int k; (k = dfs(S, T, INT_MAX)) > 0; )
			{
				flow += k;
				sum += cost * k;
			}
		return mp(flow, sum);
	}
}

inline void solve()
{
	LL ans = 0;
	for(int k = 1; k <= n; ++k)
	{
		static int X[MAXN + 5], Y[MAXN + 5];

		int cnt = 0, S = 0, T = 0;
		S = ++cnt, T = ++cnt;
		for(int i = 1; i <= k; ++i)
		{
			X[i] = ++cnt, Y[i] = ++cnt;
			FLOW::add_edge(S, X[i], 1, 0);
			FLOW::add_edge(Y[i], T, 1, 0);
		}

		static pii p[MAXN + 5], q[MAXN + 5];

		for(int i = 1; i <= k; ++i) p[i] = q[i] = mp(0, 101);
		for(int i = 1; i <= k; ++i)
		{
			chkmax(p[i].fst, l0[i]);
			chkmin(p[i].snd, r0[k - i + 1]);
			chkmax(q[i].fst, l1[i]);
			chkmin(q[i].snd, r1[k - i + 1]);
		}
		for(int i = 2; i <= k; ++i)
		{
			chkmax(p[i].fst, p[i - 1].fst);
			chkmax(q[i].fst, q[i - 1].fst);
		}
		for(int i = k - 1; i >= 1; --i)
		{
			chkmin(p[i].snd, p[i + 1].snd);
			chkmin(q[i].snd, q[i + 1].snd);
		}

		static int in[MAXN + 5], out[MAXN + 5];

		for(int i = 1; i <= n; ++i)
		{
			in[i] = ++cnt, out[i] = ++cnt;
			FLOW::add_edge(in[i], out[i], 1, A[i].w);
			for(int j = 1; j <= k; ++j) if(p[j].fst < A[i].x && A[i].x < p[j].snd) FLOW::add_edge(X[j], in[i], 1, 0);
			for(int j = 1; j <= k; ++j) if(q[j].fst < A[i].y && A[i].y < q[j].snd) FLOW::add_edge(out[i], Y[j], 1, 0);
		}

		auto res = FLOW::solve(S, T, cnt);
		if(res.fst == k) chkmax(ans, res.snd);
	}

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

int main()
{
#ifndef ONLINE_JUDGE
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
#endif

	input();
	solve();

	return 0;
}



Measured memory_bytes: 896