You have two friends. You want to present each of them several positive integers. You want to present cnt_1 numbers to the first friend and cnt_2 numbers to the second friend. Moreover, you want all presented numbers to be distinct, that also means that no number should be presented to both friends.

In addition, the first friend does not like the numbers that are divisible without remainder by prime number x. The second one does not like the numbers that are divisible without remainder by prime number y. Of course, you're not going to present your friends numbers they don't like.

Your task is to find such minimum number v, that you can form presents using numbers from a set 1, 2, ..., v. Of course you may choose not to present some numbers at all.

A positive integer number greater than 1 is called prime if it has no positive divisors other than 1 and itself.


-----Input-----

The only line contains four positive integers cnt_1, cnt_2, x, y (1 ≤ cnt_1, cnt_2 < 10^9; cnt_1 + cnt_2 ≤ 10^9; 2 ≤ x < y ≤ 3·10^4) — the numbers that are described in the statement. It is guaranteed that numbers x, y are prime.


-----Output-----

Print a single integer — the answer to the problem.


-----Examples-----
Input
3 1 2 3

Output
5

Input
1 3 2 3

Output
4



-----Note-----

In the first sample you give the set of numbers {1, 3, 5} to the first friend and the set of numbers {2} to the second friend. Note that if you give set {1, 3, 5} to the first friend, then we cannot give any of the numbers 1, 3, 5 to the second friend. 

In the second sample you give the set of numbers {3} to the first friend, and the set of numbers {1, 2, 4} to the second friend. Thus, the answer to the problem is 4.

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Sorting

Mathematics


Solutions:
(c1, c2, x, y) = list(map(int, input().split()))

def get(n):
	if n - n // (x * y) >= c1 + c2 and n - n // x >= c1 and (n - n // y >= c2):
		return True
	else:
		return False
l = 0
r = c1 * x + c2 * y
while r - l > 1:
	m = (l + r) // 2
	if get(m):
		r = m
	else:
		l = m
print(r)


(cnt1, cnt2, x, y) = [int(x) for x in input().split()]
(lo, hi) = (1, 10 * (cnt1 + cnt2))
while lo < hi:
	mid = (lo + hi) // 2
	div_by_both = mid // (x * y)
	div_by_x_only = mid // x - div_by_both
	div_by_y_only = mid // y - div_by_both
	total_wasted = div_by_both
	total_wasted += div_by_y_only - min(cnt1, div_by_y_only)
	total_wasted += div_by_x_only - min(cnt2, div_by_x_only)
	is_enough = True
	if cnt1 + cnt2 + total_wasted > mid:
		is_enough = False
	if is_enough:
		hi = mid
	else:
		lo = mid + 1
print(lo)


(a, b, x, y) = map(int, input().split())
(l, r) = (a + b, (a + b) * 5)
while l < r:
	v = (l + r) // 2
	if v - v // x >= a and v - v // y >= b and (v - v // (x * y) >= a + b):
		r = v
	else:
		l = v + 1
print(r)


def main():
	(cnt1, cnt2, x, y) = map(int, input().split())
	lo = cnt3 = cnt1 + cnt2
	(hi, z) = (10 ** 10, x * y)
	while lo < hi:
		v = (lo + hi) // 2
		if v - v // x < cnt1 or v - v // y < cnt2 or v - v // z < cnt3:
			lo = v + 1
		else:
			hi = v
	print(lo)
main()


3
from fractions import gcd
(cnt1, cnt2, a, b) = tuple(map(int, input().split()))
lcm = a * b // gcd(a, b)

def check(v):
	c1 = int(v / b) - int(v / lcm)
	c2 = int(v / a) - int(v / lcm)
	rest = v - c1 - c2 - int(v / lcm)
	c1 = min(c1, cnt1)
	c2 = min(c2, cnt2)
	return rest >= cnt1 + cnt2 - c1 - c2
(left, right) = (1, 10 ** 18)
while left + 1 < right:
	mid = (left + right) // 2
	if check(mid):
		right = mid
	else:
		left = mid
print(right)


line = input().split()
cnt1 = int(line[0])
cnt2 = int(line[1])
x = int(line[2])
y = int(line[3])
maxNum = 100000000000

