#define LOCAL

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <list>
#include <ctime>
#include <sstream>
#include <queue>
#include <stack>
#include <random>
#include <bitset>
#include <numeric>
#include <cassert>
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;
#define rep(x, b, e) for(int x=(b); x<(e); ++x)
#define ford(x, b, e) for(int x=((int)(b))-1; x>=(e); --x)
#define all(c) c.begin(),c.end()
#define sz(x) ((int)((x).size()))
#define pb push_back
#define st first
#define nd second
#define mp(x,y) make_pair(x,y)
typedef short int sint;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it) {
	*this << ((it != d.b) ? ", " : "") << *it;
  }
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

const int inf = 1e9 + 5;
const int nax = 4 * 1010;
bool vis[nax][nax];
bool edge[nax][nax][4];
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};

int main() {
	ios_base::sync_with_stdio(false);
	int n, m;
	scanf("%d %d", &n, &m);
	vector<pair<int, pii>> pion(n), poz(m);
	vector<ll> rows, cols;
	rows.pb(-inf);
	rows.pb(0);
	rows.pb(inf);
	cols.pb(-inf);
	cols.pb(0);
	cols.pb(inf);
	rep(i, 0, n) {
		scanf("%d %d %d", &pion[i].nd.st, &pion[i].nd.nd, &pion[i].st);
		cols.pb(pion[i].st);
		rows.pb(pion[i].nd.st);
		rows.pb(pion[i].nd.nd);
	}
	rep(i, 0, m) {
		scanf("%d %d %d", &poz[i].st, &poz[i].nd.st, &poz[i].nd.nd);
		rows.pb(poz[i].st);
		cols.pb(poz[i].nd.st);
		cols.pb(poz[i].nd.nd);
	}
	// printf("Read\n");
	sort(all(rows)); sort(all(cols));
	rows.resize(unique(all(rows)) - rows.begin() - 1);
	cols.resize(unique(all(cols)) - cols.begin() - 1);
	// debug() << imie(sz(rows));
	// debug() << imie(sz(cols));
	int nn = rows.size();
	int mm = cols.size();
	rep(i, 0, nn) {
		rep(j,0,mm) {
			rep(dir, 0, 4) {
				int ni = i + dx[dir], nj = j + dy[dir];
				if (ni < 0 || ni >= nn || nj < 0 || nj >= mm) {
					continue;
				}
				edge[i][j][dir] = true;
				// printf("Adding edge: %d, %d, %d\n", i,j,dir);
			}
		}
	}
	rep(i, 0, n) {
		// printf("Pion: %d\n", i);
		int col = lower_bound(all(cols), pion[i].st) - cols.begin();
		int lower_row = lower_bound(all(rows), pion[i].nd.st) - rows.begin();
		int upper_row = lower_bound(all(rows), pion[i].nd.nd) - rows.begin();
		rep(row, lower_row, upper_row) {
			edge[row][col-1][0] = false;
			edge[row][col][2] = false;
			// printf("removing edge: %d->%d, %d\n", row,col-1, 0);
			// printf("removing edge: %d->%d, %d\n", row,col,2);
		}
	}
	rep(i, 0, m) {
		int row = lower_bound(all(rows), poz[i].st) - rows.begin();
		int lower_col = lower_bound(all(cols), poz[i].nd.st) - cols.begin();
		int upper_col = lower_bound(all(cols), poz[i].nd.nd) - cols.begin();
		rep(col, lower_col, upper_col) {
			edge[row-1][col][1] = false;
			edge[row][col][3] = false;
			// printf("removing edge: %d->%d, %d\n", row-1,col, 1);
			// printf("removing edge: %d->%d, %d\n", row,col,3);
		}
	}
	
	int srow = lower_bound(all(rows), 0) - rows.begin();
	int scol = lower_bound(all(cols), 0) - cols.begin();
	queue<pii> q;
	q.push({srow, scol});
	vis[srow][scol] = true;
	// debug() << "Start " imie(srow) imie(scol);
	while (!q.empty()) {
		pii cur = q.front(); q.pop();
		// debug() << "visiting: " imie(cur) " repr: " imie(rows[cur.st]) "-" imie(rows[cur.st+1]) "x" imie(cols[cur.nd]) "-" imie(cols[cur.nd+1]);
		rep(i,0,4) {
			if (!edge[cur.st][cur.nd][i]) {
				continue;
			}
			int nx = cur.st + dx[i], ny = cur.nd + dy[i];
			if (!vis[nx][ny]) {
				q.push({nx,ny});
				vis[nx][ny] = true;
			}
		}
	}
	rep(row,0,sz(rows)) {
		if (vis[row][0] || vis[row][sz(cols) - 1]) {
			cout << "INF\n";
			return 0;
		}
	}
	rep(col,0,sz(cols)) {
		if (vis[0][col] || vis[sz(rows)-1][col]) {
			cout << "INF\n";
			return 0;
		}
	}
	ll res = 0;
	rep(row,1,sz(rows)-1) {
		rep(col,1,sz(cols)-1) {
			if (vis[row][col]) {
				ll kw = (rows[row+1] - rows[row])*(cols[col+1] - cols[col]);
				res += kw;
			}
		}
	}
	cout << res << endl;
}

Measured memory_bytes: 62800