import java.util.*;
import java.awt.Point;
import java.io.*;
import java.math.BigInteger;

public class B 
{
    FastScanner in;
    PrintWriter out;
    
    int gcd(int a, int b) 
    {
        while (b !=0) 
        {
            int tmp = a % b;
            a = b;
            b = tmp;
        }
        return a;
    }
    
    public void solve() throws IOException 
    {
        int cnt1 = in.nextInt();
        int cnt2 = in.nextInt();
        int x    = in.nextInt();
        int y    = in.nextInt();
        
        int left  = 1;
        int right = 2000000;
        
        int prev  = -1;
        
        int nok = x * y / gcd(x, y);
        int sum = cnt1 + cnt2;
        
        boolean needBreak = false;
        
        while(right - left > 0)
        {
            int c = left + (right - left) / 2;
            if(c == prev)
            {
                c = right;
                needBreak = true;
            }
            
            int i = c - c / x;
            int j = c - c / y;
            int p = i + j - (c - c / nok);
            
            if(i >= cnt1 && j >= cnt2 && (i + j - p) >= sum)
                right = c;
            else
                left = c;
            
            prev = c;
            
            if(needBreak)
                break;
        }
        
        out.print(right);
    }

    public void run() 
    {
        try 
        {
            in  = new FastScanner();
            out = new PrintWriter(System.out);

            solve();

            out.close();
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }

    class FastScanner 
    {
        BufferedReader  br;
        StringTokenizer st;
        
        FastScanner() 
        {
            br = new BufferedReader(new InputStreamReader(System.in));        
        }

        FastScanner(File f) 
        {
            try
            {
                br = new BufferedReader(new FileReader(f));
            }
            catch (FileNotFoundException e) 
            {
                e.printStackTrace();
            }
        }

        String nextLine() 
        {
            String ret = null;
            try
        {
                ret = br.readLine();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
            
            return ret;
        }

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

        int nextInt() 
        {
            return Integer.parseInt(next());
        }
        
        long nextLong() 
        {
            return Long.parseLong(next());
        }
        
        double nextDouble() 
        {
            return Double.parseDouble(next());
        }
        
        int[] nextIntArray(int size) 
        {
            int[] array = new int[size];
            
            for (int i = 0; i < size; i++)
            {
                array[i] = nextInt();
            }
            
            return array;
        }
        
        long[] nextLongArray(int size) 
        {
            long[] array = new long[size];
            
            for (int i = 0; i < size; i++)
            {
                array[i] = nextLong();
            }
            
            return array;
        }
        
        BigInteger nextBigInteger() 
        {
            return new BigInteger(next());
        }
        
        Point nextIntPoint()
        {
            int x = nextInt();
            int y = nextInt();
            return new Point(x, y);
        }
        
        Point[] nextIntPointArray(int size)
        {
            Point[] array = new Point[size];
            
            for (int index = 0; index < size; ++index)
            {
                array[index] = nextIntPoint();
            }
            
            return array;
        }
        
        List<Integer>[] readGraph(int vertexNumber, int edgeNumber, boolean undirected)
        {
            List<Integer>[] graph = new List[vertexNumber];
                    
            for (int index = 0; index < vertexNumber; ++index)
            {
                graph[index] = new ArrayList<Integer>();
            }
                    
            while (edgeNumber-- > 0)
            {
                int from = nextInt() - 1;
                int to   = nextInt() - 1;
                        
                graph[from].add(to);
                
                if(undirected)
                    graph[to].add(from);
            }
                    
            return graph;
        }
    }

    public static void main(String[] arg) 
    {
        new B().run();
    }
}