Problem: In the year of 3000 travelling around parallel realities became a routine thing. However one has to take into consideration that travelling like that is highly dangerous as you never know beforehand where you're gonna get...

Little Vasya, for instance, found himself in a gaming reality and now he has to successfully complete all levels of a very weird game to get back. The gaming reality is a three-dimensional space where n points are given. The game has m levels and at the beginning of the i-th level the player is positioned at some plane Qi that passes through the origin. On each level Vasya has to use special robots to construct and activate n powerful energy spheres of the equal radius with centers at the given points. The player chooses the radius of the spheres himself. The player has to spend R units of money to construct spheres whose radius equals R (consequently, one can construct spheres whose radius equals zero for free). Besides, once for each level a player can choose any point in space and release a laser ray from there, perpendicular to plane Qi (this action costs nothing). The ray can either be directed towards the plane or from the plane. The spheres that share at least one point with the ray will be immediately activated. The level is considered completed if the player has managed to activate all spheres. Note that the centers of the spheres are the same for all m levels but the spheres do not remain: the player should construct them anew on each new level.

Help Vasya find out what minimum sum of money will be enough to complete each level.

Input

The first line contains two integers n and m (1 ≤ n ≤ 900, 1 ≤ m ≤ 100) — the number of energetic spheres and the number of levels in the game correspondingly. 

Each of the following n lines contains three integers xi, yi, zi (0 ≤ xi, yi, zi ≤ 104) — the coordinates of the center of the i-th sphere. Assume that these points do not change their positions throughout the game.

Then follow m lines, each containing three integers ai, bi, ci (0 ≤ ai, bi, ci ≤ 100, ai2 + bi2 + ci2 > 0). These numbers are the coefficients in the equation of plane Qi (aix + biy + ciz = 0), where the player is positioned at the beginning of the i-th level.

Output

Print m numbers, one per line: the i-th line should contain the minimum sum of money needed to complete the i-th level. The absolute or relative error should not exceed 10 - 6.

Examples

Input

4 1
0 0 0
0 1 0
1 0 0
1 1 0
0 0 1


Output

0.7071067812


Input

5 3
0 1 0
1 0 1
1 2 1
2 0 1
1 3 0
1 1 1
1 2 3
3 0 3


Output

1.6329931619
1.6366341768
1.5411035007


Input

2 1
0 20 0
0 0 0
0 10 0


Output

0.0000000000

Solution (in JAVA):

Solution:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.StringTokenizer;

public class e {

    static long MOD = 1_000_000_007;
    static double EPS = 1e-6;

