Problem: The determinant of a matrix 2 × 2 is defined as follows:

<image>

A matrix is called degenerate if its determinant is equal to zero. 

The norm ||A|| of a matrix A is defined as a maximum of absolute values of its elements.

You are given a matrix <image>. Consider any degenerate matrix B such that norm ||A - B|| is minimum possible. Determine ||A - B||.

Input

The first line contains two integers a and b (|a|, |b| ≤ 109), the elements of the first row of matrix A. 

The second line contains two integers c and d (|c|, |d| ≤ 109) the elements of the second row of matrix A.

Output

Output a single real number, the minimum possible value of ||A - B||. Your answer is considered to be correct if its absolute or relative error does not exceed 10 - 9.

Examples

Input

1 2
3 4


Output

0.2000000000


Input

1 0
0 1


Output

0.5000000000

Note

In the first sample matrix B is <image>

In the second sample matrix B is <image>

Solution (in JAVA):

Solution:
import java.util.ArrayList;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Artem Gilmudinov
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		Reader in = new Reader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskH solver = new TaskH();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskH {

    double[][] d = {{-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

    public void solve(int testNumber, Reader in, PrintWriter out) {
        Point p1 = new Point(in.nd(), in.nd());
        Point p2 = new Point(in.nd(), in.nd());
        double dist = GeomUtils.dist(p1, p2);
        double left, right, mid;
        left = 0; right = dist / 2;
        double eps = 1e-12;
        Point center = new Point(0, 0);
        boolean found;
        double x, y;
        while((right - left) / right >= eps) {
            mid = left + (right - left) / 2;
            found = false;
            ArrayList<Point> firstSquare = new ArrayList<>();
            ArrayList<Point> secondSquare = new ArrayList<>();
            for(int i = 0; i < 4; i++) {
                firstSquare.add(new Point(p1.x + d[i][0] * mid, p1.y + d[i][1] * mid));
                secondSquare.add(new Point(p2.x + d[i][0] * mid, p2.y + d[i][1] * mid));
            }
            for(int i = 0; i < 4; i++) {
                Line line = GeomUtils.points2Line(firstSquare.get(i), center);

                if(line == null) {
                    continue;
                }
                if(Math.abs(line.a) <= eps) {
                    y = -line.c / line.b;
                    if(y >= secondSquare.get(3).y - eps && y <= secondSquare.get(0).y + eps) {
                        found = true;
                    }
                } else if(Math.abs(line.b) <= eps) {
                    x = -line.c / line.a;
                    if(x >= secondSquare.get(0).x - eps && x <= secondSquare.get(1).x + eps) {
                        found = true;
                        }
                } else {
                    y = -(line.c + line.a *  secondSquare.get(0).x) / line.b;
                    if(y >= secondSquare.get(3).y - eps && y <= secondSquare.get(0).y + eps) {
                        found = true;
                       }
                    y = -(line.c + line.a * secondSquare.get(2).x) / line.b;
                    if(y >= secondSquare.get(3).y - eps && y <= secondSquare.get(0).y + eps) {
                        found = true;
                     }
                    x = -(line.c + line.b * secondSquare.get(0).y) / line.a;
                    if(x >= secondSquare.get(0).x - eps && x <= secondSquare.get(1).x + eps) {
                        found = true;
                   }
                    x = -(line.c + line.b * secondSquare.get(2).y) / line.a;
                    if(x >= secondSquare.get(0).x - eps && x <= secondSquare.get(1).x + eps) {
                        found = true;
                        }
                }
            }
            for(int i = 0; i < 4; i++) {
                Line line = GeomUtils.points2Line(secondSquare.get(i), center);
                if(line == null) {
                    continue;
                }
                if(Math.abs(line.a) <= eps) {
                    y = -line.c / line.b;
                    if(y >= firstSquare.get(3).y - eps && y <= firstSquare.get(0).y + eps) {
                        found = true;
                      }
                } else if(Math.abs(line.b) <= eps) {
                    x = -line.c / line.a;
                    if(x >= firstSquare.get(0).x - eps && x <= firstSquare.get(1).x + eps) {
                        found = true;
                    }
                } else {
                    y = -(line.c + line.a *  firstSquare.get(0).x) / line.b;
                    if(y >= firstSquare.get(3).y - eps && y <= firstSquare.get(0).y + eps) {
                        found = true;
                  }
                    y = -(line.c + line.a * firstSquare.get(2).x) / line.b;
                    if(y >= firstSquare.get(3).y - eps && y <= firstSquare.get(0).y + eps) {
                        found = true;
                }
                    x = -(line.c + line.b * firstSquare.get(0).y) / line.a;
                    if(x >= firstSquare.get(0).x - eps && x <= firstSquare.get(1).x + eps) {
                        found = true;
              }
                    x = -(line.c + line.b * firstSquare.get(2).y) / line.a;
                    if(x >= firstSquare.get(0).x - eps && x <= firstSquare.get(1).x + eps) {
                        found = true;
                        }
                }
            }
            if(found) {
                right = mid;
            } else {
                left = mid;
            }
            }
        out.println(left);
    }
}

class Reader {
    private BufferedReader in;
    private StringTokenizer st = new StringTokenizer("");
    private String delim = " ";

    public Reader(InputStream in) {
        this.in = new BufferedReader(new InputStreamReader(in));
    }

    public String next() {
        if (!st.hasMoreTokens()) {
            st = new StringTokenizer(rl());
        }
        return st.nextToken(delim);
    }

    public String rl() {
        try {
            return in.readLine();
        } catch(IOException e) {
            throw new RuntimeException(e);
        }
    }

    public double nd() {
        return Double.parseDouble(next());
    }

}

class Point {
    public double x, y;
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public String toString() {
        return x + " " + y;
    }

    public boolean equals(Object obj) {
        Point p = (Point)obj;
        return Math.abs(this.x - p.x) <= GeomUtils.eps && Math.abs(this.y - p.y) <= GeomUtils.eps;
    }
}

class GeomUtils {

    public static final double eps = 1e-15;

    public static double dist(Point p1, Point p2) {
        return Math.sqrt(dist2(p1, p2));
    }

    public static double dist2(Point p1, Point p2) {
        return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
    }

    public static Line points2Line(Point p1, Point p2) {
        if(p1.equals(p2)) {
            return null;
        }
        if(Math.abs(p1.x - p2.x) <= eps) {
            return new Line(1, 0, -p1.x);
        }
        if(Math.abs(p1.y - p2.y) <= eps) {
            return new Line(0, 1, -p1.y);
        }
        return new Line(p1.y - p2.y, p2.x - p1.x, p1.x * p2.y - p1.y * p2.x);

    }

}

class Line {

    public double a, b, c;
    public Line(double a, double b, double c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public String toString() {
        return this.a + " " + this.b + " " + this.c;
    }


}