#include<bits/stdc++.h>
using namespace std;
 
#define INF 1234567890
#define ll long long

struct Hline {
	int x, sy, ey;
};

struct Wline {
	int y, sx, ex;
};

int N, M, SY = -1, SX = -1;
vector<int> Y, X;
vector<Hline> H;
vector<Wline> W;
map<int, int> newY, newX;
ll area[7070][7070];
bool vis[7070][7070], cutY[7070][7070], cutX[7070][7070];
int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

void DFS(int y, int x)
{
	vis[y][x] = true;
	for(int i=0; i<4; i++)
	{
		int ny = y + dir[i][0], nx = x + dir[i][1];
		if (nx < x && cutX[y][x]) continue;
		if (x < nx && cutX[y][x+1]) continue;
		if (ny < y && cutY[y][x]) continue;
		if (y < ny && cutY[y+1][x]) continue;
		if (ny < 0 || nx < 0 || ny >= (int)Y.size()-1 || nx >= (int)X.size()-1)
		{
			printf("INF");
			exit(0);
		}
		if (vis[ny][nx]) continue;
		DFS(ny, nx);
	}
}

void BFS(int sy, int sx)
{
	queue<pair<int, int> > q;
	q.push({sy, sx}); vis[sy][sx] = true;
	while(!q.empty())
	{
		int y = q.front().first, x = q.front().second; q.pop();
		for(int i=0; i<4; i++)
		{
			int ny = y + dir[i][0], nx = x + dir[i][1];
			if (nx < x && cutX[y][x]) continue;
			if (x < nx && cutX[y][x+1]) continue;
			if (ny < y && cutY[y][x]) continue;
			if (y < ny && cutY[y+1][x]) continue;
			if (ny < 0 || nx < 0 || ny >= (int)Y.size()-1 || nx >= (int)X.size()-1)
			{
				printf("INF");
				exit(0);
			}
			if (vis[ny][nx]) continue;
			q.push({ny, nx}); vis[ny][nx] = true;
		}
	}
}

int main()
{
	scanf("%d %d", &N, &M);
	for(int i=1; i<=N; i++) // 세로선
	{
		int sy, ey, x;
		scanf("%d %d %d", &sy, &ey, &x);
		H.push_back({x, sy, ey});
	}
	for(int i=1; i<=M; i++) // 가로선
	{
		int y, sx, ex;
		scanf("%d %d %d", &y, &sx, &ex);
		W.push_back({y, sx, ex});
	}

	// 좌표 압축
	for(int i=0; i<H.size(); i++)
	{
		X.push_back(H[i].x);
		Y.push_back(H[i].sy);
		Y.push_back(H[i].ey);
	}
	for(int i=0; i<W.size(); i++)
	{
		X.push_back(W[i].sx);
		X.push_back(W[i].ex);
		Y.push_back(W[i].y);
	}
	sort(Y.begin(), Y.end());
	sort(X.begin(), X.end());
	Y.erase(unique(Y.begin(), Y.end()), Y.end());
	X.erase(unique(X.begin(), X.end()), X.end());

	for(int i=0; i<Y.size(); i++)
		newY[Y[i]] = i;
	for(int i=0; i<X.size(); i++)
		newX[X[i]] = i;

	// 영역 넓이 전처리
	for(int i=0; i<(int)Y.size()-1; i++)
	{
		for(int j=0; j<(int)X.size()-1; j++)
		{
			area[i][j] = (ll)(Y[i+1]-Y[i])*(X[j+1]-X[j]);
			if (Y[i] <= 0 && 0 < Y[i+1] && X[j] <= 0 && 0 < X[j+1]) //
				SY = i, SX = j;
		}
	}

	// 컷 구하기
	for(int i=0; i<H.size(); i++)
	{
		int x = H[i].x, sy = H[i].sy, ey = H[i].ey;
		x = newX[x]; sy = newY[sy]; ey = newY[ey];
		for(int y=sy; y<ey; y++)
			cutX[y][x] = true;
	}
	for(int i=0; i<W.size(); i++)
	{
		int y = W[i].y, sx = W[i].sx, ex = W[i].ex;
		y = newY[y]; sx = newX[sx]; ex = newX[ex];
		for(int x=sx; x<ex; x++)
			cutY[y][x] = true;
	}

	// 상하좌우 밖으로 나갔을 때 예외 처리
	if (SY == -1 && SX == -1) return !printf("INF");
	// 도달 가능한 넓이 구하기
	BFS(SY, SX);

	ll res = 0;
	for(int i=0; i<7070; i++)
		for(int j=0; j<7070; j++)
			if (vis[i][j])
				res += area[i][j];
	printf("%lld", res);
	return 0;
}