#pragma GCC optimize ("O3")
// #pragma GCC target ("avx")
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<string.h>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...) do {} while (0)
#endif
#include<cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)

template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
    for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
    putchar('\n');
}

const int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
const int dx[] = {1, 1, 0, -1, -1, -1, 0, 1 };

struct Ve {
    int x;
    int y0, y1;
};
struct Ho {
    int x0, x1;
    int y;
};

int N, M;
Ve V[1011];
Ho H[1011];

const int SIZE = 6011;
char F[SIZE][SIZE];

bool in(int y, int x) {
    return 0 <= y && y < SIZE && 0 <= x && x < SIZE;
}

void MAIN() {
    scanf("%d%d", &N, &M);
    REP (i, N) {
	int a, b, c;
	scanf("%d%d%d", &a, &b, &c);
	V[i].x = c;
	V[i].y0 = a;
	V[i].y1 = b;
    }
    REP (i, M) {
	int a, b, c;
	scanf("%d%d%d", &a, &b, &c);
	H[i].y = a;
	H[i].x0 = b;
	H[i].x1 = c;
    }

    VI xs, ys;
    REP (i, N) {
	xs.push_back(V[i].x);
	ys.push_back(V[i].y0);
	ys.push_back(V[i].y1);
    }
    REP (i, M) {
	xs.push_back(H[i].x0);
	xs.push_back(H[i].x1);
	ys.push_back(H[i].y);
    }

    const int INF = 1000000001;
    xs.push_back(-INF);
    xs.push_back(INF);
    ys.push_back(-INF);
    ys.push_back(INF);
    xs.push_back(0);
    ys.push_back(0);
    sort(xs.begin(), xs.end());
    xs.erase(unique(xs.begin(), xs.end()), xs.end());
    sort(ys.begin(), ys.end());
    ys.erase(unique(ys.begin(), ys.end()), ys.end());

    auto get_x = [&](int x) {
	int k = lower_bound(xs.begin(), xs.end(), x) - xs.begin();
	return k*2;
    };

    auto get_y = [&](int y) {
	int k = lower_bound(ys.begin(), ys.end(), y) - ys.begin();
	return k*2;
    };

    REP (i, N) {
	int x = get_x(V[i].x);
	int y0 = get_y(V[i].y0);
	int y1 = get_y(V[i].y1);
	if (y0 > y1) swap(y0, y1);
	for (int y=y0; y<=y1; y++) F[y][x] = 1;
    }
    REP (i, M) {
	int x0 = get_x(H[i].x0);
	int x1 = get_x(H[i].x1);
	int y = get_y(H[i].y);
	if (x0 > x1) swap(x0, x1);
	for (int x=x0; x<=x1; x++) F[y][x] = 1;
    }

    int x = get_x(0);
    int y = get_y(0);
    vector<pair<int, int> > stk;
    stk.emplace_back(y, x);
    LL ans = 0;
    F[y][x] = 2;
    while (!stk.empty()) {
	y = stk.back().first;
	x = stk.back().second;
	stk.pop_back();
	REP (d, 8) {
	    int yy = y + dy[d];
	    int xx = x + dx[d];
	    if (!in(yy, xx)) {
		ans = -1;
		goto END;
	    }

	    if (F[yy][xx] == 0) {
		F[yy][xx] = 2;
		if ((yy & 1) && (xx & 1)) {
		    LL a = xs[xx/2+1] - xs[xx/2];
		    LL b = ys[yy/2+1] - ys[yy/2];
		    ans += a*b;
		}
		stk.emplace_back(yy, xx);
	    }
	}
    }

END:;

    if (ans == -1) puts("INF");
    else printf("%lld\n", ans);
}

int main() {
    int TC = 1;
//    scanf("%d", &TC);
    REP (tc, TC) MAIN();
    return 0;
}



Measured memory_bytes: 102800