use std::io::{self, BufRead};
use std::collections::BTreeSet;

pub fn lower_bound<T: Ord>(vec: &[T], val: T) -> usize {
  let mut lo = 0;
  let mut hi = vec.len();
  while hi - lo > 0 {
    let p = (hi + lo) / 2;
    if vec[p] < val {
      lo = p + 1;
    } else {
      hi = p;
    }
  }
  return lo;
}

fn dfs(visited: &mut Vec<Vec<bool>>, vbars: &Vec<Vec<bool>>, hbars: &Vec<Vec<bool>>, x: usize, y: usize) -> bool {
  if x == 0 || x == hbars[0].len() || y == 0 || y == vbars.len() {
    return false;
  }
  visited[x][y] = true;
  if !vbars[y-1][x-1] && !visited[x][y-1] && !dfs(visited, vbars, hbars, x, y - 1) {
    return false;
  }
  if !vbars[y][x-1] && !visited[x][y+1] && !dfs(visited, vbars, hbars, x, y + 1) {
    return false;
  }
  if !hbars[y-1][x-1] && !visited[x-1][y] && !dfs(visited, vbars, hbars, x - 1, y) {
    return false;
  }
  if !hbars[y-1][x] && !visited[x+1][y] && !dfs(visited, vbars, hbars, x + 1, y) {
    return false;
  }
  return true;
}

fn main() {
  let stdin = io::stdin();
  let mut lines = stdin.lock().lines();
  let zs: Vec<usize> = lines.next().unwrap().unwrap().split(' ').map(|x| x.parse().unwrap()).collect();
  let (n, m) = (zs[0], zs[1]);
  let mut vs: Vec<(i32, i32, i32)> = Vec::new();
  let mut hs: Vec<(i32, i32, i32)> = Vec::new();
  for _ in 0..n {
    let zs: Vec<i32> = lines.next().unwrap().unwrap().split(' ').map(|x| x.parse().unwrap()).collect();
    vs.push((zs[0], zs[1], zs[2]));
  }
  for _ in 0..m {
    let zs: Vec<i32> = lines.next().unwrap().unwrap().split(' ').map(|x| x.parse().unwrap()).collect();
    hs.push((zs[0], zs[1], zs[2]));
  }
  let ys: BTreeSet<i32> = vs.iter().map(|y| y.2).collect();
  let ys: Vec<i32> = ys.into_iter().collect();
  let xs: BTreeSet<i32> = hs.iter().map(|x| x.0).collect();
  let xs: Vec<i32> = xs.into_iter().collect();
  let mut visited: Vec<Vec<bool>> = vec![vec![false; xs.len() + 1]; ys.len() + 1];
  let mut vbars: Vec<Vec<bool>> = vec![vec![false; xs.len() - 1]; ys.len()];
  let mut hbars: Vec<Vec<bool>> = vec![vec![false; xs.len()]; ys.len() - 1];
  for i in 0..n {
    let (a, b, c) = vs[i];
    let k = lower_bound(&ys, c);
    for j in 0..(xs.len()-1) {
      let x1 = xs[j];
      let x2 = xs[j+1];
      if x1 < b && a < x2 {
        vbars[k][j] = true;
      }
    }
  }
  for j in 0..m {
    let (d, e, f) = hs[j];
    let k = lower_bound(&xs, d);
    for i in 0..(ys.len()-1) {
      let y1 = ys[i];
      let y2 = ys[i+1];
      if y1 < f && e < y2 {
        hbars[i][k] = true;
      }
    }
  }
  let x = lower_bound(&xs, 0);
  let y = lower_bound(&ys, 0);
  let ok = dfs(&mut visited, &vbars, &hbars, x, y);
  if !ok {
    println!("INF");
    return;
  }
  let mut ans: i64 = 0;
  for i in 0..(ys.len()-1) {
    for j in 0..(xs.len()-1) {
      if visited[i+1][j+1] {
        ans += ((ys[i+1] - ys[i]) * (xs[j+1] - xs[j])) as i64;
      }
    }
  }
  println!("{}", ans);
}