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.

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.

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.

import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class E {

	private static final double EPS = 1e-8;

       	private E (Scanner sc) throws Throwable {
//		double [][] X = { { 0,1,-1} };
//		double [] K =  { -1,1,0 };
//		print(Arrays.deepToString(rodrigues(X,normalize(K))));

		int N = sc.nextInt();
		int M = sc.nextInt();

		double [][] X = new double [N][];
		for (int i = 0; i < N; ++i)
			X[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };

		double [][] A = new double [M][];
		for (int i = 0; i < M; ++i)
			A[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };
		for (int i = 0; i < M; ++i)
			solve(X, A[i]);
	}

	private void solve (double [][] X, double [] A) throws Throwable {
		try {
		// Project X on plane
		double [][] Y = new double [X.length][];
		for (int i = 0; i < X.length; ++i)
			Y[i] = project(X[i], A);

		// Rotate plane, so that z = 0
		double [] K = new double [] { -A[1], A[0], 0 };
		if (!isZero(K))
			Y = rodrigues(Y, normalize(K));

		// Welzl Algorithm
		Y = randomize(Y);
		double [][] S = new double [3][];
		double [] C = welzl(Y, Y.length, S, 0);

		print(C[C.length - 1]);
		} catch (Throwable e) {
			print(3.3);
		}
	}

	double [] project(double [] X, double [] A) {
		return diff(X, scalar(dot(X,A)/dot(A,A), A));
	}

	double [][] rodrigues(double [][] X, double [] K) {
		// Rotate to z=0, K is unit vector in X and z=0 planes
		try {
		double [] V = null;
		for (double [] x : X) {
			double [] v = project(x,K);
			if (!isZero(v))
				V = v;
		}

		if (V == null)
			return X;

		double [] T = new double [] {
				dot(new double [] { K[1], -K[0] }, V),
				V[2] };
		T = normalize(T);

		double [] w = scalar(T[0] ,V);
		w = sum(w, scalar(T[1] ,cross(K,V)));
		w = sum(w, scalar(dot(K,V)*(1-T[0]), K));

		for (int i = 0; i < X.length; ++i) {
			double [] x = scalar(T[0] ,X[i]);
			x = sum(x, scalar(T[1] ,cross(K,X[i])));
			x = sum(x, scalar(dot(K,X[i])*(1-T[0]), K));
			X[i] = x;
		}
		return X;
		} catch (Throwable e) {
			print (4.4);
			return null;
		}
	}

	double [] welzl(double [][] X, int N, double [][] S, int B) {
		try {
		if (B == 3)
			return circle(S[0], S[1], S[2]);
		else if (N == 1 && B == 0)
			return new double [] { X[0][0], X[0][1], X[0][2], 0 };
		else if (N == 0 && B == 2)
			return circle (S[0], S[1]);
		else if (N == 1 && B == 1)
			return circle (S[0], X[0]);
		else {
			double [] C = welzl(X, N-1, S, B);
			if (dist (new double [] { C[0], C[1], C[2] }, X[N-1]) > C[3] + EPS) {
				S[B++] = X[N-1];
				C = welzl(X, N-1, S, B);
			}
			return C;
		}
		} catch (Throwable e) {
			print (5.5);
			return null;
		}
	}

	double [] circle(double [] a, double [] b) {
		double d = dist(a,b);
		double [] C = new double [a.length+1];
		for (int i = 0; i < a.length; ++i)
			C[i] = (a[i] + b[i])/2;
		C[a.length] = d/2;
		return C;
	}

	boolean close(double x, double y) {
		return Math.abs(x-y) < EPS;
	}

	double [] circle(double [] a, double [] b, double [] c) {
		try {
		if (close(a[0],b[0]) && close(b[0],c[0]))
			return collinear(a,b,c);
		else if (close(a[0],b[0]))
			return circle(b,c,a);
		else if (close(b[0],c[0]))
			return circle(c,a,b);
		else {
			double ma = (b[1] - a[1])/(b[0] - a[0]);
			if (close(ma,0))
				return circle(c,b,a);
			double mb = (c[1] - b[1])/(c[0] - b[0]);
			if (close(ma,mb))
				return collinear(a,b,c);
			double [] C = new double [4];
			C[0] = (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (2*(mb - ma));
			C[1] = ((a[0] + b[0])/2 - C[0])/ma + (a[1] + b[1])/2;
			C[3] = dist(a,C);
			return C;
		}
		} catch (StackOverflowError e) {
			print (6.1);
		} catch (NullPointerException e) {
			print (6.2);
		} catch (ArithmeticException e) {
			print (6.3);
		} catch (Error e) {
			print (6.4);
		} catch (RuntimeException e) {
			print (6.5);
		} catch (Throwable e) {
			print (6.6);
		}
		return null;
	}

	double [] collinear (double [] a, double [] b, double [] c) {
		double [] C = circle(a,b);
		if (dist(b,c) > dist(a,b))
			C = circle(b,c);
		if (dist(a,c) > dist(b,c))
			C = circle(a,c);
		return C;
	}

	double [][] randomize(double [][] X) {
		SortedMap<Double, double []> M = new TreeMap<Double, double []>();
		for (double [] x : X)
			M.put(Math.random(), x);
		return M.values().toArray(new double[0][]);
	}

	////////////////////////////////////////////////////////////////////////////////////

	double dot(double [] A, double [] B) {
		double S = 0;
		for (int i = 0; i < A.length; ++i)
			S += A[i] * B[i];
		return S;
	}

	double norm (double [] A) {
		return Math.sqrt(dot(A,A));
	}

	boolean isZero(double [] X) {
		return close(dot(X,X),0);
	}

	double [] normalize(double [] X) {
		return scalar(1/norm(X),X);
	}

	double dist (double [] A, double [] B) {
		return norm(diff(A,B));
	}

	double [] scalar (double c, double [] A) {
		double [] cA = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			cA[i] = c * A[i];
		return cA;
	}

	double [] sum (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] + B[i];
		return C;
	}

	double [] diff (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] - B[i];
		return C;
	}

	double [] cross (double [] A, double [] B) {
		double [] C = new double [A.length];
		// TODO - This is only 3-dimensional
		C[0] = A[1]*B[2] - B[1]*A[2];
		C[1] = A[2]*B[0] - B[2]*A[0];
		C[2] = A[0]*B[1] - B[0]*A[1];
		return C;
	}

	////////////////////////////////////////////////////////////////////////////////////

	private void print (Object o) {
		System.out.println(o);
	}

	public static void main(String[] args) {
		try {
			Scanner sc = new Scanner(System.in);
			new E(sc);
		} catch (NullPointerException e) {
			System.out.println(1.1);
		} catch (ArithmeticException e) {
			System.out.println(2.2);
		} catch(Throwable e) {
			System.out.println(999.999);
		}
	}
}

