Problem: SmallR is an archer. SmallR is taking a match of archer with Zanoes. They try to shoot in the target in turns, and SmallR shoots first. The probability of shooting the target each time is <image> for SmallR while <image> for Zanoes. The one who shoots in the target first should be the winner.

Output the probability that SmallR will win the match.

Input

A single line contains four integers <image>.

Output

Print a single real number, the probability that SmallR will win the match.

The answer will be considered correct if the absolute or relative error doesn't exceed 10 - 6.

Examples

Input

1 2 1 2


Output

0.666666666667

Solution (in JAVA):

Solution:
import static java.lang.System.*;
import static java.lang.Math.*;

import java.lang.reflect.Array;
import java.util.*;
import java.util.Map.Entry;

public class B311 {
    public static Scanner sc=new Scanner(in);
    //public static Random sc=new Random();



    final int mod=1000000007;
    void run() throws RuntimeException{
        double a=sc.nextInt(),b=sc.nextInt(),c=sc.nextInt(),d=sc.nextInt();

        ln((a*d)/(b*c+a*d-a*c));
    }

    public static void main(String[] args) {
        new B311().run();
    }


    //output lib
    static final String br=System.getProperty("line.separator");
    static final String[] asep=new String[]{""," ",br,br+br};
    static String str(boolean o){
        return o?"YES":"NO";
    }
    static <K,V> String str(Map<K, V> map){
        StringBuilder sb=new StringBuilder();
        boolean isFirst=true;
        for(Entry<K,V> set:map.entrySet()){
            if(!isFirst)sb.append(br);
            sb.append(str(set.getKey())).append(":").append(str(set.getValue()));
            isFirst=false;
        }
        return sb.toString();
    }
    static <E> String str(Collection<E> list){
        StringBuilder sb=new StringBuilder();
        boolean isFirst=true;
        for(E e:list){
            if(!isFirst)sb.append(" ");
            sb.append(str(e));
            isFirst=false;
        }
        return sb.toString();
    }
    static String str(Object o){
        int depth=_getArrayDepth(o);
        if(depth>0)return _strArray(o,depth);
        return o.toString();
    }
    static int _getArrayDepth(Object o){
        if(!o.getClass().isArray() || Array.getLength(o)==0) return 0;
        return  1+_getArrayDepth(Array.get(o,0));
    }
    //depth ex A[10]…1 A[10][10]…2 exception A[0]…0 A[10][0]…1 A[0][0]…0
    static String _strArray(Object o,int depth){
        if(depth==0) return str(o);
        StringBuilder sb=new StringBuilder();
        for(int i=0,len=Array.getLength(o);i<len;i++){
            if(i!=0)sb.append(asep[depth]);
            sb.append(_strArray(Array.get(o,i),depth-1));
        }
        return sb.toString();
    }
    static void pr(Object... os){
        boolean isFirst=true;
        for(Object o:os){
            if(!isFirst)out.print(" ");
            out.print(o);
            isFirst=false;
        }
    }
    static void ln(){
        out.println();
    }
    static void ln(Object... os){
        for(Object o:os){
            pr(o);ln();
        }
    }
}