Problem:
Score : 300 points

Problem Statement

You are given four integers A, B, C, and D. Find the number of integers between A and B (inclusive) that can be evenly divided by neither C nor D.

Constraints

1\leq A\leq B\leq 10^{18}

1\leq C,D\leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

A B C D

Output

Print the number of integers between A and B (inclusive) that can be evenly divided by neither C nor D.

Sample Input 1

4 9 2 3

Sample Output 1

2

5 and 7 satisfy the condition.

Sample Input 2

10 40 6 8

Sample Output 2

23

Sample Input 3

314159265358979323 846264338327950288 419716939 937510582

Sample Output 3

532105071133627368

Solution in Rust (1.15.1) (judge verdict: Accepted)

pub mod contest {
    pub mod input {
        use std::io;
        use std::str::FromStr;
        use std::fmt::Debug;

        pub fn read_one<F>() -> F
        where F: FromStr, <F as FromStr>::Err: Debug {
            let mut input = String::new();
            io::stdin().read_line(&mut input).unwrap();
            input.trim().parse().unwrap()
        }

        pub fn read_line() -> String {
            let mut input = String::new();
            io::stdin().read_line(&mut input).unwrap();
            input
        }

        pub fn read_words<F>() -> Vec<F>
        where F: FromStr, <F as FromStr>::Err: Debug {
            let mut input = String::new();
            io::stdin().read_line(&mut input).unwrap();
            input
                .split_whitespace()
                .map(|i| i.parse().unwrap())
                .collect()
        }

        pub fn read_matrix<F>(num_lines: usize) -> Vec<Vec<F>>
        where F: FromStr, <F as FromStr>::Err: Debug {
            (0..num_lines).map(|_| read_words()).collect()
        }

        // 所有権的な問題で SplitWhitespace を直接持てないので妥協
        // まあ、一行のデータの数なんてそんなに多くないだろうし
        pub struct WordsReader {
            words: Vec<String>,
            cur: usize,
        }

        impl WordsReader {
            pub fn new() -> Self {
                let mut input = String::new();
                io::stdin().read_line(&mut input).unwrap();
                WordsReader {
                    words: input.split_whitespace().map(|i| i.to_owned()).collect(),
                    cur: 0,
                }
            }

            pub fn next<F>(&mut self) -> F
            where F: FromStr, <F as FromStr>::Err: Debug {
                let v: F = self.words[self.cur].parse().unwrap();
                self.cur += 1;
                v
            }
        }
    }
}

fn gcd(x: i64, y: i64) -> i64 {
    if x == 0 {
        return y;
    } else {
        return gcd(y % x, x);
    }
}

fn lcm(x: i64, y: i64) -> i64 {
    return (x * y) / gcd(x, y);
}


fn count_multiples(a: i64, b: i64, x: i64) -> i64 {
    let q1 = a / x;
    let r1 = a % x;
    let q2 = b / x;
    if r1 == 0 {
        q2 - q1 + 1
    } else {
        q2 - q1
    }
}

fn multiples_of_two(a: i64, b: i64, c: i64, d: i64) -> i64 {
    let x = count_multiples(a, b, c);
    let y = count_multiples(a, b, d);
    let z = count_multiples(a, b, lcm(c, d));
    // println!("x = {}, y = {}, z = {}, lcm = {}", x, y, z, lcm(c, d));
    x + y - z
}

fn solve(a: i64, b: i64, c: i64, d: i64) -> i64 {
    let cnt = multiples_of_two(a, b, c, d);
    let total = b - a + 1;
    total - cnt
}

fn main() {
    let mut wr = contest::input::WordsReader::new();
    let a: i64 = wr.next();
    let b: i64 = wr.next();
    let c: i64 = wr.next();
    let d: i64 = wr.next();
    println!("{}", solve(a, b, c, d));
}