#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp> 
using namespace std;
//using namespace __gnu_pbds; 

#define rep(i,a,b) for(ll i = (ll)(a); i < (ll)(b); i++)
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define trace(x) cout << #x << ": " << x << endl
#define all(x) (x).begin(), (x).end()
#define sz(x) (x).size()
#define fill(x,v) memset(x, v, sizeof(x))
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

typedef long long ll;
typedef unsigned long long ull;
typedef vector<ll> vi;
typedef pair<ll,ll> ii;
typedef vector<ii> vii;

set<int> ver, hor;
unordered_map<int,int> posH, posV;//mapaH, mapaV;
unordered_map<int,int> mapaH,mapaV;//mapaH[3010], mapaV[3010];

set<int> adj[3100][3100];//[9500000];
//unordered_map<int,unordered_set<int> > adj;

vector<pair<ii,ll> > arrV;
vector<pair<ll,ii> > arrH;

ll grid[3100][3100];
bool vis[3100][3100];

int movX[] = {1,0,-1,0};
int movY[] = {0,1,0,-1};

int f(ll x,ll y){
  return 3110*x + y;
}

pair<ll,bool> dfs(int x, int y){
  vis[x][y] = true;
  
  stack<pair<int, int> > pila;
  pila.push(mp(x,y));
  ll x1,y1;
  pair<ll,bool> rpta = mp(0,true);
  while(pila.size()){
    pair<int, int> nodo = pila.top();
   // trace(nodo.ff);
    //trace(nodo.ss);
    pila.pop();
    rpta.ff += grid[nodo.ff][nodo.ss];
    if(grid[nodo.ff][nodo.ss] == -1){
     // trace(grid[nodo.ff][nodo.ss]);
      rpta.ss  = false; 
      break;
    }
    rep(i,0,4){
      x1 = nodo.ff + movX[i];
      y1 = nodo.ss + movY[i];
      if(!vis[x1][y1] && !(adj[nodo.ff][nodo.ss].count(f(x1,y1)))){
        vis[x1][y1] = true;
        pila.push(mp(x1,y1));
      }
    }
  }
  return rpta;
}

int main(){
  fastio;
  fill(vis,0);
  int n,m;
  ll a,b,c,d,e,f1;
  cin >> n >> m;
  hor.insert(0);
  ver.insert(0);
  rep(i,0,n){
    cin >> a >> b >> c;
    hor.insert(a);
    hor.insert(b);
    ver.insert(c);
    arrV.pb(mp(mp(a,b),c));
  }
  
  rep(j,0,m){
    cin >> d >> e >> f1;
    hor.insert(d);
    ver.insert(e);
    ver.insert(f1);
    arrH.pb(mp(d,mp(e,f1)));
  }
  int indH = 0;
  for(set<int>::iterator it  = hor.begin(); it != hor.end(); it++){
    int x = *it;
    posH[x] = indH;
    mapaH[indH++] = x;
  }
  int indV = 0;
  for(set<int>::iterator it  = ver.begin(); it != ver.end(); it++){
    int x = *it;
    posV[x] = indV;
    mapaV[indV++] = x;
  }
 // ll grid[indH+1][indV+1];
  ll val,dy,dx;
  rep(i,0,indH+1){
    rep(j,0,indV+1){
      if(i == 0 || i == indH) val = -1;
      else if(j == 0 || j == indV) val = -1;
      else{
        dy = mapaV[j] - mapaV[j-1];
        dx = mapaH[i] - mapaH[i-1];
        val = dy*dx;
      // trace(val);
      }
      grid[i][j] = val;
    }
  }
  rep(i,0,indH+1){
    rep(j,0,indV+1){
    //  cout << grid[i][j] << " ";
    }
  //  cout << endl;
  }
  
  ll p,q,h1,h2,v;
  rep(i,0,n){
    h1 = posH[arrV[i].ff.ff];
    h2 = posH[arrV[i].ff.ss];
    v = posV[arrV[i].ss];
    rep(j,h1+1,h2+1){
      p = f(j,v);//2000*j + v;
      q = f(j,v+1);//2000*j + v + 1;
      adj[j][v].insert(q);
      adj[j][v+1].insert(p);
    }
  }
  
  ll h, v1,v2;
  rep(i,0,m){
    h = posH[arrH[i].ff];
    v1 = posV[arrH[i].ss.ff];
    v2 = posV[arrH[i].ss.ss];
   // trace(h);
    //trace(v1);
    //trace(v2);
    rep(j,v1+1,v2+1){
      p = f(h,j);//2000*h + j;
      q = f(h+1,j);//2000*(h+1) + j;
      adj[h][j].insert(q);
      adj[h+1][j].insert(p);
    }
  }
  
  pair<ll,bool> rpta = dfs(posH[0], posV[0]);
  
  if(rpta.ss) cout << rpta.ff << endl;
  else cout << "INF" << endl;
  
  return 0;
} 

Measured memory_bytes: 866460