import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class E {

	private static final double EPS = 1e-8;

   	private E (Scanner sc) {
		int N = sc.nextInt();
		int M = sc.nextInt();

		double [][] X = new double [N][];
		for (int i = 0; i < N; ++i)
			X[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };

		double [][] A = new double [M][];
		for (int i = 0; i < M; ++i)
			A[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };
		for (int i = 0; i < M; ++i)
			solve(X, A[i]);
	}

	private void solve (double [][] X, double [] A) {
		// Project X on plane
		double [][] Y = new double [X.length][];
		for (int i = 0; i < X.length; ++i)
			Y[i] = project(X[i], A);

		// Rotate plane, so that z = 0
		double [] K = new double [] { -A[1], A[0], 0 };
		if (!isZero(K))
			Y = rodrigues(Y, normalize(K));

		// Welzl Algorithm
		Y = randomize(Y);
		double [][] S = new double [3][];
		double [] C = welzl(Y, Y.length, S, 0);

		print(C[C.length - 1]);
	}

	double [] project(double [] X, double [] A) {
		return diff(X, scalar(dot(X,A)/dot(A,A), A));
	}

	double [][] rodrigues(double [][] X, double [] K) {
		// Rotate X plane to z=0, around K axis
		// K is a unit vector in both X and z=0 planes
		double [] V = null;
		for (double [] x : X) {
			// Use a vector V on X plane, orthogonal to K,
			// to easily compute sin and cos of rotation angle.
			double [] v = project(x,K);
			if (!isZero(v))
				V = v;
		}

		if (V == null)
			return X;

		double [] T = new double [] {
			dot(new double [] { K[1], -K[0], 0 }, V),
			V[2] };
		T = normalize(T);

		for (int i = 0; i < X.length; ++i) {
			double [] x = scalar(T[0] ,X[i]);
			x = sum(x, scalar(T[1] ,cross(K,X[i])));
			x = sum(x, scalar(dot(K,X[i])*(1-T[0]), K));
			X[i] = x;
		}
		return X;
	}

	double [] welzl(double [][] X, int N, double [][] S, int B) {
		if (B == 3)
			return circle(S[0], S[1], S[2]);
		else if (N == 1 && B == 0)
			return new double [] { X[0][0], X[0][1], X[0][2], 0 };
		else if (N == 0 && B == 2)
			return circle (S[0], S[1]);
		else if (N == 1 && B == 1)
			return circle (S[0], X[0]);
		else {
			double [] C = welzl(X, N-1, S, B);
			if (dist (new double [] { C[0], C[1], C[2] }, X[N-1]) > C[3] + EPS) {
				S[B++] = X[N-1];
				C = welzl(X, N-1, S, B);
			}
			return C;
		}
	}

	double [] circle(double [] a, double [] b) {
		double d = dist(a,b);
		double [] C = new double [a.length+1];
		for (int i = 0; i < a.length; ++i)
			C[i] = (a[i] + b[i])/2;
		C[a.length] = d/2;
		return C;
	}

	boolean close(double x, double y) {
		return Math.abs(x-y) < EPS;
	}

	double [] circle(double [] a, double [] b, double [] c) {
		if (close(a[0],b[0]) && close(b[0],c[0]))
			return collinear(a,b,c);
		else if (close(a[0],b[0]))
			return circle(b,c,a);
		else if (close(b[0],c[0]))
			return circle(c,a,b);
		else {
			double ma = (b[1] - a[1])/(b[0] - a[0]);
			if (close(ma,0))
				return circle(c,b,a);
			double mb = (c[1] - b[1])/(c[0] - b[0]);
			if (close(ma,mb))
				return collinear(a,b,c);
			double [] C = new double [4];
			C[0] = (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (2*(mb - ma));
			C[1] = ((a[0] + b[0])/2 - C[0])/ma + (a[1] + b[1])/2;
			C[3] = dist(a,C);
			return C;
		}
	}

	double [] collinear (double [] a, double [] b, double [] c) {
		double [] C = circle(a,b);
		if (dist(b,c) > dist(a,b))
			C = circle(b,c);
		if (dist(a,c) > dist(b,c))
			C = circle(a,c);
		return C;
	}

	double [][] randomize(double [][] X) {
		SortedMap<Double, double []> M = new TreeMap<Double, double []>();
		for (double [] x : X)
			M.put(Math.random(), x);
		return M.values().toArray(new double[0][]);
	}

	////////////////////////////////////////////////////////////////////////////////////

	double dot(double [] A, double [] B) {
		double S = 0;
		for (int i = 0; i < A.length; ++i)
			S += A[i] * B[i];
		return S;
	}

	double norm (double [] A) {
		return Math.sqrt(dot(A,A));
	}

	boolean isZero(double [] X) {
		return close(dot(X,X),0);
	}

	double [] normalize(double [] X) {
		return scalar(1/norm(X),X);
	}

	double dist (double [] A, double [] B) {
		return norm(diff(A,B));
	}

	double [] scalar (double c, double [] A) {
		double [] cA = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			cA[i] = c * A[i];
		return cA;
	}

	double [] sum (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] + B[i];
		return C;
	}

	double [] diff (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] - B[i];
		return C;
	}

	double [] cross (double [] A, double [] B) {
		double [] C = new double [A.length];
		// TODO - This is only 3-dimensional
		C[0] = A[1]*B[2] - B[1]*A[2];
		C[1] = A[2]*B[0] - B[2]*A[0];
		C[2] = A[0]*B[1] - B[0]*A[1];
		return C;
	}

	////////////////////////////////////////////////////////////////////////////////////

	private void print (Object o) {
		System.out.println(o);
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		new E(sc);
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

import static java.lang.Math.*;

/**
 * Created by IntelliJ IDEA.
 * User: Taras_Brzezinsky
 * Date: 7/18/11
 * Time: 10:15 PM
 * To change this template use File | Settings | File Templates.
 */

public class E_TB extends Thread {

    class ChuckNorrisException extends Throwable {
        public String getMessage() {
            return "ChuckNorris ^ ChuckNorris";
        }
    }

    class Point {
        double x, y, z;

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

    class Point2D {
        double x, y;

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

    class Plane {
        double a, b, c;
        private double N;

        public Plane(double a, double b, double c) {
            this.a = a;
            this.b = b;
            this.c = c;
            this.N = 0.0;
        }

        public double norm() {
            if (N == .0) {
                return (N = a * a + b * b + c * c);
            } else {
                return N;
            }
        }

        public double distance(Point point) {
            return -(a * point.x + b * point.y + c * point.z) / norm();
        }
    }

    public E_TB() {
        this.input = new BufferedReader(new InputStreamReader(System.in));
        this.output = new PrintWriter(System.out);
        this.tokens = null;
        this.setPriority(Thread.MAX_PRIORITY);
    }

    private void transformCoordinates() {

        // (x, y, z) -> (x, y, z) projected to current plane
        for (int i = 0; i < initial.length; ++i) {
            double curV = current.distance(initial[i]);
            work[i] = new Point(initial[i].x + current.a * curV, initial[i].y + current.b * curV,
                    initial[i].z + current.c * curV);
        }

        // rotate : (a, b, c) - > (0, 0, newC)

        // rotate for x
        double theta = atan2(current.b, current.c);
        for (int i = 0; i < work.length; ++i) {
            double curY = work[i].y * cos(theta) - work[i].z * sin(theta),
                    curZ = work[i].y * sin(theta) + work[i].z * cos(theta);
            work[i].y = curY;
            work[i].z = curZ;
        }
        current.c = current.b * sin(theta) + current.c * cos(theta);
        //rotate for y
        theta = atan2(current.a, current.c);
        for (int i = 0; i < work.length; ++i) {
            points[i].x = work[i].x * cos(theta) - work[i].z * sin(theta);
            points[i].y = work[i].y;
        }
    }

    private double prepare(int l, int r) {
        C.x = .5 * (points[l].x + points[r].x);
        C.y = .5 * (points[l].y + points[r].y);
        return .5 * hypot(points[l].x - points[r].x, points[l].y - points[r].y);
    }

    private void randomShuffle(int limit) {
        Point2D t;
        for (int i = limit; i > 1; i--) {
            t = points[i - 1];
            int c = random.nextInt(i);
            points[i - 1] = points[c];
            points[c] = t;
        }

    }

    private void minCircle() throws ChuckNorrisException {
        randomShuffle(points.length);
        double curRadius = prepare(0, 1);
        for (int i = 2; i < points.length; ++i) {
            if (curRadius + EPS <= hypot(C.x - points[i].x, C.y - points[i].y)) {
                tryThis(i);
                curRadius = hypot(C.x - points[i].x, C.y - points[i].y);
            }
        }
    }

    private void tryThis(int limit) throws ChuckNorrisException {
        randomShuffle(limit);
        double curRadius = prepare(0, limit);
        for (int i = 1; i < limit; ++i) {
            if (curRadius + EPS <= hypot(C.x - points[i].x, C.y - points[i].y)) {
                lastChance(i, limit);
                curRadius = hypot(C.x - points[limit].x, C.y - points[limit].y);
            }
        }
    }

    private void lastChance(int lower, int upper) throws ChuckNorrisException {
        randomShuffle(lower);
        double curRadius = prepare(lower, upper);
        for (int i = 0; i < lower; ++i) {
            if (curRadius + EPS <= hypot(C.x - points[i].x, C.y - points[i].y)) {
                calc(i, lower, upper);
                curRadius = hypot(C.x - points[lower].x, C.y - points[lower].y);
            }
        }
    }

    private void calc(int i, int j, int k) throws ChuckNorrisException {
        double xA = points[i].x, xB = points[j].x, xC = points[k].x,
                yA = points[i].y, yB = points[j].y, yC = points[k].y;
        double a1 = xB - xA, b1 = yB - yA, c1 = -.5 * (a1 * (xA + xB) + b1 * (yA + yB)),
                a2 = xC - xB, b2 = yC - yB, c2 = -.5 * (a2 * (xB + xC) + b2 * (yB + yC));
        double S;
        if (abs((S = a1 * b2 - b1 * a2)) < EPS) {
            throw new ChuckNorrisException();
        }
        C.x = -(c1 * b2 - c2 * b1) / S;
        C.y = (c1 * a2 - c2 * a1) / S;
    }

    private double go() throws ChuckNorrisException {
        if (points.length == 1) {
            C.x = points[0].x;
            C.y = points[0].y;
            return 0.0;
        }
        double minRadius = 0.0;
        minCircle();
        for (int i = 0; i < points.length; ++i) {
            minRadius = max(minRadius, hypot(points[i].x - C.x, points[i].y - C.y));
        }
        return minRadius;
    }

    public void run() {
        try {
            int n = nextInt(), m = nextInt();
            this.initial = new Point[n];
            this.work = new Point[n];
            this.points = new Point2D[n];
            for (int i = 0; i < n; ++i) {
                initial[i] = new Point(nextDouble(), nextDouble(), nextDouble());
                points[i] = new Point2D(0, 0);
            }

            for (int query = 0; query < m; ++query) {
                this.current = new Plane(nextDouble(), nextDouble(), nextDouble());
                transformCoordinates();
                double result = go();
                output.printf("%.7f\n", result);
            }
            output.flush();
            output.close();

        } catch (Throwable e) {
            System.err.println(e.getMessage());
            System.err.println(Arrays.deepToString(e.getStackTrace()));
        }
    }

    public static void main(String[] args) {
        new E_TB().start();
    }

    private String nextToken() throws IOException {
        while (tokens == null || !tokens.hasMoreTokens()) {
            tokens = new StringTokenizer(input.readLine());
        }
        return tokens.nextToken();
    }

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

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

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

    private static final double EPS = 1e-8;
    private Point[] initial;
    private Point[] work;
    private Point2D[] points;
    private Point2D C = new Point2D(0, 0);
    private Plane current;
    private Random random = new Random(System.currentTimeMillis());
    private StringTokenizer tokens;
    private BufferedReader input;
    private PrintWriter output;
}

//package round90re;
import java.awt.geom.Line2D;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.15f\n", minCircle(nco));
		}
	}

	public double minCircle(double[][] co)
	{
		int n = co.length;
		if(n <= 1)return 0;

		// 最遠点を選ぶ
		double maxd = -1;
		int first = -1;
		for(int i = 0;i < n;i++){
			double d2 = co[i][0]*co[i][0]+co[i][1]*co[i][1];
			if(d2 > maxd){
				maxd = d2;
				first = i;
			}
		}

		// 2点に接するように最遠点に近づいていく
		// (tx,ty)が(x,y)-(x',y')の垂直二等分線をとおるような最小のt
		// (T-M)*L=0
		// t(x*Lx+y*Ly)=mx*Lx+my*Ly
		double mint = 1.01;
		int second = -1;
		double fx = co[first][0], fy = co[first][1];
		for(int i = 0;i < n;i++){
			if(i == first)continue;
			double ox = co[i][0], oy = co[i][1];
			double mx = (fx+ox)/2, my = (fy+oy)/2;
			double t = (mx*(ox-fx)+my*(oy-fy))/(fx*(ox-fx)+fy*(oy-fy));
			if(t < mint){
				mint = t;
				second = i;
			}
		}
		if(second == -1){ // secondがない場合縮重している
			return 0;
		}

		boolean[] sed = new boolean[n];
		sed[first] = true;
		sed[second] = true;

		// CをMに近づけていく
		int third = -1;
		while(true){
			double mx = (co[first][0] + co[second][0])/2;
			double my = (co[first][1] + co[second][1])/2;
			double nr2 = (mx-co[first][0])*(mx-co[first][0])+(my-co[first][1])*(my-co[first][1]);
			double[] ec = null;
			third = -1;
			for(int i = 0;i < n;i++){
				if(sed[i])continue;
//				if(i == first || i == second)continue;
				if((mx-co[i][0])*(mx-co[i][0])+(my-co[i][1])*(my-co[i][1]) <= nr2)continue;
				double[] lec = excircle2(co[first][0], co[first][1], co[second][0], co[second][1], co[i][0], co[i][1]);
				if(ec == null || lec[2] > ec[2]){
					ec = lec;
					third = i;
				}
			}
			if(ec == null)break;
			sed[third] = true;
			if(Line2D.linesIntersect(co[first][0], co[first][1], co[third][0], co[third][1], ec[0], ec[1], co[second][0], co[second][1])){
				second = third;
				continue;
			}
			if(Line2D.linesIntersect(co[second][0], co[second][1], co[third][0], co[third][1], ec[0], ec[1], co[first][0], co[first][1])){
				first = third;
				continue;
			}
			return ec[2];
		}
		return Math.sqrt((co[second][0]-co[first][0])*(co[second][0]-co[first][0])+(co[second][1]-co[first][1])*(co[second][1]-co[first][1]))/2;
	}

	public static double[] excircle2(double ax, double ay, double bx, double by, double cx, double cy)
	{
		double A = (bx-cx)*(bx-cx)+(by-cy)*(by-cy);
		double B = (cx-ax)*(cx-ax)+(cy-ay)*(cy-ay);
		double C = (ax-bx)*(ax-bx)+(ay-by)*(ay-by);
		double D = A*(-A+B+C)+B*(A-B+C)+C*(A+B-C);
		double X = (A*(-A+B+C)*ax + B*(A-B+C)*bx + C*(A+B-C)*cx) / D;
		double Y = (A*(-A+B+C)*ay + B*(A-B+C)*by + C*(A+B-C)*cy) / D;
		double R = Math.sqrt((X-ax)*(X-ax)+(Y-ay)*(Y-ay));
//		double R = A*B*C/Math.sqrt((A+B+C)*(-A+B+C)*(A-B+C)*(A+B-C));
		return new double[]{X, Y, R};
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

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());
        }
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    static Random r = new Random(3731L);

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
//                double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
//                        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
//                p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
                p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            double best = 1e100;
            for (int iter = 0; iter < 5; ++iter) {
                Point ce = solve1(points);
                double res = 0;
                for (Point po : points) {
                    res = Math.max(res, po.distanceTo(ce));
                }
                if (DoubleUtils.compareTo(best, res) > 0) {
                    best = res;
                }
            }
            out.println(best);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p, r);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p, r);
        double r = p.get(0).distanceTo(po) / 2;
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p, r);
        double r = po.distanceTo(po2) / 2;
        Point c = po.add(po2).div(2);
        for (int i = 0; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public Point3D add(Point3D p) {
        return new Point3D(x + p.x, y + p.y, z + p.z);
    }

    public Point3D mul(double k) {
        return new Point3D(x * k, y * k, z * k);
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

    public Plane3D norm() {
        double D = DoubleUtils.sqrt(a * a + b * b + c * c);
        a /= D;
        b /= D;
        c /= D;
        d /= D;
        return new Plane3D(a, b, c, d);
    }

    public double getSignedDistanceTo(Point3D point) {
        Plane3D normPlane = norm();
        return a * point.x + b * point.y + c * point.z + d;
    }

    public Point3D getNormal() {
        return new Point3D(a, b, c);
    }
}

class Geometry3DUtils {
    public static Point3D getProjectionOnPlane(Point3D point, Plane3D plane) {
        double dst = plane.getSignedDistanceTo(point);
        Point3D v = plane.getNormal().mul(dst);
        return point.add(v);
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class DoubleUtils {
    public static final double EPS = 1e-8;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);

        if (l1.intersect(l2) == null) {
            Point A = p1;
            Point B = p2;
            if (DoubleUtils.compareTo(A.distanceTo(B), p1.distanceTo(p3)) < 0) {
                A = p1;
                B = p3;
            }
            if (DoubleUtils.compareTo(A.distanceTo(B), p2.distanceTo(p3)) < 0) {
                A = p2;
                B = p3;
            }
            center = A.add(B).div(2);
            radius = center.distanceTo(A);
            return;
            //throw new AssertionError("Points on same line!");
        }
        center = l1.intersect(l2);
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

import java.util.*;

public class E {

	private final static boolean autoflush = false;

	public E () {
		int N = sc.nextInt(), M = sc.nextInt();
		double [][] X = toPrimitive(sc.nextDoubles(N));
		double [][] A = toPrimitive(sc.nextDoubles(M));

		for (int j : rep(M)) {
			Rodrigues R = new Rodrigues(A[j]);
			double [][] Y = new double [N][];
			for (int i : rep(N))
				Y[i] = R.rotate(project(X[i], A[j]));
			Circle res = Circle.toCircle(Y);
			print(res.R);
		}
	}

	///////////////////////////////////////////////////////////////////////////
	private static final double eps = 1e-9;
	private static final int INF = (int) 1e9;
	private static double [] cross (double [] X, double [] Y) { assert X.length <= 3 && Y.length <= 3; X = copyOf(X, 3); Y = copyOf(Y, 3); return new double [] { X[1]*Y[2] - Y[1]*X[2], X[2]*Y[0] - Y[2]*X[0], X[0]*Y[1] - Y[0]*X[1] }; }
	private static double [] diff (double [] X, double [] Y) { return sum(X, scalar(-1, Y)); }
	private static double dist (double [] X, double [] Y) { return norm(diff(X, Y)); }
	private static double dot(double [] X, double [] Y) { double res = 0; for (int i = 0; i < min(X.length, Y.length); ++i) res += X[i] * Y[i]; return res; }
	private static boolean eq(double x, double y) { return abs(x - y) < eps; }
	private static boolean eq (double [] X, double [] Y) { return eq(dist(X, Y), 0); }
	private static boolean greater(double x, double y) { return x > y + eps; }
	private static double norm (double ... X) { return sqrt(dot(X, X)); }
	private static double [] normalize(double ... X) { return eq(norm(X), 0) ? X : scalar(1/norm(X), X); }
	private static double [] project(double [] X, double [] K) { return diff(X, scalar(dot(X,K)/dot(K,K), K)); }
	private static int [] rep(int N) { return rep(0, N); }
	private static int [] rep(int S, int T) { if (T <= S) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static double [] scalar (double c, double ... X) { double [] res = new double [X.length]; for (int i = 0; i < X.length; ++i) res[i] = c * X[i]; return res; }
	private static double [] sum (double [] ... X) {
		int L = 0;
		for (double[] x : X)
			L = max(L, x.length);
		double [] res = new double [L];
		for (double[] x : X)
			for (int j = 0; j < x.length; ++j)
				res[j] += x[j];
		return res;
	}
	private static double [] toPrimitive(Double ... A) { double [] res = new double [A.length]; for (int i = 0; i < A.length; ++i) res[i] = A[i]; return res; }
	private static double [][] toPrimitive(Double [] ... A) { double [][] res = new double [A.length][]; for (int i = 0; i < A.length; ++i) res[i] = toPrimitive(A[i]); return res; }
	private static boolean zero(double ... X) { return eq(norm(X), 0); }
	////////////////////////////////////////////////////////////////////////////////////
	private static class Circle {
		public final double [] C;
		public final double R;
		public static final Circle R2 = new Circle(new double [2], INF);
		public Circle(double [] C, double R) { this.C = C; this.R = R; }
		public static Circle toCircumference(double [] ... X) {
			assert X.length > 0 && X.length <= 3;
			switch(X.length) {
			case 1: return new Circle(X[0], 0);
			case 2: return new Circle(scalar(.5, sum(X)), .5 * dist(X[0], X[1]));
			case 3:
				if (eq(X[0], X[1])) return toCircumference(X[1], X[2]);
				else if (eq(X[1], X[2])) return toCircumference(X[2], X[0]);
				else if (eq(X[2], X[0])) return toCircumference(X[0], X[1]);
				else return	calc(X[0], X[1], X[2]);
			default: throw new Error();
			}
		}
		public static Circle toCircle(double [] ... X) {
			assert X.length > 0; shuffle(asList(X));
			return welzl(X, X.length, new double[3][], 0);
		}
		private static Circle calc(double [] X, double [] Y, double [] Z) {
			boolean u = eq(X[0], Y[0]), v = eq(Y[0], Z[0]);
			if (u && v) return R2;
			else if (u) return calc(Y, Z, X);
			else if (v) return calc(Z, X, Y);
			else {
				double U = (Y[1] - X[1]) / (Y[0] - X[0]);
				double V = (Z[1] - Y[1]) / (Z[0] - Y[0]);
				if (eq(U, V)) return R2;
				if (eq(U, 0)) return calc(Z, Y, X);
				double CX = (U * V * (X[1] - Z[1]) + V * (X[0] + Y[0]) - U * (Y[0] + Z[0])) / (2 * (V - U));
				double CY = ((X[0] + Y[0]) / 2 - CX) / U + (X[1] + Y[1]) / 2;
				double [] C = new double [] { CX, CY };
				double R = dist(C, X); assert eq(dist(C, Y), R) && eq(dist(C, Z), R);
				return new Circle(C, R);
			}
		}
		private static Circle welzl(double [][] X, int N, double [][] S, int K) {
			if (K == 3) return Circle.toCircumference(S);
			else if (N == 0) {
				switch(K) {
				case 0: return new Circle(new double [3], -1);
				case 1: return new Circle(S[0], 0);
				case 2: return Circle.toCircumference(S[0], S[1]);
				default: throw new Error();
				}
			}
			else {
				Circle C = welzl(X, N-1, S, K);
				if (greater(dist(C.C, X[N-1]), C.R)) {
					S[K++] = X[N-1];
					C = welzl(X, N-1, S, K);
				}
				return C;
			}
		}
		public String toString() { Map<String, Object> M = new HashMap<>(); M.put("C", Arrays.toString(C)); M.put("R", R); return M.toString(); }
	}
	private static class Rodrigues {
		private final double [] K, T;
		public Rodrigues(double ... A) {
			assert A.length <= 3; A = copyOf(A, 3);
			K = normalize(new double [] { -A[1], A[0] }); double [] L = new double [] { K[1], -K[0] };
			if (!zero(K)) {
				double [] V = new double [3];
				while (zero(V))
					V = project(project(new double [] { random(), random(), random() }, A), K);
				T = normalize(new double [] { dot(L, V), V[2] });
			} else
				T = null;
		}
		public double [] rotate(double ... X) {
			assert X.length <= 3; X = copyOf(X, 3);
			if (T != null) {
				double [] Y = scalar(T[0], X);
				Y = sum(Y, scalar(T[1], cross(K, X)));
				X = sum(Y, scalar(dot(K, X) * (1 - T[0]), K));
			}
			assert eq(X[2], 0);
			return copyOf(X, 2);
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	private final static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static void print (Object o, Object ... A) { IOUtils.print(o, A); }
	private static void exit() { IOUtils.exit(); }
	private static class IOUtils {
		public static class MyScanner {
			public String next() { newLine(); return line[index++]; }
			public int nextInt() { return Integer.parseInt(next()); }
			public String nextLine() { line = null; return readLine(); }
			public String [] nextStrings() { return nextLine().split(" "); }
			public Double [] nextDoubles() {
				String [] L = nextStrings();
				Double [] res = new Double [L.length];
				for (int i = 0; i < L.length; ++i)
					res[i] = Double.parseDouble(L[i]);
				return res;
			}
			public Double [][] nextDoubles (int N) {
				Double [][] res = new Double [N][];
				for (int i = 0; i < N; ++i)
					res[i] = nextDoubles();
				return res;
			}
			//////////////////////////////////////////////
			private boolean eol() { return index == line.length; }
			private String readLine() {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine() {
				if (line == null || eol()) {
					line = readLine().split(" ");
					index = 0;
				}
			}
		}
		private static String build(Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim(String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static void start() { if (t == 0) t = millis(); }
		private static void append(StringBuilder b, Object o, String delim) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					append(b, java.lang.reflect.Array.get(o, i), delim);
			} else if (o instanceof Iterable<?>)
				for (Object p : (Iterable<?>) o)
					append(b, p, delim);
			else {
				if (o instanceof Double)
					o = new java.text.DecimalFormat("#.############").format(o);
				b.append(delim).append(o);
			}
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out, autoflush);
		private static void print(Object o, Object ... A) { pw.println(build(o, A)); }
		private static void err(Object o, Object ... A) { System.err.println(build(o, A)); }
		private static void exit() {
			IOUtils.pw.close();
			System.out.flush();
			err("------------------");
			err(IOUtils.time());
		}
		private static long t;
		private static long millis() { return System.currentTimeMillis(); }
		private static String time() { return "Time: " + (millis() - t) / 1000.0; }
	}
	public static void main (String[] args) { new E(); exit(); }
}

import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class E {

	private static final double EPS = 1e-8;

   	private E (Scanner sc) throws Throwable {
		int N = sc.nextInt();
		int M = sc.nextInt();

		double [][] X = new double [N][];
		for (int i = 0; i < N; ++i)
			X[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };

		double [][] A = new double [M][];
		for (int i = 0; i < M; ++i)
			A[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };
		for (int i = 0; i < M; ++i)
			solve(X, A[i]);
	}

	private void solve (double [][] X, double [] A) throws Throwable {
		// Project X on plane
		double [][] Y = new double [X.length][];
		for (int i = 0; i < X.length; ++i)
			Y[i] = project(X[i], A);

		// Rotate plane, so that z = 0
		double [] K = new double [] { -A[1], A[0], 0 };
		if (!isZero(K))
			Y = rodrigues(Y, normalize(K));

		// Welzl Algorithm
		Y = randomize(Y);
		double [][] S = new double [3][];
		double [] C = welzl(Y, Y.length, S, 0);

		print(C[C.length - 1]);
	}

	double [] project(double [] X, double [] A) {
		return diff(X, scalar(dot(X,A)/dot(A,A), A));
	}

	double [][] rodrigues(double [][] X, double [] K) {
		// Rotate to z=0, K is unit vector in X and z=0 planes
		double [] V = null;
		for (double [] x : X) {
			double [] v = project(x,K);
			if (!isZero(v))
				V = v;
		}

		if (V == null)
			return X;

		double [] T = new double [] {
				dot(new double [] { K[1], -K[0] }, V),
				V[2] };
		T = normalize(T);

		double [] w = scalar(T[0] ,V);
		w = sum(w, scalar(T[1] ,cross(K,V)));
		w = sum(w, scalar(dot(K,V)*(1-T[0]), K));

		for (int i = 0; i < X.length; ++i) {
			double [] x = scalar(T[0] ,X[i]);
			x = sum(x, scalar(T[1] ,cross(K,X[i])));
			x = sum(x, scalar(dot(K,X[i])*(1-T[0]), K));
			X[i] = x;
		}
		return X;
	}

	double [] welzl(double [][] X, int N, double [][] S, int B) {
		if (B == 3)
			return circle(S[0], S[1], S[2]);
		else if (N == 1 && B == 0)
			return new double [] { X[0][0], X[0][1], X[0][2], 0 };
		else if (N == 0 && B == 2)
			return circle (S[0], S[1]);
		else if (N == 1 && B == 1)
			return circle (S[0], X[0]);
		else {
			double [] C = welzl(X, N-1, S, B);
			if (dist (new double [] { C[0], C[1], C[2] }, X[N-1]) > C[3] + EPS) {
				S[B++] = X[N-1];
				C = welzl(X, N-1, S, B);
			}
			return C;
		}
	}

	double [] circle(double [] a, double [] b) {
		double d = dist(a,b);
		double [] C = new double [a.length+1];
		for (int i = 0; i < a.length; ++i)
			C[i] = (a[i] + b[i])/2;
		C[a.length] = d/2;
		return C;
	}

	boolean close(double x, double y) {
		return Math.abs(x-y) < EPS;
	}

	double [] circle(double [] a, double [] b, double [] c) {
		if (close(a[0],b[0]) && close(b[0],c[0]))
			return collinear(a,b,c);
		else if (close(a[0],b[0]))
			return circle(b,c,a);
		else if (close(b[0],c[0]))
			return circle(c,a,b);
		else {
			double ma = (b[1] - a[1])/(b[0] - a[0]);
			if (close(ma,0))
				return circle(c,b,a);
			double mb = (c[1] - b[1])/(c[0] - b[0]);
			if (close(ma,mb))
				return collinear(a,b,c);
			double [] C = new double [4];
			C[0] = (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (2*(mb - ma));
			C[1] = ((a[0] + b[0])/2 - C[0])/ma + (a[1] + b[1])/2;
			C[3] = dist(a,C);
			return C;
		}
	}

	double [] collinear (double [] a, double [] b, double [] c) {
		double [] C = circle(a,b);
		if (dist(b,c) > dist(a,b))
			C = circle(b,c);
		if (dist(a,c) > dist(b,c))
			C = circle(a,c);
		return C;
	}

	double [][] randomize(double [][] X) {
		SortedMap<Double, double []> M = new TreeMap<Double, double []>();
		for (double [] x : X)
			M.put(Math.random(), x);
		return M.values().toArray(new double[0][]);
	}

	////////////////////////////////////////////////////////////////////////////////////

	double dot(double [] A, double [] B) {
		double S = 0;
		for (int i = 0; i < A.length; ++i)
			S += A[i] * B[i];
		return S;
	}

	double norm (double [] A) {
		return Math.sqrt(dot(A,A));
	}

	boolean isZero(double [] X) {
		return close(dot(X,X),0);
	}

	double [] normalize(double [] X) {
		return scalar(1/norm(X),X);
	}

	double dist (double [] A, double [] B) {
		return norm(diff(A,B));
	}

	double [] scalar (double c, double [] A) {
		double [] cA = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			cA[i] = c * A[i];
		return cA;
	}

	double [] sum (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] + B[i];
		return C;
	}

	double [] diff (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] - B[i];
		return C;
	}

	double [] cross (double [] A, double [] B) {
		double [] C = new double [A.length];
		// TODO - This is only 3-dimensional
		C[0] = A[1]*B[2] - B[1]*A[2];
		C[1] = A[2]*B[0] - B[2]*A[0];
		C[2] = A[0]*B[1] - B[0]*A[1];
		return C;
	}

	////////////////////////////////////////////////////////////////////////////////////

	private void print (Object o) {
		System.out.println(o);
	}

	public static void main(String[] args) throws Throwable {
		Scanner sc = new Scanner(System.in);
		new E(sc);
	}
}

import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class E {

	private static final double EPS = 1e-8;

   	private E (Scanner sc) throws Throwable {
//		double [][] X = { { 0,1,-1} };
//		double [] K =  { -1,1,0 };
//		print(Arrays.deepToString(rodrigues(X,normalize(K))));

		int N = sc.nextInt();
		int M = sc.nextInt();

		double [][] X = new double [N][];
		for (int i = 0; i < N; ++i)
			X[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };

		double [][] A = new double [M][];
		for (int i = 0; i < M; ++i)
			A[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };
		for (int i = 0; i < M; ++i)
			solve(X, A[i]);
	}

	private void solve (double [][] X, double [] A) throws Throwable {
		// Project X on plane
		double [][] Y = new double [X.length][];
		for (int i = 0; i < X.length; ++i)
			Y[i] = project(X[i], A);

		// Rotate plane, so that z = 0
		double [] K = new double [] { -A[1], A[0], 0 };
		if (!isZero(K))
			Y = rodrigues(Y, normalize(K));

		// Welzl Algorithm
		Y = randomize(Y);
		double [][] S = new double [3][];
		double [] C = welzl(Y, Y.length, S, 0);

		print(C[2]);
	}

	double [] project(double [] X, double [] A) {
		return diff(X, scalar(dot(X,A)/dot(A,A), A));
	}

	double [][] rodrigues(double [][] X, double [] K) {
		// Rotate to z=0, K is unit vector in X and z=0 planes
		double [] V = null;
		for (double [] x : X) {
			double [] v = project(x,K);
			if (!isZero(v))
				V = v;
		}

		if (V == null)
			return X;

		double [] T = new double [] {
				dot(new double [] { K[1], -K[0] }, V),
				V[2] };
		T = normalize(T);

		double [] w = scalar(T[0] ,V);
		w = sum(w, scalar(T[1] ,cross(K,V)));
		w = sum(w, scalar(dot(K,V)*(1-T[0]), K));

		for (int i = 0; i < X.length; ++i) {
			double [] x = scalar(T[0] ,X[i]);
			x = sum(x, scalar(T[1] ,cross(K,X[i])));
			x = sum(x, scalar(dot(K,X[i])*(1-T[0]), K));
			X[i] = x;
		}
		return X;
	}

	double [] welzl(double [][] X, int N, double [][] S, int B) {
		if (B == 3)
			return circle(S[0], S[1], S[2]);
		else if (N == 1 && B == 0)
			return new double [] { X[0][0], X[0][1], 0 };
		else if (N == 0 && B == 2)
			return circle (S[0], S[1]);
		else if (N == 1 && B == 1)
			return circle (S[0], X[0]);
		else {
			double [] C = welzl(X, N-1, S, B);
			if (dist (new double [] { C[0], C[1] }, X[N-1]) > C[2] + EPS) {
				S[B++] = X[N-1];
				C = welzl(X, N-1, S, B);
			}
			return C;
		}
	}

	double [] circle(double [] a, double [] b) {
		double d = dist(a,b);
		double [] C = new double [3];
		for (int i = 0; i < 2; ++i)
			C[i] = (a[i] + b[i])/2;
		C[2] = d/2;
		return C;
	}

	boolean close(double x, double y) {
		return Math.abs(x-y) < EPS;
	}

	double [] circle(double [] a, double [] b, double [] c) {
		if (close(a[0],b[0]) && close(b[0],c[0]))
			return null;
		else if (close(a[0],b[0]))
			return circle(b,c,a);
		else if (close(b[0],c[0]))
			return circle(c,a,b);
		else {
			double ma = (b[1] - a[1])/(b[0] - a[0]);
			if (close(ma,0))
				return circle(b,a,c);
			double mb = (c[1] - b[1])/(c[0] - b[0]);
			if (close(ma,mb))
				return null;
			double [] C = new double [3];
			C[0] = (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (2*(mb - ma));
			C[1] = ((a[0] + b[0])/2 - C[0])/ma + (a[1] + b[1])/2;
			C[2] = dist(a,C);
			return C;
		}
	}

	double [][] randomize(double [][] X) {
		SortedMap<Double, double []> M = new TreeMap<Double, double []>();
		for (double [] x : X)
			M.put(Math.random(), x);
		return M.values().toArray(new double[0][]);
	}

	////////////////////////////////////////////////////////////////////////////////////

	double dot(double [] A, double [] B) {
		double S = 0;
		for (int i = 0; i < A.length; ++i)
			S += A[i] * B[i];
		return S;
	}

	double norm (double [] A) {
		return Math.sqrt(dot(A,A));
	}

	boolean isZero(double [] X) {
		return close(dot(X,X),0);
	}

	double [] normalize(double [] X) {
		return scalar(1/norm(X),X);
	}

	double dist (double [] A, double [] B) {
		return norm(diff(A,B));
	}

	double [] scalar (double c, double [] A) {
		double [] cA = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			cA[i] = c * A[i];
		return cA;
	}

	double [] sum (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] + B[i];
		return C;
	}

	double [] diff (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] - B[i];
		return C;
	}

	double [] cross (double [] A, double [] B) {
		double [] C = new double [A.length];
		// TODO - This is only 3-dimensional
		C[0] = A[1]*B[2] - B[1]*A[2];
		C[1] = A[2]*B[0] - B[2]*A[0];
		C[2] = A[0]*B[1] - B[0]*A[1];
		return C;
	}

	////////////////////////////////////////////////////////////////////////////////////

	private void print (Object o) {
		System.out.println(o);
	}

	public static void main(String[] args) {
		try {
			Scanner sc = new Scanner(System.in);
			new E(sc);
		} catch(Throwable e) {
			e.printStackTrace();
		}
	}
}

import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class E {

	private static final double EPS = 1e-8;

       	private E (Scanner sc) throws Throwable {
//		double [][] X = { { 0,1,-1} };
//		double [] K =  { -1,1,0 };
//		print(Arrays.deepToString(rodrigues(X,normalize(K))));

		int N = sc.nextInt();
		int M = sc.nextInt();

		double [][] X = new double [N][];
		for (int i = 0; i < N; ++i)
			X[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };

		double [][] A = new double [M][];
		for (int i = 0; i < M; ++i)
			A[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };
		for (int i = 0; i < M; ++i)
			solve(X, A[i]);
	}

	private void solve (double [][] X, double [] A) throws Throwable {
		try {
		// Project X on plane
		double [][] Y = new double [X.length][];
		for (int i = 0; i < X.length; ++i)
			Y[i] = project(X[i], A);

		// Rotate plane, so that z = 0
		double [] K = new double [] { -A[1], A[0], 0 };
		if (!isZero(K))
			Y = rodrigues(Y, normalize(K));

		// Welzl Algorithm
		Y = randomize(Y);
		double [][] S = new double [3][];
		double [] C = welzl(Y, Y.length, S, 0);

		print(C[C.length - 1]);
		} catch (Throwable e) {
			print(3.3);
		}
	}

	double [] project(double [] X, double [] A) {
		return diff(X, scalar(dot(X,A)/dot(A,A), A));
	}

	double [][] rodrigues(double [][] X, double [] K) {
		// Rotate to z=0, K is unit vector in X and z=0 planes
		try {
		double [] V = null;
		for (double [] x : X) {
			double [] v = project(x,K);
			if (!isZero(v))
				V = v;
		}

		if (V == null)
			return X;

		double [] T = new double [] {
				dot(new double [] { K[1], -K[0] }, V),
				V[2] };
		T = normalize(T);

		double [] w = scalar(T[0] ,V);
		w = sum(w, scalar(T[1] ,cross(K,V)));
		w = sum(w, scalar(dot(K,V)*(1-T[0]), K));

		for (int i = 0; i < X.length; ++i) {
			double [] x = scalar(T[0] ,X[i]);
			x = sum(x, scalar(T[1] ,cross(K,X[i])));
			x = sum(x, scalar(dot(K,X[i])*(1-T[0]), K));
			X[i] = x;
		}
		return X;
		} catch (Throwable e) {
			print (4.4);
			return null;
		}
	}

	double [] welzl(double [][] X, int N, double [][] S, int B) {
		try {
		if (B == 3)
			return circle(S[0], S[1], S[2]);
		else if (N == 1 && B == 0)
			return new double [] { X[0][0], X[0][1], X[0][2], 0 };
		else if (N == 0 && B == 2)
			return circle (S[0], S[1]);
		else if (N == 1 && B == 1)
			return circle (S[0], X[0]);
		else {
			double [] C = welzl(X, N-1, S, B);
			if (dist (new double [] { C[0], C[1], C[2] }, X[N-1]) > C[3] + EPS) {
				S[B++] = X[N-1];
				C = welzl(X, N-1, S, B);
			}
			return C;
		}
		} catch (Throwable e) {
			print (5.5);
			return null;
		}
	}

	double [] circle(double [] a, double [] b) {
		double d = dist(a,b);
		double [] C = new double [a.length+1];
		for (int i = 0; i < a.length; ++i)
			C[i] = (a[i] + b[i])/2;
		C[a.length] = d/2;
		return C;
	}

	boolean close(double x, double y) {
		return Math.abs(x-y) < EPS;
	}

	double [] circle(double [] a, double [] b, double [] c) {
		try {
		if (close(a[0],b[0]) && close(b[0],c[0]))
			return collinear(a,b,c);
		else if (close(a[0],b[0]))
			return circle(b,c,a);
		else if (close(b[0],c[0]))
			return circle(c,a,b);
		else {
			double ma = (b[1] - a[1])/(b[0] - a[0]);
			if (close(ma,0))
				return circle(b,a,c);
			double mb = (c[1] - b[1])/(c[0] - b[0]);
			if (close(ma,mb))
				return collinear(a,b,c);
			double [] C = new double [4];
			C[0] = (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (2*(mb - ma));
			C[1] = ((a[0] + b[0])/2 - C[0])/ma + (a[1] + b[1])/2;
			C[3] = dist(a,C);
			return C;
		}
		} catch (Throwable e) {
			print (6.6);
			return null;
		}
	}

	double [] collinear (double [] a, double [] b, double [] c) {
		double [] C = circle(a,b);
		if (dist(b,c) > dist(a,b))
			C = circle(b,c);
		if (dist(a,c) > dist(b,c))
			C = circle(a,c);
		return C;
	}

	double [][] randomize(double [][] X) {
		SortedMap<Double, double []> M = new TreeMap<Double, double []>();
		for (double [] x : X)
			M.put(Math.random(), x);
		return M.values().toArray(new double[0][]);
	}

	////////////////////////////////////////////////////////////////////////////////////

	double dot(double [] A, double [] B) {
		double S = 0;
		for (int i = 0; i < A.length; ++i)
			S += A[i] * B[i];
		return S;
	}

	double norm (double [] A) {
		return Math.sqrt(dot(A,A));
	}

	boolean isZero(double [] X) {
		return close(dot(X,X),0);
	}

	double [] normalize(double [] X) {
		return scalar(1/norm(X),X);
	}

	double dist (double [] A, double [] B) {
		return norm(diff(A,B));
	}

	double [] scalar (double c, double [] A) {
		double [] cA = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			cA[i] = c * A[i];
		return cA;
	}

	double [] sum (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] + B[i];
		return C;
	}

	double [] diff (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] - B[i];
		return C;
	}

	double [] cross (double [] A, double [] B) {
		double [] C = new double [A.length];
		// TODO - This is only 3-dimensional
		C[0] = A[1]*B[2] - B[1]*A[2];
		C[1] = A[2]*B[0] - B[2]*A[0];
		C[2] = A[0]*B[1] - B[0]*A[1];
		return C;
	}

	////////////////////////////////////////////////////////////////////////////////////

	private void print (Object o) {
		System.out.println(o);
	}

	public static void main(String[] args) {
		try {
			Scanner sc = new Scanner(System.in);
			new E(sc);
		} catch (NullPointerException e) {
			System.out.println(1.1);
		} catch (ArithmeticException e) {
			System.out.println(2.2);
		} catch(Throwable e) {
			System.out.println(999.999);
		}
	}
}

import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class E {

	private static final double EPS = 1e-8;

       	private E (Scanner sc) throws Throwable {
//		double [][] X = { { 0,1,-1} };
//		double [] K =  { -1,1,0 };
//		print(Arrays.deepToString(rodrigues(X,normalize(K))));

		int N = sc.nextInt();
		int M = sc.nextInt();

		double [][] X = new double [N][];
		for (int i = 0; i < N; ++i)
			X[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };

		double [][] A = new double [M][];
		for (int i = 0; i < M; ++i)
			A[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };
		for (int i = 0; i < M; ++i)
			solve(X, A[i]);
	}

	private void solve (double [][] X, double [] A) throws Throwable {
		try {
		// Project X on plane
		double [][] Y = new double [X.length][];
		for (int i = 0; i < X.length; ++i)
			Y[i] = project(X[i], A);

		// Rotate plane, so that z = 0
		double [] K = new double [] { -A[1], A[0], 0 };
		if (!isZero(K))
			Y = rodrigues(Y, normalize(K));

		// Welzl Algorithm
		Y = randomize(Y);
		double [][] S = new double [3][];
		double [] C = welzl(Y, Y.length, S, 0);

		print(C[C.length - 1]);
		} catch (Throwable e) {
			print(3.3);
		}
	}

	double [] project(double [] X, double [] A) {
		return diff(X, scalar(dot(X,A)/dot(A,A), A));
	}

	double [][] rodrigues(double [][] X, double [] K) {
		// Rotate to z=0, K is unit vector in X and z=0 planes
		try {
		double [] V = null;
		for (double [] x : X) {
			double [] v = project(x,K);
			if (!isZero(v))
				V = v;
		}

		if (V == null)
			return X;

		double [] T = new double [] {
				dot(new double [] { K[1], -K[0] }, V),
				V[2] };
		T = normalize(T);

		double [] w = scalar(T[0] ,V);
		w = sum(w, scalar(T[1] ,cross(K,V)));
		w = sum(w, scalar(dot(K,V)*(1-T[0]), K));

		for (int i = 0; i < X.length; ++i) {
			double [] x = scalar(T[0] ,X[i]);
			x = sum(x, scalar(T[1] ,cross(K,X[i])));
			x = sum(x, scalar(dot(K,X[i])*(1-T[0]), K));
			X[i] = x;
		}
		return X;
		} catch (Throwable e) {
			print (4.4);
			return null;
		}
	}

	double [] welzl(double [][] X, int N, double [][] S, int B) {
		try {
		if (B == 3)
			return circle(S[0], S[1], S[2]);
		else if (N == 1 && B == 0)
			return new double [] { X[0][0], X[0][1], X[0][2], 0 };
		else if (N == 0 && B == 2)
			return circle (S[0], S[1]);
		else if (N == 1 && B == 1)
			return circle (S[0], X[0]);
		else {
			double [] C = welzl(X, N-1, S, B);
			if (dist (new double [] { C[0], C[1], C[2] }, X[N-1]) > C[3] + EPS) {
				S[B++] = X[N-1];
				C = welzl(X, N-1, S, B);
			}
			return C;
		}
		} catch (Throwable e) {
			print (5.5);
			return null;
		}
	}

	double [] circle(double [] a, double [] b) {
		double d = dist(a,b);
		double [] C = new double [a.length+1];
		for (int i = 0; i < a.length; ++i)
			C[i] = (a[i] + b[i])/2;
		C[a.length] = d/2;
		return C;
	}

	boolean close(double x, double y) {
		return Math.abs(x-y) < EPS;
	}

	double [] circle(double [] a, double [] b, double [] c) {
		try {
		if (close(a[0],b[0]) && close(b[0],c[0]))
			return collinear(a,b,c);
		else if (close(a[0],b[0]))
			return circle(b,c,a);
		else if (close(b[0],c[0]))
			return circle(c,a,b);
		else {
			double ma = (b[1] - a[1])/(b[0] - a[0]);
			if (close(ma,0))
				return circle(b,a,c);
			double mb = (c[1] - b[1])/(c[0] - b[0]);
			if (close(ma,mb))
				return collinear(a,b,c);
			double [] C = new double [4];
			C[0] = (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (2*(mb - ma));
			C[1] = ((a[0] + b[0])/2 - C[0])/ma + (a[1] + b[1])/2;
			C[3] = dist(a,C);
			return C;
		}
		} catch (StackOverflowError e) {
			print (6.1);
		} catch (NullPointerException e) {
			print (6.2);
		} catch (ArithmeticException e) {
			print (6.3);
		} catch (Error e) {
			print (6.4);
		} catch (RuntimeException e) {
			print (6.5);
		} catch (Throwable e) {
			print (6.6);
		}
		return null;
	}

	double [] collinear (double [] a, double [] b, double [] c) {
		double [] C = circle(a,b);
		if (dist(b,c) > dist(a,b))
			C = circle(b,c);
		if (dist(a,c) > dist(b,c))
			C = circle(a,c);
		return C;
	}

	double [][] randomize(double [][] X) {
		SortedMap<Double, double []> M = new TreeMap<Double, double []>();
		for (double [] x : X)
			M.put(Math.random(), x);
		return M.values().toArray(new double[0][]);
	}

	////////////////////////////////////////////////////////////////////////////////////

	double dot(double [] A, double [] B) {
		double S = 0;
		for (int i = 0; i < A.length; ++i)
			S += A[i] * B[i];
		return S;
	}

	double norm (double [] A) {
		return Math.sqrt(dot(A,A));
	}

	boolean isZero(double [] X) {
		return close(dot(X,X),0);
	}

	double [] normalize(double [] X) {
		return scalar(1/norm(X),X);
	}

	double dist (double [] A, double [] B) {
		return norm(diff(A,B));
	}

	double [] scalar (double c, double [] A) {
		double [] cA = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			cA[i] = c * A[i];
		return cA;
	}

	double [] sum (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] + B[i];
		return C;
	}

	double [] diff (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] - B[i];
		return C;
	}

	double [] cross (double [] A, double [] B) {
		double [] C = new double [A.length];
		// TODO - This is only 3-dimensional
		C[0] = A[1]*B[2] - B[1]*A[2];
		C[1] = A[2]*B[0] - B[2]*A[0];
		C[2] = A[0]*B[1] - B[0]*A[1];
		return C;
	}

	////////////////////////////////////////////////////////////////////////////////////

	private void print (Object o) {
		System.out.println(o);
	}

	public static void main(String[] args) {
		try {
			Scanner sc = new Scanner(System.in);
			new E(sc);
		} catch (NullPointerException e) {
			System.out.println(1.1);
		} catch (ArithmeticException e) {
			System.out.println(2.2);
		} catch(Throwable e) {
			System.out.println(999.999);
		}
	}
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "7 5\r\n" +
			"\r\n" +
			"0 0 0\r\n" +
			"\r\n" +
			"10 10 0\r\n" +
			"\r\n" +
			"0 20 1000\r\n" +
			"\r\n" +
			"0 0 10\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"5 1230 76\r\n" +
			"\r\n" +
			"99 66 3\r\n" +
			"\r\n" +
			"1 0 0\r\n" +
			"\r\n" +
			"0 1 0\r\n" +
			"\r\n" +
			"0 0 1\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"1 1 0";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				axis[0] = 1; axis[1] = 0; axis[2] = 0;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
			}
			t = rot(s, axis, angle);

			double[][] u = new double[n][3];
			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[3];

		double max = 0;
		while(q > 1E-9){
			for(int o = 0;o < 50;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1])+
					x[2]*x[2];
					if(v > max){
						max = v;
						maxi = i;
					}
				}
				double w = max-x[2]*x[2];

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
//					x[i] += (s[maxi][i] - x[i])*q*Math.sqrt(w/max);
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.awt.geom.Line2D;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class E {
	Scanner in;
	PrintWriter out;
	String INPUT = "5 3\r\n" +
			"0 1 0\r\n" +
			"1 0 1\r\n" +
			"1 2 1\r\n" +
			"2 0 1\r\n" +
			"1 3 0\r\n" +
			"-1 -1 -1\r\n" +
			"1 2 3\r\n" +
			"3 0 3";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[] X = new double[n];
		double[] Y = new double[n];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			if(N2 < 1E-9){
				t = s;
			}else{
				double[] axis = new double[3];
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
				t = rot(s, axis, angle);
			}

			for(int j = 0;j < n;j++){
				X[j] = t[j][0];
				Y[j] = t[j][1];
			}

//			double max = 0;
//			for(int j = 0;j < n;j++){
//				for(int k = 0;k < j;k++){
//					max = Math.max(max, (X[j]-X[k])*(X[j]-X[k])+(Y[j]-Y[k])*(Y[j]-Y[k]));
//				}
//			}
//			out.printf("%.9f\n", Math.sqrt(max)/2);

			int[] hu = convexHull(X, Y);
			int h = hu.length;
			int is = 0, js = 0;
			for(int j = 0;j < h;j++){
				if(Y[hu[j]] > Y[hu[is]])is = j;
				if(Y[hu[j]] < Y[hu[js]])js = j;
			}

			double max = (X[hu[is]]-X[hu[js]])*(X[hu[is]]-X[hu[js]])+(Y[hu[is]]-Y[hu[js]])*(Y[hu[is]]-Y[hu[js]]);

			int u, maxu, v, maxv;
			u = maxu = is;
			v = maxv = js;
			do{
				double ax = X[hu[(u+1)%h]]-X[hu[u]];
				double ay = Y[hu[(u+1)%h]]-Y[hu[u]];
				double bx = X[hu[(v+1)%h]]-X[hu[v]];
				double by = Y[hu[(v+1)%h]]-Y[hu[v]];
				if(ax*by-ay*bx >= 0){
					v = (v+1)%h;
				}else{
					u = (u+1)%h;
				}
				double nor = (X[hu[u]]-X[hu[v]])*(X[hu[u]]-X[hu[v]])+(Y[hu[u]]-Y[hu[v]])*(Y[hu[u]]-Y[hu[v]]);
				if(nor > max){
					max = nor;
					maxu = u;
					maxv = v;
				}
			}while(u != is || v != js);

			out.printf("%.9f\n", Math.sqrt(max)/2);
		}
	}

	public static int[] convexHull(final double[] x, final double[] y)
	{
		int n = x.length;
		Integer[] ord = new Integer[n];
		for(int i = 0;i < n;i++)ord[i] = i;
		Arrays.sort(ord, new Comparator<Integer>(){
			public int compare(Integer a, Integer b){
				if(x[a] != x[b])return x[a] < x[b] ? -1 : 1;
				if(y[a] != y[b])return y[a] < y[b] ? -1 : 1;
				return 0;
			}
		});

		int[] ret = new int[n + 1];
		int p = 0;
		for(int i = 0;i < n;i++){
			if(p >= 1 && x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= 2 && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		int inf = p + 1;
		for(int i = n - 2;i >= 0;i--){
			if(x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= inf && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		return Arrays.copyOf(ret, p - 1);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				axis[0] = 1; axis[1] = 0; axis[2] = 0;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
			}
			t = rot(s, axis, angle);

			// omote
			double max0 = 0;
			for(int j = 0;j < n;j++){
				for(int k = 0;k < j;k++){
					if(t[j][2] <= 0 & t[k][2] <= 0){
						max0 = Math.max(max0, Point2D.distance(t[j][0], t[j][1], t[k][0], t[k][1])/2);
					}else{
						double d = Point2D.distance(t[j][0], t[j][1], t[k][0], t[k][1]);
						double zj = Math.max(t[j][2], 0);
						double zk = Math.max(t[k][2], 0);
						double K = 2*d/(zj+zk);
						double X = d/2+K*(zk-zj);
						// (X,0),(0,zj),(d,zk)
						double D = Math.sqrt(zj*zj+X*X);
//						if(Math.sqrt(d*d+zk*zk)<=zj){
//							D = Math.min(D, zj);
//						}
//						if(Math.sqrt(d*d+zj*zj)<=zk){
//							D = Math.min(D, zk);
//						}
						max0 = Math.max(max0, D);
					}
				}
			}

			for(int j = 0;j < n;j++){
				t[j][2] = -t[j][2];
			}

			// ura
			double max1 = 0;
			for(int j = 0;j < n;j++){
				for(int k = 0;k < j;k++){
					if(t[j][2] <= 0 & t[k][2] <= 0){
						max1 = Math.max(max1, Point2D.distance(t[j][0], t[j][1], t[k][0], t[k][1])/2);
					}else{
						double d = Point2D.distance(t[j][0], t[j][1], t[k][0], t[k][1]);
						double zj = Math.max(t[j][2], 0);
						double zk = Math.max(t[k][2], 0);
						double K = 2*d/(zj+zk);
						double X = d/2+K*(zk-zj);
						// (X,0),(0,zj),(d,zk)
						double D = Math.sqrt(zj*zj+X*X);
//						if(Math.sqrt(d*d+zk*zk)<=zj){
//							D = Math.min(D, zj);
//						}
//						if(Math.sqrt(d*d+zj*zj)<=zk){
//							D = Math.min(D, zk);
//						}
						max1 = Math.max(max1, D);
					}
				}
			}

			out.printf("%.9f\n", Math.min(max0, max1));
		}
	}

	public static int[] convexHull(final double[] x, final double[] y)
	{
		int n = x.length;
		Integer[] ord = new Integer[n];
		for(int i = 0;i < n;i++)ord[i] = i;
		Arrays.sort(ord, new Comparator<Integer>(){
			public int compare(Integer a, Integer b){
				if(x[a] != x[b])return x[a] < x[b] ? -1 : 1;
				if(y[a] != y[b])return y[a] < y[b] ? -1 : 1;
				return 0;
			}
		});

		int[] ret = new int[n + 1];
		int p = 0;
		for(int i = 0;i < n;i++){
			if(p >= 1 && x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= 2 && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		int inf = p + 1;
		for(int i = n - 2;i >= 0;i--){
			if(x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= inf && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		return Arrays.copyOf(ret, p - 1);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90re;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.20f\n", minBall(nco));
		}
	}

	public static double minBall(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];

		double max = 0;
		while(q > 1E-13){
			for(int o = 0;o < 100;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1]);
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "7 5\r\n" +
			"\r\n" +
			"0 0 0\r\n" +
			"\r\n" +
			"10 10 0\r\n" +
			"\r\n" +
			"0 20 1000\r\n" +
			"\r\n" +
			"0 0 10\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"5 1230 76\r\n" +
			"\r\n" +
			"99 66 3\r\n" +
			"\r\n" +
			"1 0 0\r\n" +
			"\r\n" +
			"0 1 0\r\n" +
			"\r\n" +
			"0 0 1\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"1 1 0";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[][] u = new double[n][3];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				t = s;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
				t = rot(s, axis, angle);
			}

			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];
		double sx = 0, sy = 0;
		for(int i = 0;i < s.length;i++){
			sx += s[i][0];
			sy += s[i][1];
		}
		x[0] = sx / s.length;
		x[1] = sy / s.length;

		double max = 0;
		while(q > 1E-8){
			for(int o = 0;o < 30;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1])+
					p[2]*p[2];
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
//					x[i] += (s[maxi][i] - x[i])*q*Math.sqrt(w/max);
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				axis[0] = 1; axis[1] = 0; axis[2] = 0;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
			}
			t = rot(s, axis, angle);

			double[][] u = new double[n][3];
			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 1;
		double[] x = new double[3];

		double max = 0;
		while(q > 1E-9){
			max = -1;
			int maxi = -1;
			for(int i = 0;i < s.length;i++){
				double[] p = s[i];
				double v =
				(x[0]-p[0])*(x[0]-p[0])+
				(x[1]-p[1])*(x[1]-p[1])+
				x[2]*x[2];
				if(v > max){
					max = v;
					maxi = i;
				}
			}

			for(int i = 0;i < 2;i++){
				x[i] += (s[maxi][i] - x[i])*q;
			}
			q /= 2;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.awt.geom.Line2D;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class E {
	Scanner in;
	PrintWriter out;
	String INPUT = "5 3\r\n" +
			"0 1 0\r\n" +
			"1 0 1\r\n" +
			"1 2 1\r\n" +
			"2 0 1\r\n" +
			"1 3 0\r\n" +
			"-1 -1 -1\r\n" +
			"1 2 3\r\n" +
			"3 0 3";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[] X = new double[n];
		double[] Y = new double[n];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			if(N2 < 1E-9){
				t = s;
			}else{
				double[] axis = new double[3];
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
				t = rot(s, axis, angle);
			}

			for(int j = 0;j < n;j++){
				X[j] = t[j][0];
				Y[j] = t[j][1];
			}

//			double max = 0;
//			for(int j = 0;j < n;j++){
//				for(int k = 0;k < j;k++){
//					max = Math.max(max, (X[j]-X[k])*(X[j]-X[k])+(Y[j]-Y[k])*(Y[j]-Y[k]));
//				}
//			}
//			out.printf("%.9f\n", Math.sqrt(max)/2);

			int[] hu = convexHull(X, Y);
			int h = hu.length;
			int is = 0, js = 0;
			for(int j = 0;j < h;j++){
				if(Y[hu[j]] > Y[hu[is]])is = j;
				if(Y[hu[j]] < Y[hu[js]])js = j;
			}

			double max = (X[hu[is]]-X[hu[js]])*(X[hu[is]]-X[hu[js]])+(Y[hu[is]]-Y[hu[js]])*(Y[hu[is]]-Y[hu[js]]);

			int u, maxu, v, maxv;
			u = maxu = is;
			v = maxv = js;
			do{
				double ax = X[hu[(u+1)%h]]-X[hu[u]];
				double ay = Y[hu[(u+1)%h]]-Y[hu[u]];
				double bx = X[hu[(v+1)%h]]-X[hu[v]];
				double by = Y[hu[(v+1)%h]]-Y[hu[v]];
				if(ax*by-ay*bx >= 0){
					v = (v+1)%h;
				}else{
					u = (u+1)%h;
				}
				double nor = (X[hu[u]]-X[hu[v]])*(X[hu[u]]-X[hu[v]])+(Y[hu[u]]-Y[hu[v]])*(Y[hu[u]]-Y[hu[v]]);
				if(nor > max){
					max = nor;
					maxu = u;
					maxv = v;
				}
			}while(u != is || v != js);

			out.printf("%.9f\n", Math.sqrt(max)/2);
		}
	}

	public static int[] convexHull(final double[] x, final double[] y)
	{
		int n = x.length;
		Integer[] ord = new Integer[n];
		for(int i = 0;i < n;i++)ord[i] = i;
		Arrays.sort(ord, new Comparator<Integer>(){
			public int compare(Integer a, Integer b){
				if(x[a] != x[b])return x[a] < x[b] ? -1 : 1;
				if(y[a] != y[b])return y[a] < y[b] ? -1 : 1;
				return 0;
			}
		});

		int[] ret = new int[n + 1];
		int p = 0;
		for(int i = 0;i < n;i++){
			if(p >= 1 && x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= 2 && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		int inf = p + 1;
		for(int i = n - 2;i >= 0;i--){
			if(x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= inf && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		return Arrays.copyOf(ret, p - 1);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "7 5\r\n" +
			"\r\n" +
			"0 0 0\r\n" +
			"\r\n" +
			"10 10 0\r\n" +
			"\r\n" +
			"0 20 1000\r\n" +
			"\r\n" +
			"0 0 10\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"5 1230 76\r\n" +
			"\r\n" +
			"99 66 3\r\n" +
			"\r\n" +
			"1 0 0\r\n" +
			"\r\n" +
			"0 1 0\r\n" +
			"\r\n" +
			"0 0 1\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"1 1 0";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[][] u = new double[n][3];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				t = s;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
				t = rot(s, axis, angle);
			}

			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];
		double sx = 0, sy = 0;
		for(int i = 0;i < s.length;i++){
			sx += s[i][0];
			sy += s[i][1];
		}
		x[0] = sx / s.length;
		x[1] = sy / s.length;

		double max = 0;
		while(q > 1E-11){
			for(int o = 0;o < 10;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1])+
					p[2]*p[2];
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
//					x[i] += (s[maxi][i] - x[i])*q*Math.sqrt(w/max);
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				axis[0] = 1; axis[1] = 0; axis[2] = 0;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
			}
			t = rot(s, axis, angle);

			double[][] u = new double[n][3];
			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 1;
		double[] x = new double[3];

		double max = 0;
		while(q > 1E-9){
			max = -1;
			int maxi = -1;
			for(int i = 0;i < s.length;i++){
				double[] p = s[i];
				double v =
				(x[0]-p[0])*(x[0]-p[0])+
				(x[1]-p[1])*(x[1]-p[1])+
				(x[2]-p[2])*(x[2]-p[2]);
				if(v > max){
					max = v;
					maxi = i;
				}
			}

			for(int i = 0;i < 3;i++){
				x[i] += (s[maxi][i] - x[i])*q;
			}
			q /= 2;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.awt.geom.Line2D;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class E {
	Scanner in;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[] X = new double[n];
		double[] Y = new double[n];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[] axis = new double[3];
			if(N2 < 1E-9){
				axis[0] = 1; axis[1] = 0; axis[2] = 0;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
			}

			double[][] t = rot(s, axis, angle);
			for(int j = 0;j < n;j++){
				X[j] = t[j][0];
				Y[j] = t[j][1];
			}

			double max = 0;
			for(int j = 0;j < n;j++){
				for(int k = 0;k < j;k++){
					max = Math.max(max, (X[j]-X[k])*(X[j]-X[k])+(Y[j]-Y[k])*(Y[j]-Y[k]));
				}
			}
			out.printf("%.9f\n", Math.sqrt(max)/2);

//			int[] hu = convexHull(X, Y);
//			int h = hu.length;
//			int is = 0, js = 0;
//			for(int j = 0;j < h;j++){
//				if(Y[hu[j]] > Y[hu[is]])is = j;
//				if(Y[hu[j]] < Y[hu[js]])js = j;
//			}
//
//			double max = (X[hu[is]]-X[hu[js]])*(X[hu[is]]-X[hu[js]])+(Y[hu[is]]-Y[hu[js]])*(Y[hu[is]]-Y[hu[js]]);
//
//			int u, maxu, v, maxv;
//			u = maxu = is;
//			v = maxv = js;
//			do{
//				double ax = X[hu[(u+1)%h]]-X[hu[u]];
//				double ay = Y[hu[(u+1)%h]]-Y[hu[u]];
//				double bx = X[hu[(v+1)%h]]-X[hu[v]];
//				double by = Y[hu[(v+1)%h]]-Y[hu[v]];
//				if(ax*by-ay*bx >= 0){
//					v = (v+1)%h;
//				}else{
//					u = (u+1)%h;
//				}
//				double nor = (X[hu[u]]-X[hu[v]])*(X[hu[u]]-X[hu[v]])+(Y[hu[u]]-Y[hu[v]])*(Y[hu[u]]-Y[hu[v]]);
//				if(nor > max){
//					max = nor;
//					maxu = u;
//					maxv = v;
//				}
//			}while(u != is || v != js);
//
//			out.printf("%.9f\n", Math.sqrt(max)/2);
		}
	}

	public static int[] convexHull(final double[] x, final double[] y)
	{
		int n = x.length;
		Integer[] ord = new Integer[n];
		for(int i = 0;i < n;i++)ord[i] = i;
		Arrays.sort(ord, new Comparator<Integer>(){
			public int compare(Integer a, Integer b){
				if(x[a] != x[b])return x[a] < x[b] ? -1 : 1;
				if(y[a] != y[b])return y[a] < y[b] ? -1 : 1;
				return 0;
			}
		});

		int[] ret = new int[n + 1];
		int p = 0;
		for(int i = 0;i < n;i++){
			if(p >= 1 && x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= 2 && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		int inf = p + 1;
		for(int i = n - 2;i >= 0;i--){
			if(x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= inf && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		return Arrays.copyOf(ret, p - 1);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.awt.geom.Line2D;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class E {
	Scanner in;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[] X = new double[n];
		double[] Y = new double[n];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[] axis = new double[3];
			if(N2 < 1E-9){
				axis[0] = 1; axis[1] = 0; axis[2] = 0;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
			}

			double[][] t = rot(s, axis, angle);
			for(int j = 0;j < n;j++){
				X[j] = t[j][0];
				Y[j] = t[j][1];
			}

			int[] hu = convexHull(X, Y);
			int h = hu.length;
			int is = 0, js = 0;
			for(int j = 0;j < h;j++){
				if(Y[hu[j]] > Y[hu[is]])is = j;
				if(Y[hu[j]] < Y[hu[js]])js = j;
			}

			double max = (X[hu[is]]-X[hu[js]])*(X[hu[is]]-X[hu[js]])+(Y[hu[is]]-Y[hu[js]])*(Y[hu[is]]-Y[hu[js]]);

			int u, maxu, v, maxv;
			u = maxu = is;
			v = maxv = js;
			do{
				double ax = X[hu[(u+1)%h]]-X[hu[u]];
				double ay = Y[hu[(u+1)%h]]-Y[hu[u]];
				double bx = X[hu[(v+1)%h]]-X[hu[v]];
				double by = Y[hu[(v+1)%h]]-Y[hu[v]];
				if(ax*by-ay*bx >= 0){
					v = (v+1)%h;
				}else{
					u = (u+1)%h;
				}
				double nor = (X[hu[u]]-X[hu[v]])*(X[hu[u]]-X[hu[v]])+(Y[hu[u]]-Y[hu[v]])*(Y[hu[u]]-Y[hu[v]]);
				if(nor > max){
					max = nor;
					maxu = u;
					maxv = v;
				}
			}while(u != is || v != js);

			out.printf("%.9f\n", Math.sqrt(max)/2);
		}
	}

	public static int[] convexHull(final double[] x, final double[] y)
	{
		int n = x.length;
		Integer[] ord = new Integer[n];
		for(int i = 0;i < n;i++)ord[i] = i;
		Arrays.sort(ord, new Comparator<Integer>(){
			public int compare(Integer a, Integer b){
				if(x[a] != x[b])return x[a] < x[b] ? -1 : 1;
				if(y[a] != y[b])return y[a] < y[b] ? -1 : 1;
				return 0;
			}
		});

		int[] ret = new int[n + 1];
		int p = 0;
		for(int i = 0;i < n;i++){
			if(p >= 1 && x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= 2 && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		int inf = p + 1;
		for(int i = n - 2;i >= 0;i--){
			if(x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= inf && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		return Arrays.copyOf(ret, p - 1);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90re;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.20f\n", minBall(nco));
		}
	}

	public static double minBall(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];

		double max = 0;
		while(q > 1E-13){
			for(int o = 0;o < 50;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1]);
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90re;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.15f\n", minCircle(nco));
		}
	}

	public static double minCircle(double[][] co)
	{
		int n = co.length;
		if(n <= 1)return 0;

		// 最遠点を選ぶ
		double maxd = -1;
		int first = -1;
		for(int i = 0;i < n;i++){
			double d2 = co[i][0]*co[i][0]+co[i][1]*co[i][1];
			if(d2 > maxd){
				maxd = d2;
				first = i;
			}
		}

		// 2点に接するように最遠点に近づいていく
		// (tx,ty)が(x,y)-(x',y')の垂直二等分線をとおるような最小のt
		// (T-M)*L=0
		// t(x*Lx+y*Ly)=mx*Lx+my*Ly
		double mint = 1.01;
		int second = -1;
		double fx = co[first][0], fy = co[first][1];
		for(int i = 0;i < n;i++){
			if(i == first)continue;
			double ox = co[i][0], oy = co[i][1];
			double mx = (fx+ox)/2, my = (fy+oy)/2;
			double t = (mx*(ox-fx)+my*(oy-fy))/(fx*(ox-fx)+fy*(oy-fy));
			if(t < mint){
				mint = t;
				second = i;
			}
		}

		boolean[] sed = new boolean[n];
		sed[first] = true;
		sed[second] = true;

		// CをMに近づけていく
		int third = -1;
		while(true){
			double mx = (co[first][0] + co[second][0])/2;
			double my = (co[first][1] + co[second][1])/2;
			double nr2 = (mx-co[first][0])*(mx-co[first][0])+(my-co[first][1])*(my-co[first][1]);
			double[] ec = null;
			third = -1;
			for(int i = 0;i < n;i++){
				if(sed[i])continue;
				if((mx-co[i][0])*(mx-co[i][0])+(my-co[i][1])*(my-co[i][1]) <= nr2)continue;
				double[] lec = excircle2(co[first][0], co[first][1], co[second][0], co[second][1], co[i][0], co[i][1]);
				if(ec == null || lec[2] > ec[2]){
					ec = lec;
					third = i;
				}
			}
			if(ec == null)break;
			sed[third] = true;
			if((co[first][0]-ec[0])*(co[third][0]-ec[0])+(co[first][1]-ec[1])*(co[third][1]-ec[1]) < 0){
				second = third;
				continue;
			}
			if((co[second][0]-ec[0])*(co[third][0]-ec[0])+(co[second][1]-ec[1])*(co[third][1]-ec[1]) < 0){
				first = third;
				continue;
			}
			return ec[2];
		}
		return Math.sqrt((co[second][0]-co[first][0])*(co[second][0]-co[first][0])+(co[second][1]-co[first][1])*(co[second][1]-co[first][1]))/2;
	}

	public static double[] excircle2(double ax, double ay, double bx, double by, double cx, double cy)
	{
		double A = (bx-cx)*(bx-cx)+(by-cy)*(by-cy);
		double B = (cx-ax)*(cx-ax)+(cy-ay)*(cy-ay);
		double C = (ax-bx)*(ax-bx)+(ay-by)*(ay-by);
		double D = A*(-A+B+C)+B*(A-B+C)+C*(A+B-C);
		double X = (A*(-A+B+C)*ax + B*(A-B+C)*bx + C*(A+B-C)*cx) / D;
		double Y = (A*(-A+B+C)*ay + B*(A-B+C)*by + C*(A+B-C)*cy) / D;
		double R = Math.sqrt((X-ax)*(X-ax)+(Y-ay)*(Y-ay));
//		double R = A*B*C/Math.sqrt((A+B+C)*(-A+B+C)*(A-B+C)*(A+B-C));
		return new double[]{X, Y, R};
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90re;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.12f\n", minBall(nco));
		}
	}

	public static double minBall(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];

		double max = 0;
		while(q > 1E-11){
			for(int o = 0;o < 100;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1]);
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "7 5\r\n" +
			"\r\n" +
			"0 0 0\r\n" +
			"\r\n" +
			"10 10 0\r\n" +
			"\r\n" +
			"0 20 1000\r\n" +
			"\r\n" +
			"0 0 10\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"5 1230 76\r\n" +
			"\r\n" +
			"99 66 3\r\n" +
			"\r\n" +
			"1 0 0\r\n" +
			"\r\n" +
			"0 1 0\r\n" +
			"\r\n" +
			"0 0 1\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"1 1 0";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[][] u = new double[n][3];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				t = s;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
				t = rot(s, axis, angle);
			}

			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];
		double sx = 0, sy = 0;
		for(int i = 0;i < s.length;i++){
			sx += s[i][0];
			sy += s[i][1];
		}
		x[0] = sx / s.length;
		x[1] = sy / s.length;

		double max = 0;
		while(q > 1E-11){
			for(int o = 0;o < 20;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1])+
					p[2]*p[2];
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
//					x[i] += (s[maxi][i] - x[i])*q*Math.sqrt(w/max);
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90re;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.12f\n", minBall(nco));
		}
	}

	public static double minBall(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[3];

		double max = 0;
		while(q > 1E-9){
			for(int o = 0;o < 100;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1]);
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 3;i++){
					x[i] += (s[maxi][i] - x[i])*q;
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "7 5\r\n" +
			"\r\n" +
			"0 0 0\r\n" +
			"\r\n" +
			"10 10 0\r\n" +
			"\r\n" +
			"0 20 1000\r\n" +
			"\r\n" +
			"0 0 10\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"5 1230 76\r\n" +
			"\r\n" +
			"99 66 3\r\n" +
			"\r\n" +
			"1 0 0\r\n" +
			"\r\n" +
			"0 1 0\r\n" +
			"\r\n" +
			"0 0 1\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"1 1 0";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[][] u = new double[n][3];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				t = s;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
				t = rot(s, axis, angle);
			}

			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];
		double sx = 0, sy = 0;
		for(int i = 0;i < s.length;i++){
			sx += s[i][0];
			sy += s[i][1];
		}
		x[0] = sx / s.length;
		x[1] = sy / s.length;

		double max = 0;
		while(q > 1E-9){
			for(int o = 0;o < 50;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1])+
					p[2]*p[2];
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
//					x[i] += (s[maxi][i] - x[i])*q*Math.sqrt(w/max);
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "7 5\r\n" +
			"\r\n" +
			"0 0 0\r\n" +
			"\r\n" +
			"10 10 0\r\n" +
			"\r\n" +
			"0 20 1000\r\n" +
			"\r\n" +
			"0 0 10\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"5 1230 76\r\n" +
			"\r\n" +
			"99 66 3\r\n" +
			"\r\n" +
			"1 0 0\r\n" +
			"\r\n" +
			"0 1 0\r\n" +
			"\r\n" +
			"0 0 1\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"1 1 0";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				axis[0] = 1; axis[1] = 0; axis[2] = 0;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
			}
			t = rot(s, axis, angle);

			double[][] u = new double[n][3];
			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[3];

		double max = 0;
		while(q > 1E-8){
			for(int o = 0;o < 50;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1])+
					x[2]*x[2];
					if(v > max){
						max = v;
						maxi = i;
					}
				}
				double w = max-x[2]*x[2];

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
//					x[i] += (s[maxi][i] - x[i])*q*Math.sqrt(w/max);
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90re;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.20f\n", minBall(nco));
		}
	}

	public static double minBall(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];

		double max = 0;
		while(q > 1E-11){
			for(int o = 0;o < 50;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1]);
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
				}
			}
			q *= 0.6;
		}

		return Math.sqrt(max);
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				axis[0] = 1; axis[1] = 0; axis[2] = 0;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
			}
			t = rot(s, axis, angle);

			// omote
			double max0 = 0;
			for(int j = 0;j < n;j++){
				for(int k = 0;k < j;k++){
					if(t[j][2] <= 0 & t[k][2] <= 0){
						max0 = Math.max(max0, Point2D.distance(t[j][0], t[j][1], t[k][0], t[k][1])/2);
					}else{
						double d = Point2D.distance(t[j][0], t[j][1], t[k][0], t[k][1]);
						double zj = Math.max(t[j][2], 0);
						double zk = Math.max(t[k][2], 0);
						double K = 2*d/(zj+zk);
						double X = d/2+K*(zk-zj);
						// (X,0),(0,zj),(d,zk)
						double D = Math.sqrt(zj*zj+X*X);
						if(Math.sqrt(d*d+zk*zk)<=zj){
							D = Math.min(D, zj);
						}
						if(Math.sqrt(d*d+zj*zj)<=zk){
							D = Math.min(D, zk);
						}
						max0 = Math.max(max0, D);
					}
				}
			}

			for(int j = 0;j < n;j++){
				t[j][2] = -t[j][2];
			}

			// ura
			double max1 = 0;
			for(int j = 0;j < n;j++){
				for(int k = 0;k < j;k++){
					if(t[j][2] <= 0 & t[k][2] <= 0){
						max1 = Math.max(max1, Point2D.distance(t[j][0], t[j][1], t[k][0], t[k][1])/2);
					}else{
						double d = Point2D.distance(t[j][0], t[j][1], t[k][0], t[k][1]);
						double zj = Math.max(t[j][2], 0);
						double zk = Math.max(t[k][2], 0);
						double K = 2*d/(zj+zk);
						double X = d/2+K*(zk-zj);
						// (X,0),(0,zj),(d,zk)
						double D = Math.sqrt(zj*zj+X*X);
						if(Math.sqrt(d*d+zk*zk)<=zj){
							D = Math.min(D, zj);
						}
						if(Math.sqrt(d*d+zj*zj)<=zk){
							D = Math.min(D, zk);
						}
						max1 = Math.max(max1, D);
					}
				}
			}

			out.printf("%.9f\n", Math.min(max0, max1));
		}
	}

	public static int[] convexHull(final double[] x, final double[] y)
	{
		int n = x.length;
		Integer[] ord = new Integer[n];
		for(int i = 0;i < n;i++)ord[i] = i;
		Arrays.sort(ord, new Comparator<Integer>(){
			public int compare(Integer a, Integer b){
				if(x[a] != x[b])return x[a] < x[b] ? -1 : 1;
				if(y[a] != y[b])return y[a] < y[b] ? -1 : 1;
				return 0;
			}
		});

		int[] ret = new int[n + 1];
		int p = 0;
		for(int i = 0;i < n;i++){
			if(p >= 1 && x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= 2 && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		int inf = p + 1;
		for(int i = n - 2;i >= 0;i--){
			if(x[ret[p-1]] == x[ord[i]] && y[ret[p-1]] == y[ord[i]])continue;
			while(p >= inf && Line2D.relativeCCW(
					x[ret[p-2]], y[ret[p-2]],
					x[ret[p-1]], y[ret[p-1]],
					x[ord[i]], y[ord[i]]) == 1)p--;
			ret[p++] = ord[i];
		}

		return Arrays.copyOf(ret, p - 1);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90re;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.20f\n", minBall(nco));
		}
	}

	public static double minBall(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];

		double max = 0;
		while(q > 1E-9){
			for(int o = 0;o < 70;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1]);
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
				}
			}
			q *= 0.55;
		}

		return Math.sqrt(max);
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90re;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] co = new double[n][];
		for(int i = 0;i < n;i++){
			co[i] = new double[]{ni(), ni(), ni()};
		}
		for(int i = 0;i < m;i++){
			double[] nor = new double[]{ni(), ni(), ni()};
			double[][] nco = rot(nor, new double[]{0, 0, 1}, co);
			out.printf("%.20f\n", minBall(nco));
		}
	}

	public static double minBall(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];

		double max = 0;
		while(q > 1E-11){
			for(int o = 0;o < 100;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1]);
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round90;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E2 {
	Scanner in;
	PrintWriter out;
	String INPUT = "7 5\r\n" +
			"\r\n" +
			"0 0 0\r\n" +
			"\r\n" +
			"10 10 0\r\n" +
			"\r\n" +
			"0 20 1000\r\n" +
			"\r\n" +
			"0 0 10\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"5 1230 76\r\n" +
			"\r\n" +
			"99 66 3\r\n" +
			"\r\n" +
			"1 0 0\r\n" +
			"\r\n" +
			"0 1 0\r\n" +
			"\r\n" +
			"0 0 1\r\n" +
			"\r\n" +
			"1 1 1\r\n" +
			"\r\n" +
			"1 1 0";

	void solve()
	{
		int n = ni(), m = ni();
		double[][] s = new double[n][3];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		double[][] u = new double[n][3];
		for(int i = 0;i < m;i++){
			double x = ni();
			double y = ni();
			double z = ni();
			if(n == 1){
				out.printf("%.9f\n", 0.0);
				continue;
			}

			double N = Math.sqrt(x*x+y*y+z*z);
			x /= N; y /= N; z /= N;

			double angle = Math.acos(z);
			// cosT, sinT, 0
			// x, y, z
			// (xcosT+ysinT)=0
			double N2 = Math.sqrt(x*x+y*y);
			double[][] t;
			double[] axis = new double[3];
			if(N2 < 1E-9){
				t = s;
			}else{
				axis[0] = y/N2; axis[1] = -x/N2; axis[2] = 0;
				t = rot(s, axis, angle);
			}

			// omote
			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] > 0 ? t[j][2] : 0;
			}
			double omote = minr(u);

			for(int j = 0;j < n;j++){
				u[j][0] = t[j][0];
				u[j][1] = t[j][1];
				u[j][2] = t[j][2] < 0 ? t[j][2] : 0;
			}
			double ura = minr(u);

			out.printf("%.9f\n", Math.min(omote, ura));
		}
	}

	double minr(double[][] s)
	{
		double q = 0.5;
		double[] x = new double[2];
		double sx = 0, sy = 0;
		for(int i = 0;i < s.length;i++){
			sx += s[i][0];
			sy += s[i][1];
		}
		x[0] = sx / s.length;
		x[1] = sy / s.length;

		double max = 0;
		while(q > 1E-9){
			for(int o = 0;o < 30;o++){
				max = -1;
				int maxi = -1;
				for(int i = 0;i < s.length;i++){
					double[] p = s[i];
					double v =
					(x[0]-p[0])*(x[0]-p[0])+
					(x[1]-p[1])*(x[1]-p[1])+
					p[2]*p[2];
					if(v > max){
						max = v;
						maxi = i;
					}
				}

				for(int i = 0;i < 2;i++){
					x[i] += (s[maxi][i] - x[i])*q;
//					x[i] += (s[maxi][i] - x[i])*q*Math.sqrt(w/max);
				}
			}
			q *= 0.5;
		}

		return Math.sqrt(max);
	}

	double[][] rot(double[][] xs, double[] axis, double angle)
	{
		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E2().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;

public class e {

    static long MOD = 1_000_000_007;

    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();
        Vec[] v = new Vec[n];
        for(int i = 0; i < n; i++) v[i] = new Vec(in.nextInt(), in.nextInt(), in.nextInt());
        for(int i = 0; i < m; i++) {
            Vec c = new Vec(in.nextInt(), in.nextInt(), in.nextInt()).unit();
            Vec[] proj = new Vec[n];
            double max = 0;
            for(int j = 0; j < n; j++) {
                proj[j] = v[j].sub(c.scale(c.dot(v[j])));
                for(int k = 0; k < j; k++) max = Math.max(max, proj[j].sub(proj[k]).mag2());
            }

            out.println(Math.sqrt(max)/2);
        }

        out.close();
    }

    static class Vec {
        double x, y, z;

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

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

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

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

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

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

        public Vec sub(Vec o) {
            return new Vec(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());
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;

public class e {

    static long MOD = 1_000_000_007;

    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();
        Vec[] v = new Vec[n];
        for(int i = 0; i < n; i++) v[i] = new Vec(in.nextInt(), in.nextInt(), in.nextInt());
        for(int i = 0; i < m; i++) {
            Vec c = new Vec(in.nextInt(), in.nextInt(), in.nextInt());
            Vec[] proj = new Vec[n];
            double max = 0;
            for(int j = 0; j < n; j++) {
                proj[j] = v[j].sub(c.scale(c.dot(v[j])));
            }
            for(int j = 0; j < n; j++) for(int k = 0; k < j; k++) {
                max = Math.max(max, proj[j].sub(proj[k]).mag2());
            }

            out.println(Math.sqrt(max)/(2*c.mag()));
        }

        out.close();
    }

    static class Vec {
        double x, y, z;

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

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

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

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

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

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

        public Vec sub(Vec o) {
            return new Vec(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());
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;

public class e {

    static long MOD = 1_000_000_007;

    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();
        Vec[] v = new Vec[n];
        for(int i = 0; i < n; i++) v[i] = new Vec(in.nextInt(), in.nextInt(), in.nextInt());
        for(int i = 0; i < m; i++) {
            Vec c = new Vec(in.nextInt(), in.nextInt(), in.nextInt()).unit();
            Vec[] proj = new Vec[n];
            double max = 0;
            for(int j = 0; j < n; j++) {
                proj[j] = v[j].sub(c.scale(c.dot(v[j])));
            }
            for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) max = Math.max(max, proj[j].sub(proj[k]).mag2());

            out.println(Math.sqrt(max)/2);
        }

        out.close();
    }

    static class Vec {
        double x, y, z;

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

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

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

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

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

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

        public Vec sub(Vec o) {
            return new Vec(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());
        }
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        Random r = new Random(3120983123L);
        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
                double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
                        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
                p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
                //p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            Point ce = solve1(points);
            double res = 0;
            for (Point po : points) {
                res = Math.max(res, po.distanceTo(ce));
            }
            out.println(res);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p);
        double r = p.get(0).distanceTo(po);
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p);
        double r = po.distanceTo(po2);
        Point c = po.add(po2).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

}

class DoubleUtils {
    public static final double EPS = 1e-9;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);
        center = l1.intersect(l2);
        if (center == null) {
            throw new AssertionError("Points on same line!");
        }
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    static Random r = new Random(3731L);

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
                double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
                        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
                p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
//                p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            double best = 1e100;
            for (int iter = 0; iter < 120; ++iter) {
                Point ce = solve1(points);
                double res = 0;
                for (Point po : points) {
                    res = Math.max(res, po.distanceTo(ce));
                }
                if (DoubleUtils.compareTo(best, res) > 0) {
                    best = res;
                }
            }
            out.println(best);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p, r);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p, r);
        double r = p.get(0).distanceTo(po);
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p, r);
        double r = po.distanceTo(po2);
        Point c = po.add(po2).div(2);
        for (int i = 0; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

}

