fun main(args: Array<String>)
{
    val (a, b, c, d) = readLine()!!.split(" ").map(String::toLong)
    val cdlcm = lcm(c, d)
    
    val cNearestA = a + step(a % c) * c - (a % c)
    val cNearestB = b - (b % c)
    val dNearestA = a + step(a % d) * d - (a % d)
    val dNearestB = b - (b % d)
    val cdNearestA = a + step(a % cdlcm) * cdlcm - (a % cdlcm)    
    val cdNearestB = b - (b % cdlcm)

    val cDiv = if (cNearestB >= cNearestA) cNearestB / c - cNearestA / c + 1L else 0L
    val dDiv = if (dNearestB >= dNearestA) dNearestB / d - dNearestA / d + 1L else 0L
    val cdDiv = if (cdNearestB >= cdNearestA) cNearestB / cdlcm - cdNearestA / cdlcm + 1L else 0L
    
    println(b - a + 1 - cDiv - dDiv + cdDiv)
}

// Read an integer
// Usage: val a = readInt()
fun readInt() = readLine()!!.toInt()

// Read N integers separated by " "
// Usage: val (a, b, c) = readNInts()
fun readNInts() = readLine()!!.split(" ").map(String::toInt)

// Read a string
// Usage: val a = readString()
fun readString() = readLine()!!

fun step(x: Long) = if (x > 0L) 1L else 0L

// ユークリッドの互除法
// O(log(n))
fun gcd(a: Long, b: Long):Long {
    var tmp: Long
    var m = a
    var n = b
    while (m % n != 0L) {
        tmp = n
        n = m % n 
        m = tmp
   }
   return n
}

// 
fun lcm(m: Long, n: Long):Long = m * n / gcd(m, n)

