use std::io;
use std::collections::HashSet;
use std::iter::FromIterator;

fn main() {
    io::stdin().read_line(&mut String::new()).unwrap();
    let mut line0 = String::new();
    io::stdin().read_line(&mut line0).unwrap();
    let vec_a: Vec<i64> = line0
        .as_str()
        .trim()
        .split(' ')
        .map(|v| v.parse::<i64>().unwrap())
        .collect();
    let mut line1 = String::new();
    io::stdin().read_line(&mut line1).unwrap();
    let vec_b: Vec<i64> = line1
        .as_str()
        .trim()
        .split(' ')
        .map(|v| v.parse::<i64>().unwrap())
        .collect();

    print!("{}", transform_cost(&vec_a, &vec_b));
}

#[derive(Debug)]
struct Procedure {
    divisors: Vec<i64>,
}

impl PartialEq for Procedure {
    fn eq(&self, other: &Self) -> bool {
        self.divisors
            .iter()
            .zip(other.divisors.iter())
            .fold(true, |flag, (&v1, &v2)| flag && v1 == v2)
    }
}
impl Eq for Procedure {}

impl Procedure {
    fn new(divisors: &[i64]) -> Self {
        if divisors.len() == 0 {
            Procedure { divisors: vec![] }
        } else {
            Procedure {
                divisors: divisors.iter().map(|v| *v).collect(),
            }
        }
    }
}

fn transform_cost(pr1: &[i64], pr2: &[i64]) -> i64 {
    let procedures: Vec<Option<Vec<Procedure>>> = pr1.iter()
        .zip(pr2.iter())
        .map(|(a, b)| transform_steps(*a, *b))
        .collect();

    let mut k_set: HashSet<i64> = HashSet::from_iter(0..51);
    for l in (0..51).rev() {
        k_set.remove(&l);
        if !find_comb(&k_set, &procedures) {
            if l == 50 {
                return -1;
            }
            k_set.insert(l);
        }
    }
    k_set.iter().fold(0, |acc, v| acc + 2_i64.pow(*v as u32))
}

fn find_comb(k_set: &HashSet<i64>, procedures: &Vec<Option<Vec<Procedure>>>) -> bool {
    procedures.iter().fold(true, |flag, p| match p {
        &Some(ref pros) => {
            flag && pros.iter().fold(false, |flag, pro| {
                flag
                    || pro.divisors
                        .iter()
                        .fold(true, |flag, d| flag && k_set.contains(d))
            })
        }
        &None => false,
    })
}

fn transform_steps(a: i64, b: i64) -> Option<Vec<Procedure>> {
    if b > a {
        None
    } else if a == b {
        Some(vec![Procedure::new(&[])])
    } else {
        let mut procedures = Vec::<Procedure>::new();
        for k in b + 1..a + 1 {
            let r = a % k;
            if let Some(pros) = transform_steps(r, b) {
                for p in pros {
                    procedures.push(Procedure {
                        divisors: vec![k].into_iter().chain(p.divisors).collect::<Vec<i64>>(),
                    });
                }
            }
        }
        if procedures.len() > 0 {
            Some(procedures)
        } else {
            None
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_transform_steps_23_to_3() {
        let expected = vec![
            Procedure::new(&[4]),
            Procedure::new(&[5]),
            Procedure::new(&[8, 4]),
            Procedure::new(&[10]),
            Procedure::new(&[12, 4]),
            Procedure::new(&[12, 8]),
            Procedure::new(&[13, 7]),
            Procedure::new(&[14, 6]),
            Procedure::new(&[15, 5]),
            Procedure::new(&[16, 4]),
            Procedure::new(&[20]),
        ];
        let steps = transform_steps(23, 3).unwrap();
        assert!(
            expected
                .iter()
                .zip(&steps)
                .fold(true, |f, (v1, v2)| f && *v1 == *v2),
            "got {:?}",
            steps,
        );
    }

    #[test]
    fn test_transform_steps_19_to_0() {
        let steps = transform_steps(19, 0).unwrap();
        assert!(steps.len() > 1);
    }

    #[test]
    fn test_transform_steps_5_to_3() {
        assert_eq!(transform_steps(5, 3), None)
    }

    #[test]
    fn test_transform_cost_160() {
        let c = transform_cost(&[19, 10, 14], &[0, 3, 4]);
        assert_eq!(c, 160);
    }

    #[test]
    fn test_transform_cost_2() {
        let c = transform_cost(&[19, 15, 14], &[0, 0, 0]);
        assert_eq!(c, 2);
    }

    #[test]
    fn test_transform_cost_none() {
        let c = transform_cost(&[8, 13], &[5, 13]);
        assert_eq!(c, -1);
    }

    #[test]
    fn test_transform_cost_0() {
        let c = transform_cost(&[2, 0, 1, 8], &[2, 0, 1, 8]);
        assert_eq!(c, 0);
    }

    #[test]
    fn test_transform_cost_137438953472() {
        let c = transform_cost(&[50], &[13]);
        assert_eq!(c, 137438953472);
    }
}


Measured memory_bytes: 4352