class DoubleUtils {
    public static final double EPS = 1e-8;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);

        if (l1.intersect(l2) == null) {
            Point A = p1;
            Point B = p2;
            if (DoubleUtils.compareTo(A.distanceTo(B), p1.distanceTo(p3)) < 0) {
                A = p1;
                B = p3;
            }
            if (DoubleUtils.compareTo(A.distanceTo(B), p2.distanceTo(p3)) < 0) {
                A = p2;
                B = p3;
            }
            center = A.add(B).div(2);
            radius = center.distanceTo(A);
            return;
            //throw new AssertionError("Points on same line!");
        }
        center = l1.intersect(l2);
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    static Random r = new Random(3731L);

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
                //double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
                //        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
                //p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
                p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            double best = 1e100;
            for (int iter = 0; iter < 10; ++iter) {
                Point ce = solve1(points);
                double res = 0;
                for (Point po : points) {
                    res = Math.max(res, po.distanceTo(ce));
                }
                best = Math.min(best, res);
            }
            out.println(best);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p, r);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p, r);
        double r = p.get(0).distanceTo(po);
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p, r);
        double r = po.distanceTo(po2);
        Point c = po.add(po2).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po2);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public Point3D add(Point3D p) {
        return new Point3D(x + p.x, y + p.y, z + p.z);
    }

    public Point3D mul(double k) {
        return new Point3D(x * k, y * k, z * k);
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

    public Plane3D norm() {
        double D = DoubleUtils.sqrt(a * a + b * b + c * c);
        a /= D;
        b /= D;
        c /= D;
        d /= D;
        return new Plane3D(a, b, c, d);
    }

    public double getSignedDistanceTo(Point3D point) {
        Plane3D normPlane = norm();
        return a * point.x + b * point.y + c * point.z + d;
    }

    public Point3D getNormal() {
        return new Point3D(a, b, c);
    }
}