    public static void main(String[] args) {
        FS in = new FS(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int n = in.nextInt();
        int m = in.nextInt();
        Vec3[] v = new Vec3[n];
        for (int i = 0; i < n; i++) {
            v[i] = new Vec3(in.nextInt(), in.nextInt(), in.nextInt());
        }
        for (int i = 0; i < m; i++) {
            Vec3 c = new Vec3(in.nextInt(), in.nextInt(), in.nextInt()).unit();
            Vec3[] proj = new Vec3[n];
            double max = 0;
            int ind = -1;
            for (int j = 0; j < n; j++) {
                proj[j] = v[j].sub(c.scale(c.dot(v[j])));
                if (proj[j].mag2() > EPS) {
                    ind = j;
                }
            }
            if (ind == -1) {
                out.println(0.0);
                continue;
            }
            
            Vec3 dx = proj[ind].unit();
            Vec3 dy = dx.cross(c).unit();
            
            Vec[] vecs = new Vec[n];
            for(int j = 0; j < n; j++) {
                vecs[j] = new Vec(dx.dot(proj[j]), dy.dot(proj[j]));
            }
            ArrayList<Vec> uniq = new ArrayList<>();
            outer: for(int j = 0; j < n; j++) {
                for(int k = 0; k < j; k++) if(vecs[j].equals(vecs[k])) continue outer;
                uniq.add(vecs[j]);
            }
            out.println(MinEnclosingCircle.minEnclosingCircle(uniq.toArray(new Vec[uniq.size()])).r);
        }

        out.close();
    }

    static class MinEnclosingCircle {

        //circle defined by a, b, and c, assumes all points are unique
        //if a is null, returns a circle at (1<<31, 0) r=0
        //if b is null, it returns a circle centered at a, r=0
        //if c is null, it returns the circle defined by a and b
        //
        //O(n)
        public static Circle enclosing(Vec a, Vec b, Vec c) {
            if (a == null) {
                return new Circle(new Vec(Integer.MAX_VALUE, 0), 0);
            }
            if (b == null) {
                return new Circle(a, 0);
            }
            if (c == null) {
                return new Circle(a.add(b).scale(.5), a.sub(b).mag() / 2);
            }
            Vec abDir = b.sub(a), bcDir = c.sub(b);
            Vec abMid = a.add(b).scale(.5), bcMid = b.add(c).scale(.5);
            Seg abSeg = new Seg(abMid, abMid.add(abDir.rot90())), bcSeg = new Seg(bcMid, bcMid.add(bcDir.rot90()));
            Vec center = abSeg.lineIntersect(bcSeg);
            return new Circle(center, center.sub(a).mag());
        }

        private static Circle minEnclosingCircle(Vec[] toProcess, int toProcessIndex, Vec b1, Vec b2, Vec b3) {
            if (toProcessIndex == toProcess.length || b3 != null) {
                return enclosing(b1, b2, b3);
            }
            Vec p = toProcess[toProcessIndex];
            Circle smaller = minEnclosingCircle(toProcess, toProcessIndex + 1, b1, b2, b3);
            if (smaller.contains(p)) {
                return smaller;
            }
            return minEnclosingCircle(toProcess, toProcessIndex + 1, p, b1, b2);
        }

        //returns the minimum enclosing circle
        public static Circle minEnclosingCircle(Vec[] toProcess) {
            ArrayList<Vec> temp = new ArrayList<>(Arrays.asList(toProcess));
            Collections.shuffle(temp);
            Vec[] a = temp.toArray(new Vec[0]);
            return minEnclosingCircle(a, 0, null, null, null);
        }

    }

    static class Vec {

        static final double EPS = 1e-6;
        double x, y;

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

        public Vec add(Vec o) {
            return new Vec(x + o.x, y + o.y);
        }

        public Vec sub(Vec o) {
            return new Vec(x - o.x, y - o.y);
        }

        public Vec scale(double s) {
            return new Vec(x * s, y * s);
        }

        public double dot(Vec o) {
            return x * o.x + y * o.y;
        }

        public double cross(Vec o) {
            return x * o.y - y * o.x;
        }

        public double mag2() {
            return dot(this);
        }

        public double mag() {
            return Math.sqrt(mag2());
        }

        public Vec unit() {
            return scale(1 / mag());
        }

        public Vec rot90() {
            return new Vec(-y, x);
        }

        public Vec rot270() {
            return new Vec(y, -x);
        }

        public Vec rotate(double theta) {
            double PI = Math.PI;
            double newX = x * Math.cos(theta) + y * Math.cos(PI / 2 + theta);
            double newY = x * Math.sin(theta) + y * Math.sin(PI / 2 + theta);
            return new Vec(newX, newY);
        }

        //angle between 0 and 2PI
        public double angle() {
            return (Math.atan2(y, x) + 2 * Math.PI) % (2 * Math.PI);
        }

        public String toString() {
            DecimalFormat df = new DecimalFormat("#.##");
            return "(" + df.format(x) + ", " + df.format(y) + ")";
        }

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

        static boolean leq(double a, double b) {
            return a - EPS < b;
        }

        static boolean geq(double a, double b) {
            return a + EPS > b;
        }

        public boolean equals(Object oo) {
            Vec o = (Vec) oo;
            return eq(x, o.x) && eq(y, o.y);
        }
    }

    static class Seg {

        Vec from, to, dir;

        public Seg(Vec from, Vec to) {
            this.from = from;
            this.to = to;
            dir = to.sub(from);
        }

        //line-line intersection
        public Vec lineIntersect(Seg o) {
            double det = o.dir.x * dir.y - dir.x * o.dir.y;
            if (Vec.eq(det, 0)) {
                return null;
            }
            double dist = (o.dir.x * (o.from.y - from.y)
                - o.dir.y * (o.from.x - from.x)) / det;
            return from.add(dir.scale(dist));
        }

        public boolean containsPoint(Vec o) {
            double distFromLine = dir.unit().cross(o.sub(from));
            if (!Vec.eq(distFromLine, 0)) {
                return false;
            }
            return Vec.eq(dir.mag(), from.sub(o).mag() + to.sub(o).mag());
        }

        //seg-seg intersection
        public Vec segIntersection(Seg o) {
            Vec intersect = lineIntersect(o);
            return containsPoint(intersect) && o.containsPoint(intersect) ? intersect : null;
        }

        //returns 1 if above, 0 if on, -1 if below
        public int side(Vec o) {
            Vec oDir = o.sub(from);
            double distFromLine = dir.unit().cross(oDir);
            if (Vec.eq(distFromLine, 0)) {
                return 0;
            }
            return (int) Math.signum(distFromLine);
        }

        public boolean intersects(Seg o) {
            return side(o.from) != side(o.to) && o.side(from) != o.side(to);
        }

        public Vec getClosestTo(Vec o) {
            double percentThere = o.sub(from).dot(dir) / dir.mag2();
            return from.add(dir.scale(Math.max(0, Math.min(1, percentThere))));
        }

        public Vec projectToLine(Vec o) {
            return dir.scale(o.sub(from).dot(dir) / dir.mag2()).add(from);
        }

        //toContain must be a point with positive x and y coordinates.
        //this method returns the shortest line segment from the x-axis to the point to the y axis
        public static Seg getShortestSegFromAxesContainingQ1Point(Vec toContain) {
            double slope = -Math.pow(toContain.y / toContain.x, 1.0 / 3);
            double b = toContain.y - toContain.x * slope;
            double xInt = -b / slope;
            return new Seg(new Vec(0, b), new Vec(xInt, 0));
        }

        public String toString() {
            return from + " -> " + to;
        }
    }

    static class Circle {

        Vec c;
        double r;

        public Circle(Vec c, double r) {
            this.c = c;
            this.r = r;
        }

        public boolean contains(Vec v) {
            return c.sub(v).mag2() - Vec.EPS * Vec.EPS <= r * r;
        }

        //when standing at this circle, returns right tangent, then left tangent
        public Vec[] intersect(Circle o) {
            if (c.equals(o.c)) {
                return null;
            }
            Vec dir = o.c.sub(c);
            double d2 = dir.mag2(), d = Math.sqrt(d2);
            if (r + o.r < d || r + d < o.r || o.r + d < r) {
                return null;
            }
            if (Vec.eq(r + o.r, d) || Vec.eq(o.r + d, r)) {
                return new Vec[]{c.add(dir.scale(r / d))};
            }
            if (Vec.eq(r + d, o.r)) {
                return new Vec[]{c.sub(dir.scale(r / d))};//.sub()!!
            }
            double d1 = (r * r + d2 - o.r * o.r) / (2 * d);
            double h = Math.sqrt(r * r - d1 * d1);
            Vec unitDir = dir.unit();
            Vec rInt = c.add(unitDir.scale(d1).add(unitDir.rot270().scale(h)));
            Vec lInt = c.add(unitDir.scale(d1).add(unitDir.rot90().scale(h)));
            return new Vec[]{rInt, lInt};
        }

        public double intersectionArea(Circle o) {
            double d = o.c.sub(c).mag();
            if (r + o.r < d) {
                return 0;
            }
            double minR = Math.min(r, o.r), maxR = Math.max(r, o.r), pi = Math.PI;
            if (Vec.leq(d + minR, maxR)) {
                return pi * minR * minR;
            }

            double theta1 = 2 * Math.acos((r * r + d * d - o.r * o.r) / (2 * r * d));
            double theta2 = 2 * Math.acos((o.r * o.r + d * d - r * r) / (2 * o.r * d));
            double part1Area = theta1 / 2 * r * r;
            double part2Area = theta2 / 2 * o.r * o.r;

            double tri1 = r * r * Math.sin(theta1) / 2;
            double tri2 = o.r * o.r * Math.sin(theta2) / 2;
            return part1Area + part2Area - tri1 - tri2;
        }

        //returns right tangent, then left tangent from perspective of the point
        public Vec[] getTangentPoints(Vec p) {
            if (contains(p)) {
                return null;
            }
            double d2 = c.sub(p).mag2();
            return new Circle(p, Math.sqrt(d2 - r * r)).intersect(this);
        }

        //line going from my left to his right, then my right to his left
        //lines go from me to him
        public Seg[] internalTangentLines(Circle o) {
            Vec[] tangentPoints = new Circle(c, r + o.r).getTangentPoints(o.c);
            Vec offset1 = tangentPoints[0].sub(o.c).rot90().unit().scale(o.r);
            Vec offset2 = tangentPoints[1].sub(o.c).rot270().unit().scale(o.r);
            return new Seg[]{new Seg(tangentPoints[0].add(offset1), o.c.add(offset1)),
                new Seg(tangentPoints[1].add(offset2), o.c.add(offset2))};
        }

        //right external tangent, then left external tangent, from my perspective
        //lines go from me to him
        public Seg[] externalTangentLines(Circle o) {
            if (o.r > r) {
                Seg[] oAnswer = o.externalTangentLines(this);
                return new Seg[]{new Seg(oAnswer[1].to, oAnswer[1].from), new Seg(oAnswer[0].to, oAnswer[0].from)};
            }
            Vec[] tangentPoints = new Circle(c, r - o.r).getTangentPoints(o.c);
            Vec offset1 = tangentPoints[0].sub(o.c).rot270().unit().scale(o.r);
            Vec offset2 = tangentPoints[1].sub(o.c).rot90().unit().scale(o.r);
            return new Seg[]{new Seg(tangentPoints[1].add(offset2), o.c.add(offset2)),
                new Seg(tangentPoints[0].add(offset1), o.c.add(offset1))};
        }

        //line (not line segment)-circle intersection in the order of line.dir
        public Vec[] intersectLine(Seg line) {
            Vec closest = line.projectToLine(c);
            double d2 = closest.sub(c).mag2();
            if (d2 > r * r) {
                return null;
            }
            double l = Math.sqrt(r * r - d2);
            if (Vec.eq(l, 0)) {
                return new Vec[]{closest};
            }
            Vec lVec = line.dir.unit().scale(l);
            return new Vec[]{closest.sub(lVec), closest.add(lVec)};
        }

        //line segment-circle intersection
        public Vec[] intersectSeg(Seg seg) {
            Vec[] lineIntersections = intersectLine(seg);
            if (lineIntersections == null) {
                return null;
            }
            ArrayList<Vec> contained = new ArrayList<>();
            for (Vec v : lineIntersections) {
                if (seg.containsPoint(v)) {
                    contained.add(v);
                }
            }
            if (contained.isEmpty()) {
                return null;
            }
            return contained.toArray(new Vec[contained.size()]);
        }

        public String toString() {
            DecimalFormat df = new DecimalFormat();
            return "center: " + c + ", r: " + df.format(r);
        }
    }

    static class Vec3 {

        double x, y, z;

        public Vec3(double X, double Y, double Z) {
            x = X;
            y = Y;
            z = Z;
        }

        public double dot(Vec3 o) {
            return x * o.x + y * o.y + z * o.z;
        }

        public Vec3 cross(Vec3 o) {
            return new Vec3(y * o.z - z * o.y, z * o.x - x * o.z, x * o.y - y * o.x);
        }

        public double mag2() {
            return dot(this);
        }

        public double mag() {
            return Math.sqrt(dot(this));
        }

        public Vec3 scale(double d) {
            return new Vec3(x * d, y * d, z * d);
        }

        public Vec3 unit() {
            return scale(1 / mag());
        }

        public Vec3 sub(Vec3 o) {
            return new Vec3(x - o.x, y - o.y, z - o.z);
        }
    }

    static class FS {

        BufferedReader in;
        StringTokenizer token;

        public FS(InputStream str) {
            in = new BufferedReader(new InputStreamReader(str));
        }

        public String next() {
            if (token == null || !token.hasMoreElements()) {
                try {
                    token = new StringTokenizer(in.readLine());
                } catch (IOException ex) {
                }
                return next();
            }
            return token.nextToken();
        }

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

        public long nextLong() {
            return Long.parseLong(next());
        }
    }
}