Problem: Alex enjoys performing magic tricks. He has a trick that requires a deck of n cards. He has m identical decks of n different cards each, which have been mixed together. When Alex wishes to perform the trick, he grabs n cards at random and performs the trick with those. The resulting deck looks like a normal deck, but may have duplicates of some cards.

The trick itself is performed as follows: first Alex allows you to choose a random card from the deck. You memorize the card and put it back in the deck. Then Alex shuffles the deck, and pulls out a card. If the card matches the one you memorized, the trick is successful.

You don't think Alex is a very good magician, and that he just pulls a card randomly from the deck. Determine the probability of the trick being successful if this is the case.

Input

First line of the input consists of two integers n and m (1 ≤ n, m ≤ 1000), separated by space — number of cards in each deck, and number of decks.

Output

On the only line of the output print one floating point number – probability of Alex successfully performing the trick. Relative or absolute error of your answer should not be higher than 10 - 6.

Examples

Input

2 2


Output

0.6666666666666666


Input

4 4


Output

0.4000000000000000


Input

1 2


Output

1.0000000000000000

Note

In the first sample, with probability <image> Alex will perform the trick with two cards with the same value from two different decks. In this case the trick is guaranteed to succeed.

With the remaining <image> probability he took two different cards, and the probability of pulling off the trick is <image>.

The resulting probability is <image>

Solution (in JAVA):

Solution:
import java.util.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;

public class Main {
	BigInteger bi(int x) {
		return BigInteger.valueOf(x);
	}
	BigDecimal bd(int x) {
		return BigDecimal.valueOf(x);
	}
	BigDecimal comb(int n, int m) {
		BigDecimal ret = bd(1);
		for (int i = 1; i <= m; ++ i) ret = ret.multiply(bd(n + 1 - i)).divide(bd(i));
		return ret; 
	}
	void solve() {
		int n, m;
		n = cin.nextInt();
		m = cin.nextInt();
		BigDecimal t0 = bd(m), t1 = comb(m * n - m, n - 1);
		BigDecimal ans = t0.multiply(t1);
		for (int i = 2; i <= n; ++ i) {
			t0 = t0.multiply(bd(m - i + 1)).divide(bd(i), 20, BigDecimal.ROUND_HALF_DOWN);
			t1 = t1.multiply(bd(n - i + 1)).divide(bd(m * n - m - n + i), 20, BigDecimal.ROUND_HALF_DOWN);
			ans = ans.add(bd(i).multiply(bd(i)).multiply(t0).multiply(t1));
		}
		ans = ans.divide(bd(n), 20, BigDecimal.ROUND_HALF_DOWN).divide(comb(m * n, n), 20, BigDecimal.ROUND_HALF_DOWN);
		cout.println(ans);
	}
	FastScanner cin;
	PrintWriter cout;
	void run() {
		cin = new FastScanner();
		cout = new PrintWriter(System.out);
		solve();
		cout.flush();
	}
	class FastScanner {
		BufferedReader br;
		StringTokenizer st;
		boolean hasNext;
		
		public FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
			hasNext = true;
		}
		
//		public FastScanner(String s) {
//			try {
//				br = new BufferedReader(new FileReader(s));
//			} catch (FileNotFoundException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//			hasNext = true;
//		}
		
		public String nextToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					hasNext = false;
					return "##";
				}
			}
			return st.nextToken();
		}
		String next = null;
		public boolean hasNext() {
			next = nextToken();
			return hasNext;
		}
		public int nextInt() {
			if (next == null) next = nextToken();
			String more = next;
			next = null;
			return Integer.parseInt(more);
		}
		public long nextLong() {
			return Long.parseLong(nextToken());
		}

		public double nextDouble() {
			return Double.parseDouble(nextToken());
		}
	}
	public static void main(String[] args) {
		new Main().run();
	}
}