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 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 {
//		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.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 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;
}

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

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