#include <bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define VI vector<int>
#define VPII vector<PII>
#define LL long long
#define LD long double
#define f first
#define s second
#define MP make_pair
#define PB push_back
#define endl '\n'
#define ALL(c) (c).begin(), (c).end()
#define SIZ(c) (int)(c).size()
#define REP(i, n) for(int i = 0; i < (int)(n); ++i)
#define FOR(i, b, e) for(int i = (b); i <= (int)(e); ++i)
#define FORD(i, b, e) for(int i = (b); i >= (int)(e); --i)

#define sim template<class n
sim, class s> ostream & operator << (ostream &p, pair<n, s> x)
{return p << "<" << x.f << ", " << x.s << ">";}
sim> auto operator << (ostream &p, n y) ->
typename enable_if<!is_same<n, string>::value, decltype(y.begin(), p)>::type 
{int o = 0; p << "{"; for(auto c: y) {if(o++) p << ", "; p << c;} return p << "}";}
void dor() {cerr << endl;}
sim, class...s> void dor(n p, s...y) {cerr << p << " "; dor(y...);}
sim, class s> void mini(n &p, s y) {if(p>y) p = y;}
sim, class s> void maxi(n &p, s y) {if(p<y) p = y;}
#ifdef DEB
#define debug(...) dor(__FUNCTION__, ":", __LINE__, ": ", __VA_ARGS__)
#else
#define debug(...)
#endif 

#define I(x) #x " =", (x), " "
#define A(a, i) #a "[" #i " =", i, "] =", a[i], " "


LL INF = 6e18;
vector<pair<int, PII>> V[2];

map<int, set<PII>> MM[2]; 

const int MXN = 1005;
PII fu[MXN][MXN];
PII find(PII x){return fu[x.f][x.s] == x ? x : fu[x.f][x.s] = find(fu[x.f][x.s]);}
void unio(PII x, PII y)
  {
  x = find(x);
  y = find(y);
  fu[x.f][x.s] = y;
  }
int n, m;
LL pole(int a, int b)
  {
  if(a == 0 || a == n)return INF * 1.1;
  if(b == 0 || b == m)return INF * 1.1;
  PII s1 = {V[0][a-1].f, V[0][a].f};
  PII s2 = {V[1][b-1].f, V[1][b].f};
  return ((LL)s1.s - s1.f) * ((LL)s2.s - s2.f);
  }

PII gdzie_lezy(int x, int y)
  {
  int xx = 0;
  while(xx < V[0].size() && x > V[0][xx].f)xx++;

  int yy = 0;
  while(yy < V[1].size() && y > V[1][yy].f)yy++;
  return {xx, yy};
  }

bool connected_x(int x1, int y1, int x2, int y2)
  {
  if(y1 == 0 && y2 == 0)return 1;
  if(y1 == m && y2 == m)return 1;

  assert(y1 == y2);

//  debug(x1, x2, y1, y2);
  int ex = V[0][x1].f;
  for(auto rozdziela: MM[0][ex])
    {
    PII seg = {V[1][y1-1].f, V[1][y1].f};

    if(rozdziela.f <= seg.f && seg.s <= rozdziela.s)return 0;
    }

  return 1;
  }
bool connected_y(int x1, int y1, int x2, int y2)
  {
  if(x1 == 0 && x2 == 0)return 1;
  if(x1 == n && x2 == n)return 1;

  assert(x1 == x2);
  int ex = V[1][y1].f;
  for(auto rozdziela: MM[1][ex])
    {
    PII seg = {V[0][x1-1].f, V[0][x1].f};

    if(rozdziela.f <= seg.f && seg.s <= rozdziela.s)return 0;
    }
  return 1;
  }

int main()
  {
  ios_base::sync_with_stdio(0); 

  cin >> n >> m;
  REP(i, n)
    {
    int a, b, c;
    cin >> a >> b >> c;
    V[0].PB(MP(c, MP(a, b)));
    MM[0][c].insert(MP(a, b));
    }
  REP(i, m)
    {
    int a, b, c;
    cin >> c >> a >> b;
    V[1].PB(MP(c, MP(a, b)));
    MM[1][c].insert(MP(a, b));
    }

  REP(i, n+1)
    REP(j, m+1)fu[i][j] = {i, j};

  sort(ALL(V[0]));
  sort(ALL(V[1]));

  FOR(i, 0, n-1)
    FOR(j, 0, m)
      {
      if(connected_x(i, j, i+1, j))
        {
        unio({i, j}, {i+1, j});
        }
      }
  FOR(i, 0, n)
    FOR(j, 0, m-1)
      {
      if(connected_y(i, j, i, j+1))
        {
        unio({i, j}, {i, j+1});
        }
      }

  PII kro = gdzie_lezy(0, 0);
  PII spojna = find(kro);
  LL sum = 0;
  REP(i, n+1)
    REP(j, m+1)
      {
      if(find({i, j}) == spojna)
        {
        LL res = pole(i, j);
        if(res >= INF)
          {
          puts("INF");
          return 0;
          }
        sum += res;
        }
      }
  cout << sum << endl;
  }


Measured memory_bytes: 23328