Problem: You are given a convex polygon P with n distinct vertices p1, p2, ..., pn. Vertex pi has coordinates (xi, yi) in the 2D plane. These vertices are listed in clockwise order.

You can choose a real number D and move each vertex of the polygon a distance of at most D from their original positions.

Find the maximum value of D such that no matter how you move the vertices, the polygon does not intersect itself and stays convex.

Input

The first line has one integer n (4 ≤ n ≤ 1 000) — the number of vertices.

The next n lines contain the coordinates of the vertices. Line i contains two integers xi and yi ( - 109 ≤ xi, yi ≤ 109) — the coordinates of the i-th vertex. These points are guaranteed to be given in clockwise order, and will form a strictly convex polygon (in particular, no three consecutive points lie on the same straight line).

Output

Print one real number D, which is the maximum real number such that no matter how you move the vertices, the polygon stays convex.

Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Namely, let's assume that your answer is a and the answer of the jury is b. The checker program will consider your answer correct if <image>.

Examples

Input

4
0 0
0 1
1 1
1 0


Output

0.3535533906


Input

6
5 0
10 0
12 -4
10 -8
5 -8
3 -4


Output

1.0000000000

Note

Here is a picture of the first sample

<image>

Here is an example of making the polygon non-convex.

<image>

This is not an optimal solution, since the maximum distance we moved one point is  ≈ 0.4242640687, whereas we can make it non-convex by only moving each point a distance of at most  ≈ 0.3535533906.

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.io.BufferedInputStream;
import java.util.concurrent.Callable;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.io.InputStream;

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

	static class TaskB {
		public void solve(int testNumber, BufferedInputStream _in, PrintWriter out) {

			InputReader in = new InputReader(_in);
			long startTime = System.currentTimeMillis();
			int nt = 1;
			Task t = new Task(1);
			t.readInput(in);
			t.call();
			t.writeOutput(out);
			in.close();
			System.err.println("Time: " + (System.currentTimeMillis() - startTime) + " miliseconds");
		}

	}

	static class Line {
		Point a;
		Point ab;

		Line(Point a, Point b, boolean twoPoints) {
			this.a = new Point(a);
			if (twoPoints) {
				this.ab = Point._opSub(b, a);
			} else {
				this.ab = new Point(b);
			}
		}

		Line(long xa, long ya, long xb, long yb) {
			this.a = new Point(xa, ya);

			this.ab = new Point((xb - xa), (yb - ya));
		}

		Point b() {
			return Point._opPlus(a, ab);
		}


		public String toString() {
			return "Line{" +
					"(" + a +
					") (" + b() +
					")}";
		}

		public double distLine(Point point) {
			//if (!line) return dist(point, line.a);
			//return abs((point - line.a) ^ line.ab) / norm(line.ab);

			if (this.ab.isZeroPoint()) return a.dist(point);
			Point temp = Point._opSub(point, this.a);
			long temp2 = Point._opPow(temp, ab);

			return Math.abs(temp2) / this.ab.norm();
		}

	}

	static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public static boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public void close() {

		}

	}

	static class Point implements Comparable<Point> {
		public long x;
		public long y;

		public Point(Point o) {
			this.x = o.x;
			this.y = o.y;

		}

		public Point(long x, long y) {
			super();

			this.x = x;
			this.y = y;
		}

		public boolean isZeroPoint() {
			return x == 0 && y == 0;
		}


		public int compareTo(Point o2) {
			int t = Long.compare(y, o2.y);
			if (t != 0) return t;
			return Long.compare(x, o2.x);
		}

		public double dist(Point p) {
			return Math.sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));
			//return _Rational._opSub(this, p).norm();
		}

		public long abs() {
			return (x * x) + (y * y);
		}

		public double norm() {
			return Math.sqrt(abs());
		}

		public static long _opPow(Point lhs, Point rhs) {
			//return LongMath.checkedSubtract(LongMath.checkedMultiply(lhs.x , rhs.y) , LongMath.checkedMultiply(lhs.y , rhs.x));
			return ((lhs.x * rhs.y) - (lhs.y * rhs.x));
		}

		public static Point _opSub(Point lhs, Point rhs) {
			return new Point((lhs.x - rhs.x), (lhs.y - rhs.y));
		}

		public static Point _opPlus(Point lhs, Point rhs) {
			return new Point((lhs.x + rhs.x), (lhs.y + rhs.y));
		}


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


		public int hashCode() {
			return Long.hashCode(x) ^ Long.hashCode(y);
		}

		public boolean equals(Object obj) {
			if (obj instanceof Point) {
				return compareTo((Point) obj) == 0;
			}
			return false;
		}

	}

	static class Polygon {
		public ArrayList<Point> lp = new ArrayList<>();

		int next(int i) {
			return i == lp.size() - 1 ? 0 : i + 1;
		}

		int prev(int i) {
			return i == 0 ? lp.size() - 1 : i - 1;
		}


		public String toString() {
			return "[" + lp + "]";
		}

		public Point get(int v) {
			return lp.get(v);
		}

	}

	static class Task implements Callable<Task> {
		Polygon poly = new Polygon();
		int n;
		double re = Double.MAX_VALUE;
		int testNumber;

		public void readInput(InputReader in) {
	/* read input here */
			n = in.nextInt();
			for (int i = 0; i < n; ++i) {
				poly.lp.add(new Point(in.nextInt(), in.nextInt()));
			}
		}

		public Task call() {
	/* process main algorithm here */

			for (int i = 0; i < n; ++i) {
				Line l = new Line(poly.get(poly.next(i)), poly.get(poly.prev(i)), true);
				re = Math.min(re, l.distLine(poly.get(i)) / 2.0);
			}

			System.err.println("Test case: " + testNumber + " done!");
			return this;
		}

		public void writeOutput(PrintWriter out) {
			out.println(String.format("%.30f", re));
		}

		Task(int testNumber) {
			this.testNumber = testNumber;
		}

	}
}