#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PII;

// chmax, chmin
template <class T>
inline bool chmax(T &a, T b)
{
  if (a < b)
  {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T &a, T b)
{
  if (a > b)
  {
    a = b;
    return 1;
  }
  return 0;
}

template <typename T>
function<T(T, T)> op_max = [](T a, T b) -> T { return max(a, b); };
template <typename T>
function<T(T, T)> op_min = [](T a, T b) -> T { return min(a, b); };

template <typename T>
function<T(T, T)> op_sum = [](T a, T b) -> T { return a + b; };

using namespace std;
//********************  dumps ************************//

template <typename T>
void dump(const T &data, vector<int> &iter)
{
  cout << data << " ";
}
template <typename T>
void dump(const vector<T> &data, vector<int> &iter)
{
  for (auto elem : data)
    dump(elem, iter);
  cout << endl;
}

template <typename T>
void dump(const vector<vector<T>> &data, vector<int> &iter)
{
  for (auto elem : iter)
  {
    cout << "[" << elem << "]";
  }
  cout << endl;
  for (int i = 0; i < data.size(); i++)
  {
    iter.push_back(i);
    dump(data[i], iter);
    iter.pop_back();
  }
  cout << endl;
}

template <typename T>
void dump(const vector<T> &data, int dummy)
{
  for (int i = 0; i < data.size(); i++)
  {
    cout << "[" << i << "] " << data[i] << endl;
  }
}
template <typename T>
void dump(const T &data)
{ // T : data, U = base type val.
  vector<int> iter;
  dump(data, iter);
}
///////////////////////////////////////////////

/**
 * 座標圧縮を行うライブラリ
 */
class CompressingValues
{
  map<LL, LL> mapping;
  vector<LL> restration;

public:
  CompressingValues(vector<LL> data)
  {
    sort(data.begin(), data.end());
    data.erase(unique(data.begin(), data.end()), data.end());
    restration.resize(data.size());
    for (int i = 0; i < data.size(); i++)
    {
      mapping[data[i]] = i;
      restration[i] = data[i];
    }
  }

  LL get_compressed(LL x)
  {
    if (mapping.find(x) == mapping.end())
      assert(false);
    return mapping[x];
  }

  LL get_original(LL x)
  {
    if (x < 0 || x >= restration.size())
      assert(false);
    return restration[x];
  }
};

// 使用例
/*

int main() {
  vector<LL> data = {1, 100, 10000, 100000, 100000000};
  CompressingValues cx(data);
  cout << cx.get_compressed(10000) << endl; // 2
  cout << cx.get_original(4) << endl; // 100000000
  return 0;
}

*/

void solve(long long N, long long M, std::vector<long long> A, std::vector<long long> B, std::vector<long long> C, std::vector<long long> D, std::vector<long long> E, std::vector<long long> F)
{

  vector<LL> xs = {0};
  vector<LL> ys = {0};
  for (auto x : A)
    xs.push_back(x);
  for (auto x : B)
    xs.push_back(x);
  for (auto x : D)
    xs.push_back(x);

  for (auto x : C)
    ys.push_back(x);
  for (auto x : E)
    ys.push_back(x);
  for (auto x : F)
    ys.push_back(x);

  CompressingValues xc(xs);
  CompressingValues yc(ys);

  LL H = 0, W = 0;
  for (auto x : xs)
    chmax(H, xc.get_compressed(x));
  for (auto y : ys)
    chmax(W, yc.get_compressed(y));

  vector<vector<int>> data(2 * H + 2, vector<int>(2 * W + 2, 0));

  for (int i = 0; i < N; i++)
  {
    LL a = xc.get_compressed(A[i]);
    LL b = xc.get_compressed(B[i]);
    LL c = yc.get_compressed(C[i]);

    for (int j = 2 * a; j <= 2 * b; j++)
    {
      data[j][2 * c] = 1;
    }
  }

  for (int i = 0; i < M; i++)
  {

    LL d = xc.get_compressed(D[i]);
    LL e = yc.get_compressed(E[i]);
    LL f = yc.get_compressed(F[i]);
    for (int j = 2 * e; j <= 2 * f; j++)
    {
      data[2 * d][j] = 1;
    }
  }

  int posx = xc.get_compressed(0);
  int posy = yc.get_compressed(0);
  stack<PII> sta;
  sta.push(PII(2 * posx, 2 * posy));

  LL ans = 0;
  bool out = false;
  while (!sta.empty())
  {
    PII cur = sta.top();
    sta.pop();
    int x = cur.first;
    int y = cur.second;
    data[x][y] = 2;
    if (x == 0 || y == 0 || x == 2 * H || y == 2 * W)
    {
      out = true;
      break;
    }
    if (x % 2 == 1 && y % 2 == 1)
    {
      int z = x / 2;
      int w = y / 2;
      LL dx = xc.get_original(z + 1) - xc.get_original(z);
      LL dy = yc.get_original(w + 1) - yc.get_original(w);
      ans += dx * dy;
    }
    vector<int> dx = {1, -1, 0, 0};
    vector<int> dy = {0, 0, 1, -1};
    for (int d = 0; d < 4; d++)
    {
      int nx = x + dx[d];
      int ny = y + dy[d];
      if (data[nx][ny] == 0)
      {
        data[nx][ny] = 2;
        sta.push(PII(nx, ny));
      }
    }
  }
  if (out)
  {
    cout << "INF" << endl;
  }
  else
    cout << ans << endl;
}

int main()
{
  cout << setprecision(10);
  long long N;
  scanf("%lld", &N);
  long long M;
  scanf("%lld", &M);
  std::vector<long long> A(N);
  std::vector<long long> B(N);
  std::vector<long long> C(N);
  for (int i = 0; i < N; i++)
  {
    scanf("%lld", &A[i]);
    scanf("%lld", &B[i]);
    scanf("%lld", &C[i]);
  }
  std::vector<long long> D(M);
  std::vector<long long> E(M);
  std::vector<long long> F(M);
  for (int i = 0; i < M; i++)
  {
    scanf("%lld", &D[i]);
    scanf("%lld", &E[i]);
    scanf("%lld", &F[i]);
  }
  solve(N, M, std::move(A), std::move(B), std::move(C), std::move(D), std::move(E), std::move(F));
  return 0;
}


Measured memory_bytes: 310684