//---------- begin union_find ----------
#[allow(dead_code)]
mod union_find {
    pub struct UF {
        p: Vec<i32>,
    }
    impl UF {
        pub fn new(n: usize) -> UF {
            UF {p: vec![-1; n] }
        }
        pub fn init(&mut self) {
            for p in self.p.iter_mut() {
                *p = -1;
            }
        }
        pub fn root(&self, mut x: usize) -> usize {
            while self.p[x] >= 0 {
                x = self.p[x] as usize;
            }
            x
        }
        pub fn same(&self, x: usize, y: usize) -> bool {
            self.root(x) == self.root(y)
        }
        pub fn unite(&mut self, mut x: usize, mut y: usize) -> Option<(usize, usize)> {
            x = self.root(x);
            y = self.root(y);
            if x == y {
                return None;
            }
            if self.p[x] > self.p[y] {
                let s = x;
                x = y;
                y = s;
            }
            self.p[x] += self.p[y];
            self.p[y] = x as i32;
            Some((x, y))
        }
        pub fn parent(&self, x: usize) -> Option<usize> {
            let p = self.p[x];
            if p >= 0 {
                Some(p as usize)
            } else {
                None
            }
        }
        pub fn get_size(&self, x: usize) -> usize {
            let r = self.root(x);
            (-self.p[r]) as usize
        }
    }
}
//---------- end union_find ----------


fn run() {
    proconio::input! {
        n: usize,
        m: usize,
        mut col: [(i64, i64, i64); n],
        mut row: [(i64, i64, i64); m],
    }
    for p in col.iter_mut().chain(row.iter_mut()) {
        p.0 = 2 * p.0 + 1;
        p.1 = 2 * p.1 + 1;
        p.2 = 2 * p.2 + 1;
    }
    let inf = 2_000_000_000 + 3;
    let mut x = vec![-inf, inf];
    let mut y = vec![-inf, inf];
    for &(d, e, f) in row.iter() {
        x.push(d);
        y.push(e);
        y.push(f);
    }
    for &(a, b, c) in col.iter() {
        x.push(a);
        x.push(b);
        y.push(c);
    }
    x.sort();
    x.dedup();
    y.sort();
    y.dedup();
    let h = x.len();
    let w = y.len();
    let mut vertex: Vec<Option<Vec<usize>>> = (0..((h + 1) * (w + 1))).map(|k| Some(vec![k])).collect();
    let mut u = union_find::UF::new((h + 1) * (w + 1));
    for (i, x) in x.iter().enumerate().skip(1) {
        let mut imos = vec![0i32; w + 1];
        for &(_, e, f) in row.iter().filter(|p| p.0 == *x) {
            let l = y.binary_search(&e).unwrap();
            let r = y.binary_search(&f).unwrap();
            imos[l] += 1;
            imos[r] -= 1;
        }
        for j in 1..=w {
            imos[j] += imos[j - 1];
        }
        for j in 0..w {
            if imos[j] == 0 {
                let s = (i - 1)* (w + 1) + j;
                let t = i * (w + 1) + j;
                if let Some((a, b)) = u.unite(s, t) {
                    let mut p = vertex[b].take().unwrap();
                    vertex[a].as_mut().unwrap().append(&mut p);
                }
            }
        }
    }
    for (j, y) in y.iter().enumerate().skip(1) {
        let mut imos = vec![0i32; h + 1];
        for &(a, b, _) in col.iter().filter(|p| p.2 == *y) {
            let l = x.binary_search(&a).unwrap();
            let r = x.binary_search(&b).unwrap();
            imos[l] += 1;
            imos[r] -= 1;
        }
        for i in 1..=h {
            imos[i] += imos[i - 1];
        }
        for i in 0..h {
            if imos[i] == 0 {
                let s = i * (w + 1) + j - 1;
                let t = i * (w + 1) + j;
                if let Some((a, b)) = u.unite(s, t) {
                    let mut p = vertex[b].take().unwrap();
                    vertex[a].as_mut().unwrap().append(&mut p);
                }
            }
        }
    }
    let mut p = 0;
    while x[p] < 0 {
        p += 1;
    }
    let mut q = 0;
    while y[q] < 0 {
        q += 1;
    }
    let root = u.root((p - 1) * (w + 1) + q - 1);
    for x in [0, h].iter() {
        for y in 0..=w {
            if u.same(x * (w + 1) + y, root) {
                println!("INF");
                return;
            }
        }
    }
    for y in [0, w].iter() {
        for x in 0..=h {
            if u.same(x * (w + 1) + y, root) {
                println!("INF");
                return;
            }
        }
    }
    let mut ans = 0i64;
    for p in vertex[root].as_ref().unwrap().iter() {
        let a = *p / (w + 1);
        let b = *p % (w + 1);
        ans += (x[a] - x[a - 1]) * (y[b] - y[b - 1]);
    }
    println!("{}", ans / 4);
}

fn main() {
    run();
}
