// #pragma GCC optimize("Ofast","unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #include<bits/stdc++.h>
// #include <xmmintrin.h>
// #include <immintrin.h>
// using namespace::std;
// using namespace std::chrono;
// //struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}} __init;
// __attribute__((constructor))
// void init(){
// 	cin.tie(0);
// 	ios::sync_with_stdio(false);
// 	cout<<fixed<<setprecision(15);
// }
// // random_device rd;
// // mt19937 mt(rd());
// // #include <boost/numeric/interval.hpp>
// // #include <boost/numeric/interval/io.hpp>
// // #include <boost/intrusive/rbtree.hpp>
// // #include <boost/dynamic_bitset.hpp>
// // #include <boost/geometry.hpp>
// // #include <boost/geometry/geometries/linestring.hpp>
// // #include <boost/geometry/geometries/polygon.hpp>
// // #include <boost/geometry/geometries/point_xy.hpp>
// // #include <boost/math/tools/minima.hpp>
// // using boost::math::tools::brent_find_minima;
// // #include <boost/multiprecision/cpp_dec_float.hpp>
// // #include <boost/multiprecision/cpp_int.hpp>
// // namespace mp = boost::multiprecision;
// // typedef mp::number<mp::cpp_dec_float<0>> cdouble;
// // typedef mp::cpp_int cint;
// // #include <boost/unordered_map.hpp>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/priority_queue.hpp>
// #include<ext/pb_ds/tag_and_trait.hpp>
// template<typename T=long long>using pbds=__gnu_pbds::tree<T,__gnu_pbds::null_type,less<T>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>;
// template<typename T=long long>using pbds_map=__gnu_pbds::tree<T,T,less<T>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>;
// template<typename T=long long>using pqueue =__gnu_pbds::priority_queue<T, less<T>,__gnu_pbds::rc_binomial_heap_tag>;
// typedef long long lint;
// typedef long long ll;
// typedef long double ldouble;
// typedef vector<lint> vec;
// typedef vector<vector<lint>> mat;
// typedef vector<vector<vector<lint>>> mat3;
// typedef vector<double> dvec;
// typedef vector<vector<double>> dmat;
// typedef vector<vector<vector<double>>> dmat3;
// typedef vector<string> svec;
// typedef vector<vector<string>> smat;
// typedef vector<vector<vector<string>>> smat3;
// template<typename T>using Vec=vector<T>;
// template<typename T>using Mat=vector<vector<T>>;
// template<typename T>using Mat3=vector<vector<vector<T>>>;
// template<typename T>using Mat4=vector<vector<vector<vector<T>>>>;
// template<typename S,typename T>using pvec=vector<pair<S,T>>;
// template<typename S,typename T>using pmat=vector<vector<pair<S,T>>>;
// template<typename S,typename T>using pmat3=vector<vector<vector<pair<S,T>>>>;
// template<typename S,typename T>using pmat4=vector<vector<vector<vector<pair<S,T>>>>>;
// template<typename... T>using tvec=vector<tuple<T...>>;
// template<typename... T>using tmat=vector<vector<tuple<T...>>>;
// template<typename... T>using tmat3=vector<vector<vector<tuple<T...>>>>;
// template<typename... T>using tmat4=vector<vector<vector<vector<tuple<T...>>>>>;
// #define rep(i, n) for(lint i = 0; i < (lint)(n); i++)
// #define irep(i) for(lint i = 0;; i++)
// #define irepi(i,n) for(lint i = (n);; i++)
// #define rrep(i, n) for(lint i = (lint)(n-1); i >-1; i--)
// #define rrepi(i,a,b) for(lint i = (lint)(b-1); i >a-1; i--)
// #define repi(i,a,b) for(lint i=lint(a);i<lint(b);i++)
// #define rep2(i,a,b,c) for(lint i=lint(a);i>lint(b);i+=c)
// #define all(x) (x).begin(),(x).end()
// #define dist(x1,y1,x2,y2) (pow(pow(x2-x1,2)+pow(y2-y1,2),0.5))
// //#define input(a,n) lint n;cin>>n;vector<lint>a(n);rep(i,n)cin>>a[i];
// #define SUM(v) accumulate(all(v),0LL)
// #define INF (1LL<<60)
// #define IINF (1<<30)
// #define EPS (1e-10)
// #define LINF 9223372036854775807LL
// //#define MOD 998244353LL
// #define MOD 1000000007LL
// #define endl "\n"
// template<typename T>inline void numout(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i<INF/2?i:"INF";f=1;}cout<<endl;}
// template<typename T>inline void numout2(T t){for(auto i:t)numout(i);}
// template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
// template<typename T>inline void output2(T t){for(auto i:t)output(i);}
// template<typename T>inline void _output(T t){bool f=0;for(int i=0;i<t.size();i++){cout<<f?"":" "<<t[i];f=1;}cout<<endl;}
// template<typename T>inline void _output2(T t){for(int i=0;i<t.size();i++)output(t[i]);}
// auto call=[](auto f,auto... args){return f(f,args...);};
// template<typename T=lint>T in(){return *istream_iterator<T>(cin);}
// template<typename T=lint>inline T gcd(T a,T b){return b?gcd(b,a%b):a;}
// template<typename T=lint>inline T lcm(T a,T b){return a/gcd(a,b)*b;}
// template<typename T>inline T minq(T a,T b){return min(a,b);}
// template<typename T>inline T maxq(T a,T b){return max(a,b);}
// inline bool chmin(auto& s,const auto& t){bool res=s>t;s=min(s,t);return res;}
// inline bool chmax(auto& s,const auto& t){bool res=s<t;s=max(s,t);return res;}
// const vector<lint> dx={-1,1,0,0,1,1,-1,-1};
// const vector<lint> dy={0,0,-1,1,1,-1,1,-1};

