// Arup Guha
// 11/1/2017

// Uses a new approach based on what Tim told me.
// I binary search the current. To evaluate a current, I just intersect all pairs of circles
// and those are "points of interest" in addition to the four corners. Then I test to see if
// each of those points of interest are covered at that current level by k+1 or more lights.

import java.util.*;

public class blackout {

	public static int numBulbs;
	public static int numOut;
	public static int length;
	public static int width;
	public static bulb[] lights;
	public static ArrayList<double[]> corners;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int numCases = stdin.nextInt();

		// Go through each case.
		for (int loop=0; loop<numCases; loop++) {

			// Main input case parameters.
			numBulbs = stdin.nextInt();
			numOut = stdin.nextInt();
			width = stdin.nextInt();
			length = stdin.nextInt();
			lights = new bulb[numBulbs];

			// Read in each bulb.
			for (int i=0; i<numBulbs; i++) {
				int x = stdin.nextInt();
				int y = stdin.nextInt();
				int p = stdin.nextInt();
				lights[i] = new bulb(x,y,p);
			}

			// Print result.
			System.out.printf("%.2f\n", solve());
		}
	}

	// Solves problem instance.
	public static double solve() {

		// Corners...
		corners = new ArrayList<double[]>();
		corners.add(new double[]{0,0});
		corners.add(new double[]{width,0});
		corners.add(new double[]{0,length});
		corners.add(new double[]{width,length});

		// Get the current necessary for each light to shine the whole house.
		ArrayList<Double> currents = new ArrayList<Double>();
		for (int i=0; i<numBulbs; i++)
			currents.add(lights[i].maxCur(corners));
		Collections.sort(currents);

		// Initial boundaries for the binary search based on lighting the house with a single light.
		double low = 0, high = currents.get(numOut), mid = 0;

		// Run binary search here.
		for (int loop=0; loop<50; loop++) {

			mid = (low+high)/2;

			// Answer is no bigger than mid, since mid works.
			if (valid(mid))
				high = mid;

			// Gotta try something higher.
			else
				low = mid;
		}

		// This is answer.
		return mid;
	}

	// Returns true iff current c works.
	public static boolean valid(double c) {

		// Always check these.
		for (double[] pt: corners)
			if (!works(pt, c))
				return false;

		// Go through all pairs of bulbs.
		for (int i=0; i<numBulbs; i++) {
			for (int j=0; j<numBulbs; j++) {
				if (i == j) continue;

				// Determines points of interest right outside circle i by the intersection of circle j.
				ArrayList<double[]> tmp = lights[i].intersect(lights[j], c);

				// We only test the points that are in the rectangle.
				for (double[] pt : tmp) {
					if (!inbounds(pt)) continue;
					if (!works(pt, c))
						return false;
				}
			}
		}

		// If we make it here, all critical points can be covered by numOut+1 lights at current c.
		return true;
	}

	public static boolean inbounds(double[] pt) {
		return pt[0] >= 0 && pt[0] <= width && pt[1] >= 0 && pt[1] <= length;
	}

	// Returns true iff the point pt can be light appropriately with current c.
	public static boolean works(double[] pt, double c) {
		int tot = 0;
		for (int i=0; i<numBulbs; i++)
			if (lights[i].reach(pt, c))
				tot++;
		return tot > numOut;
	}
}

class bulb {

	public int x;
	public int y;
	public int power;

	public bulb(int myx, int myy, int p) {
		x = myx;
		y = myy;
		power = p;
	}

	// Returns true iff this bulb can reach pt with current c.
	public boolean reach(double[] pt, double c) {
		return Math.sqrt((pt[0]-x)*(pt[0]-x)+(pt[1]-y)*(pt[1]-y)) <= power*c;
	}

	// Amount of current necessary for this light to reach (ptX, ptY).
	public double getCurrent(double[] pt) {
		return Math.sqrt((pt[0]-x)*(pt[0]-x)+(pt[1]-y)*(pt[1]-y))/power;
	}

	// Returns the amount of current necessary for this light to reach all of the points in pts.
	public double maxCur(ArrayList<double[]> pts) {
		double res = 0;
		for (double[] pt : pts)
			res = Math.max(res, getCurrent(pt));
		return res;
	}

	public ArrayList<double[]> intersect(bulb other, double c) {

		// Store answer here.
		ArrayList<double[]> res = new ArrayList<double[]>();

		// Calculate some basic values.
		double r1 = power*c;
		double r2 = other.power*c;
		double d = this.dist(other);
		double dx = (other.x - x)/d;
		double dy = (other.y - y)/d;
		double theta = Math.atan2(dy, dx);

		// Circles don't touch.
		if (d > r1+r2) {
			double[] pt = new double[]{x+dx*(r1+1e-9), y+dy*(r1+1e-9)};
			res.add(pt);
		}

		// They touch, get two intersection points and go left and right (barely) from them.
		else {

			// The four angles emanating from this circle that we want to test.
			double dtheta = Math.acos((d*d+r1*r1-r2*r2)/(2*d*r1));
			ArrayList<Double> angles = new ArrayList<Double>();
			angles.add(theta+dtheta+1e-9);
			angles.add(theta+dtheta-1e-9);
			angles.add(theta-dtheta+1e-9);
			angles.add(theta-dtheta-1e-9);
			for (double a : angles)
				res.add(new double[]{x+Math.cos(a)*(r1+1e-9), y+Math.sin(a)*(r1+1e-9)});
		}

		return res;
	}

	public double dist(bulb other) {
		return Math.sqrt((x-other.x)*(x-other.x) + (y-other.y)*(y-other.y));
	}
}