// Timothy Buzzelli
// 2/23/2017
// Solution (with data verification) to 2017 FHSPS Playoff Question: Frogger

import java.util.*;
import java.math.*;

public class frogger_buzzelli {

    static boolean IGNORE_ZERO_LENGTH_INTERVALS = false;

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

		// Read in input and verify.
        String line = in.nextLine();
        String[] tokens = line.split(" ");
        if(tokens.length != 1) {
            System.err.println("Invalid number of tokens when reading in c!");
        }
        int c = Integer.parseInt(tokens[0]);
        if(c < 1 || c > 10) {
            System.err.println("C is out of bounds!");
        }
        
        // Process each case.
        for(int ci = 0; ci < c; ci++) {
        	
        	// Get top level input for case.
            line = in.nextLine();
            tokens = line.split(" ");
            if(tokens.length != 3) {
                System.err.println("Invalid number of tokens when reading in n, v, and w!");
            }
            int n = Integer.parseInt(tokens[0]);
            long v = Integer.parseInt(tokens[1]);
            long w = Integer.parseInt(tokens[2]);

			// Set up velocities as fractions.
            BigInteger vBI = BigInteger.valueOf(v);
            BigInteger wBI = BigInteger.valueOf(w);

            Fraction vF = new Fraction(vBI, BigInteger.ONE);
            Fraction wF = new Fraction(wBI, BigInteger.ONE);

            Fraction centF = new Fraction(BigInteger.valueOf(1000000), BigInteger.ONE);

			// Cehck bounds.
            if(n < 1 || n > 100000)
                System.err.println("N is out of bounds!");
            if(v < 1 || v > 100)
                System.err.println("V is out of bounds!");
            if(w < 1 || w > 100)
                System.err.println("W is out of bounds!");

            PriorityQueue<Event> pq = new PriorityQueue<>();

			// Get each "prize"/"event".
            for(int i = 0; i < n; i++) {
            	
            	// Read and verify prize.
                line = in.nextLine();
                tokens = line.split(" ");
                if(tokens.length != 4)
                    System.err.println("Invalid number of tokens when reading in x, y, l, and p!");
                long x = Integer.parseInt(tokens[0]);
                long y = Integer.parseInt(tokens[1]);
                long l = Integer.parseInt(tokens[2]);
                long p = Integer.parseInt(tokens[3]);

                if(x < 1 || x >= 1000000)
                    System.err.println("X is out of bounds!");
                if(y < 1 || y > 1000)
                    System.err.println("Y is out of bounds!");
                if(l < 1 || l > 1000)
                    System.err.println("L is out of bounds!");
                if(p < 1 || p > 10000)
                    System.err.println("P is out of bounds!");

                BigInteger xBI = BigInteger.valueOf(x);
                BigInteger yBI = BigInteger.valueOf(y);
                BigInteger lBI = BigInteger.valueOf(l);

                Fraction xF = new Fraction(xBI, BigInteger.ONE);
                Fraction yF = new Fraction(yBI, BigInteger.ONE);
                Fraction lF = new Fraction(lBI, BigInteger.ONE);

                // Calulate how long it would take us to get up to this prize's y coordinate
                Fraction temp = yF.divide(vF);

                // If we left now, where would the prize be by the time we get there?
                Fraction tempXLoc = xF.add(lF).add(wF.mult(temp));

                // The start time we can leave is going to be the amount of time it takes for the prize to get in place so we will hit it once we leave
                Fraction startTime = centF.sub(tempXLoc).divide(wF);

                // The end time will occur at L / W after the start time
                Fraction endTime = startTime.add(lF.divide(wF));

                // If the start time is negative, just make it 0
                if(startTime.compareTo(Fraction.ZERO) < 0) {
                    startTime = Fraction.ZERO;
                }

                // If the start time doesn't come after the end time, we add these events
                // If it came afterwards, that means they were both negative so we were too late regardless
                if(startTime.compareTo(endTime) <= 0) {
                    pq.add(new Event(startTime, p));
                    pq.add(new Event(endTime, -p));
                }
            }

            long best = 0;
            long score = 0;
            Fraction prev = Fraction.ZERO;
            Fraction minTime = null;
            
            // Now run through the priority queue in order.
            while(!pq.isEmpty()) {
            	
            	// Process this event, updating best if necessary. Also check difference in time between events.
                Event e = pq.poll();
                Fraction dif = e.t.sub(prev);
                if(score >= best && (!IGNORE_ZERO_LENGTH_INTERVALS || dif.compareTo(Fraction.ZERO) > 0)) {
                    if(score > best || minTime == null || dif.compareTo(minTime) < 0)
                        minTime = dif;
                    best = score;
                }
                
                // Update score and previous time.
                score += e.s;
                prev = e.t;
            }
            
            // Checking time of optimal span.
            if(minTime != null && minTime.compareTo(new Fraction(BigInteger.ONE, BigInteger.valueOf(1000))) < 0) {
                System.err.printf("The optimal answer of %d can be achieved for a span of %s seconds!\n", best, minTime);
            }
            
            // Here is our result.
            System.out.println(best);
        }
    }

    static class Event implements Comparable<Event> {
        Fraction t;
        long s;
        public Event(Fraction tt, long ss) {
            t = tt; s = ss;
        }
        public int compareTo(Event e) {
            int tmp = t.compareTo(e.t);
            if(tmp == 0) {
                return Long.compare(e.s, s);
            }
            return tmp;
        }
    }

    static class Fraction implements Comparable<Fraction> {
        static Fraction ZERO = new Fraction(BigInteger.ZERO, BigInteger.ONE);
        static Fraction ONE = new Fraction(BigInteger.ONE, BigInteger.ONE);
        BigInteger n, d;
        public Fraction(BigInteger nn, BigInteger dd) {
            n = nn; d = dd;
            if(d.compareTo(BigInteger.ZERO) < 0) {
                n = n.negate();
                d = d.negate();
            }
            BigInteger gcd = n.gcd(d);
            n = n.divide(gcd);
            d = d.divide(gcd);
        }
        public Fraction add(Fraction f) {
            return new Fraction(n.multiply(f.d).add(f.n.multiply(d)), d.multiply(f.d));
        }

        public Fraction sub(Fraction f) {
            return new Fraction(n.multiply(f.d).subtract(f.n.multiply(d)), d.multiply(f.d));
        }
        public Fraction mult(Fraction f) {
            return new Fraction(n.multiply(f.n), d.multiply(f.d));
        }
        public Fraction divide(Fraction f) {
            return new Fraction(n.multiply(f.d), d.multiply(f.n));
        }
        public int compareTo(Fraction f) {
            return sub(f).n.compareTo(BigInteger.ZERO);
        }
        public String toString() {
            return n + " / " + d;
        }
    }
}
