import java.io.*;
import java.util.*;

public class Main {
	
	static long div(long l,long r,long x) {
		return r/x-(l-1)/x;
	}
	static long lcm(long a,long b) {
		return a/gcd(a,b)*b;
	}
	static long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		long A=sc.nextLong(),B=sc.nextLong(),C=sc.nextLong(),D=sc.nextLong();
		long all=B-A+1;
		out.println(all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))));
		
		out.close();

	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}

	}

} import java.io.*; io.* java import java.util.*; util.* java public class Main {
	
	static long div(long l,long r,long x) {
		return r/x-(l-1)/x;
	}
	static long lcm(long a,long b) {
		return a/gcd(a,b)*b;
	}
	static long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		long A=sc.nextLong(),B=sc.nextLong(),C=sc.nextLong(),D=sc.nextLong();
		long all=B-A+1;
		out.println(all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))));
		
		out.close();

	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}

	}

} Main static long div(long l,long r,long x) {
		return r/x-(l-1)/x;
	} div {
		return r/x-(l-1)/x;
	} return r/x-(l-1)/x; r/x-(l-1)/x r/x r x (l-1)/x (l-1) l 1 x long l l long r r long x x static long lcm(long a,long b) {
		return a/gcd(a,b)*b;
	} lcm {
		return a/gcd(a,b)*b;
	} return a/gcd(a,b)*b; a/gcd(a,b)*b a/gcd(a,b) a gcd(a,b) gcd a b b long a a long b b static long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	} gcd {
		return b==0?a:gcd(b,a%b);
	} return b==0?a:gcd(b,a%b); b==0?a:gcd(b,a%b) b==0 b 0 a gcd(b,a%b) gcd b a%b a b long a a long b b public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		long A=sc.nextLong(),B=sc.nextLong(),C=sc.nextLong(),D=sc.nextLong();
		long all=B-A+1;
		out.println(all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))));
		
		out.close();

	} main {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		long A=sc.nextLong(),B=sc.nextLong(),C=sc.nextLong(),D=sc.nextLong();
		long all=B-A+1;
		out.println(all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))));
		
		out.close();

	} Scanner sc = new Scanner(); sc new Scanner() PrintWriter out = new PrintWriter(System.out); out new PrintWriter(System.out) long A=sc.nextLong() A sc.nextLong() sc.nextLong sc B=sc.nextLong() B sc.nextLong() sc.nextLong sc C=sc.nextLong() C sc.nextLong() sc.nextLong sc D=sc.nextLong(); D sc.nextLong() sc.nextLong sc long all=B-A+1; all B-A+1 B-A B A 1 out.println(all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D)))) out.println out all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))) all (div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))) div(A,B,C)+div(A,B,D) div(A,B,C) div A B C div(A,B,D) div A B D div(A,B,lcm(C,D)) div A B lcm(C,D) lcm C D out.close() out.close out String[] args args static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}

	} Scanner BufferedReader br; br StringTokenizer st; st Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		} Scanner {
			br = new BufferedReader(new InputStreamReader(System.in));
		} br = new BufferedReader(new InputStreamReader(System.in)) br new BufferedReader(new InputStreamReader(System.in)) Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		} Scanner {
			br = new BufferedReader(new FileReader(fileName));
		} br = new BufferedReader(new FileReader(fileName)) br new BufferedReader(new FileReader(fileName)) String fileName fileName String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		} next {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		} while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine()); st == null || !st.hasMoreTokens() st == null st null !st.hasMoreTokens() st.hasMoreTokens() st.hasMoreTokens st st = new StringTokenizer(br.readLine()) st new StringTokenizer(br.readLine()) return st.nextToken(); st.nextToken() st.nextToken st String nextLine() throws IOException {
			return br.readLine();
		} nextLine {
			return br.readLine();
		} return br.readLine(); br.readLine() br.readLine br int nextInt() throws IOException {
			return Integer.parseInt(next());
		} nextInt {
			return Integer.parseInt(next());
		} return Integer.parseInt(next()); Integer.parseInt(next()) Integer.parseInt Integer next() next long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		} nextLong {
			return Long.parseLong(next());
		} return Long.parseLong(next()); Long.parseLong(next()) Long.parseLong Long next() next double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		} nextDouble {
			return Double.parseDouble(next());
		} return Double.parseDouble(next()); Double.parseDouble(next()) Double.parseDouble Double next() next boolean ready() throws IOException {
			return br.ready();
		} ready {
			return br.ready();
		} return br.ready(); br.ready() br.ready br public class Main {
	
	static long div(long l,long r,long x) {
		return r/x-(l-1)/x;
	}
	static long lcm(long a,long b) {
		return a/gcd(a,b)*b;
	}
	static long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		long A=sc.nextLong(),B=sc.nextLong(),C=sc.nextLong(),D=sc.nextLong();
		long all=B-A+1;
		out.println(all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))));
		
		out.close();

	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}

	}

} public class Main {
	
	static long div(long l,long r,long x) {
		return r/x-(l-1)/x;
	}
	static long lcm(long a,long b) {
		return a/gcd(a,b)*b;
	}
	static long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		long A=sc.nextLong(),B=sc.nextLong(),C=sc.nextLong(),D=sc.nextLong();
		long all=B-A+1;
		out.println(all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))));
		
		out.close();

	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}

	}

} Main
import java.io.*;
import java.util.*;

public class Main {
	
	static long div(long l,long r,long x) {
		return r/x-(l-1)/x;
	}
	static long lcm(long a,long b) {
		return a/gcd(a,b)*b;
	}
	static long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		long A=sc.nextLong(),B=sc.nextLong(),C=sc.nextLong(),D=sc.nextLong();
		long all=B-A+1;
		out.println(all-(div(A,B,C)+div(A,B,D)-div(A,B,lcm(C,D))));
		
		out.close();

	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		}

		boolean ready() throws IOException {
			return br.ready();
		}

	}

}