class Geometry3DUtils {
    public static Point3D getProjectionOnPlane(Point3D point, Plane3D plane) {
        double dst = plane.getSignedDistanceTo(point);
        Point3D v = plane.getNormal().mul(dst);
        return point.add(v);
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class DoubleUtils {
    public static final double EPS = 1e-9;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);

        if (l1.intersect(l2) == null) {
            Point A = p1;
            Point B = p2;
            if (DoubleUtils.compareTo(A.distanceTo(B), p1.distanceTo(p3)) < 0) {
                A = p1;
                B = p3;
            }
            if (DoubleUtils.compareTo(A.distanceTo(B), p2.distanceTo(p3)) < 0) {
                A = p2;
                B = p3;
            }
            center = A.add(B).div(2);
            radius = center.distanceTo(A);
            return;
            //throw new AssertionError("Points on same line!");
        }
        center = l1.intersect(l2);
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    static Random r = new Random(3731L);

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
                //double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
                //        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
                //p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
                p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            double best = 1e100;
            for (int iter = 0; iter < 100; ++iter) {
                Point ce = solve1(points);
                double res = 0;
                for (Point po : points) {
                    res = Math.max(res, po.distanceTo(ce));
                }
                if (DoubleUtils.compareTo(best, res) > 0) {
                    best = res;
                }
            }
            out.println(best);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p, r);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p, r);
        double r = p.get(0).distanceTo(po);
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p, r);
        double r = po.distanceTo(po2);
        Point c = po.add(po2).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po2);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public Point3D add(Point3D p) {
        return new Point3D(x + p.x, y + p.y, z + p.z);
    }

    public Point3D mul(double k) {
        return new Point3D(x * k, y * k, z * k);
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

    public Plane3D norm() {
        double D = DoubleUtils.sqrt(a * a + b * b + c * c);
        a /= D;
        b /= D;
        c /= D;
        d /= D;
        return new Plane3D(a, b, c, d);
    }

    public double getSignedDistanceTo(Point3D point) {
        Plane3D normPlane = norm();
        return a * point.x + b * point.y + c * point.z + d;
    }

    public Point3D getNormal() {
        return new Point3D(a, b, c);
    }
}

