#include <bits/stdc++.h>
using namespace std;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
using Int = long long;
const char newl = '\n';

template<typename T>
vector<T> shift(vector<T> vs,vector<T> as){
  assert(vs.size()==as.size());
  for(int i=0;i<(int)vs.size();i++) vs[i]+=as[i];
  return vs;
}
template<typename T>
vector<T> shift(vector<T> vs,T a){
  return shift(vs,vector<T>(vs.size(),a));
}

template<typename T, typename ...Ts>
vector<T> near(vector<T> vs,Ts... ts){
  vector<T> rs;
  rs.reserve(vs.size()*sizeof...(ts));
  auto append=[&](auto a){
    auto ws=shift(vs,a);
    for(auto w:ws) rs.emplace_back(w);
  };
  initializer_list<int>{(void(append(ts)),0)...};
  return rs;
}


template<typename T, typename ...Ts>
vector<T> fusion(vector<T> bs,Ts... ts){
  auto append=[&](auto vs){for(auto v:vs) bs.emplace_back(v);};
  initializer_list<int>{(void(append(ts)),0)...};
  return bs;
}

template<typename V>
V compress(V vs){
  sort(vs.begin(),vs.end());
  vs.erase(unique(vs.begin(),vs.end()),vs.end());
  return vs;
}
template<typename T>
map<T, int> dict(const vector<T> &vs){
  map<T, int> res;
  for(int i=0;i<(int)vs.size();i++)
    res[vs[i]]=i;
  return res;
}
map<char, int> dict(const string &s){
  return dict(vector<char>(s.begin(),s.end()));
}


template<typename T> void drop(const T &x){cout<<x<<endl;exit(0);}


template<typename T>
vector<T> make_v(size_t a){return vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

template<typename T,typename U,typename... V>
typename enable_if<is_same<T, U>::value!=0>::type
fill_v(U &u,const V... v){u=U(v...);}

template<typename T,typename U,typename... V>
typename enable_if<is_same<T, U>::value==0>::type
fill_v(U &u,const V... v){
  for(auto &e:u) fill_v<T>(e,v...);
}

//INSERT ABOVE HERE
signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m;
  cin>>n>>m;
  vector<int> as(n),bs(n),cs(n);
  for(int i=0;i<n;i++) cin>>as[i]>>bs[i]>>cs[i];

  vector<int> ds(m),es(m),fs(m);
  for(int i=0;i<m;i++) cin>>ds[i]>>es[i]>>fs[i];

  auto xs=fusion(near(as,-1,0),near(bs,0,1),near(ds,-1,0));
  auto ys=fusion(near(cs,-1,0),near(es,-1,0),near(fs,0,1));

  for(int v:{(int)0,(int)1,(int)1e9+1,(int)1e9+2,(int)1e9+3}){
    xs.emplace_back(+v);
    xs.emplace_back(-v);
    ys.emplace_back(+v);
    ys.emplace_back(-v);
  }

  xs=compress(xs);
  ys=compress(ys);
  auto dx=dict(xs);
  auto dy=dict(ys);

  auto wx=make_v<int>(dx.size(),dy.size());
  fill_v<int>(wx,0);

  for(int i=0;i<m;i++)
    for(int j=dy[es[i]];j<dy[fs[i]];j++)
      wx[dx[ds[i]]][j]=1;

  auto wy=make_v<int>(dx.size(),dy.size());
  fill_v<int>(wy,0);

  for(int i=0;i<n;i++)
    for(int j=dx[as[i]];j<dx[bs[i]];j++)
      wy[j][dy[cs[i]]]=1;

  auto con=[&](int cx,int cy,int nx,int ny){
    assert(abs(cx-nx)+abs(cy-ny)==1);
    if(cx>nx) swap(cx,nx),swap(cy,ny);
    if(cy>ny) swap(cx,nx),swap(cy,ny);
    if(cx==nx){
      assert(cy+1==ny);
      return wy[nx][ny]==0;
    }
    if(cy==ny){
      assert(cx+1==nx);
      return wx[nx][ny]==0;
    }
    abort();
  };

  using P = pair<int, int>;
  auto used=make_v<int>(dx.size(),dy.size());
  fill_v<int>(used,0);
  queue<P> que;
  auto push=[&](int x,int y){
    if(used[x][y]) return;
    used[x][y]=1;
    que.emplace(x,y);
  };

  push(dx[0],dy[0]);

  while(!que.empty()){
    auto [x,y]=que.front();que.pop();
    if(x==0 or x==(int)dx.size()-2) drop("INF");
    if(y==0 or y==(int)dy.size()-2) drop("INF");

    int kx[]={0,0,1,-1};
    int ky[]={1,-1,0,0};
    for(int k=0;k<4;k++){
      int nx=x+kx[k],ny=y+ky[k];
      if(con(x,y,nx,ny)) push(nx,ny);
    }
  }

  using ll = long long;
  ll ans=0;
  for(int i=0;i+1<(int)xs.size();i++)
    for(int j=0;j+1<(int)ys.size();j++)
      if(used[i][j]) ans+=(ll)(xs[i+1]-xs[i])*(ll)(ys[j+1]-ys[j]);

  cout<<ans<<newl;
  return 0;
}


Measured memory_bytes: 428016