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.awt.geom.Point2D;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;

public class Main implements Runnable {
    BufferedReader in;
    PrintWriter out;
    StringTokenizer st;

    String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }
    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }
    long nextLong() throws IOException{
        return Long.parseLong(nextToken());
    }

    double cc(int n1, int m1, int n2, int m2, int n3, int m3) {
        double res = 1;
        for (int i = 0; i < m3; ++i) {
            if (i < m2) {
                res *= (double)(n2 - i) / (n3 - i);
            } else {
                res *= (double)(n1 - i + m2) / (n3 - i);
            }
        }
        for (int i = m2 + 1; i <= m3; ++i) {
            res *= (double)i / (i - m2);
        }
        return res;
    }

    void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        double res = 0;
        for (int x = 1; x <= Math.min(n, m); ++x) {
            res += x * x * cc(m, x, (n - 1) * m, n - x, n * m, n) / n;
        }
        out.printf("%.10f\n", res);
    }

    public void run() {
        try {
//            in = new BufferedReader(new FileReader("input.txt"));
//            out = new PrintWriter("output.txt");
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
            Locale.setDefault(Locale.UK);
//            for (int tt = nextInt(); tt > 0; tt--)
                solve();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        } finally {
            out.close();
        }
    }

    public static void main(String Args[]) {
        new Thread(null, new Main(), "1", 1 << 28).start();
    }
}