// template<typename T,typename E>
// class segment2d{
//     class segment_y{
//         E* node;
//         int n=1;
//         public:
//         segment_y(auto sz){
//             while(n<=(int)sz)n<<=1;
//             node=new E[(n<<1)-1];
//             for(int i=0;i<(n<<1)-1;i++)node[i]=e;
//         }
//         T get(auto l,auto r){
//             l+=n;r+=n;
//             E s=e;
//             while(l<r){
//                 if(l&1)s=f(s,node[l++-1]);
//                 if(r&1)s=f(s,node[--r-1]);
//                 l>>=1;r>>=1;
//             }
//             return s;
//         }
//         void update(auto t,E val){
//             t+=n-1;
//             while(t){
//                 node[t]=f(node[t],val);
//                 t=(t-1)>>1;
//             }
//             node[0]=f(node[0],val);
//         }
//     };
// 	vector<vector<pair<T,E>>>node;
//     vector<vector<T>> y_list;
//     segment_y** seg;
// 	int n=1,sz;
//     vector<tuple<T,T,E>>v;
//     vector<T>x_list;
//     bool built=0;
// 	public:
// 	segment2d(){}
//     void update(T x,T y,E val){
//         v.emplace_back(x,y,val);
//         x_list.push_back(x);
//     }
//     T get(T lx,T ly,T rx,T ry){
//         if(!built){
//             build();
//             built=1;
//         }
//         lx=lower_bound(x_list.begin(),x_list.end(),lx)-x_list.begin();
//         rx=lower_bound(x_list.begin(),x_list.end(),rx)-x_list.begin();
// 		lx+=n;rx+=n;
// 		T s=e;
// 		while(lx<rx){
// 			if((lx&1)&&y_list[lx-1].size()){
//                 s=f(s,seg[lx-1]->get(lower_bound(y_list[lx-1].begin(),y_list[lx-1].end(),ly)-y_list[lx-1].begin(),lower_bound(y_list[lx-1].begin(),y_list[lx-1].end(),ry)-y_list[lx-1].begin()));
//                 ++lx;
//             }
// 			if((rx&1)&&y_list[--rx-1].size()){
//                 s=f(s,seg[rx-1]->get(lower_bound(y_list[rx-1].begin(),y_list[rx-1].end(),ly)-y_list[rx-1].begin(),lower_bound(y_list[rx-1].begin(),y_list[rx-1].end(),ry)-y_list[rx-1].begin()));
//             }
// 			lx>>=1;rx>>=1;
// 		}
// 		return s;
// 	}
//     void build(){
//         sort(x_list.begin(),x_list.end());
//         x_list.erase(unique(x_list.begin(),x_list.end()),x_list.end());
//         sz=x_list.size();
//         while(n<=sz)n<<=1;
// 		node.resize((n<<1)-1);
//         y_list.resize((n<<1)-1,vector<T>());
//         seg=new segment_y*[(n<<1)-1];
//         for(auto d:v){
//             T x,y;E val;
//             tie(x,y,val)=d;
//             _update(lower_bound(x_list.begin(),x_list.end(),x)-x_list.begin(),y,val);
//         }
//         for(int i=0;i<(n<<1)-1;i++){
//             sort(y_list[i].begin(),y_list[i].end());
//             y_list[i].erase(unique(y_list[i].begin(),y_list[i].end()),y_list[i].end());
//             if(y_list[i].size()==0){
//                 seg[i]=nullptr;
//                 continue;
//             }
//             seg[i]=new segment_y(y_list[i].size());
//             for(auto d:node[i]){
//                 T y;E val;
//                 tie(y,val)=d;
//                 seg[i]->update(lower_bound(y_list[i].begin(),y_list[i].end(),y)-y_list[i].begin(),val);
//             }
//         }
//     }
//     private:
// 	void _update(int x,T y,E val){
// 		x+=n-1;
// 		while(x){
// 			node[x].emplace_back(y,val);
//             y_list[x].emplace_back(y);
// 			x=(x-1)>>1;
// 		}
//         node[0].emplace_back(y,val);
//         y_list[0].emplace_back(y);
// 	}
// 	constexpr static E e=0;
// 	constexpr static
// 	E f(const E& s,const E& t){
// 		return s+t;
// 	}
// };

