uses math;
const fi = '';
      fo = '';
var l, r, p, q, m, n, ans: int64;
    f: array [0..100, 0..100] of int64;
    ep, eq: array [0..100] of int64;

function pow(x, n: int64): int64;
var i: longint;
    res: int64;
begin
 res:=1;
 for i:=1 to n do res:=res*x;
 exit(res);
end;

function GCD(a, b: int64): int64;
begin
 if (b = 0) then exit(a);
 exit(GCD(b, a mod b));
end;

function LCM(a, b: int64): int64;
begin
 exit((a div GCD(a, b)) * b);
end;

function CheckOverflow(m, n: int64): boolean;
const e = 0.000001;
      oo = round(1e18)+1;
var tmp, tmpm, tmpn, tmpu, tmpr: double;
begin
 tmpm:=m; tmpn:=n; tmpu:=GCD(m, n);
 tmp:=tmpm/tmpu*tmpn;
 tmpr:=oo;
 exit(tmp-e < tmpr);
end;

procedure EndProg;
begin
 close(input); close(output);
 halt;
end;

procedure Enter;
var i, j: longint;
begin
 readln(l, r, p, q);
 m:=trunc(logn(p, r));
 n:=trunc(logn(q, r));

 ep[0]:=1;
 for i:=1 to m do ep[i]:=ep[i-1]*p;
 eq[0]:=1;
 for i:=1 to n do eq[i]:=eq[i-1]*q;

 for i:=0 to m do
  for j:=0 to n do f[i, j]:=-1;
end;

function Find(i, j: longint): int64;
var res: int64;
    u, v: longint;
begin
 if (f[i, j] <> -1) then exit(f[i, j]);
 res:=r div LCM(ep[i], eq[j]) - (l-1) div LCM(ep[i], eq[j]);
 for u:=i to m do
  for v:=j to n do
   if (u > i) or (v > j) then
    begin
     if CheckOverflow(ep[u], eq[v]) and (LCM(ep[u], eq[v]) <= r) then res:=max(0, res-Find(u, v))
     else break;
    end;
 f[i, j]:=res;
 exit(res);
end;

procedure Work;
var i, j: longint;
begin
 for i:=0 to m do
  for j:=0 to i-1 do
   begin
    if CheckOverflow(ep[i], eq[j]) and (LCM(ep[i], eq[j]) <= r) then ans:=ans+Find(i, j)
    else break;
   end;
end;

procedure Answer;
begin
 writeln(ans);
end;

begin
 assign(input, fi); reset(input);
 assign(output, fo); rewrite(output);

 Enter;
 Work;
 Answer;

 close(input); close(output);
end.

