import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class B483 {
    private static StreamTokenizer in;

    public static void main(String[] args) throws IOException {
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        solve();
    }

    private static void solve() throws IOException {
        int cnt1 = nextInt();
        int cnt2 = nextInt();
        int x = nextInt();
        int y = nextInt();

        int lo = cnt1 + cnt2;
        int hi = Integer.MAX_VALUE;
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            if (check(cnt1, cnt2, x, y, mid)) hi = mid;
            else lo = mid + 1;
        }
        System.out.println(lo);
    }

    private static boolean check(int cnt1, int cnt2, int x, int y, int mid) {
        int divX = mid / x;
        int divY = mid / y;
        int both = mid / (x * y);

        int allUsed = mid - divX - divY + both;
        int num1 = divY - both;
        int num2 = divX - both;
        cnt1 -= num1;
        cnt2 -= num2;

        return cnt1 + cnt2 <= allUsed;
    }

    private static int nextInt() throws IOException {
        in.nextToken();
        return (int) in.nval;
    }
}
