#ifdef MY_LOCAL
#define MY_NAMESPACE(ns) namespace ns {
#define MY_NAMESPACE_    }
#define MY_DEBUG
#else
#define MY_NAMESPACE(ns) 
#define MY_NAMESPACE_    
#define MY_DEBUG         //
#endif

#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;


MY_NAMESPACE(testbed)
void dump(vector<vector<int>> const& field)
{
	cerr << "\n" << flush;
	for (size_t i = 0; i < field.size(); i++)
	{
		for (size_t j = 0; j < field[i].size(); j++)
		{
			cerr << field[i][j] << " ";
		}
		cerr << "\n";
	}
	cerr << "\n" << flush;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m;
	cin >> n >> m;
	vector<tuple<int, int, int>> xlines(n), ylines(m);
	map<int, int> xpoints, ypoints;  // address lookup
	xpoints[0] = -1;  // initial location of the cow
	ypoints[0] = -1;
	for (int i = 0; i < n; i++)
	{
		int a, b, c;
		cin >> a >> b >> c;
		xlines[i] = { a, b, c };
		xpoints[a] = -1;
		xpoints[b] = -1;
		ypoints[c] = -1;
	}
	for (int j = 0; j < m; j++)
	{
		int d, e, f;
		cin >> d >> e >> f;
		ylines[j] = { d, e, f };
		xpoints[d] = -1;
		ypoints[e] = -1;
		ypoints[f] = -1;
	}
	vector<int> xgrid, ygrid;
	for (auto& it : xpoints)
	{
		it.second = xgrid.size();
		xgrid.emplace_back(it.first);
	}
	for (auto& it : ypoints)
	{
		it.second = ygrid.size();
		ygrid.emplace_back(it.first);
	}

	int fsizex = xgrid.size() * 2 - 1;
	int fsizey = ygrid.size() * 2 - 1;
	vector<vector<int>> field(fsizex, vector<int>(fsizey));
	for (auto it : xlines)
	{
		for (int i = xpoints[get<0>(it)] * 2; i <= xpoints[get<1>(it)] * 2; i++)
		{
			field[i][ypoints[get<2>(it)] * 2] = 2;  // 2:fence
		}
	}
	for (auto it : ylines)
	{
		for (int j = ypoints[get<1>(it)] * 2; j <= ypoints[get<2>(it)] * 2; j++)
		{
			field[xpoints[get<0>(it)] * 2][j] = 2;
		}
	}
	//MY_DEBUG dump(field);

	int dx0[] = { -1, -1, 1, 1 };
	int dy0[] = { -1, 1, -1, 1 };
	bool is_inf = false;
	queue<pii> bfs;
	int xpoint0 = xpoints[0];
	int ypoint0 = ypoints[0];
	for (int k = 0; k < 4; k++)
	{
		int this_fx = xpoint0 * 2 + dx0[k];
		int this_fy = ypoint0 * 2 + dy0[k];
		if (0 <= this_fx && this_fx < fsizex && 0 <= this_fy && this_fy < fsizey)
		{
			field[this_fx][this_fy] = 1;
			bfs.push(make_pair(this_fx, this_fy));
		}
	}
	while (!bfs.empty())
	{
		int this_fx = bfs.front().first;
		int this_fy = bfs.front().second;
		bfs.pop();

		int dx[] = { -1, 0, 1, 0 };
		int dy[] = { 0, -1, 0, 1 };
		for (int k = 0; k < 4; k++)
		{
			int next_fx = this_fx + dx[k];
			int next_fy = this_fy + dy[k];
			if (field[next_fx][next_fy] == 2)
				continue;
			next_fx += dx[k];
			next_fy += dy[k];

			if (next_fx < 0 || fsizex <= next_fx || next_fy < 0 || fsizey <= next_fy)
			{
				cout << "INF" << "\n";
				return 0;
			}
			if (field[next_fx][next_fy] == 0)
			{
				field[next_fx][next_fy] = 1;
				bfs.push(make_pair(next_fx, next_fy));
			}
		}
	}
	//MY_DEBUG dump(field);

	ll count = 0;
	for (int i = 1; i < fsizex; i += 2)
	{
		for (int j = 1; j < fsizey; j += 2)
		{
			if (field[i][j] == 1)
				count += ((ll)xgrid[(i + 1) / 2] - (ll)xgrid[(i - 1) / 2]) * ((ll)ygrid[(j + 1) / 2] - (ll)ygrid[(j - 1) / 2]);
		}
	}
	cout << count << "\n";
	return 0;
}
MY_NAMESPACE_

Measured memory_bytes: 144440