def solve(n):
	a = n // x
	b = n // y
	both = n // (x * y)
	only_a = a - both
	only_b = b - both
	curr_cnt1 = max(0, cnt1 - only_b)
	curr_cnt2 = max(0, cnt2 - only_a)
	shared = curr_cnt1 + curr_cnt2
	remaining = n - only_a - only_b - both
	if remaining > shared:
		return 1
	elif remaining == shared:
		return 0
	else:
		return -1

def binary_search(left, right):
	middle = (left + right) // 2
	if solve(middle) == 0:
		return middle
	elif solve(middle) == 1:
		return binary_search(left, middle - 1)
	else:
		return binary_search(middle + 1, right)
ans = binary_search(1, maxNum)
while True:
	if solve(ans - 1) == 0:
		ans -= 1
	else:
		break
print(ans)


(n0, n1, x, y) = map(int, input().split())

def f(m, n, x, y):
	return max(0, n - (m // y - m // (x * y)))
lo = -1
hi = x * y * (n0 + n1)
while lo + 1 < hi:
	mid = lo + (hi - lo) // 2
	if f(mid, n0, x, y) + f(mid, n1, y, x) <= mid - mid // x - mid // y + mid // (x * y):
		hi = mid
	else:
		lo = mid
print(hi)


def check(v):
	a = v // y - v // (x * y)
	b = v // x - v // (x * y)
	c = v - (a + b + v // (x * y))
	fa = c + a
	fb = min(c, fa - cnt1) + b
	return fa >= cnt1 and fb >= cnt2
(cnt1, cnt2, x, y) = list(map(int, input().split()))
(l, r) = (0, (cnt1 + cnt2) * 2)
while l <= r:
	mid = (l + r) // 2
	if check(mid):
		ans = mid
		r = mid - 1
	else:
		l = mid + 1
print(ans)


s = input()
(c1, c2, x, y) = list(map(int, s.split()))
l = 0
r = int(1e+18)
while r - l > 1:
	m = (l + r) // 2
	d1 = m // x
	d2 = m // y
	b = m // (x * y)
	k1 = d2 - b
	k2 = d1 - b
	rr = m - d1 - d2 + b
	r1 = max(0, c1 - k1)
	r2 = max(0, c2 - k2)
	if rr >= r1 + r2:
		r = m
	else:
		l = m
print(r)


s = input()
arrIn = s.split()
n = int(arrIn[0])
m = int(arrIn[1])
x = int(arrIn[2])
y = int(arrIn[3])
l = 1
r = 2000000000.0
while l < r:
	mid = int((r + l) / 2)
	if n <= mid - int(mid / x) and m <= mid - int(mid / y) and (m + n <= mid - int(mid / (x * y))):
		r = mid
	else:
		l = mid + 1
else:
	print(r)


def valid(n1, n2, p1, p2, mid):
	x = mid - mid // p1
	y = mid - mid // p2
	rem = mid - mid // (p1 * p2)
	return x < n1 or y < n2 or rem < n1 + n2

def binary_search(n1, n2, p1, p2):
	(l, r) = (0, 1 << 61)
	while l <= r:
		mid = l + r >> 1
		if valid(n1, n2, p1, p2, mid):
			l = mid + 1
		else:
			r = mid - 1
	return l

def main():
	(n1, n2, p1, p2) = map(int, input().split())
	print(binary_search(n1, n2, p1, p2))
main()


def fastio():
	import sys
	from io import StringIO
	from atexit import register
	global input
	sys.stdin = StringIO(sys.stdin.read())
	input = lambda : sys.stdin.readline().rstrip('\r\n')
	sys.stdout = StringIO()
	register(lambda : sys.__stdout__.write(sys.stdout.getvalue()))
MOD = 10 ** 9 + 7
I = lambda : list(map(int, input().split()))
from math import ceil
(c1, c2, x, y) = I()
l = c1 // (x - 1) * x - 1
l += c1 - l // x - 1
high = 10 ** 18
low = 1
while low < high:
	mid = (low + high) // 2
	if mid - mid // (x * y) >= c1 + c2 and mid - mid // x >= c1 and (mid - mid // y >= c2):
		high = mid
	else:
		low = mid + 1
print(low)


(c1, c2, x, y) = map(int, input().split())
(l, r) = (0, 1 << 179)
while r - l > 1:
	m = l + r >> 1
	if m - m // x >= c1 and m - m // y - max(0, c1 - m // y + m // x // y) >= c2:
		r = m
	else:
		l = m
print(r)


def gcd(a, b):
	return b if a % b == 0 else gcd(b, a % b)
(cntx, cnty, x, y) = list(map(int, input().split()))
d = x * y // gcd(x, y)
v = cnt = 0
while cntx + cnty > cnt:
	dxy = cntx + cnty - cnt
	cx = (v + dxy) // x - v // x
	cy = (v + dxy) // y - v // y
	cxy = (v + dxy) // d - v // d
	cnt += dxy - cx - cy + cxy
	cntx -= min(cy - cxy, cntx)
	cnty -= min(cx - cxy, cnty)
	v += dxy
print(v)


(cnt1, cnt2, x, y) = map(int, input().split())
do = cnt1 + cnt2
up = 10 ** 12

def checker(mid):
	if mid - mid // x >= cnt1 and mid - mid // y - max(cnt1 - mid // y + mid // (y * x), 0) >= cnt2:
		return True
	elif mid - mid // y >= cnt2 and mid - mid // x - max(cnt2 - mid // x + mid // (y * x), 0) >= cnt1:
		return True
	return False
while up >= do:
	mid = (up + do) // 2
	if checker(mid):
		up = mid - 1
		an = mid
	else:
		do = mid + 1
print(an)


(a, b, x, y) = list(map(int, input().split()))
(L, R) = (0, 10 ** 18)
while R - L > 1:
	M = (L + R) // 2
	if M - M // x < a or min(M - a - M // (x * y), M - M // y) < b:
		L = M
	else:
		R = M
print(R)


(a, b, x, y) = map(int, input().split())
l = 0
r = 10000000000000
res = 0

def judge(n, a, b, x, y):
	return n - n // (x * y) >= a + b and n - n // x >= a and (n - n // y >= b)
while l <= r:
	m = (l + r) // 2
	if judge(m, a, b, x, y):
		r = m - 1
		res = m
	else:
		l = m + 1
print(res)


__author__ = 'neki'
import sys
words = input().split()
cnt1 = int(words[0])
cnt2 = int(words[1])
x = int(words[2])
y = int(words[3])

def determine(num, x, y, cnt1, cnt2):
	like1 = num - num // x
	like2 = num - num // y
	like1and2 = like1 + like2 - num + num // (x * y)
	friend1 = like1 - like1and2
	friend2 = like2 - like1and2
	both = like1and2
	cond1 = 0
	cond2 = 0
	if friend1 + both >= cnt1 and friend2 + both >= cnt2:
		cond1 += 1
	if friend1 + friend2 + both >= cnt1 + cnt2:
		cond2 += 1
	if cond1 > 0 and cond2 > 0:
		return 1
	return 0
lim = 0
lim1 = 1
lim2 = -1
while 1:
	if lim2 < 0:
		lim = lim1 * 2
	else:
		lim = (lim1 + lim2) // 2
	if lim == lim1:
		break
	if determine(lim, x, y, cnt1, cnt2) == 1:
		lim2 = lim
	else:
		lim1 = lim
print(lim2)


import os, sys
from io import BytesIO, IOBase

def check(mid, c1, c2, x, y):
	(a, b, c) = (mid // x, mid // y, mid // (x * y))
	c1 = max(0, c1 - b + c)
	c2 = max(0, c2 - a + c)
	if c1 + c2 <= mid - a - b + c:
		return 1
	return 0

def main():
	(c1, c2, x, y) = map(int, input().split())
	(hi, lo, ans) = (10 ** 10, 0, 10 ** 10)
	while hi >= lo:
		mid = (hi + lo) // 2
		if check(mid, c1, c2, x, y):
			ans = mid
			hi = mid - 1
		else:
			lo = mid + 1
	print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


(n, m, x, y) = map(int, input().split())
tmp = [1]

def judge(n, m, sum, tmp):
	cnt = int(sum / x / y)
	if x == y:
		cnt = int(sum / x)
	n = max(0, n - int(sum / y) + cnt)
	m = max(0, m - int(sum / x) + cnt)
	if sum - int(sum / x) - int(sum / y) + cnt >= n + m:
		tmp = sum
		re = 0
	else:
		tmp = m + n - (sum - int(sum / x) - int(sum / y) + cnt)
		re = tmp
	return re
sum = n + m
while True:
	temp = judge(n, m, sum, tmp)
	if temp == 0:
		break
	sum += temp
print(sum)


def spliter():
	d = input()
	a = d.split()
	r = []
	for i in a:
		k = int(i)
		r.append(k)
	return r

def counter(a, b):
	i = a // b
	j = i
	while i > 0:
		a += i
		i = a // b - j
		j += i
	return a
lst = spliter()
l1 = lst[0]
l2 = lst[1]
l3 = lst[2]
l4 = lst[3]
count1 = counter(l1, l3)
count2 = counter(l2, l4)
count3 = counter(l1 + l2, l3 * l4)
count = max(count1, count2, count3)
print(count)


(c1, c2, x, y) = map(int, input().split())

def fn(val):
	f = [val // x, val // y]
	both = val // (x * y)
	f = [i - both for i in f]
	oth = val - f[0] - f[1] - both
	cnt = [c1 - f[1], c2 - f[0]]
	if cnt[0] < 0:
		cnt[0] = 0
	if cnt[1] < 0:
		cnt[1] = 0
	return sum(cnt) <= oth
l = 0
r = int(1e+18)
while r - l > 1:
	m = (r + l) // 2
	if fn(m):
		r = m
	else:
		l = m
print(r)


R = lambda : map(int, input().split())
(c1, c2, x, y) = R()
(l, r) = (c1 + c2, 2 * 10 ** 9 + 7)
while l < r:
	m = (l + r) // 2
	r1 = max(0, c1 - m // y + m // (x * y))
	r2 = max(0, c2 - m // x + m // (x * y))
	if m - m // x - m // y + m // (x * y) < r1 + r2:
		l = m + 1
	else:
		r = m
print(l)


(c1, c2, x, y) = map(int, input().split())

def poss(v):
	global c1, c2, x, y
	divbyx = v // x
	divbyy = v // y
	divbyxy = v // (x * y)
	cc1 = c2 - divbyx + divbyxy
	cc2 = c1 - divbyy + divbyxy
	cc1 = max(cc1, 0)
	cc2 = max(cc2, 0)
	remaining = v - divbyx - divbyy + divbyxy
	if cc1 + cc2 <= remaining:
		return True
	return False
(lo, hi) = (1, int(1e+19))
ans = int(1e+19)
while lo <= hi:
	mid = (lo + hi) // 2
	if poss(mid):
		ans = min(ans, mid)
		hi = mid - 1
	else:
		lo = mid + 1
print(ans)


(c1, c2, x, y) = map(int, input().split())

def valid(m):
	a = m - m // x
	b = m - m // y - max(0, c1 - m // y + m // x // y)
	return a >= c1 and b >= c2
(l, r) = (0, 1 << 62)
while l + 1 < r:
	m = l + r >> 1
	if valid(m):
		r = m
	else:
		l = m
print(r)


(cnt1, cnt2, x, y) = map(int, input().split())
upper_limit = (cnt1 + cnt2) * (x * y) // (x * y - x - y + 1)

def bin_search(low, high):
	if low >= high - 1:
		return high
	mid = (low + high) // 2
	best_way = max(0, cnt1 - mid // y + mid // (x * y)) + max(0, cnt2 - mid // x + mid // (x * y))
	leftovers = mid - mid // x - mid // y + mid // (x * y)
	if best_way <= leftovers:
		return bin_search(low, mid)
	return bin_search(mid, high)
print(bin_search(1, upper_limit + 10))


(cnt1, cnt2, x, y) = list(map(int, input().split(' ')))
lo = 1
hi = 10 ** 10
while lo < hi:
	xx = cnt1
	yy = cnt2
	mid = (lo + hi) // 2
	intx = mid // x
	inty = mid // y
	intxy = mid // (x * y)
	notxy = mid - intx - inty + intxy
	notx = mid - intx - notxy
	noty = mid - inty - notxy
	xx -= notx
	yy -= noty
	if max(xx, 0) + max(yy, 0) > notxy:
		lo = mid + 1
	else:
		hi = mid
print(lo)


import math

def expr(N, x, y, cnt1, cnt2):
	cnt1 = max(cnt1res - math.floor(N / y) + math.floor(N / (y * x)), 0)
	cnt2 = max(cnt2res - math.floor(N / x) + math.floor(N / (y * x)), 0)
	b = N - math.floor(N / x) - math.floor(N / y) + math.floor(N / (x * y)) >= cnt1 + cnt2
	return b
(cnt1, cnt2, x, y) = map(int, list(input().split()))
cnt1res = cnt1
cnt2res = cnt2
N = math.ceil((cnt1 + cnt2 + 1) / (1 - 1 / x - 1 / y + 1 / (y * x)))
(start, last) = (1, N)
while last > start:
	mid = start + (last - start) // 2
	if expr(mid, x, y, cnt1, cnt2):
		last = mid
	else:
		start = mid
	if start + 1 == last:
		break
print(last)


def works(v):
	shared = v // (x * y)
	(cnt_1loc, cnt_2loc) = (v // x, v // y)
	split = v - cnt_1loc - cnt_2loc + shared
	(cnt_1loc, cnt_2loc) = (cnt_1loc - shared, cnt_2loc - shared)
	return max(cnt1 - cnt_2loc, 0) + max(cnt2 - cnt_1loc, 0) <= split
(cnt1, cnt2, x, y) = map(int, input().split())
(low, mid, high) = (0, -1, 10 ** 18)
while high - low > 1:
	mid = (high + low) // 2
	if works(mid):
		high = mid
	else:
		low = mid
print(high)


(cnt1, cnt2, x, y) = list(map(int, input().split()))

def present(v, x, y, cnt1, cnt2):
	div_x = v // x
	div_y = v // y
	div_xy = v // (x * y)
	div_x -= div_xy
	div_y -= div_xy
	left = v - (div_x + div_y + div_xy)
	cnt1 -= div_y
	cnt2 -= div_x
	cnt1 = cnt1 if cnt1 > 0 else 0
	cnt2 = cnt2 if cnt2 > 0 else 0
	return left >= cnt1 + cnt2
l = 0
r = 1e+18
while r - l > 1:
	mid = l + (r - l) // 2
	if present(mid, x, y, cnt1, cnt2):
		r = mid
	else:
		l = mid
print(int(r))


(cnt1, cnt2, x, y) = map(int, input().split())
l = 0
r = (cnt1 // (x - 1) + 1) * x + (cnt2 // (y - 1) + 1) * y + 5
while r - l != 1:
	m = l + (r - l) // 2
	t_cnt1 = m // y - m // (x * y)
	t_cnt2 = m // x - m // (x * y)
	if max(0, cnt1 - t_cnt1) + max(0, cnt2 - t_cnt2) <= m - (m // x + m // y - m // (x * y)):
		r = m
	else:
		l = m
print(r)


class FriendsPresents:

	def __init__(self, c1, c2, x, y):
		(self.c1, self.c2, self.x, self.y) = (c1, c2, x, y)

	def check(self, v):
		xval = int(v / self.x)
		yval = int(v / self.y)
		xyval = int(v / (self.x * self.y))
		c1rem = max(0, self.c1 - (yval - xyval))
		c2rem = max(0, self.c2 - (xval - xyval))
		if c1rem + c2rem <= v - xval - yval + xyval:
			return True
		else:
			return False

	def min_val(self):
		mn = self.c1 + self.c2 - 1
		mx = self.c1 * self.c2
		while not self.check(mx):
			mx = mx * 2
		while mx > mn + 1:
			md = int((mn + mx) / 2)
			if self.check(md):
				mx = md
			else:
				mn = md
		return mx
(c1, c2, x, y) = list(map(int, input().strip(' ').split(' ')))
fp = FriendsPresents(c1, c2, x, y)
print(fp.min_val())


from sys import stdin
lines = list([_f for _f in stdin.read().split('\n') if _f])

def parseline(line):
	return list(map(int, line.split()))
lines = list(map(parseline, lines))

def search(f, v, l, r):
	while l + 1 < r:
		p = l + (r - l) // 2
		if f(p) <= v:
			l = p
		else:
			r = p
	return l
(c1, c2, x, y) = lines[0]

def check(v, debug=False):
	m1 = max(c1 - v // y + v // (x * y), 0)
	m2 = max(c2 - v // x + v // (x * y), 0)
	f = v - v // x - v // y + v // (x * y)
	if debug:
		print(v, ':', m1, m2, f)
	if m2 <= f - m1:
		return 1
	else:
		return 0
print(1 + search(check, 0, 1, y * c1 + x * c2 + 1))


import os
import sys
from math import *
from collections import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
ALPHA = 'abcdefghijklmnopqrstuvwxyz'
M = 998244353
EPS = 1e-06

def Ceil(a, b):
	return a // b + int(a % b > 0)

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]

def ok(n):
	have = n - n // (x * y)
	first = n // y - n // (x * y)
	second = n // x - n // (x * y)
	have -= first + second
	return have >= max(c1 - first, 0) + max((c2 - second, 0))
(c1, c2, x, y) = value()
low = 0
high = 10 ** 10
while low <= high:
	mid = low + (high - low) // 2
	if not ok(mid):
		low = mid + 1
	else:
		ans = mid
		high = mid - 1
print(ans)


import math
(u, v, x, y) = map(int, input().split())
z = x * y // math.gcd(x, y)

def check(ans):
	inter = ans - ans // x - ans // y + ans // z
	fx = ans // y - ans // z
	fy = ans // x - ans // z
	if fx + inter < u:
		return False
	if fy + inter < v:
		return False
	if fx + fy + inter < u + v:
		return False
	return True
ans = 0
for i in range(31, -1, -1):
	if not check(ans + 2 ** i):
		ans += 2 ** i
print(ans + 1)


(a, b, c, d) = map(int, input().split())
l = 1
r = 10 ** 10
while r - l > 1:
	m = (r + l) // 2
	both = m // (c * d)
	f = [m // c, m // d]
	other = m - f[0] - f[1] + both
	f[0] -= both
	f[1] -= both
	if max(0, b - f[0]) + max(0, a - f[1]) <= other:
		r = m
	else:
		l = m
print(r)


(c1, c2, x, y) = map(int, input().split())
xy = x * y
n = 1
while n - n // x < c1 or n - n // y < c2 or n - n // xy < c1 + c2:
	n = n << 1
l = 1
r = n
while r - l > 1:
	m = r + l >> 1
	if m - m // x < c1 or m - m // y < c2 or m - m // xy < c1 + c2:
		l = m
	else:
		r = m
m = l
if m - m // x < c1 or m - m // y < c2 or m - m // xy < c1 + c2:
	print(r)
else:
	print(l)


(cnt_1, cnt_2, x, y) = map(int, input().split())
l = 0
r = 10 ** 18
lcm = x * y
while r > l + 1:
	mid = (l + r) // 2
	if mid - mid // x < cnt_1 or min(mid - cnt_1 - mid // lcm, mid - mid // y) < cnt_2:
		l = mid
	else:
		r = mid
print(r)


(c1, c2, x, y) = map(int, input().split())
l = c1 + c2
temp = l
h = pow(10, 10)
while l < h:
	ans = (l + h) // 2
	if c1 > ans - ans // x or c2 > ans - ans // y or temp > ans - ans // (x * y):
		l = ans + 1
	else:
		h = ans
print(l)


from math import gcd

def check(n):
	global cnt1, cnt2, x, y
	xdiv = n // x
	ydiv = n // y
	xydiv = n // (x * y)
	xndiv = n - xdiv
	yndiv = n - ydiv
	xyndiv = n - xydiv
	xyndiv -= ydiv
	xyndiv -= xdiv
	xyndiv += 2 * xydiv
	yndiv -= xyndiv
	xndiv -= xyndiv
	if xndiv + xyndiv < cnt1:
		return 0
	xyndiv -= max(0, cnt1 - xndiv)
	if yndiv + xyndiv < cnt2:
		return 0
	return 1
(cnt1, cnt2, x, y) = map(int, input().split())
s = 1
e = 10 ** 20
while s <= e:
	mid = (s + e) // 2
	if check(mid) == 1:
		ans = mid
		e = mid - 1
	else:
		s = mid + 1
print(ans)


def Solve(n, m, sum):
	cnt = int(sum / x / y)
	if x == y:
		cnt = int(sum / x)
	n = max(0, n - int(sum / y) + cnt)
	m = max(0, m - int(sum / x) + cnt)
	if sum - int(sum / x) - int(sum / y) + cnt >= n + m:
		tmp = 0
	else:
		tmp = m + n - (sum - int(sum / x) - int(sum / y) + cnt)
	return tmp
(n, m, x, y) = map(int, input().split())
sum = n + m
while True:
	temp = Solve(n, m, sum)
	if temp == 0:
		break
	sum += temp
print(sum)