import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long A = sc.nextLong();
		long B = sc.nextLong();
		long C = sc.nextLong();
		long D = sc.nextLong();
		sc.close();

		// CとDの最大公約数
		long gcd = gcd(C, D);
		// CとDの最小公倍数
		long lcm = (C * D) / gcd;
		// System.out.println("gcd=" + gcd + " lcm=" + lcm);

		// B以下のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// B以下の割り切れる個数を求める
		long bCnt = (B / C) + (B / D) - (B / lcm);
		
		// A未満のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// A未満の割り切れる個数が求められる
		long a = A - 1;
		long aCnt = (a / C) + (a / D) - (a / lcm);
		// System.out.println("bCnt=" + bCnt + " aCnt=" + aCnt);

		// BからB以下の割り切る個数を引く = B以下の割れない個数
		// A未満の割り切れる個数を引く = A未満の割れない個数
		// B以下の割れない個数からA未満の割れない個数を引く
		System.out.println((B - bCnt) - (a - aCnt));
	}

	// 最大公約数
    public static long gcd(long x, long y) {
        // System.out.println("x = " + x + " y = " + y);
        if(y == 0) return x;
        else return gcd(y, x % y);
	}

	// 最小公倍数
    public static long lcm(long x, long y) {
        return (x * y) / gcd(x, y);
    }
} import java.util.Scanner; Scanner java.util public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long A = sc.nextLong();
		long B = sc.nextLong();
		long C = sc.nextLong();
		long D = sc.nextLong();
		sc.close();

		// CとDの最大公約数
		long gcd = gcd(C, D);
		// CとDの最小公倍数
		long lcm = (C * D) / gcd;
		// System.out.println("gcd=" + gcd + " lcm=" + lcm);

		// B以下のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// B以下の割り切れる個数を求める
		long bCnt = (B / C) + (B / D) - (B / lcm);
		
		// A未満のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// A未満の割り切れる個数が求められる
		long a = A - 1;
		long aCnt = (a / C) + (a / D) - (a / lcm);
		// System.out.println("bCnt=" + bCnt + " aCnt=" + aCnt);

		// BからB以下の割り切る個数を引く = B以下の割れない個数
		// A未満の割り切れる個数を引く = A未満の割れない個数
		// B以下の割れない個数からA未満の割れない個数を引く
		System.out.println((B - bCnt) - (a - aCnt));
	}

	// 最大公約数
    public static long gcd(long x, long y) {
        // System.out.println("x = " + x + " y = " + y);
        if(y == 0) return x;
        else return gcd(y, x % y);
	}

	// 最小公倍数
    public static long lcm(long x, long y) {
        return (x * y) / gcd(x, y);
    }
} Main public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long A = sc.nextLong();
		long B = sc.nextLong();
		long C = sc.nextLong();
		long D = sc.nextLong();
		sc.close();

		// CとDの最大公約数
		long gcd = gcd(C, D);
		// CとDの最小公倍数
		long lcm = (C * D) / gcd;
		// System.out.println("gcd=" + gcd + " lcm=" + lcm);

		// B以下のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// B以下の割り切れる個数を求める
		long bCnt = (B / C) + (B / D) - (B / lcm);
		
		// A未満のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// A未満の割り切れる個数が求められる
		long a = A - 1;
		long aCnt = (a / C) + (a / D) - (a / lcm);
		// System.out.println("bCnt=" + bCnt + " aCnt=" + aCnt);

		// BからB以下の割り切る個数を引く = B以下の割れない個数
		// A未満の割り切れる個数を引く = A未満の割れない個数
		// B以下の割れない個数からA未満の割れない個数を引く
		System.out.println((B - bCnt) - (a - aCnt));
	} main {
		Scanner sc = new Scanner(System.in);
		long A = sc.nextLong();
		long B = sc.nextLong();
		long C = sc.nextLong();
		long D = sc.nextLong();
		sc.close();

		// CとDの最大公約数
		long gcd = gcd(C, D);
		// CとDの最小公倍数
		long lcm = (C * D) / gcd;
		// System.out.println("gcd=" + gcd + " lcm=" + lcm);

		// B以下のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// B以下の割り切れる個数を求める
		long bCnt = (B / C) + (B / D) - (B / lcm);
		
		// A未満のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// A未満の割り切れる個数が求められる
		long a = A - 1;
		long aCnt = (a / C) + (a / D) - (a / lcm);
		// System.out.println("bCnt=" + bCnt + " aCnt=" + aCnt);

		// BからB以下の割り切る個数を引く = B以下の割れない個数
		// A未満の割り切れる個数を引く = A未満の割れない個数
		// B以下の割れない個数からA未満の割れない個数を引く
		System.out.println((B - bCnt) - (a - aCnt));
	} Scanner sc = new Scanner(System.in); sc new Scanner(System.in) long A = sc.nextLong(); A sc.nextLong() sc.nextLong sc long B = sc.nextLong(); B sc.nextLong() sc.nextLong sc long C = sc.nextLong(); C sc.nextLong() sc.nextLong sc long D = sc.nextLong(); D sc.nextLong() sc.nextLong sc sc.close() sc.close sc long gcd = gcd(C, D); gcd gcd(C, D) gcd C D long lcm = (C * D) / gcd; lcm (C * D) / gcd (C * D) C D gcd long bCnt = (B / C) + (B / D) - (B / lcm); bCnt (B / C) + (B / D) - (B / lcm) (B / C) + (B / D) (B / C) B C (B / D) B D (B / lcm) B lcm long a = A - 1; a A - 1 A 1 long aCnt = (a / C) + (a / D) - (a / lcm); aCnt (a / C) + (a / D) - (a / lcm) (a / C) + (a / D) (a / C) a C (a / D) a D (a / lcm) a lcm System.out.println((B - bCnt) - (a - aCnt)) System.out.println System.out System System.out (B - bCnt) - (a - aCnt) (B - bCnt) B bCnt (a - aCnt) a aCnt String[] args args // 最大公約数
    public static long gcd(long x, long y) {
        // System.out.println("x = " + x + " y = " + y);
        if(y == 0) return x;
        else return gcd(y, x % y);
	} gcd {
        // System.out.println("x = " + x + " y = " + y);
        if(y == 0) return x;
        else return gcd(y, x % y);
	} if(y == 0) return x;
        else return gcd(y, x % y); y == 0 y 0 return x; x return gcd(y, x % y); gcd(y, x % y) gcd y x % y x y long x x long y y // 最小公倍数
    public static long lcm(long x, long y) {
        return (x * y) / gcd(x, y);
    } lcm {
        return (x * y) / gcd(x, y);
    } return (x * y) / gcd(x, y); (x * y) / gcd(x, y) (x * y) x y gcd(x, y) gcd x y long x x long y y public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long A = sc.nextLong();
		long B = sc.nextLong();
		long C = sc.nextLong();
		long D = sc.nextLong();
		sc.close();

		// CとDの最大公約数
		long gcd = gcd(C, D);
		// CとDの最小公倍数
		long lcm = (C * D) / gcd;
		// System.out.println("gcd=" + gcd + " lcm=" + lcm);

		// B以下のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// B以下の割り切れる個数を求める
		long bCnt = (B / C) + (B / D) - (B / lcm);
		
		// A未満のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// A未満の割り切れる個数が求められる
		long a = A - 1;
		long aCnt = (a / C) + (a / D) - (a / lcm);
		// System.out.println("bCnt=" + bCnt + " aCnt=" + aCnt);

		// BからB以下の割り切る個数を引く = B以下の割れない個数
		// A未満の割り切れる個数を引く = A未満の割れない個数
		// B以下の割れない個数からA未満の割れない個数を引く
		System.out.println((B - bCnt) - (a - aCnt));
	}

	// 最大公約数
    public static long gcd(long x, long y) {
        // System.out.println("x = " + x + " y = " + y);
        if(y == 0) return x;
        else return gcd(y, x % y);
	}

	// 最小公倍数
    public static long lcm(long x, long y) {
        return (x * y) / gcd(x, y);
    }
} public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long A = sc.nextLong();
		long B = sc.nextLong();
		long C = sc.nextLong();
		long D = sc.nextLong();
		sc.close();

		// CとDの最大公約数
		long gcd = gcd(C, D);
		// CとDの最小公倍数
		long lcm = (C * D) / gcd;
		// System.out.println("gcd=" + gcd + " lcm=" + lcm);

		// B以下のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// B以下の割り切れる個数を求める
		long bCnt = (B / C) + (B / D) - (B / lcm);
		
		// A未満のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// A未満の割り切れる個数が求められる
		long a = A - 1;
		long aCnt = (a / C) + (a / D) - (a / lcm);
		// System.out.println("bCnt=" + bCnt + " aCnt=" + aCnt);

		// BからB以下の割り切る個数を引く = B以下の割れない個数
		// A未満の割り切れる個数を引く = A未満の割れない個数
		// B以下の割れない個数からA未満の割れない個数を引く
		System.out.println((B - bCnt) - (a - aCnt));
	}

	// 最大公約数
    public static long gcd(long x, long y) {
        // System.out.println("x = " + x + " y = " + y);
        if(y == 0) return x;
        else return gcd(y, x % y);
	}

	// 最小公倍数
    public static long lcm(long x, long y) {
        return (x * y) / gcd(x, y);
    }
} Main
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long A = sc.nextLong();
		long B = sc.nextLong();
		long C = sc.nextLong();
		long D = sc.nextLong();
		sc.close();

		// CとDの最大公約数
		long gcd = gcd(C, D);
		// CとDの最小公倍数
		long lcm = (C * D) / gcd;
		// System.out.println("gcd=" + gcd + " lcm=" + lcm);

		// B以下のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// B以下の割り切れる個数を求める
		long bCnt = (B / C) + (B / D) - (B / lcm);
		
		// A未満のCまたはDで割り切れる個数からCとDで割り切れる重複個数を引く
		// A未満の割り切れる個数が求められる
		long a = A - 1;
		long aCnt = (a / C) + (a / D) - (a / lcm);
		// System.out.println("bCnt=" + bCnt + " aCnt=" + aCnt);

		// BからB以下の割り切る個数を引く = B以下の割れない個数
		// A未満の割り切れる個数を引く = A未満の割れない個数
		// B以下の割れない個数からA未満の割れない個数を引く
		System.out.println((B - bCnt) - (a - aCnt));
	}

	// 最大公約数
    public static long gcd(long x, long y) {
        // System.out.println("x = " + x + " y = " + y);
        if(y == 0) return x;
        else return gcd(y, x % y);
	}

	// 最小公倍数
    public static long lcm(long x, long y) {
        return (x * y) / gcd(x, y);
    }
}
