use std::collections::{BTreeMap, BTreeSet, VecDeque};

fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());
    let n: usize = sc.read();
    let m: usize = sc.read();

    let mut is = vec![0];
    let mut js = vec![0];
    let mut vertical = vec![];
    for _ in 0..n {
        let from_i: i64 = sc.read();
        let to_i: i64 = sc.read();
        let fixed_j: i64 = sc.read();

        let (from_i, to_i) = if from_i > to_i {
            (to_i, from_i)
        } else {
            (from_i, to_i)
        };

        vertical.push(((from_i, to_i), fixed_j));

        is.push(from_i);
        is.push(to_i);
        js.push(fixed_j);
    }

    let mut horizontal = vec![];
    for _ in 0..m {
        let fixed_i: i64 = sc.read();
        let from_j: i64 = sc.read();
        let to_j: i64 = sc.read();

        let (from_j, to_j) = if from_j > to_j {
            (to_j, from_j)
        } else {
            (from_j, to_j)
        };

        horizontal.push(((from_j, to_j), fixed_i));

        is.push(fixed_i);
        js.push(from_j);
        js.push(to_j);
    }

    is.sort();
    js.sort();
    is.dedup();
    js.dedup();
    assert!(is.len() >= 2);
    assert!(js.len() >= 2);

    let h = is.len() + 1;
    let w = js.len() + 1;

    let horizontal_lines = make_line_map(&is, &js, &horizontal);
    let vertical_lines = make_line_map(&js, &is, &vertical);

    let mut map = vec![vec![false; w]; h];
    let si = is.binary_search(&0).unwrap();
    let sj = js.binary_search(&0).unwrap();
    map[si][sj] = true;
    map[si + 1][sj] = true;
    map[si][sj + 1] = true;
    map[si + 1][sj + 1] = true;
    let mut q = VecDeque::new();
    q.push_back((si, sj));
    q.push_back((si + 1, sj));
    q.push_back((si, sj + 1));
    q.push_back((si + 1, sj + 1));
    while let Some((i, j)) = q.pop_front() {
        for &(di, dj) in [(0, !0), (0, 1), (!0, 0), (1, 0)].iter() {
            let ni = i.wrapping_add(di);
            let nj = j.wrapping_add(dj);
            if ni >= h || nj >= w {
                continue;
            }

            let mut conflict = false;
            if ni == i {
                if j < nj {
                    if let Some((_, &to_x)) = vertical_lines[j].range(..i).next_back() {
                        if i <= to_x {
                            conflict = true;
                        }
                    }
                } else {
                    if let Some((_, &to_x)) = vertical_lines[nj].range(..i).next_back() {
                        if i <= to_x {
                            conflict = true;
                        }
                    }
                }
            } else {
                if i < ni {
                    if let Some((_, &to_y)) = horizontal_lines[i].range(..j).next_back() {
                        if j <= to_y {
                            conflict = true;
                        }
                    }
                } else {
                    if let Some((_, &to_y)) = horizontal_lines[ni].range(..j).next_back() {
                        if j <= to_y {
                            conflict = true;
                        }
                    }
                }
            }

            if conflict {
                continue;
            }

            if map[ni][nj] {
                continue;
            }
            map[ni][nj] = true;
            q.push_back((ni, nj));
        }
    }

    for i in 0..h {
        if map[i][0] || map[i][w - 1] {
            println!("INF");
            return;
        }
    }

    for j in 0..w {
        if map[0][j] || map[h - 1][j] {
            println!("INF");
            return;
        }
    }

    let mut ans = 0;
    for i in 0..h {
        for j in 0..w {
            if map[i][j] {
                let dx = is[i] - is[i - 1];
                let dy = js[j] - js[j - 1];
                ans += dx * dy;
            }
        }
    }

    println!("{}", ans);
}

fn make_line_map(
    is: &[i64],
    js: &[i64],
    horizontal: &[((i64, i64), i64)],
) -> Vec<BTreeMap<usize, usize>> {
    let h = is.len() + 1;
    let mut horizontal_lines = vec![BTreeMap::new(); h - 1];
    for &((from_j, to_j), fixed_i) in horizontal.iter() {
        let mut from_j = js.binary_search(&from_j).unwrap();
        let mut to_j = js.binary_search(&to_j).unwrap();
        let fixed_i = is.binary_search(&fixed_i).unwrap();

        if let Some((&prev_from, &prev_to)) = horizontal_lines[fixed_i].range(..from_j).next_back()
        {
            if prev_to >= from_j {
                from_j = prev_from;
                assert_eq!(horizontal_lines[fixed_i].remove(&prev_from), Some(prev_to));
            }
        }

        loop {
            if let Some((&next_from, &next_to)) = horizontal_lines[fixed_i].range(from_j..).next() {
                if next_from <= to_j {
                    to_j = next_to;
                    assert_eq!(horizontal_lines[fixed_i].remove(&next_from), Some(next_to));
                } else {
                    break;
                }
            } else {
                break;
            }
        }
        horizontal_lines[fixed_i].insert(from_j, to_j);
    }
    horizontal_lines
}

pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        Self(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}


Measured memory_bytes: 11756