#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<utility>

//壁の実際の座標を保存
struct L{
	int a, b, c;
	L(int a = 0, int b = 0, int c = 0) : a(a), b(b), c(c) {}
};

//マスの移動 direction
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int main(){
	int n, m;
	std::cin >> n >> m;

	std::map<int, int> mpx, mpy; //<実際の座標, 圧縮後のindex>
	mpx[0] = 0;
	mpy[0] = 0;
	std::vector<L> lh, lv; //線ごとの、実際の座標情報を持つ
	for(int i=0; i<n; i++){
		int a, b, c;
		std::cin >> a >> b >> c;
		mpx[a] = 0; //この段階では、要素の値は正直なんでも良い
		mpx[b] = 0;
		mpy[c] = 0;
		lh.emplace_back(a, b, c);
	}
	for(int i=0; i<m; i++){
		int a, b, c;
		std::cin >> c >> a >> b;
		mpy[a] = 0;
		mpy[b] = 0;
		mpx[c] = 0;
		lv.emplace_back(a, b, c);
	}

	// 座標圧縮
	//index順に実際の座標を記録する
	std::vector<int> sx, sy;
	for(auto& p : mpx){
		p.second = sx.size();
		sx.push_back(p.first);
	}
	for(auto& p : mpy){
		p.second = sy.size();
		sy.push_back(p.first);
	}

	// 壁を線ではなく、面積で扱う。圧縮した座標を2倍のサイズにする。
	int h = sx.size()*2; //horizontal
	int v = sy.size()*2; //vertical
	//壁の部分を-1とする配列を作る
	std::vector<std::vector<int>> d(h, std::vector<int>(v));
	for(int i=0; i<n; i++){
		int a = mpx[lh[i].a]*2;
		int b = mpx[lh[i].b]*2;
		int c = mpy[lh[i].c]*2;
		for(int x=a; x<=b; x++){
			d[x][c] = -1;
		}
	}
	for(int i=0; i<m; i++){
		int a = mpy[lv[i].a]*2;
		int b = mpy[lv[i].b]*2;
		int c = mpx[lv[i].c]*2;
		for(int y=a; y<=b; y++){
			d[c][y] = -1;
		}
	}

	//BFS
	std::queue<std::pair<int, int>> q;
	int tmpx = mpx[0]*2;
	int tmpy = mpy[0]*2;
	d[tmpx][tmpy] = 1;
	q.emplace(tmpx, tmpy);
	while(!q.empty()){
		int x = q.front().first;
		int y = q.front().second;
		q.pop();
		//移動
		for(int i=0; i<4; i++){
			int nx = x + dx[i];
			int ny = y + dy[i];
			if(nx >=h || nx < 0) continue;
			if(ny >=v || ny < 0) continue;
			if(d[nx][ny] != 0) continue;
			d[nx][ny] = 1;
			q.emplace(nx, ny);
		}
	}

	//到達しているマス(d = 1)の個数を数える
	//壁に到達せず、端のマスにたどり着いた場合、ans = INF
	long long ans = 0;
	for(int x=0; x<h; x++){
		for(int y=0; y<v; y++){
			if(d[x][y] != 1){ //到達できない
				continue;
			}
			if(x == 0 || x == h-1 || y == 0 || y == v-1){
				std::cout << "INF" << std::endl;
				return 0;
			}
			if(x%2  == 0 || y%2 == 0){ //壁
				continue;
			}
			//マスの圧縮前の面積を計算
			long long ex = sx[x/2 + 1] - sx[x/2];
			long long ey = sy[y/2 + 1] - sy[y/2];
			ans += ex * ey;

		}
	}
	std::cout << ans << std::endl;
	return 0;
}