
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

public class B483 {

    public static BufferedReader in;
    public static PrintWriter out;
    public static StringTokenizer tokenizer;

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        in = new BufferedReader(new InputStreamReader(inputStream), 32768);
        out = new PrintWriter(outputStream);
        solve();
        out.close();
    }

    public static void solve() {
        int cnt1 = nextInt();
        int cnt2 = nextInt();
        int x = nextInt();
        int y = nextInt();
        long l = 1L;
        long r = (long) 1e18;
        while (l != r) {
            long m = (l + r) / 2;
            long f1 = (m - l + 1) / x;
            long f2 = (m - l + 1) / y;
            long nok = x * y / gcd(x, y);
            long both = m / nok;
            long to1 = f2 - both;
            long to2 = f1 - both;
            long left = m - f1 - f2 + both;
//            if (r - l < 10) {
//                out.println("l: " + l);
//                out.println("r: " + r);
//                out.println("f1: " + f1);
//                out.println("f2: " + f2);
//                out.println("both: " + both);
//                out.println("left: " + left);
//            }
            if (to1 < cnt1) {
                left -= (cnt1 - to1);
                to1 = cnt1;
            }
            if (to2 < cnt2) {
                left -= (cnt2 - to2);
                to2 = cnt2;
            }
            if (left >= 0) {
                r = m;
            } else {
                l = m + 1;
            }
        }
        out.println(l);
    }

    public static long gcd(long x, long y) {
        return (y == 0 ? x : gcd(y, x % y));
    }

    public static String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(in.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public static int nextInt() {
        return Integer.parseInt(next());
    }

    public static long nextLong() {
        return Long.parseLong(next());
    }

    public static double nextDouble() {
        return Double.parseDouble(next());
    }
}
