fn main() {
    let test_cases = vec![
        [6, 9, 20],
        [12, 14, 17],
        [12, 13, 34],
        [5, 9, 21],
        [10, 18, 21],
        [71, 98, 99],
        [7_074_047, 8_214_596, 9_098_139],
        [582_795_988, 1_753_241_221, 6_814_151_015],
        [4, 30, 16],
        [12, 12, 13],
        [6, 15, 1],
    ];
    for case in &test_cases {
        print!("g({}, {}, {}) = ", case[0], case[1], case[2]);
        println!(
            "{}",
            match frobenius(case.to_vec()) {
                Ok(g) => format!("{}", g),
                Err(e) => e,
            }
        );
    }
}

fn frobenius(unsorted_a: Vec<i64>) -> Result<i64, String> {
    let mut a = unsorted_a;
    a.sort();
    assert!(a[0] >= 1);
    if gcd(gcd(a[0], a[1]), a[2]) > 1 {
        return Err("Undefined".to_string());
    }
    let d12 = gcd(a[0], a[1]);
    let d13 = gcd(a[0] / d12, a[2]);
    let d23 = gcd(a[1] / d12, a[2] / d13);
    let mut a_prime = vec![a[0] / d12 / d13, a[1] / d12 / d23, a[2] / d13 / d23];
    a_prime.sort();
    let rod = if a_prime[0] == 1 {
        -1
    } else {