#include <bits/stdc++.h>
using namespace std;

#define pb push_back

#define jael(args...) { string  _s =#args; replace(_s.begin(), _s.end(), ',',' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args);}
void err(istream_iterator<string> it){}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args){
    cout <<  *it  << " : " << a << endl;
    err(++it, args...);
}


const int N=4010,inf = 1e9 + 7;
int a[N],b[N],c[N],d[N],e[N],f[N];
int uu[N][N],dd[N][N],ll[N][N],rr[N][N];
bool vis[N][N];

int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};

int main(){

	std::ios::sync_with_stdio(0); std::cin.tie(0);

	int n,m; cin>>n>>m;
	vector<int>  xs,ys;
	xs.pb(inf),xs.pb(inf*-1);
	ys.pb(inf),ys.pb(inf*-1);

	for(int i=0;i<n;i++){
		cin>>a[i]>>b[i]>>c[i];
		xs.pb(a[i]),xs.pb(b[i]);
		ys.pb(c[i]);
	}
	for(int i=0;i<m;i++){
		cin>>d[i]>>e[i]>>f[i];
		xs.pb(d[i]);
		ys.pb(e[i]),ys.pb(f[i]);
	}

	// la magie opère ici
	sort(xs.begin(),xs.end()),sort(ys.begin(),ys.end());
	xs.resize(unique(xs.begin(),xs.end())-xs.begin());
	ys.resize(unique(ys.begin(),ys.end())-ys.begin());

	for(int i=0;i<n;i++){ // ici on remplit les contraintes de mouvements de haut en bas
		int x1=lower_bound(xs.begin(),xs.end(),a[i])-xs.begin();
		int x2=lower_bound(xs.begin(),xs.end(),b[i])-xs.begin();
		int y=lower_bound(ys.begin(),ys.end(),c[i])-ys.begin();
		for(int j=x1;j<x2;j++){
			uu[j][y-1]=1;
			dd[j][y]=1;
		}
	}

	for(int i=0;i<m;i++){// ici on remplit les contraintes de mouvements gauche et droite
		int x=lower_bound(xs.begin(),xs.end(),d[i])-xs.begin();
		int y1=lower_bound(ys.begin(),ys.end(),e[i])-ys.begin();
		int y2=lower_bound(ys.begin(),ys.end(),f[i])-ys.begin();
		for(int j=y1;j<y2;j++){
			rr[x-1][j]=1;
			ll[x][j]=1;
		}
	}
	////////ici se termine la magie /////////
	////////////////////////////////////////

	int x=lower_bound(xs.begin(),xs.end(),0)-xs.begin();
	int y=lower_bound(ys.begin(),ys.end(),0)-ys.begin();
	x--,y--;

	//trace(x,y);
	///////////////// largeur première recherche //////////////////////

	queue<pair<int,int> > q;
	q.push({x,y});
	vis[x][y]=1;
	//trace(q.size())	;
	while(!q.empty()){
		int xf=q.front().first;
		int yf=q.front().second;
		//trace(xf,yf,vis[xf][yf]);
		q.pop();
		for(int i=0;i<4;i++){
			if(i==0 and uu[xf][yf]) continue;
			if(i==1 and dd[xf][yf]) continue;
			if(i==2 and rr[xf][yf]) continue;
			if(i==3 and ll[xf][yf]) continue;
			int nx=xf+dx[i],ny=yf+dy[i];
			if(nx<0 or nx>=xs.size()-1 or ny<0 or ny>=ys.size()-1) continue;
			if(vis[nx][ny]) continue;
			vis[nx][ny]=true;
			q.push({nx,ny});
		}
	}

	////////////////////////////////////////////////////////////////

	if(vis[0][0] or vis[xs.size()-1][ys.size()-1]){cout<<"INF"<<endl;return 0;}

	long long wyn=0;
	for(int i=0;i<xs.size()-1;i++){
		for(int j=0;j<ys.size()-1;j++){
			if(vis[i][j]) {
			//	trace(i,j);
				wyn+=(long long)(xs[i+1]-xs[i])*(ys[j+1]-ys[j]);
			}
		}
	}
	cout<<wyn<<endl;

	return 0;
}