// int main(){
//     lint n;
//     cin>>n;
//     segment2d<lint,lint> seg_l,seg_r;
//     vec a(n),b(n),c(n),d(n);
//     rep(i,n){
//         cin>>a[i]>>b[i]>>c[i]>>d[i];
//         seg_l.update(a[i],c[i],1);
//         seg_r.update(b[i],d[i],1);
//     }
//     rep(i,n){
//         //a[i]++;b[i]++;c[i]++;d[i]++;
//         if(
//             seg_l.get(0,0,a[i],c[i])==seg_r.get(0,0,a[i],c[i])&&
//             seg_l.get(a[i]+1,c[i]+1,b[i],d[i])==seg_r.get(a[i]+1,c[i]+1,b[i],d[i])&&
//             seg_l.get(b[i]+1,d[i]+1,INF,INF)==seg_r.get(b[i]+1,d[i]+1,INF,INF)&&
//             seg_l.get(0,d[i]+1,a[i],INF)==seg_r.get(0,d[i]+1,a[i],INF)&&
//             seg_l.get(b[i]+1,0,INF,c[i])==seg_r.get(b[i]+1,0,INF,c[i]))continue;
//         else {
//              cout<<i<<endl;
//              if(seg_l.get(0,0,a[i],c[i])==seg_r.get(0,0,a[i],c[i]))cout<<"a"<<endl;
//             if(seg_l.get(a[i],c[i],b[i]+1,d[i]+1)==seg_r.get(a[i],c[i],b[i]+1,d[i]+1))cout<<"b"<<endl;
//             if(seg_l.get(b[i]+1,d[i]+1,INF,INF)==seg_r.get(b[i]+1,d[i]+1,INF,INF))cout<<"c"<<endl;
//             if(seg_l.get(0,d[i]+1,a[i],INF)==seg_r.get(0,d[i]+1,a[i],INF))cout<<"f"<<endl;
//             if(seg_l.get(b[i]+1,0,INF,c[i])==seg_r.get(b[i]+1,0,INF,c[i]))cout<<"r"<<endl;
//             cout<<seg_l.get(b[i]+1,d[i]+1,INF,INF)<<seg_r.get(b[i]+1,d[i]+1,INF,INF)<<endl;
//             cout<<"NO"<<endl;
//             return 0;
//         }
//     }
//     cout<<"YES"<<endl;
// }

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
long gcd(long a,long b){return b?gcd(b,a%b):a;}
long lcm(long a,long b){return a/gcd(a,b)*b;}
 
int main(void){
    long a,b,c,d,l,ans;
    scanf("%ld%ld%ld%ld",&a,&b,&c,&d);
    l = lcm(c,d);
    ans = (b-a+1) - ( b/c - (a-1)/c + b/d - (a-1)/d - b/l + (a-1)/l );
    printf("%ld\n",ans);
    return 0;
}

Measured memory_bytes: 128