// Arup Guha
// 3/15/2020
// Solution to 2020 Mercer Contest Problem: Geospatial Coverage

// Note: This would probably fail good comprehenive data and is pretty poorly designed.

import java.util.*;

public class geospatial {

	public static int maxX;
	public static int maxY;
	public static int n;
	
	// Stores non-vertical lines.
	public static ArrayList<line> lines;
	
	// Stores x coordinates of vertical lines. arr[0] = left, arr[1] = right
	public static ArrayList<int[]> vertLines;
	
	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		int nC = stdin.nextInt();
		
		// Process cases.
		for (int loop=0; loop<nC; loop++) {
		
			// Set up basic variables.
			maxX = stdin.nextInt();
			maxY = stdin.nextInt();
			n = stdin.nextInt();
			
			lines = new ArrayList<line>();
			
			// All x's for evaluation are in this list.
			ArrayList<Double> impX = new ArrayList<Double>();
			impX.add(0.0);
			impX.add(1.0*maxX);
			
			// Read in lines.
			for (int i=0; i<n; i++) {
			
				// Get all the points.
				int x1 = stdin.nextInt();
				int y1 = stdin.nextInt();
				int x2 = stdin.nextInt();
				int y2 = stdin.nextInt();
				int w = stdin.nextInt();
				
				// Vertical line case - sub with two horizontal line segments.
				if (x1 == x2) {
					lines.add(new line(x1-w, 0, x1+w, 0, false, 1));
					lines.add(new line(x1-w, maxY, x1+w, maxY, false, -1));
					if (x1-w >= 0) impX.add(1.0*x1-w);
					if (x1+w < maxX) impX.add(1.0*x1+w);
				}
				
				// Regular line (one add, one sub)
				else {
					lines.add(new line(x1, y1-w, x2, y2-w, true, 1));
					lines.add(new line(x1, y1+w, x2, y2+w, true, -1));
				}
			}

			// A hack to prevent segments that cross from out/in in/out of the scanning region.
			line bottom = new line(0,0,maxX,0,true, 0);
			line top = new line(0,maxY,maxX,maxY,true, 0);
			
			// Find all intersections.
			for (int i=0; i<lines.size(); i++) {
				
				// Add x's for lines crossing top or bottom.
				Double tmp = lines.get(i).crossX(bottom);
				if (tmp != null && tmp > 0 && tmp < maxX) impX.add(tmp);
				tmp = lines.get(i).crossX(top);
				if (tmp != null && tmp > 0 && tmp < maxX) impX.add(tmp);
				
				// Now add intersections between lines.
				for (int j=i+1; j<lines.size(); j++) {
					tmp = lines.get(i).crossX(lines.get(j));
					if (tmp != null && tmp > 0 && tmp < maxX) impX.add(tmp);
				}
			}
			
			// Sort important X's.
			Collections.sort(impX);

			double res = 0;
			
			// Go through each consecutive segment.
			for (int i=0; i<impX.size()-1; i++) {
				
				// Width of this segment.
				double width = impX.get(i+1) - impX.get(i);
				if (Math.abs(width) < 1e-9) continue;
				
				// Evaluation point.
				line.cmpX = impX.get(i) + width/2;
				
				// Resort, in order of segments from bottom to top.
				Collections.sort(lines);
				
				// Sweep up through the lines.
				int curCnt = 0;
				for (int j=0; j<lines.size(); j++) {
					
					// Update our on/off count.
					int thisCnt = lines.get(j).cnt;
					curCnt += thisCnt;
					
					// Just skip these.
					if (lines.get(j).eval(line.cmpX) < 0) continue;
					
					// Means we must still be on, add this area and get out.
					if (lines.get(j).eval(line.cmpX) > maxY) {
						res += width*maxY;
						break;
					}				
					
					// Opening a count, so subtract out the area below this.
					if (thisCnt == 1 && curCnt == 1) 
						res -= (width*lines.get(j).eval(line.cmpX));

					// Closing count.
					else if (thisCnt == -1 && curCnt == 0) 
						res += (width*lines.get(j).eval(line.cmpX));
				}
			}
			
			// Ta da!
			System.out.printf("%.2f\n", res/maxX/maxY*100);
		}
	}
}

class pt {
	
	public double x;
	public double y;
	
	public pt(int myx, int myy) {
		x = myx;
		y = myy;
	}
}

class line implements Comparable<line> {
	
	public static double cmpX;
	
	public pt p;
	public pt dir;
	public boolean cont;
	public int cnt;
	
	public line(int x1, int y1, int x2, int y2, boolean isLine, int on) {
		p = new pt(x1, y1);
		dir = new pt(x2-x1, y2-y1);
		cont = isLine;
		cnt = on;
	}
	
	public double eval(double x) {
		
		// For vertical lines.
		if (!cont) {
			if (x >= p.x && x <= p.x+dir.x) return p.y;
			return 0;
		}
		
		// How far we're moving over, relatively...then calculate corresponding y.
		double ratio = 1.0*(x-p.x)/dir.x;
		
		// Corresponding y.
		return Math.max(0, p.y + ratio*dir.y);
	}
	
	// Returns x coordinate of intersection of this and other. null if no intersection or coincident.
	public Double crossX(line other) {
		
		// Kramer's rule
		double den = -dir.x*other.dir.y + dir.y*other.dir.x;
		if (Math.abs(den) < 1e-9) return null;
		
		// Solve for lambda.
		double num = -(other.p.x-p.x)*(other.dir.y) + (other.p.y-p.y)*other.dir.x;
		double lambda = num/den;
		
		// And x.
		return p.x + lambda*dir.x;
	}
	
	// Sorts by value of line at static variable cmpX.
	public int compareTo(line other) {
		double me = this.eval(cmpX);
		double you = other.eval(cmpX);
		if (me < you) return -1;
		if (you < me) return 1;
		return 0;
	}
}