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();

		// for (int i = A; i < B+1; i++) {
		// if(i%C!=0&&i%D!=0)
		// cnt++;
		// };
		// とやると10^18なのでたぶんTLE
		// BまでのCの倍数の数:NbC
		// Dの倍数の数:NbD
		// CDの倍数の数:NbCD
		// B-(NbC+NbD-NbCD)って話だと思う
		// 同様にA-1までのCの倍数の数:NaC

		// 入力例2に助けられたC*Dに公約数があるとそれで重複する
		// NbCDは最小公倍数の倍数
		// 最小公倍数はC*D/最大公約数
		// これでもO(C)でやったらTLEでは
		// ユークリッドの互除法がいいらしい

		// long maxKouyakusu = 1;
		// for (int i = 2; i < C + 1; i++) {
		// if (C % i == 0 && D % i == 0)
		// maxKouyakusu = i;
		// }
		// System.out.println(maxKouyakusu);
		long smaller;
		long r_i;
		long r_i1;
		long t_A = C;
		long t_B = D;
		if (t_A >= t_B) {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} else {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		}
		while (r_i != 0) {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		}

		long NbC = B / C;
		long NbD = B / D;
		long NbCD = B / (C * D / r_i1);

		long NaC = (A - 1) / C;
		long NaD = (A - 1) / D;
		long NaCD = (A - 1) / (C * D / r_i1);

		long ans = B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD);

		System.out.println(ans);

	}
} 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();

		// for (int i = A; i < B+1; i++) {
		// if(i%C!=0&&i%D!=0)
		// cnt++;
		// };
		// とやると10^18なのでたぶんTLE
		// BまでのCの倍数の数:NbC
		// Dの倍数の数:NbD
		// CDの倍数の数:NbCD
		// B-(NbC+NbD-NbCD)って話だと思う
		// 同様にA-1までのCの倍数の数:NaC

		// 入力例2に助けられたC*Dに公約数があるとそれで重複する
		// NbCDは最小公倍数の倍数
		// 最小公倍数はC*D/最大公約数
		// これでもO(C)でやったらTLEでは
		// ユークリッドの互除法がいいらしい

		// long maxKouyakusu = 1;
		// for (int i = 2; i < C + 1; i++) {
		// if (C % i == 0 && D % i == 0)
		// maxKouyakusu = i;
		// }
		// System.out.println(maxKouyakusu);
		long smaller;
		long r_i;
		long r_i1;
		long t_A = C;
		long t_B = D;
		if (t_A >= t_B) {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} else {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		}
		while (r_i != 0) {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		}

		long NbC = B / C;
		long NbD = B / D;
		long NbCD = B / (C * D / r_i1);

		long NaC = (A - 1) / C;
		long NaD = (A - 1) / D;
		long NaCD = (A - 1) / (C * D / r_i1);

		long ans = B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD);

		System.out.println(ans);

	}
} 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();

		// for (int i = A; i < B+1; i++) {
		// if(i%C!=0&&i%D!=0)
		// cnt++;
		// };
		// とやると10^18なのでたぶんTLE
		// BまでのCの倍数の数:NbC
		// Dの倍数の数:NbD
		// CDの倍数の数:NbCD
		// B-(NbC+NbD-NbCD)って話だと思う
		// 同様にA-1までのCの倍数の数:NaC

		// 入力例2に助けられたC*Dに公約数があるとそれで重複する
		// NbCDは最小公倍数の倍数
		// 最小公倍数はC*D/最大公約数
		// これでもO(C)でやったらTLEでは
		// ユークリッドの互除法がいいらしい

		// long maxKouyakusu = 1;
		// for (int i = 2; i < C + 1; i++) {
		// if (C % i == 0 && D % i == 0)
		// maxKouyakusu = i;
		// }
		// System.out.println(maxKouyakusu);
		long smaller;
		long r_i;
		long r_i1;
		long t_A = C;
		long t_B = D;
		if (t_A >= t_B) {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} else {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		}
		while (r_i != 0) {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		}

		long NbC = B / C;
		long NbD = B / D;
		long NbCD = B / (C * D / r_i1);

		long NaC = (A - 1) / C;
		long NaD = (A - 1) / D;
		long NaCD = (A - 1) / (C * D / r_i1);

		long ans = B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD);

		System.out.println(ans);

	} 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();

		// for (int i = A; i < B+1; i++) {
		// if(i%C!=0&&i%D!=0)
		// cnt++;
		// };
		// とやると10^18なのでたぶんTLE
		// BまでのCの倍数の数:NbC
		// Dの倍数の数:NbD
		// CDの倍数の数:NbCD
		// B-(NbC+NbD-NbCD)って話だと思う
		// 同様にA-1までのCの倍数の数:NaC

		// 入力例2に助けられたC*Dに公約数があるとそれで重複する
		// NbCDは最小公倍数の倍数
		// 最小公倍数はC*D/最大公約数
		// これでもO(C)でやったらTLEでは
		// ユークリッドの互除法がいいらしい

		// long maxKouyakusu = 1;
		// for (int i = 2; i < C + 1; i++) {
		// if (C % i == 0 && D % i == 0)
		// maxKouyakusu = i;
		// }
		// System.out.println(maxKouyakusu);
		long smaller;
		long r_i;
		long r_i1;
		long t_A = C;
		long t_B = D;
		if (t_A >= t_B) {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} else {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		}
		while (r_i != 0) {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		}

		long NbC = B / C;
		long NbD = B / D;
		long NbCD = B / (C * D / r_i1);

		long NaC = (A - 1) / C;
		long NaD = (A - 1) / D;
		long NaCD = (A - 1) / (C * D / r_i1);

		long ans = B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD);

		System.out.println(ans);

	} 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 smaller; smaller long r_i; r_i long r_i1; r_i1 long t_A = C; t_A C long t_B = D; t_B D if (t_A >= t_B) {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} else {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		} t_A >= t_B t_A t_B {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} smaller = t_B smaller t_B r_i = t_A - t_B r_i t_A - t_B t_A t_B r_i1 = t_B r_i1 t_B {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		} smaller = t_A smaller t_A r_i = t_B - t_A r_i t_B - t_A t_B t_A r_i1 = t_A r_i1 t_A while (r_i != 0) {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		} r_i != 0 r_i 0 {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		} t_A = smaller t_A smaller t_B = r_i t_B r_i r_i1 = r_i r_i1 r_i if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			} t_A >= t_B t_A t_B {
				smaller = t_B;
				r_i = t_A - t_B;
			} smaller = t_B smaller t_B r_i = t_A - t_B r_i t_A - t_B t_A t_B {
				smaller = t_A;
				r_i = t_B - t_A;
			} smaller = t_A smaller t_A r_i = t_B - t_A r_i t_B - t_A t_B t_A long NbC = B / C; NbC B / C B C long NbD = B / D; NbD B / D B D long NbCD = B / (C * D / r_i1); NbCD B / (C * D / r_i1) B (C * D / r_i1) C * D C D r_i1 long NaC = (A - 1) / C; NaC (A - 1) / C (A - 1) A 1 C long NaD = (A - 1) / D; NaD (A - 1) / D (A - 1) A 1 D long NaCD = (A - 1) / (C * D / r_i1); NaCD (A - 1) / (C * D / r_i1) (A - 1) A 1 (C * D / r_i1) C * D C D r_i1 long ans = B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD); ans B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD) B - NbC - NbD + NbCD B - NbC - NbD B - NbC - NbD B NbC NbD NbCD (A - 1 - NaC - NaD + NaCD) A - 1 - NaC - NaD NaC A - 1 - NaC - NaD A 1 NaC NaD NaCD System.out.println(ans) System.out.println System.out System System.out ans String[] args args 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();

		// for (int i = A; i < B+1; i++) {
		// if(i%C!=0&&i%D!=0)
		// cnt++;
		// };
		// とやると10^18なのでたぶんTLE
		// BまでのCの倍数の数:NbC
		// Dの倍数の数:NbD
		// CDの倍数の数:NbCD
		// B-(NbC+NbD-NbCD)って話だと思う
		// 同様にA-1までのCの倍数の数:NaC

		// 入力例2に助けられたC*Dに公約数があるとそれで重複する
		// NbCDは最小公倍数の倍数
		// 最小公倍数はC*D/最大公約数
		// これでもO(C)でやったらTLEでは
		// ユークリッドの互除法がいいらしい

		// long maxKouyakusu = 1;
		// for (int i = 2; i < C + 1; i++) {
		// if (C % i == 0 && D % i == 0)
		// maxKouyakusu = i;
		// }
		// System.out.println(maxKouyakusu);
		long smaller;
		long r_i;
		long r_i1;
		long t_A = C;
		long t_B = D;
		if (t_A >= t_B) {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} else {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		}
		while (r_i != 0) {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		}

		long NbC = B / C;
		long NbD = B / D;
		long NbCD = B / (C * D / r_i1);

		long NaC = (A - 1) / C;
		long NaD = (A - 1) / D;
		long NaCD = (A - 1) / (C * D / r_i1);

		long ans = B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD);

		System.out.println(ans);

	}
} 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();

		// for (int i = A; i < B+1; i++) {
		// if(i%C!=0&&i%D!=0)
		// cnt++;
		// };
		// とやると10^18なのでたぶんTLE
		// BまでのCの倍数の数:NbC
		// Dの倍数の数:NbD
		// CDの倍数の数:NbCD
		// B-(NbC+NbD-NbCD)って話だと思う
		// 同様にA-1までのCの倍数の数:NaC

		// 入力例2に助けられたC*Dに公約数があるとそれで重複する
		// NbCDは最小公倍数の倍数
		// 最小公倍数はC*D/最大公約数
		// これでもO(C)でやったらTLEでは
		// ユークリッドの互除法がいいらしい

		// long maxKouyakusu = 1;
		// for (int i = 2; i < C + 1; i++) {
		// if (C % i == 0 && D % i == 0)
		// maxKouyakusu = i;
		// }
		// System.out.println(maxKouyakusu);
		long smaller;
		long r_i;
		long r_i1;
		long t_A = C;
		long t_B = D;
		if (t_A >= t_B) {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} else {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		}
		while (r_i != 0) {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		}

		long NbC = B / C;
		long NbD = B / D;
		long NbCD = B / (C * D / r_i1);

		long NaC = (A - 1) / C;
		long NaD = (A - 1) / D;
		long NaCD = (A - 1) / (C * D / r_i1);

		long ans = B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD);

		System.out.println(ans);

	}
} 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();

		// for (int i = A; i < B+1; i++) {
		// if(i%C!=0&&i%D!=0)
		// cnt++;
		// };
		// とやると10^18なのでたぶんTLE
		// BまでのCの倍数の数:NbC
		// Dの倍数の数:NbD
		// CDの倍数の数:NbCD
		// B-(NbC+NbD-NbCD)って話だと思う
		// 同様にA-1までのCの倍数の数:NaC

		// 入力例2に助けられたC*Dに公約数があるとそれで重複する
		// NbCDは最小公倍数の倍数
		// 最小公倍数はC*D/最大公約数
		// これでもO(C)でやったらTLEでは
		// ユークリッドの互除法がいいらしい

		// long maxKouyakusu = 1;
		// for (int i = 2; i < C + 1; i++) {
		// if (C % i == 0 && D % i == 0)
		// maxKouyakusu = i;
		// }
		// System.out.println(maxKouyakusu);
		long smaller;
		long r_i;
		long r_i1;
		long t_A = C;
		long t_B = D;
		if (t_A >= t_B) {
			smaller = t_B;
			r_i = t_A - t_B;
			r_i1 = t_B;
		} else {
			smaller = t_A;
			r_i = t_B - t_A;
			r_i1 = t_A;
		}
		while (r_i != 0) {
			t_A = smaller;
			t_B = r_i;
			r_i1 = r_i;
			if (t_A >= t_B) {
				smaller = t_B;
				r_i = t_A - t_B;
			} else {
				smaller = t_A;
				r_i = t_B - t_A;
			}
		}

		long NbC = B / C;
		long NbD = B / D;
		long NbCD = B / (C * D / r_i1);

		long NaC = (A - 1) / C;
		long NaD = (A - 1) / D;
		long NaCD = (A - 1) / (C * D / r_i1);

		long ans = B - NbC - NbD + NbCD - (A - 1 - NaC - NaD + NaCD);

		System.out.println(ans);

	}
}