Problem: There are N holes in a two-dimensional plane. The coordinates of the i-th hole are (x_i,y_i).

Let R=10^{10^{10^{10}}}. Ringo performs the following operation:

* Randomly choose a point from the interior of a circle of radius R centered at the origin, and put Snuke there. Snuke will move to the hole with the smallest Euclidean distance from the point, and fall into that hole. If there are multiple such holes, the hole with the smallest index will be chosen.



For every i (1 \leq i \leq N), find the probability that Snuke falls into the i-th hole.

Here, the operation of randomly choosing a point from the interior of a circle of radius R is defined as follows:

* Pick two real numbers x and y independently according to uniform distribution on [-R,R].
* If x^2+y^2\leq R^2, the point (x,y) is chosen. Otherwise, repeat picking the real numbers x,y until the condition is met.

Constraints

* 2 \leq N \leq 100
* |x_i|,|y_i| \leq 10^6(1\leq i\leq N)
* All given points are pairwise distinct.
* All input values are integers.

Input

Input is given from Standard Input in the following format:


N
x_1 y_1
:
x_N y_N


Output

Print N real numbers. The i-th real number must represent the probability that Snuke falls into the i-th hole.

The output will be judged correct when, for all output values, the absolute or relative error is at most 10^{-5}.

Examples

Input

2
0 0
1 1


Output

0.5
0.5


Input

5
0 0
2 8
4 5
2 6
3 10


Output

0.43160120892732328768
0.03480224363653196956
0.13880483535586193855
0.00000000000000000000
0.39479171208028279727

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;

public class Main {
	
	static class Point implements Comparable<Point> {
		static final Point ZERO = new Point(0, 0, -1);
		int x, y;
		int id;

		public Point(int x, int y, int id) {
			this.x = x;
			this.y = y;
			this.id = id;
		}
		
		Point to(Point p) {
			return new Point(p.x - x, p.y - y, -1);
		}

		@Override
		public int compareTo(Point o) {
			if (y != o.y)
				return y < o.y ? -1 : 1;
			if (x != o.x)
				return x < o.x ? -1 : 1;
			return 0;
		}

		long cross(Point p) {
			return (long) x * p.y - (long) y * p.x;
		}
		
		long dot(Point p) {
			return (long)x * p.x + (long)y * p.y;
		}

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

		public boolean equals(Point p) {
			return x == p.x && y == p.y;
		}
	}

	static int getTurn(Point A, Point B, Point C) {
		// angle between AB and AC
		long p1 = (long) (B.x - A.x) * (C.y - A.y);
		long p2 = (long) (B.y - A.y) * (C.x - A.x);
		if (p1 == p2)
			return 0;
		else
			return p1 < p2 ? -1 : 1;
	}

	/**
	 * PERMUTES POINTS IN ARRAY, consider using convexHull(a.clone()) Points
	 * themselves are modified inside method too, but changes are reverted at the end
	 * 
	 * @param a
	 *            - array of points
	 * @return convexHull of these point in CCW order, no duplicates, no three
	 *         points on one side
	 */
	static Point[] convexHull(Point[] a) {

		if (a == null)
			return null;
		if (a.length == 0)
			return new Point[] {};

		int st = 0;
		for (int i = 1; i < a.length; i++)
			if (a[i].compareTo(a[st]) < 0)
				st = i;

		Point tmp = a[0];
		a[0] = a[st];
		a[st] = tmp;

		int sx = a[0].x;
		int sy = a[0].y;

		for (int i = 0; i < a.length; i++) {
			a[i].x -= sx;
			a[i].y -= sy;
		}

		Arrays.sort(a, 1, a.length, new Comparator<Point>() {

			@Override
			public int compare(Point o1, Point o2) {
				if (o1.equals(o2))
					return 0;
				if (o1.equals(Point.ZERO)) {
					return -1;
				}
				if (o2.equals(Point.ZERO)) {
					return 1;
				}
				long val = o1.cross(o2);
				if (val != 0)
					return val > 0 ? -1 : 1;
				if (o1.y == 0) {
					return o1.x < o2.x ? -1 : 1;
				} else {
					return o1.y < o2.y ? -1 : 1;
				}
			}
		});

		Point[] h = new Point[a.length];
		int sz = 0;
		h[sz++] = a[0];
		for (int i = 1; i < a.length; i++) {
			if (a[i].equals(h[sz - 1]))
				continue;
			while (sz > 1 && getTurn(h[sz - 2], h[sz - 1], a[i]) <= 0)
				sz--;
			h[sz++] = a[i];
		}

		for (int i = 0; i < a.length; i++) {
			a[i].x += sx;
			a[i].y += sy;
		}

		return Arrays.copyOf(h, sz);
	}

	void submit() {
		int n = nextInt();
		Point[] a = new Point[n];
		for (int i = 0; i < n; i++) {
			a[i] = new Point(nextInt(), nextInt(), i);
		}
		
		Point[] h = convexHull(a);
		double[] ans = new double[n];
		if (h.length == 1) {
			ans[h[0].id] = 1;
		} else if (h.length == 2) {
			ans[h[0].id] = ans[h[1].id] = 0.5; 
		} else {
			int m = h.length;
			for (int i = 0; i < m; i++) {
				int prv = (i + m - 1) % m;
				int nxt = (i + 1) % m;
				Point v1 = h[prv].to(h[i]);
				Point v2 = h[i].to(h[nxt]);
				ans[h[i].id] = getAngle(v1, v2) / (2 * Math.PI);
			}
		}
		
		for (double x : ans) {
			out.println(x);
		}
	}
	
	double getAngle(Point p, Point q) {
		return Math.atan2(p.cross(q), p.dot(q));
	}

	void preCalc() {

	}

	void stress() {

	}

	void test() {

	}

	Main() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		preCalc();
		submit();
		//stress();
		//test();
		out.close();
	}

	static final Random rng = new Random();

	static int rand(int l, int r) {
		return l + rng.nextInt(r - l + 1);
	}

	public static void main(String[] args) throws IOException {
		new Main();
	}

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	int nextInt() {
		return Integer.parseInt(nextToken());
	}

	long nextLong() {
		return Long.parseLong(nextToken());
	}

	double nextDouble() {
		return Double.parseDouble(nextToken());
	}
}