//  [javascript]
"use strict"
function Main(stdin){
stdin = stdin.trim().split("\n").reverse();
let stdout = [];
function input(){return stdin.pop()};
function print(x){stdout.push(x)};
function max(list){return list.reduce(function(a,b){ return Math.max(a,b) }) }
function min(list){return list.reduce(function(a,b){ return Math.min(a,b) }) }
function sum(list){return list.reduce(function(a,b){ return a+b }) }
function sortex(list, index){list.sort((a, b) => a[index] - b[index])}
function all(list){return list.reduce(function(a,b){ return a && b }) }
function any(list){return list.reduce(function(a,b){ return a || b }) }
function equal(arr, brr){
    if (arr.length !== brr.length){ throw new Error("length not match") }
    let crr = new Array(arr.length)
    for (let i = 0; i < arr.length; i++){ crr[i] = (arr[i] === brr[i]) }
    return all(crr)
}
/*START*/

function isneg(x){if(x[0]=="-"){return true}else{return false}}
function neg(x){if(isneg(x)){return x.slice(1, x.length)}else{return "-"+x}}

function zerot(x){
    let rx = Array.from(x).reverse()    
    while(rx[rx.length - 1] === "0"){
        rx.pop()
        if (rx.length === 0){
            rx = ["0"]
            break;
        }
    }
    return rx.reverse().join("")
}

function zerocut(x){
    if (isneg(x)){
        let ans = neg(zerot(neg(x)))
        if (ans === "-0"){ return "0" }
        return ans
    }else{
        return zerot(x)
    }
}

function bigsmal(x, y){
    if (isneg(x) || isneg(y)){ throw new Error("negative input") }
    if (x.length > y.length){
        return [x, y]
    }else if(x.length < y.length){
        return [y, x]
    }else{
        return [x, y].sort().reverse()
    }
}

function bigsmall(x, y){
    if (!isneg(x) && isneg(y)){
        return [x,y]
    }else if (isneg(x) && !isneg(y)){
        return [y,x]
    }else if (!isneg(x) && !isneg(y)){
        return bigsmal(x, y)
    }else if (isneg(x) && isneg(y)){
        let tmp = bigsmal(neg(x), neg(y)).reverse()
        return Array.from(tmp, i => neg(i))   
    }
}

function greater(x, y){
    if (equal(bigsmall(x, y), [x, y]) && (x !== y)){
        return true
    }else{ return false }
}

function ad(x, y){
    if (isneg(x) || isneg(y)){ throw new Error("negative input") }
    let ra = Array(Math.max(x.length, y.length) + 1).fill(0)
    let rx = Array.from(x, i => parseInt(i)).reverse()
    let ry = Array.from(y, i => parseInt(i)).reverse()
    for (let i = 0; i < rx.length; i++){ ra[i] += rx[i] }
    for (let i = 0; i < ry.length; i++){ ra[i] += ry[i] }
    for (let i = 0; i < ra.length - 1; i++){
        ra[i+1] += ra[i]/10|0
        ra[i] = ra[i] % 10
    }
    let ans = Array.from(ra, i => i+"").reverse().join("")
    return zerocut(ans)
}

function s_b(x, y){
    if (isneg(x) || isneg(y)){ throw new Error("negative input") }
    if (!equal(bigsmall(x, y), [x, y])){ throw new Error("not x>=y error") }
    let ra = Array(Math.max(x.length, y.length)).fill(0)
    let rx = Array.from(x, i => parseInt(i)).reverse()
    let ry = Array.from(y, i => parseInt(i)).reverse()
    for (let i = 0; i < rx.length; i++){ ra[i] += rx[i] }
    for (let i = 0; i < ry.length; i++){ ra[i] -= ry[i] }
    for (let i = 0; i < ra.length - 1; i++){
        if (ra[i] < 0){
            ra[i] = 10 + ra[i]
            ra[i+1] -= 1
        }
    }
    let ans = Array.from(ra, i => i+"").reverse().join("")
    return zerocut(ans)
}

function sb(x, y){
    if (isneg(x) || isneg(y)){ throw new Error("negative input") }
    if (equal(bigsmall(x, y), [x, y])){
        return s_b(x, y)
    }else{ return neg(s_b(y, x)) }
}

function add(x, y){
    if(isneg(x) && isneg(y)){
        return neg(ad(neg(x), neg(y)))
    }else if(!isneg(x) && !isneg(y)){
        return ad(x, y)
    }else if(!isneg(x) && isneg(y)){
        return sb(x, neg(y))
    }else if(isneg(x) && !isneg(y)){
        return sb(y, neg(x))
    }
}

function sub(x, y){
    if(isneg(x) && isneg(y)){
        return sb(neg(y), neg(x))
    }else if(!isneg(x) && !isneg(y)){
        return sb(x, y)
    }else if(!isneg(x) && isneg(y)){
        return ad(x, neg(y))
    }else if(isneg(x) && !isneg(y)){
        return neg(ad(neg(x), y))
    }
}

function ml(x, y){
    if (isneg(x) || isneg(y)){ throw new Error("negative input") }
    let ra = Array(x.length + y.length).fill(0)
    let rx = Array.from(x, i => parseInt(i)).reverse()
    let ry = Array.from(y, i => parseInt(i)).reverse()
    for (let i = 0; i < rx.length; i++){ 
        for (let j = 0; j < ry.length; j++){
            ra[i+j] += rx[i] * ry[j]
        }
    }
    for (let i = 0; i < ra.length - 1; i++){
        ra[i+1] += ra[i]/10|0
        ra[i] = ra[i] % 10
    }
    let ans = Array.from(ra, i => i+"").reverse().join("")
    return zerocut(ans)
}

function mul(x, y){
    if(isneg(x) && isneg(y)){
        return ml(neg(x), neg(y))
    }else if(!isneg(x) && !isneg(y)){
        return ml(x, y)
    }else if(!isneg(x) && isneg(y)){
        return zerocut(neg(ml(x, neg(y))))
    }else if(isneg(x) && !isneg(y)){
        return zerocut(neg(ml(neg(x), y)))
    }
}

function mod2(x){
    return parseInt(x[x.length-1]) % 2
}

function div2(x){
    if (isneg(x)){ throw new Error("negative input") }
    let ans = Array(x.length).fill(0)
    let xs = Array.from(x, i => parseInt(i))
    for (let i = 0; i < x.length - 1; i++){ 
        ans[i] += xs[i]
        ans[i+1] += (ans[i]%2) * 10
        ans[i] = ans[i]/2|0
    }
    ans[x.length-1] = (ans[x.length-1] + xs[x.length-1])/2|0
    ans = Array.from(ans, i => i+"").join("")
    return zerocut(ans)
}

function dv(a, b){
    if (isneg(a) || isneg(b)){ throw new Error("negative input") }
    if (b === "0"){ throw new Error("zero div error") }
    if (b === "1"){ return a }
    let left = "0"
    let right = a
    while (greater(right, add(left, "1"))){
        let x = div2(add(left, right))
        //print(x)
        if (equal([a, mul(b, x)], bigsmall(a, mul(b, x)))){
            left = x
        }else{ right = x }
    }
    return left
}

function div(x, y){
    if(isneg(x) && isneg(y)){
        return dv(neg(x), neg(y))
    }else if(!isneg(x) && !isneg(y)){
        return dv(x, y)
    }else if(!isneg(x) && isneg(y)){
        return zerocut(neg(dv(x, neg(y))))
    }else if(isneg(x) && !isneg(y)){
        return zerocut(neg(dv(neg(x), y)))
    }
}

function mod(x, y){
    if (isneg(x) || isneg(y)){ throw new Error("negative input") }
    let divmul = mul(div(x, y), y)
    return sub(x, divmul)
}

function addall(list){return list.reduce(function(a,b){ return add(a, b) }) }

function gcd(x, y){
    let tmp = bigsmall(x, y)
    let a = tmp[0]
    let b = tmp[1]
    let r = mod(a, b)
    while (r !== "0"){
        a = b
        b = r
        r = mod(a, b)
    }
    return b
}


let tmp = input().split(" ")
let a = tmp[0]
let b = tmp[1]
let c = tmp[2]
let d = tmp[3]
let a1c = div(sub(a, "1"), c)
let a1d = div(sub(a, "1"), d)
let a1cd = div(sub(a, "1"), div(mul(c, d), gcd(c, d)))
let bc = div(b, c)
let bd = div(b, d)
let bcd = div(b, div(mul(c, d), gcd(c, d)))
let A = addall([sub(a, "1"), neg(a1c), neg(a1d), a1cd])
let B = addall([b, neg(bc), neg(bd), bcd])
print(sub(B, A))



/*END*/
console.log(stdout.join("\n"));
return stdout
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"))