The dragon and the princess are arguing about what to do on the New Year's Eve. The dragon suggests flying to the mountains to watch fairies dancing in the moonlight, while the princess thinks they should just go to bed early. They are desperate to come to an amicable agreement, so they decide to leave this up to chance.

They take turns drawing a mouse from a bag which initially contains w white and b black mice. The person who is the first to draw a white mouse wins. After each mouse drawn by the dragon the rest of mice in the bag panic, and one of them jumps out of the bag itself (the princess draws her mice carefully and doesn't scare other mice). Princess draws first. What is the probability of the princess winning?

If there are no more mice in the bag and nobody has drawn a white mouse, the dragon wins. Mice which jump out of the bag themselves are not considered to be drawn (do not define the winner). Once a mouse has left the bag, it never returns to it. Every mouse is drawn from the bag with the same probability as every other one, and every mouse jumps out of the bag with the same probability as every other one.

Input

The only line of input data contains two integers w and b (0 ≤ w, b ≤ 1000).

Output

Output the probability of the princess winning. The answer is considered to be correct if its absolute or relative error does not exceed 10 - 9.

Examples

Input

1 3


Output

0.500000000


Input

5 5


Output

0.658730159

Note

Let's go through the first sample. The probability of the princess drawing a white mouse on her first turn and winning right away is 1/4. The probability of the dragon drawing a black mouse and not winning on his first turn is 3/4 * 2/3 = 1/2. After this there are two mice left in the bag — one black and one white; one of them jumps out, and the other is drawn by the princess on her second turn. If the princess' mouse is white, she wins (probability is 1/2 * 1/2 = 1/4), otherwise nobody gets the white mouse, so according to the rule the dragon wins.

Difficulty: MEDIUM_HARD
Tags: Dynamic programming

Game theory

Mathematics

Probability
Skill types: Dynamic programming

Starter code:

Solutions:
(w, b) = list(map(int, input().split()))
p = []
for i in range(w + 1):
	p.append([0] * (b + 1))
for i in range(1, w + 1):
	p[i][0] = 1
for i in range(1, w + 1):
	for j in range(1, b + 1):
		p[i][j] = i / (i + j)
		if j >= 3:
			p[i][j] += j / (i + j) * ((j - 1) / (i + j - 1)) * ((j - 2) / (i + j - 2)) * p[i][j - 3]
		if j >= 2:
			p[i][j] += j / (i + j) * ((j - 1) / (i + j - 1)) * (i / (i + j - 2)) * p[i - 1][j - 2]
print('%.9f' % p[w][b])


import sys
input = sys.stdin.readline
memo = {}

def prob(w, b):
	if w == 0 or b < 0:
		return 0
	if b == 0:
		return 1
	if (w, b) in memo:
		return memo[w, b]
	ans1 = w / (w + b)
	if b == 1:
		ans2 = 0
	else:
		ans2 = b / (w + b) * ((b - 1) / (w + b - 1)) * (prob(w - 1, b - 2) * (w / (b + w - 2)) + prob(w, b - 3) * ((b - 2) / (b + w - 2)))
	memo[w, b] = ans1 + ans2
	return ans1 + ans2
(w, b) = map(int, input().split())
print(prob(w, b))


import os, sys
from io import BytesIO, IOBase

def main():
	(w, b) = map(int, input().split())
	dp = [[0] * (w + 3) for _ in range(b + 3)]
	dp[0] = [0] + [1] * (w + 2)
	for i in range(1, b + 1):
		for j in range(1, w + 1):
			dp[i][j] = j / (i + j)
			if i + j > 2:
				dp[i][j] += i * (i - 1) * (dp[i - 2][j - 1] * (j / (i - 2 + j)) + dp[i - 3][j] * ((i - 2) / (i - 2 + j))) / ((i + j) * (i + j - 1))
	print(dp[b][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')
main()


(w, b) = map(int, input().split())
if w == 0:
	print(0)
elif b == 0:
	print(1)
else:
	ans = 0
	dp = [[0.0 for i in range(b + 1)] for j in range(w + 1)]
	dp[w][b - 1] = b / (w + b)
	ans += w / (w + b)
	i = w
	while i >= 0:
		j = b - 1
		while j >= 0:
			if j + 3 <= b:
				dp[i][j] = dp[i][j] + (j + 1) * (j + 2) * (j + 3) * dp[i][j + 3] / ((i + j + 1) * (i + j + 2) * (i + j + 3))
			if j + 2 <= b and i + 1 <= w:
				dp[i][j] = dp[i][j] + (j + 1) * (i + 1) * (j + 2) * dp[i + 1][j + 2] / ((i + j + 1) * (i + j + 2) * (i + j + 3))
				ans += (i + 1) * (j + 1) * (j + 2) * dp[i + 1][j + 2] / ((i + j + 1) * (i + j + 2) * (i + j + 3))
			if i + 2 <= w and j + 1 <= b:
				ans += (i + 1) * (i + 2) * (j + 1) * dp[i + 2][j + 1] / ((i + j + 1) * (i + j + 2) * (i + j + 3))
			j += -1
		i += -1
	print(ans)


import os
from sys import stdin, stdout

def solve(tc):
	(w, b) = map(int, stdin.readline().split())
	dp = [[1.0 for j in range(1001)] for i in range(1001)]
	for i in range(1, 1001):
		dp[i][0] = 1.0
		dp[i][1] = i / (i + 1)
		dp[0][i] = 0.0
	dp[1][1] = 0.5
	if w == 0:
		print(0.0)
		return
	if b == 0:
		print(1.0)
		return
	elif b == 1:
		print(dp[w][b])
		return
	for i in range(1, w + 1):
		dp[i][2] = i / (i + 2)
		dp[i][2] += 2 / (i + 2) * 1 / (i + 1)
		for j in range(3, b + 1):
			dp[i][j] = i / (i + j)
			dp[i][j] += j / (i + j) * (j - 1) / (i + j - 1) * (j - 2) / (i + j - 2) * dp[i][j - 3]
			dp[i][j] += j / (i + j) * (j - 1) / (i + j - 1) * i / (i + j - 2) * dp[i - 1][j - 2]
	print(dp[w][b])
tcs = 1
tc = 1
while tc <= tcs:
	solve(tc)
	tc += 1


(w, b) = map(int, input().split())
(k, p, q, s) = (0, 0, 1, w + b)
while q != 0 and k < s:
	d = q * w / s
	p += d
	q -= d
	s -= 1
	d = q * w / s
	q -= d
	s -= 1
	k += 1
print(p)


from fractions import Fraction
(w, b) = [int(x) for x in input().split()]

def probability(w, b):
	memory = {}

	def recursive(w, b):
		if w <= 0:
			return 0.0
		if b <= 0:
			return 1.0
		if (w, b) in memory:
			return memory[w, b]
		white = w
		black = b
		answer = white / (black + white)
		black -= 1
		cont_p = (1 - answer) * (black / (black + white))
		if cont_p > 1e-13:
			black -= 1
			white_ch = white / (white + black)
			white_p = recursive(white - 1, black) * white_ch
			black_p = recursive(white, black - 1) * (1 - white_ch)
			answer += cont_p * (black_p + white_p)
		memory[w, b] = answer
		return answer
	return recursive(w, b)
answer = probability(w, b)
print(answer)


import os
import sys
from bisect import bisect_right
from collections import Counter, defaultdict, deque
from heapq import *
from io import BytesIO, IOBase
from math import gcd, inf, sqrt, ceil

def lcm(a, b):
	return a * b // gcd(a, b)

def sieve():
	global spf, adj, MAXN
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(2, MAXN):
		if i * i > MAXN:
			break
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i

def getdistinctFactorization(n):
	global adj, spf, MAXN
	for i in range(1, n + 1):
		index = 1
		x = i
		if x != 1:
			adj[i].append(spf[x])
		x = x // spf[x]
		while x != 1:
			if adj[i][index - 1] != spf[x]:
				adj[i].append(spf[x])
				index += 1
			x = x // spf[x]

def printDivisors(n):
	i = 2
	z = [1, n]
	while i <= sqrt(n):
		if n % i == 0:
			if n / i == i:
				z.append(i)
			else:
				z.append(i)
				z.append(n // i)
		i = i + 1
	return z

def create(n, x, f):
	pq = len(bin(n)[2:])
	if f == 0:
		tt = min
	else:
		tt = max
	dp = [[inf] * n for _ in range(pq)]
	dp[0] = x
	for i in range(1, pq):
		for j in range(n - (1 << i) + 1):
			dp[i][j] = tt(dp[i - 1][j], dp[i - 1][j + (1 << i - 1)])
	return dp

def enquiry(l, r, dp, f):
	if l > r:
		return inf if not f else -inf
	if f == 1:
		tt = max
	else:
		tt = min
	pq1 = len(bin(r - l + 1)[2:]) - 1
	return tt(dp[pq1][l], dp[pq1][r - (1 << pq1) + 1])

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	x = []
	for i in range(2, n + 1):
		if prime[i]:
			x.append(i)
	return x
cache = defaultdict(lambda : -1)

def func(w, b):
	if cache[w, b] != -1:
		return cache[w, b]
	if b < 0 or w == 0:
		return 0
	if b == 0:
		return 1
	an = 0
	if b == 1:
		an += w / (b + w)
	else:
		an += b / (w + b) * (b - 1) / (w + b - 1) * (func(w - 1, b - 2) * w / (b + w - 2))
		an += b / (w + b) * (b - 1) / (w + b - 1) * (func(w, b - 3) * (b - 2) / (b + w - 2))
		an += w / (b + w)
	cache[w, b] = an
	return cache[w, b]

def main():
	(w, b) = map(int, input().split())
	print(func(w, b))
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()


def f(W, B):
	n = B - W + 1
	(d, p, t, r) = ([0] * B, [0] * B, [0] * B, [0] * B)
	(p[0], r[0], p[1]) = (1, 1, 0.5)
	for b in range(2, n + 1):
		d[b] = (t[b - 1] + p[b - 2] * (b - 1)) / (1 + b)
		p[b] = (1 + d[b - 1] * b) / (1 + b)
	(r[0], t[0]) = (1, 1)
	(t, r, p) = (p, t, r)
	for w in range(2, W):
		(p[1], d[1]) = (w / (w + 1), 1 / (w + 1))
		for b in range(2, n + w):
			d[b] = (t[b - 1] * w + p[b - 2] * (b - 1)) * b / ((w + b) * (w + b - 1))
			p[b] = (w + d[b - 1] * b) / (w + b)
		(t, r, p) = (p, t, r)
	return t[B - 1]
(w, b) = map(int, input().split())
if w == 0:
	print(0)
elif b == 0:
	print(1)
else:
	print(f(w + 1, b + 1))


from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def main():
	(w, b) = readIntArr()
	memo = makeArr(lambda : -1, [w + 1, b + 1, 2])

	@bootstrap
	def pWin(w, b, isPrincess):
		if memo[w][b][isPrincess] == -1:
			if w == 0 and b == 0:
				if isPrincess == 1:
					p = 0
				else:
					p = 1
			elif w == 1 and b == 0:
				p = 1
			else:
				p = w / (w + b)
				if isPrincess == 1:
					if b > 0:
						p += b / (w + b) * (1 - (yield pWin(w, b - 1, 0)))
				else:
					p2 = b / (w + b)
					if b > 0:
						b -= 1
						if w == 0 and b == 0:
							if isPrincess == 0:
								p += p2 * 1
							else:
								pass
						else:
							if w > 0:
								p += p2 * (w / (w + b)) * (1 - (yield pWin(w - 1, b, 1)))
							if b > 0:
								p += p2 * (b / (w + b)) * (1 - (yield pWin(w, b - 1, 1)))
			memo[w][b][isPrincess] = p
		yield memo[w][b][isPrincess]
	ans = pWin(w, b, 1)
	print(ans)
	return
import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')

def oneLineArrayPrint(arr):
	print(' '.join([str(x) for x in arr]))

def multiLineArrayPrint(arr):
	print('\n'.join([str(x) for x in arr]))

def multiLineArrayOfArraysPrint(arr):
	print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))

def readIntArr():
	return [int(x) for x in input().split()]

def makeArr(defaultValFactory, dimensionArr):
	dv = defaultValFactory
	da = dimensionArr
	if len(da) == 1:
		return [dv() for _ in range(da[0])]
	else:
		return [makeArr(dv, da[1:]) for _ in range(da[0])]

def queryInteractive(i, j):
	print('? {} {}'.format(i, j))
	sys.stdout.flush()
	return int(input())

def answerInteractive(ans):
	print('! {}'.format(' '.join([str(x) for x in ans])))
	sys.stdout.flush()
inf = float('inf')
MOD = 10 ** 9 + 7
for _abc in range(1):
	main()


(w, b) = map(int, input().split(' '))
if w == 0:
	print(0)
elif b == 0:
	print(1)
else:
	solved = [[-1] * b for i in range(w)]

	def solve(w, b):
		if solved[w - 1][b - 1] != -1:
			return solved[w - 1][b - 1]
		if w == 0:
			ans = 0
			solved[w - 1][b - 1] = ans
			return ans
		if b == 0:
			ans = 1
			solved[w - 1][b - 1] = ans
			return ans
		if b == 1:
			ans = w / (w + 1)
			solved[w - 1][b - 1] = ans
			return ans
		if b == 2:
			if w == 1:
				ans = 1 / 3
				solved[w - 1][b - 1] = ans
				return ans
			else:
				ans = w / (w + 2) + 2 / (w + 2) * 1 / (w + 1)
				solved[w - 1][b - 1] = ans
				return ans
		x = solve(w - 1, b - 2)
		y = solve(w, b - 3)
		ans = w / (w + b) + b / (w + b) * (b - 1) / (w + b - 1) * (w / (w + b - 2) * x + (b - 2) / (w + b - 2) * y)
		solved[w - 1][b - 1] = ans
		return ans
	print(solve(w, b))


(w, b) = map(float, input().split())
dic = {}

def fun(w, b):
	if dic.get((w, b)):
		return dic[w, b]
	if w > 0 and b > 1:
		temp = b / (b + w) * (b - 1) / (w + b - 1)
		res = w / (w + b) + temp * (w / (w + b - 2) * fun(w - 1, b - 2) + (b - 2) / (w + b - 2) * fun(w, b - 3))
		dic[w, b] = res
		return res
	elif w > 0 and b == 1:
		return w / (w + b)
	elif w > 0 and b == 0:
		return 1.0
	else:
		return 0.0
pro = fun(w, b)
print(pro)


import sys
sys.setrecursionlimit(10 ** 6)
(w, b) = map(int, input().split())
w += 1
b += 1
pr_win = [[None for k in range(b)] for k in range(w)]
dr_win = [[None for k in range(b)] for k in range(w)]

def f(w0, b0, princess):
	if w0 < 0 or b0 < 0:
		return 0
	if w0 == 0 and b0 == 0:
		return 0
	if b0 == 0:
		return 1 if princess else 0
	if w0 == 0:
		return 0
	if princess:
		if pr_win[w0][b0] is None:
			p_w = w0 / (w0 + b0)
			p_b = b0 / (w0 + b0) * f(w0, b0 - 1, not princess)
			pr_win[w0][b0] = p_w + p_b
		return pr_win[w0][b0]
	else:
		if dr_win[w0][b0] is None:
			p_bb = b0 / (w0 + b0) * (b0 - 1) / (w0 + b0 - 1) * f(w0, b0 - 2, not princess)
			p_bw = b0 / (w0 + b0) * w0 / (w0 + b0 - 1) * f(w0 - 1, b0 - 1, not princess)
			dr_win[w0][b0] = p_bb + p_bw
		return dr_win[w0][b0]
print('%.10f' % f(w - 1, b - 1, True))


import collections
import time
import os
import sys
import bisect
import heapq
from typing import List
from functools import lru_cache

@lru_cache(maxsize=None)
def solve(w, b):
	if w <= 0:
		return 0
	if b <= 0:
		return 1
	ans = w / (w + b)
	p = b / (w + b)
	b -= 1
	p *= b / (w + b)
	b -= 1
	if p > 1e-13:
		pblack = solve(w, b - 1) * b / (w + b)
		pwthite = solve(w - 1, b) * w / (w + b)
		ans += p * (pblack + pwthite)
	return ans
(w, b) = map(int, input().split())
print(solve(w, b))


dp = {}

def prob(w, b):
	if (w, b) in dp:
		return dp[w, b]
	if w == 0 and b == 0:
		return 0
	if b == 0:
		return 1
	if w == 0:
		return 0
	if b == 1:
		ans = w / (w + b)
		dp[w, b] = ans
		return ans
	if b == 2:
		ans = w / (w + 2) + 2 / (w + 2) * 1 / (w + 1) * prob(w - 1, b - 2)
		dp[w, b] = ans
		return ans
	sum = w + b
	if sum == 1 or sum == 2:
		print(w, b)
	ans = w / sum + b / sum * (b - 1) / (sum - 1) * (w / (sum - 2) * prob(w - 1, b - 2) + (b - 2) / (sum - 2) * prob(w, b - 3))
	dp[w, b] = ans
	return ans
(w, b) = tuple(map(int, input().split()))
print(prob(w, b))


(w, b) = [int(i) for i in input().split()]
dp = [[-1 for i in range(b + 1)] for j in range(w + 1)]

def f(w, b):
	if w == 0 and b == 0:
		return 0
	if b <= 0:
		return 1
	if w == 0:
		return 0
	if dp[w][b] != -1:
		return dp[w][b]
	ans = w / (w + b)
	if w >= 1 and b >= 2:
		ans += b / (w + b) * ((b - 1) / (w + b - 1)) * (w / (w + b - 2) * f(w - 1, b - 2))
	if b >= 3:
		ans += b / (w + b) * ((b - 1) / (w + b - 1)) * ((b - 2) / (w + b - 2)) * f(w, b - 3)
	dp[w][b] = ans
	return ans
print(f(w, b))


MAX = 1002
(w, b) = map(int, input().split())
ans = 0
dp = [[0 for _ in range(MAX)] for _ in range(MAX)]
end = [[0 for _ in range(MAX)] for _ in range(MAX)]
dp[w][b] = 1
for i in range(w, -1, -1):
	end[i][b + 1] = 1
if w > 0:
	ans += w / (w + b) * dp[w][b]
	end[w - 1][b] = 1
if b > 0:
	for j in range(b - 1, -1, -1):
		dp[w][j] = (j + 1) / (w + j + 1) * dp[w][j + 1]
for i in range(w - 1, -1, -1):
	for j in range(b - 1, -1, -1):
		if end[i + 1][j] and end[i][j + 1]:
			end[i][j] = 1
		else:
			if not end[i + 1][j]:
				if (w + b - i - j) % 3 == 1:
					ans += (i + 1) / (i + j + 1) * dp[i + 1][j]
					if end[i][j + 1]:
						end[i][j] = 1
				elif (w + b - i - j) % 3 == 2:
					if end[i][j + 1]:
						end[i][j] = 1
				else:
					dp[i][j] += (i + 1) / (i + j + 1) * dp[i + 1][j]
			if not end[i][j + 1]:
				dp[i][j] += (j + 1) / (i + j + 1) * dp[i][j + 1]
print(ans)


import math
import collections
from sys import stdin, stdout, setrecursionlimit
from bisect import bisect_left as bsl
from bisect import bisect_right as bsr
import heapq as hq
setrecursionlimit(2 ** 20)
t = 1
dp = [[0 for i in range(1001)] for j in range(1001)]

def fun(w, b):
	if w <= 0:
		return 0
	if b <= 0:
		return 1
	if dp[w][b] == 0:
		ans = 0
		ans += w / (w + b)
		if b >= 3:
			ans += b / (w + b) * ((b - 1) / (w + b - 1)) * (fun(w, b - 3) * ((b - 2) / (w + b - 2)) + fun(w - 1, b - 2) * (w / (w + b - 2)))
		if b == 2 and w > 1:
			ans += b / (w + b) * ((b - 1) / (w + b - 1))
		dp[w][b] = ans
		return ans
	else:
		return dp[w][b]
for _ in range(t):
	(w, b) = list(map(int, stdin.readline().rstrip().split()))
	print(fun(w, b))


d = dict()

def prob(w, b):
	if w == 0 or b < 0:
		return 0
	if b == 0:
		return 1
	if (b, w) in d:
		return d[b, w]
	ans1 = w / (w + b)
	if b == 1:
		ans2 = 0
	else:
		ans2 = b / (w + b) * (b - 1) / (w + b - 1) * (prob(w - 1, b - 2) * w / (b + w - 2) + prob(w, b - 3) * (b - 2) / (b + w - 2))
	d[b, w] = ans1 + ans2
	return ans1 + ans2
(w, b) = map(int, input().split())
print(prob(w, b))


save = {}

def fun(w, b):
	global save
	key = str(w) + ' ' + str(b)
	if save.get(key) != None:
		return save[key]
	prob = 0
	if w >= 0 and b >= 0 and (w + b != 0):
		prob = w / (w + b)
		if w + b > 2:
			prob += fun(w - 1, b - 2) * (b / (w + b)) * ((b - 1) / (w + b - 1)) * (w / (w + b - 2))
			prob += fun(w, b - 3) * (b / (w + b)) * ((b - 1) / (w + b - 1)) * ((b - 2) / (w + b - 2))
	save[key] = prob
	return prob
scr = input()
(mice_w, mice_b) = map(int, scr.split())
prob = fun(mice_w, mice_b)
print(prob)


(w, b) = [int(i) for i in input().split()]
a = [[0 for i in range(w + 1)] for j in range(b + 1)]

def cnt(w, b):
	if w <= 0:
		return 0
	if b <= 0:
		return 1
	if a[b][w] != 0:
		return a[b][w]
	c = w / (w + b)
	if w + b > 2:
		wjump = cnt(w - 1, b - 2)
		bjump = cnt(w, b - 3)
		c += b / (w + b) * ((b - 1) / (w + b - 1)) * ((b - 2) / (w + b - 2)) * bjump
		c += b / (w + b) * ((b - 1) / (w + b - 1)) * (w / (w + b - 2)) * wjump
	a[b][w] = c
	return c
print(cnt(w, b))


(w, b) = map(int, input().split())
cached = [[None] * (b + 1) for i in range(w + 1)]

def cal(w, b):
	if cached[w][b] is not None:
		return cached[w][b]
	if w == 0:
		return 0
	if b == 0:
		return 1
	total = w + b
	p = w / total
	bp = 1 - p
	dbp = (b - 1) / (total - 1)
	if b == 1:
		return p
	if b == 2:
		if w == 1:
			return p
		else:
			return p + bp * dbp
	cached[w][b] = p + bp * dbp * (w / (total - 2) * cal(w - 1, b - 2) + (b - 2) / (total - 2) * cal(w, b - 3))
	return cached[w][b]
print(cal(w, b))


(n, m) = map(int, input().split(' '))
dp = [[[1, 0] if j and (not i) else [0, 0] for i in range(m + 1)] for j in range(n + 1)]
for i in range(1, n + 1):
	for j in range(1, m + 1):
		dp[i][j][0] = i / (i + j) + j / (i + j) * dp[i][j - 1][1]
		dp[i][j][1] = j / (i + j) * (dp[i][j - 2][0] * ((j - 1) / (i + j - 1)) + dp[i - 1][j - 1][0] * (i / (i + j - 1)))
print(dp[n][m][0])


(w, b) = map(int, input().split())
dp = [[[1, 0] if i and (not j) else [0, 0] for j in range(b + 2)] for i in range(w + 2)]
for i in range(1, w + 1):
	for j in range(1, b + 1):
		dp[i][j][0] = (i + j * dp[i][j - 1][1]) / (i + j)
		dp[i][j][1] = j * ((j - 1) * dp[i][j - 2][0] + i * dp[i - 1][j - 1][0]) / (i + j) / (i + j - 1)
print(dp[w][b][0])


(w, b) = map(int, input().split())
dp = [[0] * (b + 1) for _ in range(w + 1)]
for i in range(1, w + 1):
	dp[i][0] = 1
for i in range(1, w + 1):
	for j in range(1, b + 1):
		dp[i][j] += i / (i + j)
		if j >= 3:
			dp[i][j] += dp[i][j - 3] * j / (i + j) * (j - 1) / (i + j - 1) * (j - 2) / (i + j - 2)
		if i >= 1 and j >= 2:
			dp[i][j] += dp[i - 1][j - 2] * j / (i + j) * (j - 1) / (i + j - 1) * i / (i + j - 2)
print(dp[-1][-1])