class Geometry3DUtils {
    public static Point3D getProjectionOnPlane(Point3D point, Plane3D plane) {
        double dst = plane.getSignedDistanceTo(point);
        Point3D v = plane.getNormal().mul(dst);
        return point.add(v);
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class DoubleUtils {
    public static final double EPS = 1e-9;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);

        if (l1.intersect(l2) == null) {
            Point A = p1;
            Point B = p2;
            if (DoubleUtils.compareTo(A.distanceTo(B), p1.distanceTo(p3)) < 0) {
                A = p1;
                B = p3;
            }
            if (DoubleUtils.compareTo(A.distanceTo(B), p2.distanceTo(p3)) < 0) {
                A = p2;
                B = p3;
            }
            center = A.add(B).div(2);
            radius = center.distanceTo(A);
            return;
            //throw new AssertionError("Points on same line!");
        }
        center = l1.intersect(l2);
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    static Random r = new Random(3731L);

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
                double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
                        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
                p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
//                p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            double best = 1e100;
            for (int iter = 0; iter < 100; ++iter) {
                Point ce = solve1(points);
                double res = 0;
                for (Point po : points) {
                    res = Math.max(res, po.distanceTo(ce));
                }
                if (DoubleUtils.compareTo(best, res) > 0) {
                    best = res;
                }
            }
            out.println(best);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p, r);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p, r);
        double r = p.get(0).distanceTo(po);
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p, r);
        double r = po.distanceTo(po2);
        Point c = po.add(po2).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po2);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

}

