#define _CRT_SECURE_NO_WARNINGS
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#define rep(i,n) for(int i=0;i<(lint)(n);i++)
#define REP(i,n) for(int i=1;i<=(lint)(n);i++)
#define all(V) V.begin(),V.end()
typedef long long lint;
typedef unsigned long long ulint;
typedef std::pair<lint, lint> P;
constexpr int INF = INT_MAX/2;
constexpr lint LINF = LLONG_MAX/2;
constexpr double eps = DBL_EPSILON;
constexpr double PI=3.141592653589793238462643383279;
template<class T>
class prique :public std::priority_queue<T, std::vector<T>, std::greater<T>> {};
template <class T, class U>
inline bool chmax(T& lhs, const U& rhs) {
	if (lhs < rhs) {
		lhs = rhs;
		return 1;
	}
	return 0;
}
template <class T, class U>
inline bool chmin(T& lhs, const U& rhs) {
	if (lhs > rhs) {
		lhs = rhs;
		return 1;
	}
	return 0;
}
inline lint gcd(lint a, lint b) {
	while (b) {
		lint c = a;
		a = b; b = c % b;
	}
	return a;
}
inline lint lcm(lint a, lint b) {
	return a / gcd(a, b) * b;
}
bool isprime(lint n) {
	if (n == 1)return false;
	for (int i = 2; i * i <= n; i++) {
		if (n % i == 0)return false;
	}
	return true;
}
template<typename T>
T mypow(T a, unsigned int b) {
	if (!b)return T(1);
	if (b & 1)return mypow(a, b - 1) * a;
	T memo = mypow(a, b >> 1);
	return memo * memo;
}
lint modpow(lint a, lint b, lint m) {
	if (!b)return 1;
	if (b & 1)return modpow(a, b - 1, m) * a % m;
	lint memo = modpow(a, b >> 1, m);
	return memo * memo % m;
}
template<typename T>
void printArray(std::vector<T>& vec) {
	rep(i, vec.size() - 1)std::cout << vec[i] << " ";
	std::cout << vec.back() << std::endl;
}
template<typename T>
void printArray(T l, T r) {
	T rprev = r;
	rprev--;
	for (T i = l; i != rprev; i++) {
		std::cout << *i << " ";
	}
	std::cout << *rprev << std::endl;
}
template<typename T>
class Compression{
	std::vector<T> vec;
	bool built=false;
public:
	Compression(){}
	Compression(const std::vector<T>& initvec):vec(initvec){}
	void push(const T& val){vec.emplace_back(val);}
	void build(){
		std::sort(all(vec));
		vec.erase(std::unique(all(vec)),vec.end());
		built=true;
	}
	int operator[](const T& val){
		assert(built);
		return std::lower_bound(all(vec),val)-vec.begin();
	}
	T at(int p){
		assert(built);
		return vec[p];
	}
	unsigned int size(){return vec.size();}
};
lint n,m,a[1010],b[1010],c[1010],d[1010],e[1010],f[1010];
int grid[4010][4010];
bool used[4010][4010];
std::vector<int> xvec,yvec;
Compression<lint> xcomp,ycomp;
lint ans;
int g[]={0,1,0,-1};
int h[]={1,0,-1,0};
int main(){
	std::cin>>n>>m;
	xcomp.push(-LINF);xcomp.push(1);xcomp.push(LINF);
	ycomp.push(-LINF);ycomp.push(1);ycomp.push(LINF);
	rep(i,n){
		std::cin>>a[i]>>b[i]>>c[i];
		a[i]*=2;b[i]*=2;c[i]*=2;
		xcomp.push(a[i]);
		xcomp.push(b[i]+1);
		ycomp.push(c[i]);
		ycomp.push(c[i]+1);
	}
	rep(i,m){
		std::cin>>d[i]>>e[i]>>f[i];
		d[i]*=2;e[i]*=2;f[i]*=2;
		ycomp.push(e[i]);
		ycomp.push(f[i]+1);
		xcomp.push(d[i]);
		xcomp.push(d[i]+1);
	}
	xcomp.build();
	ycomp.build();
	rep(i,n){
		grid[xcomp[a[i]]][ycomp[c[i]]]++;
		grid[xcomp[b[i]+1]][ycomp[c[i]]]--;
		grid[xcomp[a[i]]][ycomp[c[i]+1]]--;
		grid[xcomp[b[i]+1]][ycomp[c[i]+1]]++;
	}
	rep(i,m){
		grid[xcomp[d[i]]][ycomp[e[i]]]++;
		grid[xcomp[d[i]]][ycomp[f[i]+1]]--;
		grid[xcomp[d[i]+1]][ycomp[e[i]]]--;
		grid[xcomp[d[i]+1]][ycomp[f[i]+1]]++;
	}
	rep(i,xcomp.size()-1){
		rep(j,(int)ycomp.size())grid[i+1][j]+=grid[i][j];
	}
	rep(i,xcomp.size()){
		rep(j,(int)ycomp.size()-1)grid[i][j+1]+=grid[i][j];
	}
	std::queue<std::pair<int,int>> que;
	que.push({xcomp[1],ycomp[1]});
	used[xcomp[1]][ycomp[1]]=true;
	while(!que.empty()){
		P p=que.front();que.pop();
		int x=p.first,y=p.second;
		if(x==0||y==0||x==(int)xcomp.size()-1||y==(int)ycomp.size()-1){
			puts("INF");
			exit(0);
		}
		lint hl=xcomp.at(x+1)-xcomp.at(x),wl=ycomp.at(y+1)-ycomp.at(y);
		if(xcomp.at(x)%2)hl++;
		if(ycomp.at(y)%2)wl++;
		hl/=2;wl/=2;
		ans+=hl*wl;
		rep(i,4){
			int nx=x+g[i],ny=y+h[i];
			if(nx<0||xcomp.size()<=nx||ny<0||ycomp.size()<=ny)continue;
			if(!grid[nx][ny]&&!used[nx][ny]){
				used[nx][ny]=true;
				que.push({nx,ny});
			}
		}
	}
	std::cout<<ans<<std::endl;
	return 0;
}


Measured memory_bytes: 82128