#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#define INF (int)(1e9 + 7)
#define maxn 3010
#define maxm 1010
using namespace std;
int n, m;//n代表竖线
int mup[maxn][maxn];
int mdown[maxn][maxn];
int mleft[maxn][maxn];
int mright[maxn][maxn];
int vis[maxn][maxn];
long long ans=0;
pair<int, int> temp;
int tempx, tempy;
int newx, newy;
pair<int, int> dir[4] = { {0,-1},{0,1},{-1,0},{1,0} };
bool flag = 0;

int a[maxm], b[maxm], c[maxm];
int d[maxm], e[maxm], f[maxm];

vector<int> xs;//存横分割
int xsize,ysize;
vector<int> ys;
queue<pair<int, int> > qu;
int main() {
	scanf("%d%d", &n, &m);
	xs.push_back(-INF);
	xs.push_back(INF);
	ys.push_back(-INF);
	ys.push_back(INF);
	xs.push_back(0);
	ys.push_back(0);
	for (int i = 0; i < n; i++) {
		scanf("%d%d%d", &a[i], &b[i], &c[i]);
		xs.push_back(a[i]);
		xs.push_back(b[i]);
		ys.push_back(c[i]);
	}
	for (int i = 0; i < m; i++) {
		scanf("%d%d%d", &d[i], &e[i], &f[i]);
		xs.push_back(d[i]);
		ys.push_back(e[i]);
		ys.push_back(f[i]);
	}
	
	//离散化的传统艺能
	//1.排序
	sort(xs.begin(), xs.end());
	sort(ys.begin(), ys.end());
	//2.去重
	xs.resize(unique(xs.begin(), xs.end()) - xs.begin());
	ys.resize(unique(ys.begin(), ys.end()) - ys.begin());
	//块分完了
	//xs[0] xs[1] ... 所有横分割（升序）
	//ys[0] ys[1] ... 所有竖分割（升序）
	//存储我们的四个方位数组
	//lower_bound(begin(),end(),k) —— 返回一个区域内，大于等于k的下标
	//等于的功能
	//所有竖线
	for (int i = 0; i < n; i++) {
		int xx = lower_bound(ys.begin(), ys.end(), c[i]) - ys.begin(); //返回横坐标
		int yy1 = lower_bound(xs.begin(), xs.end(), a[i]) - xs.begin(); //返回纵坐标起点
		int yy2 = lower_bound(xs.begin(), xs.end(), b[i]) - xs.begin(); //返回纵坐标终点
		for (int j = yy1; j < yy2; j++) {
			//代表的是，线段所覆盖的所有块
			mup[j][xx] = 1;
			mdown[j][xx-1] = 1;
		}
	}
	for (int i = 0; i < m; i++) {
		int yy = lower_bound(xs.begin(), xs.end(), d[i]) - xs.begin(); 
		int xx1 = lower_bound(ys.begin(), ys.end(), e[i]) - ys.begin(); 
		int xx2 = lower_bound(ys.begin(), ys.end(), f[i]) - ys.begin(); 
		for (int j = xx1; j < xx2; j++) {
			//代表的是，线段所覆盖的所有块
			mleft[yy][j] = 1;
			mright[yy-1][j] = 1;
		}
	}
	int x = lower_bound(xs.begin(), xs.end(), 0) - xs.begin();
	int y = lower_bound(ys.begin(), ys.end(), 0) - ys.begin();
	qu.push(pair<int, int>{x, y});
	xsize = xs.size();
	ysize = ys.size();
	while (!qu.empty()) {
		temp = qu.front();
		qu.pop();
		tempx = temp.first;
		tempy = temp.second;

		if (vis[tempx][tempy])continue;
		ans += (long long)(xs[tempx + 1] - xs[tempx]) * (long long)(ys[tempy + 1] - ys[tempy]);
		vis[tempx][tempy] = 1;
		if (tempx <= 0 || tempy <= 0) 
		{
			flag = 1; break;
	}
		if (tempx >= xsize - 1 || tempy >= ysize - 1) {
			flag = 1; break;
		}
		for (int i = 0; i < 4; i++) {
			if (i == 0 && mup[tempx][tempy]) continue;
			if (i == 1 && mdown[tempx][tempy]) continue;
			if (i == 2 && mleft[tempx][tempy]) continue;
			if (i == 3 && mright[tempx][tempy]) continue;
			newx = tempx + dir[i].first;
			newy = tempy + dir[i].second;
			qu.push(pair<int, int>(newx,newy));
		}
	}
	if (flag)printf("INF");
	else printf("%lld",ans);

}