class DoubleUtils {
    public static final double EPS = 1e-8;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);

        if (l1.intersect(l2) == null) {
            Point A = p1;
            Point B = p2;
            if (DoubleUtils.compareTo(A.distanceTo(B), p1.distanceTo(p3)) < 0) {
                A = p1;
                B = p3;
            }
            if (DoubleUtils.compareTo(A.distanceTo(B), p2.distanceTo(p3)) < 0) {
                A = p2;
                B = p3;
            }
            center = A.add(B).div(2);
            radius = center.distanceTo(A);
            return;
            //throw new AssertionError("Points on same line!");
        }
        center = l1.intersect(l2);
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    static Random r = new Random(3731L);

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
                //double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
                //        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
                //p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
                p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            double best = 1e100;
            for (int iter = 0; iter < 100; ++iter) {
                Point ce = solve1(points);
                double res = 0;
                for (Point po : points) {
                    res = Math.max(res, po.distanceTo(ce));
                }
                if (DoubleUtils.compareTo(best, res) > 0) {
                    best = res;
                }
            }
            out.println(best);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p, r);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p, r);
        double r = p.get(0).distanceTo(po);
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p, r);
        double r = po.distanceTo(po2);
        Point c = po.add(po2).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po2);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public Point3D add(Point3D p) {
        return new Point3D(x + p.x, y + p.y, z + p.z);
    }

    public Point3D mul(double k) {
        return new Point3D(x * k, y * k, z * k);
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

    public Plane3D norm() {
        double D = DoubleUtils.sqrt(a * a + b * b + c * c);
        a /= D;
        b /= D;
        c /= D;
        d /= D;
        return new Plane3D(a, b, c, d);
    }

    public double getSignedDistanceTo(Point3D point) {
        Plane3D normPlane = norm();
        return a * point.x + b * point.y + c * point.z + d;
    }

    public Point3D getNormal() {
        return new Point3D(a, b, c);
    }
}

