/*
 ID: govind.3, GhpS, govindpatel
 LANG: JAVA
 TASK: Main 
 */

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

public class Main {

    long lcm(long a, long b) {
        return a * b / gcd(a, b);
    }

    long gcd(long m, long n) {
        if (n == 0) {
            return m;
        }
        return gcd(n, m % n);
    }

    private void solve() throws IOException {
        long cnt1 = nextLong();
        long cnt2 = nextLong();
        long x = nextLong();
        long y = nextLong();
        long xy = x * y;//lcm(x,y);

        long LOW = 0;
        long MAX = Long.MAX_VALUE / 2;
        while (MAX - LOW > 1) {
            long mid = (MAX + LOW) / 2;

            long n1 = mid / x;//no div by x
            long n2 = mid / y;//no div by y
            long n3 = mid / xy;//no div by xy

            long have = mid - n1;//remove number divisible by x
            have -= n2;// remove number div by y
            have += n3; // add the nuumber divisible by both x and y

//            long f1 = n1 - n3;
//            long f2 = n2 - n3;
//            long take1 = cnt1 - f2 > 0 ? cnt1 - f2 : 0;
//            long take2 = cnt2 - f1 > 0 ? cnt2 - f1 : 0;
//            long remain = have - (take2 + take1);//remain after cnt1 and cnt2 removed..
            long player1 = have + (n2 - n3);
            long player2 = have + (n1 - n3);
//            if (remain >= 0) {
//                MAX = mid;
//            } else {
//                LOW = mid;
//            }
            if (player1 >= cnt1 && player2 >= cnt2) {
                MAX = mid;
            } else {
                LOW = mid;
            }
        }
        System.out.println(MAX);
    }

    public static void main(String[] args) {
        new Main().run();
    }

    public void run() {
        try {
            in = new BufferedReader(new FileReader("Main.in"));
            out = new PrintWriter(new BufferedWriter(new FileWriter("Main.out")));
            tok = null;
            solve();
            in.close();
            out.close();
            System.exit(0);
        } catch (IOException e) {//(FileNotFoundException e) {
            try {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(new OutputStreamWriter(System.out));
                tok = null;
                solve();
                in.close();
                out.close();
                System.exit(0);
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
                System.exit(0);
            }
        }
    }

    private String nextToken() throws IOException {
        while (tok == null || !tok.hasMoreTokens()) {
            tok = new StringTokenizer(in.readLine());
        }
        return tok.nextToken();
    }

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

    private long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    private double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }
    BufferedReader in;
    StringTokenizer tok;
    PrintWriter out;
}
