#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mp make_pair
#define pb push_back

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, n) for (int i = 0; i < (int)(n); ++ i)
#define forall(it, c) for (__typeof(c.begin()) it = c.begin(); it != c.end(); ++ it)

template <typename T> inline void read(T &x) {
	x = 0; bool f = 1; char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = 0;
	for (;  isdigit(c); c = getchar()) x = x * 10 + (c & 15);
	if (!f) x = -x;
}

const int maxn = 3e3 + 5;
const int inf = 0x3f3f3f3f;
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};
int n, m;
int a[maxn], b[maxn], c[maxn];
int d[maxn], e[maxn], f[maxn];
int scol[maxn][maxn], srow[maxn][maxn];
bool vis[maxn][maxn];
int que[maxn * maxn * 2 + 5], ql, qr;
vector <int> vx, vy;
bool ok[maxn][maxn][4];

int main() {
	read(n); read(m);
	rep(i, n) read(a[i]), read(b[i]), read(c[i]);
	rep(i, m) read(d[i]), read(e[i]), read(f[i]);
	rep(i, n) vx.pb(a[i]), vx.pb(b[i]), vy.pb(c[i]);
	rep(i, m) vx.pb(d[i]), vy.pb(e[i]), vy.pb(f[i]);
	vx.pb(0); vy.pb(0);
	vx.pb(inf); vy.pb(inf);
	sort(vx.begin(), vx.end());
	vx.erase(unique(vx.begin(), vx.end()), vx.end());
	sort(vy.begin(), vy.end());
	vy.erase(unique(vy.begin(), vy.end()), vy.end());
#define f(v, x) (lower_bound((v).begin(), (v).end(), (x)) - (v).begin())
	rep(i, n) a[i] = f(vx, a[i]), b[i] = f(vx, b[i]), c[i] = f(vy, c[i]);
	rep(i, m) d[i] = f(vx, d[i]), e[i] = f(vy, e[i]), f[i] = f(vy, f[i]);
	int sx = f(vx, 0), sy = f(vy, 0);
	rep(i, n) scol[a[i]][c[i]] ++, scol[b[i]][c[i]] --;
	rep(i, m) srow[d[i]][e[i]] ++, srow[d[i]][f[i]] --;
	rep(i, vx.size()) rep(j, vy.size()) if (i) scol[i][j] += scol[i - 1][j];
	rep(i, vx.size()) rep(j, vy.size()) if (j) srow[i][j] += srow[i][j - 1];
	rep(i, vx.size() - 1) rep(j, vy.size() - 1) {
		// up
		if (srow[i][j]) ok[i][j][0] = 0;
		else ok[i][j][0] = 1;
		// dn
		if (srow[i + 1][j]) ok[i][j][1] = 0;
		else ok[i][j][1] = 1;
		// lft
		if (scol[i][j]) ok[i][j][2] = 0;
		else ok[i][j][2] = 1;
		// rgt
		if (scol[i][j + 1]) ok[i][j][3] = 0;
		else ok[i][j][3] = 1;
	}
//	rep(i, vx.size()) printf("%d ", vx[i]); puts("");
//	rep(i, vy.size()) printf("%d ", vy[i]); puts("");
	vis[sx][sy] = 1; que[qr ++] = sx; que[qr ++] = sy;
	ll ans = 0;
	while (ql < qr) {
		int x = que[ql ++], y = que[ql ++];
//		eprintf("[%d, %d) [%d, %d) rec\n", vx[x], vx[x + 1], vy[y], vy[y + 1]);
		ans += 1LL * (vx[x + 1] - vx[x]) * (vy[y + 1] - vy[y]);
		rep(d, 4) {
			if (!ok[x][y][d]) continue;
			int nx = x + dx[d], ny = y + dy[d];
//			eprintf(" -> %d %d\n", nx, ny);
			if (nx < 0 || ny < 0 || nx >= vx.size() - 1 || ny >= vy.size() - 1) {
				puts("INF"); return 0;
			}
			if (!vis[nx][ny]) {
				vis[nx][ny] = 1; que[qr ++] = nx; que[qr ++] = ny;
			}
		}
	}
	printf("%lld\n", ans);
	return 0;
}