class Geometry3DUtils {
    public static Point3D getProjectionOnPlane(Point3D point, Plane3D plane) {
        double dst = plane.getSignedDistanceTo(point);
        Point3D v = plane.getNormal().mul(dst);
        return point.add(v);
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class DoubleUtils {
    public static final double EPS = 1e-8;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);

        if (l1.intersect(l2) == null) {
            Point A = p1;
            Point B = p2;
            if (DoubleUtils.compareTo(A.distanceTo(B), p1.distanceTo(p3)) < 0) {
                A = p1;
                B = p3;
            }
            if (DoubleUtils.compareTo(A.distanceTo(B), p2.distanceTo(p3)) < 0) {
                A = p2;
                B = p3;
            }
            center = A.add(B).div(2);
            radius = center.distanceTo(A);
            return;
            //throw new AssertionError("Points on same line!");
        }
        center = l1.intersect(l2);
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    static Random r = new Random(3731L);

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
                //double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
                //        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
                //p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
                p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            double best = 1e100;
            for (int iter = 0; iter < 100; ++iter) {
                Point ce = solve1(points);
                double res = 0;
                for (Point po : points) {
                    res = Math.max(res, po.distanceTo(ce));
                }
                if (DoubleUtils.compareTo(best, res) > 0) {
                    best = res;
                }
            }
            out.println(best);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p, r);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p, r);
        double r = p.get(0).distanceTo(po);
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p, r);
        double r = po.distanceTo(po2);
        Point c = po.add(po2).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po2);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public Point3D add(Point3D p) {
        return new Point3D(x + p.x, y + p.y, z + p.z);
    }

    public Point3D mul(double k) {
        return new Point3D(x * k, y * k, z * k);
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

    public Plane3D norm() {
        double D = DoubleUtils.sqrt(a * a + b * b + c * c);
        a /= D;
        b /= D;
        c /= D;
        d /= D;
        return new Plane3D(a, b, c, d);
    }

    public double getSignedDistanceTo(Point3D point) {
        Plane3D normPlane = norm();
        return a * point.x + b * point.y + c * point.z + d;
    }

    public Point3D getNormal() {
        return new Point3D(a, b, c);
    }
}

