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.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) {
        new Main().solve();
    }

    private void solve() {
        InputReader sc = new InputReader();
        int n = sc.nextInt();

        Point[] ps = new Point[n];
        for (int i = 0; i < n; i++) {
            ps[i] = new Point(sc.nextInt(), sc.nextInt());
        }

        if (n == 2) {
            System.out.println(0.5);
            System.out.println(0.5);
            return;
        }


        double[] ans = new double[n];
        mainLoop: for (int i = 0; i < n; i++) {
            Point startVec = null;
            Point endVec = null;
            Point p = ps[i];
            // System.out.printf("p: %s\n", p);
            for (int j = 0; j < n; j++) {
                if (i == j) continue;
                Point q = ps[j];
                Point qp = q.subtract(p);
                Point splitLine = qp.multiply(new Point(0, -1));  // rot 90. 左側はpに属する

                if (startVec == null) {
                    startVec = splitLine;
                    endVec = splitLine.multiply(-1);
                    // System.out.printf("qp: %s, sl: %s\n", qp, splitLine);
                }
                else {
                    double crossStart = splitLine.cross(startVec);
                    double crossEnd = splitLine.cross(endVec);
                    boolean isPerfectOpposite = Math.abs(crossStart) < EPS && startVec.dot(splitLine) < EPS
                            || Math.abs(crossEnd) < EPS && endVec.dot(splitLine) > -EPS;
                    boolean needsStartChange = crossStart < -EPS;
                    boolean needsEndChange = crossEnd < -EPS;
                    // System.out.printf("qp: %s, sl: %s, ns: %b, ne: %b\n", qp, splitLine, needsStartChange, needsEndChange);
                    if (isPerfectOpposite || needsStartChange && needsEndChange) {
                        // impossible
                        ans[i] = 0;
                        continue mainLoop;
                    }
                    else if (needsStartChange) {
                        startVec = splitLine;
                    }
                    else if (needsEndChange) {
                        endVec = splitLine.multiply(-1);
                    }
                }
            }

            double cos = startVec.dot(endVec) / startVec.distance() / endVec.distance();
            double angle = Math.acos(Math.max(-1, Math.min(cos, 1)));
            // System.out.printf("!! sv: %s, evInv: %s, ang: %f\n", startVec, endVec, Math.toDegrees(angle));
            ans[i] = angle / (2 * Math.PI);
        }


        for (int i = 0; i < n; i++) {
            System.out.printf("%.12f\n", ans[i]);

        }



    }


    static final double EPS = 1e-9;

    static boolean approxEquals(double a, double b) {
        return Math.abs(a - b) < EPS;
    }

    static class Point extends Point2D.Double implements Comparable<Point> {

        public Point() {
        }

        public Point(double x, double y) {
            super(x, y);
            // xとyはfinalではないが、このライブラリ関数の一部は変更されないことを前提としているので注意。
        }

        /** 内積　dot(v1,v2)=|v1||v2|cosθ */
        double dot(Point p) {
            return x * p.x + y * p.y;
        }

        /** 外積　cross(v1,v2)=|v1||v2|sinθ */
        double cross(Point p) {
            return x * p.y - y * p.x;
        }

        double distanceSqr() {
            return x * x + y * y;
        }

        double distance() {
            return Math.hypot(x, y);
        }

        Point add(Point p) {
            return new Point(x + p.x, y + p.y);
        }

        Point multiply(double k) {
            return new Point(k * x, k * y);
        }

        Point multiply(Point p) {  // complex mul: (x+yi)*(p.x+p.yi)
            return new Point(x * p.x - y * p.y, x * p.y + p.x * y);
        }

        Point subtract(Point p) {
            return new Point(x - p.x, y - p.y);
        }

        @Override
        public boolean equals(Object obj) {  // この関数はEclipseで生成して座標の比較だけ書き換えればいい
            if (this == obj) return true;
            if (obj == null) return false;
            if (getClass() != obj.getClass()) return false;
            Point other = (Point) obj;
            if (!approxEquals(x, other.x)) return false;
            if (!approxEquals(y, other.y)) return false;
            return true;
        }

        @Override
        public int compareTo(Point o) {
            if (!approxEquals(x, o.x)) return (int) Math.signum(x - o.x);
            if (!approxEquals(y, o.y)) return (int) Math.signum(y - o.y);
            return 0;
        }

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

    }

    /**
     * @return ベクトル a->b から見てベクトル b->c が左向きなら1、右向きなら-1。
     *         後はコード参照。
     * @see http://www.prefield.com/algorithm/geometry/ccw.html
     */
    static int ccw(Point a, Point b, Point c) {
        b = b.subtract(a);
        c = c.subtract(a);
        if (b.cross(c) > EPS) return +1;                  // counter clockwise
        if (b.cross(c) + EPS < 0) return -1;              // clockwise
        if (b.dot(c) + EPS < 0) return +2;                // c--a--b on line and a!=c
        if (b.distanceSqr() < c.distanceSqr()) return -2; // a--b--c on line or a==b　※基本的にa==bとなるべきでない　
        return 0;                                         // a--c--b on line or b==c
    }

    static class InputReader extends BufferedReader {
        StringTokenizer st = new StringTokenizer("");

        public InputReader() {
            super(new InputStreamReader(System.in));
        }

        public InputReader(String s) {
            super(new StringReader(s));
        }

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

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