class Geometry3DUtils {
    public static Point3D getProjectionOnPlane(Point3D point, Plane3D plane) {
        double dst = plane.getSignedDistanceTo(point);
        Point3D v = plane.getNormal().mul(dst);
        return point.add(v);
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class DoubleUtils {
    public static final double EPS = 1e-12;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);

        if (l1.intersect(l2) == null) {
            Point A = p1;
            Point B = p2;
            if (DoubleUtils.compareTo(A.distanceTo(B), p1.distanceTo(p3)) < 0) {
                A = p1;
                B = p3;
            }
            if (DoubleUtils.compareTo(A.distanceTo(B), p2.distanceTo(p3)) < 0) {
                A = p2;
                B = p3;
            }
            center = A.add(B).div(2);
            radius = center.distanceTo(A);
            return;
            //throw new AssertionError("Points on same line!");
        }
        center = l1.intersect(l2);
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    static Random r = new Random(3731L);

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        int n = in.nextInt();
        int m = in.nextInt();
        Point3D[] spheres = new Point3D[n];
        for (int i = 0; i < n; ++i) {
            spheres[i] = new Point3D(in);
        }
        for (int i = 0; i < m; ++i) {
            double a = in.nextDouble();
            double b = in.nextDouble();
            double c = in.nextDouble();
            Plane3D plane = new Plane3D(a, b, c, 0);
            Point3D[] p = new Point3D[n];
            for (int j = 0; j < n; ++j) {
                double t = -(plane.d + plane.a * spheres[j].x + plane.b * spheres[j].y + plane.c * spheres[j].z) /
                        (DoubleUtils.sqr(plane.a) + DoubleUtils.sqr(plane.b) + DoubleUtils.sqr(plane.c));
                p[j] = new Point3D(spheres[j].x + plane.a * t, spheres[j].y + plane.b * t, spheres[j].z + plane.c * t);
//                p[j] = Geometry3DUtils.getProjectionOnPlane(spheres[j], plane);
            }

            rotation(a, b, c, p);
            List<Point> points = new ArrayList<Point>();
            for (int j = 0; j < n; ++j) {
                points.add(new Point(p[j].x, p[j].y));
            }

            double best = 1e100;
            for (int iter = 0; iter < 120; ++iter) {
                Point ce = solve1(points);
                double res = 0;
                for (Point po : points) {
                    res = Math.max(res, po.distanceTo(ce));
                }
                if (DoubleUtils.compareTo(best, res) > 0) {
                    best = res;
                }
            }
            out.println(best);
        }
    }

    Point solve1(List<Point> p) {
        Collections.shuffle(p, r);
        if (p.size() == 1) {
            return p.get(0);
        } else {
            double r = p.get(0).distanceTo(p.get(1)) / 2;
            Point c = p.get(0).add(p.get(1)).div(2);
            for (int j = 2; j < p.size(); ++j) {
                if (DoubleUtils.compareTo(p.get(j).distanceTo(c), r) > 0) {
                    c = solve2(p.subList(0, j), p.get(j));
                    r = c.distanceTo(p.get(j));
                }
            }
            return c;
        }
    }

    Point solve2(List<Point> p, Point po) {
        Collections.shuffle(p, r);
        double r = p.get(0).distanceTo(po);
        Point c = p.get(0).add(po).div(2);
        for (int i = 1; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                c = solve3(p.subList(0, i), p.get(i), po);
                r = c.distanceTo(po);
            }
        }
        return c;
    }

    Point solve3(List<Point> p, Point po, Point po2) {
        Collections.shuffle(p, r);
        double r = po.distanceTo(po2);
        Point c = po.add(po2).div(2);
        for (int i = 0; i < p.size(); ++i) {
            if (DoubleUtils.compareTo(p.get(i).distanceTo(c), r) > 0) {
                Circle cc = new Circle(po, po2, p.get(i));
                c = cc.center;
                r = c.distanceTo(po2);
            }
        }
        return c;
    }

    private void rotation(double a, double b, double c, Point3D[] p) {
        double angle = Math.PI / 2 - Math.atan2(c, b);
        double tempB = b;
        double tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempB;
        b = -Math.sin(angle) * tempC + Math.cos(angle) * tempB;

        for (Point3D point : p) {
            double ty = point.y;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * ty;
            point.y = -Math.sin(angle) * tz + Math.cos(angle) * ty;

        }

        angle = Math.PI / 2 - Math.atan2(c, a);
        double tempA = a;
        tempC = c;
        c = Math.cos(angle) * tempC + Math.sin(angle) * tempA;
        a = -Math.sin(angle) * tempC + Math.cos(angle) * tempA;

        for (Point3D point : p) {
            double tx = point.x;
            double tz = point.z;
            point.z = Math.cos(angle) * tz + Math.sin(angle) * tx;
            point.x = -Math.sin(angle) * tz + Math.cos(angle) * tx;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

    public double nextDouble() {
        return Double.parseDouble(nextString());
    }

}

class Point3D implements Comparable<Point3D> {
    public double x;
    public double y;
    public double z;

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('(').append(x).append(',').append(y).append(',').append(z).append(')');
        return b.toString();
    }

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

    public Point3D(InputReader in) {
        this.x = in.nextDouble();
        this.y = in.nextDouble();
        this.z = in.nextDouble();
    }

    public int compareTo(Point3D o) {
        if (DoubleUtils.compareTo(x, o.x) != 0) {
            return DoubleUtils.compareTo(x, o.x);
        }
        if (DoubleUtils.compareTo(y, o.y) != 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return DoubleUtils.compareTo(z, o.z);
    }
}

class Plane3D {
    public double a, b, c, d;

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

}

class DoubleUtils {
    public static final double EPS = 1e-8;

    public static double sqr(double x) {
        return x * x;
    }

    public static int compareTo(double a, double b) {
        if (doubleEqual(a, b)) {
            return 0;
        }
        if (a < b) {
            return -1;
        }
        return 1;
    }

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

    public static double sqrt(double a) {
        if (compareTo(a, 0) < 0) {
            System.exit(1);
        }
        if (a < 0) return 0;
        return Math.sqrt(a);
    }

    public static double hypot(double a, double b) {
        return sqrt(sqr(a) + sqr(b));
    }
}

class Point implements Comparable<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 o) {
        Point p = (Point) o;
        return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
    }

    public int hashCode() {
        int result;
        long temp;
        temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

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

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

    public Point div(double k) {
        return new Point(x / k, y / k);
    }

    public double dotProduct(Point p) {
        return x * p.x + y * p.y;
    }

    public double length() {
        return DoubleUtils.sqrt(dotProduct(this));
    }

    public double distanceTo(Point p) {
        return sub(p).length();
    }

    /*public double distanceToLine(Line l) {
        if (l.hasPoints()) {
            return distanceToLine(l.p1, l.p2);
        }
        Line normLine = l.norm();
        return normLine.a * x + normLine.b * y + normLine.c;
    } */

    // Rotate 90 degrees clockwise (positive direction).
    Point rotate() {
        return new Point(-y, x);
    }

    public int compareTo(Point o) {
        int temp = DoubleUtils.compareTo(x, o.x);
        if (temp == 0) {
            return DoubleUtils.compareTo(y, o.y);
        }
        return temp;
    }
}

class Circle {
    public final Point center;
    public final double radius;

    public Circle(Point p1, Point p2, Point p3) {
        Point middle12 = p1.add(p2).div(2);
        Point middle23 = p2.add(p3).div(2);
        Point v12 = p2.sub(p1).rotate();
        Point v23 = p3.sub(p2).rotate();
        Point p12 = middle12.add(v12);
        Point p23 = middle23.add(v23);
        Line l1 = new Line(middle12, p12);
        Line l2 = new Line(middle23, p23);

        if (l1.intersect(l2) == null) {
            Point A = p1;
            Point B = p2;
            if (DoubleUtils.compareTo(A.distanceTo(B), p1.distanceTo(p3)) < 0) {
                A = p1;
                B = p3;
            }
            if (DoubleUtils.compareTo(A.distanceTo(B), p2.distanceTo(p3)) < 0) {
                A = p2;
                B = p3;
            }
            center = A.add(B).div(2);
            radius = center.distanceTo(A);
            return;
            //throw new AssertionError("Points on same line!");
        }
        center = l1.intersect(l2);
        radius = center.distanceTo(p1);
    }

}

class Line {
    public final double a;
    public final double b;
    public final double c;
    boolean hasPoints;

    public Line(double a, double b, double c) {
        double h = DoubleUtils.hypot(a, b);
        this.a = a / h;
        this.b = b / h;
        this.c = c / h;
        hasPoints = false;
    }

    public Line(Point p1, Point p2) {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -(p1.x * a + p1.y * b);
        new Line(a, b, c);
        hasPoints = true;
    }

    public Point intersect(Line other) {
        if (parallel(other)) {
            return null;
        }
        double determinant = b * other.a - a * other.b;
        double x = (c * other.b - b * other.c) / determinant;
        double y = (a * other.c - c * other.a) / determinant;
        return new Point(x, y);
    }

    public boolean parallel(Line other) {
        return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Line line = (Line) o;

        if (!parallel(line)) return false;
        if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS) return false;

        return true;
    }
}

import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class E {

	private static final double EPS = 1e-8;

       	private E (Scanner sc) throws Throwable {
//		double [][] X = { { 0,1,-1} };
//		double [] K =  { -1,1,0 };
//		print(Arrays.deepToString(rodrigues(X,normalize(K))));

		int N = sc.nextInt();
		int M = sc.nextInt();

		double [][] X = new double [N][];
		for (int i = 0; i < N; ++i)
			X[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };

		double [][] A = new double [M][];
		for (int i = 0; i < M; ++i)
			A[i] = new double [] { sc.nextInt(),sc.nextInt(),sc.nextInt() };
		for (int i = 0; i < M; ++i)
			solve(X, A[i]);
	}

	private void solve (double [][] X, double [] A) throws Throwable {
		// Project X on plane
		double [][] Y = new double [X.length][];
		for (int i = 0; i < X.length; ++i)
			Y[i] = project(X[i], A);

		// Rotate plane, so that z = 0
		double [] K = new double [] { -A[1], A[0], 0 };
		if (!isZero(K))
			Y = rodrigues(Y, normalize(K));

		// Welzl Algorithm
		Y = randomize(Y);
		double [][] S = new double [3][];
		double [] C = welzl(Y, Y.length, S, 0);

		print(C[C.length - 1]);
	}

	double [] project(double [] X, double [] A) {
		return diff(X, scalar(dot(X,A)/dot(A,A), A));
	}

	double [][] rodrigues(double [][] X, double [] K) {
		// Rotate to z=0, K is unit vector in X and z=0 planes
		double [] V = null;
		for (double [] x : X) {
			double [] v = project(x,K);
			if (!isZero(v))
				V = v;
		}

		if (V == null)
			return X;

		double [] T = new double [] {
				dot(new double [] { K[1], -K[0] }, V),
				V[2] };
		T = normalize(T);

		double [] w = scalar(T[0] ,V);
		w = sum(w, scalar(T[1] ,cross(K,V)));
		w = sum(w, scalar(dot(K,V)*(1-T[0]), K));

		for (int i = 0; i < X.length; ++i) {
			double [] x = scalar(T[0] ,X[i]);
			x = sum(x, scalar(T[1] ,cross(K,X[i])));
			x = sum(x, scalar(dot(K,X[i])*(1-T[0]), K));
			X[i] = x;
		}
		return X;
	}

	double [] welzl(double [][] X, int N, double [][] S, int B) {
		if (B == 3)
			return circle(S[0], S[1], S[2]);
		else if (N == 1 && B == 0)
			return new double [] { X[0][0], X[0][1], X[0][2], 0 };
		else if (N == 0 && B == 2)
			return circle (S[0], S[1]);
		else if (N == 1 && B == 1)
			return circle (S[0], X[0]);
		else {
			double [] C = welzl(X, N-1, S, B);
			if (dist (new double [] { C[0], C[1], C[2] }, X[N-1]) > C[3] + EPS) {
				S[B++] = X[N-1];
				C = welzl(X, N-1, S, B);
			}
			return C;
		}
	}

	double [] circle(double [] a, double [] b) {
		double d = dist(a,b);
		double [] C = new double [a.length+1];
		for (int i = 0; i < a.length; ++i)
			C[i] = (a[i] + b[i])/2;
		C[a.length] = d/2;
		return C;
	}

	boolean close(double x, double y) {
		return Math.abs(x-y) < EPS;
	}

	double [] circle(double [] a, double [] b, double [] c) {
		if (close(a[0],b[0]) && close(b[0],c[0]))
			return collinear(a,b,c);
		else if (close(a[0],b[0]))
			return circle(b,c,a);
		else if (close(b[0],c[0]))
			return circle(c,a,b);
		else {
			double ma = (b[1] - a[1])/(b[0] - a[0]);
			if (close(ma,0))
				return circle(b,a,c);
			double mb = (c[1] - b[1])/(c[0] - b[0]);
			if (close(ma,mb))
				return collinear(a,b,c);
			double [] C = new double [4];
			C[0] = (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (2*(mb - ma));
			C[1] = ((a[0] + b[0])/2 - C[0])/ma + (a[1] + b[1])/2;
			C[3] = dist(a,C);
			return C;
		}
	}

	double [] collinear (double [] a, double [] b, double [] c) {
		double [] C = circle(a,b);
		if (dist(b,c) > dist(a,b))
			C = circle(b,c);
		if (dist(a,c) > dist(b,c))
			C = circle(a,c);
		return C;
	}

	double [][] randomize(double [][] X) {
		SortedMap<Double, double []> M = new TreeMap<Double, double []>();
		for (double [] x : X)
			M.put(Math.random(), x);
		return M.values().toArray(new double[0][]);
	}

	////////////////////////////////////////////////////////////////////////////////////

	double dot(double [] A, double [] B) {
		double S = 0;
		for (int i = 0; i < A.length; ++i)
			S += A[i] * B[i];
		return S;
	}

	double norm (double [] A) {
		return Math.sqrt(dot(A,A));
	}

	boolean isZero(double [] X) {
		return close(dot(X,X),0);
	}

	double [] normalize(double [] X) {
		return scalar(1/norm(X),X);
	}

	double dist (double [] A, double [] B) {
		return norm(diff(A,B));
	}

	double [] scalar (double c, double [] A) {
		double [] cA = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			cA[i] = c * A[i];
		return cA;
	}

	double [] sum (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] + B[i];
		return C;
	}

	double [] diff (double [] A, double [] B) {
		double [] C = new double [A.length];
		for (int i = 0; i < A.length; ++i)
			C[i] = A[i] - B[i];
		return C;
	}

	double [] cross (double [] A, double [] B) {
		double [] C = new double [A.length];
		// TODO - This is only 3-dimensional
		C[0] = A[1]*B[2] - B[1]*A[2];
		C[1] = A[2]*B[0] - B[2]*A[0];
		C[2] = A[0]*B[1] - B[0]*A[1];
		return C;
	}

	////////////////////////////////////////////////////////////////////////////////////

	private void print (Object o) {
		System.out.println(o);
	}

	public static void main(String[] args) {
		try {
			Scanner sc = new Scanner(System.in);
			new E(sc);
		} catch(Throwable e) {
			e.printStackTrace();
		}
	}
}