/*--------------------------------------------------------------*/
/* ACM ICPC 2007-2008                                           */
/* Northeastern European Regional Contest                       */
/* St Petersburg - Barnaul - Tashkent - Batumi, November 28, 200*/
/*--------------------------------------------------------------*/
/* Problem D. Diver                                             */
/*--------------------------------------------------------------*/
/* Solution                                                     */
/*                                                              */
/* Author                Roman Satyukov                         */
/*--------------------------------------------------------------*/
 
import java.io.*;
import java.util.*;

// Uses only 100 first moves of every shark
public class diver_rs_100 implements Runnable {
    private BufferedReader in;
    private PrintWriter out;
    private static final int FLAG_AWAY = 1;
    private static final int MAX_STEP = 100;
    private static final double eps = 1e-7;
    
    private class Point {
        public double x, y;
        
        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public double distanceTo(Point that) {
            return Math.hypot(this.x - that.x, this.y - that.y);
        }
    }
    
    private class Line {
        public double a, b, c;
        
        public Line(double a, double b, double c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }
        
        public double distanceTo(Point p) {
            return (a * p.x + b * p.y + c) / Math.sqrt(a * a + b * b);
        }
    }
    
    private Point[] points;
    private Line[][] lines;
    private boolean[] mark1;
    private boolean[] mark2;
    private int[][][] offset1;
    private int[][][] offset2;
    private double vd, r, w;
    private int n;
    
    private void generateLines(int u) {
        double x0 = points[u].x;
        double y0 = points[u].y;
        lines[u][0] = new Line(-vd, 1.0, vd * x0 - y0); 
        lines[u][2] = new Line(-1.0, vd, x0 - vd * y0 - r * Math.sqrt(1 + vd * vd)); 
        lines[u][3] = new Line(-1.0, vd, x0 - vd * y0 + r * Math.sqrt(1 + vd * vd)); 
    
        lines[u][1] = new Line(vd, 1.0, -vd * x0 - y0); 
        lines[u][4] = new Line(1.0, vd, -x0 - vd * y0 - r * Math.sqrt(1 + vd * vd)); 
        lines[u][5] = new Line(1.0, vd, -x0 - vd * y0 + r * Math.sqrt(1 + vd * vd));
    }

	private void buildGraph(int[][][] offset, int index1, int index2, int index3, int index4) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (i == j) {
					continue;
				}
				int startStep = (int) ((-r - points[j].y) / 2 / w - 1);
				int minStep = MAX_STEP + 1;
				int maxStep = -MAX_STEP - 1;
				for (int step = Math.max(startStep, -MAX_STEP); (step <= MAX_STEP); step++) {
					double oldY = points[j].y; 
					points[j].y += 2 * w * step;
					
					boolean ok = points[i].distanceTo(points[j]) < 2 * r - eps;
					if (Math.abs(lines[i][index1].distanceTo(points[j])) < r - eps) {
						if (lines[i][index2].distanceTo(points[j]) > eps) {
							ok = true;
						}
					}
					if (Math.abs(lines[i][index3].distanceTo(points[j])) < r - eps) {
						if (lines[i][index4].distanceTo(points[j]) < -eps) {
							ok = true;
						}
					}
					if (ok) {
						minStep = Math.min(minStep, step);
						maxStep = Math.max(maxStep, step);
					}
					
					points[j].y = oldY;
				}
				offset[i][j][0] = minStep;
				offset[i][j][1] = maxStep < -MAX_STEP ? MAX_STEP + 1 : maxStep;
			}
		}
	}
	
    private void dfs1(int u) {
        mark1[u] = true;
        for (int i = 0; i < n; i++) {
        	for (int k = 0; k < 2; k++) {
        		int z = offset1[u / MAX_STEP][i][k];
        		if (z == MAX_STEP + 1) {
        			continue;
        		}
        		int pp = u % MAX_STEP + z;
        		if (pp < 0 || pp >= MAX_STEP || mark1[i * MAX_STEP + pp]) {
        			continue;
        		}
        		dfs1(i * MAX_STEP + pp);
        	}
        }
    }

    private void dfs2(int u) {
        mark2[u] = true;
        for (int i = 0; i < n; i++) {
        	for (int k = 0; k < 2; k++) {
        		int z = offset2[u / MAX_STEP][i][k];
        		if (z == MAX_STEP + 1) {
        			continue;
        		}
        		int pp = u % MAX_STEP + z;
        		if (pp < 0 || pp >= MAX_STEP || mark2[i * MAX_STEP + pp]) {
        			continue;
        		}
        		dfs2(i * MAX_STEP + pp);
        	}
        }
    }

    private void solve() throws IOException {
        StringTokenizer st = new StringTokenizer(in.readLine());
        int d = Integer.parseInt(st.nextToken());
        vd = Integer.parseInt(st.nextToken());
        n = Integer.parseInt(st.nextToken());
        r = Integer.parseInt(st.nextToken());
        w = Integer.parseInt(st.nextToken());
        double vs = Integer.parseInt(st.nextToken());
        vd = vd / vs;
        
        points = new Point[n];
        lines = new Line[n][6];
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(in.readLine());
            double depth = d - Integer.parseInt(st.nextToken());
            double dist = Integer.parseInt(st.nextToken());
            int flag = Integer.parseInt(st.nextToken());
            if (flag == FLAG_AWAY) {
                dist = -dist;
            }
            points[i] = new Point(depth, dist);
            generateLines(i);
        }

        offset1 = new int[n][n][2];
        offset2 = new int[n][n][2];
        buildGraph(offset1, 2, 1, 5, 0);
        buildGraph(offset2, 4, 0, 3, 1);

        mark1 = new boolean[points.length * MAX_STEP];
        mark2 = new boolean[points.length * MAX_STEP];
        for (int i = 0; i < points.length; i++) {
        	for (int step = 0; step < MAX_STEP; step++) {
        		int cur = i * MAX_STEP + step;
        		double dist = Math.abs(-points[i].x + vd * points[i].y + 2 * w * step * vd) / Math.sqrt(1 + vd * vd);
        		if (dist < r - eps && !mark1[cur]) {
        			dfs1(cur);
        		}
        		if (points[i].x < r - eps && !mark2[cur]) {
        			dfs2(cur);
        		}
        	}
        }
        for (int i = 0; i < mark1.length; i++) {
            if (mark1[i] && mark2[i]) {
                out.println("IMPOSSIBLE");
                return;
            }
        }
        double ans = d / vd;
        for (int i = 0; i < mark1.length; i++) {
            if (!mark1[i]) {
                continue;
            }
            double a = -1.0;
            double b = vd;
            double c = points[i / MAX_STEP].x - vd * points[i / MAX_STEP].y - 2 * w * vd * (i % MAX_STEP) - r * Math.sqrt(1 + vd * vd);
            double y = -(a * d + c) / b;
            ans = Math.max(ans, y);
        }
        for (int i = 0; i < n; i++) {
            if (mark1[i * MAX_STEP + MAX_STEP - 1] || mark2[i * MAX_STEP + MAX_STEP - 1]) {
                out.println("IMPOSSIBLE");
                return;
            }
        }
        out.println(ans / vs);
    }
    
    public static void main(String[] args) {
        new Thread(new diver_rs_100()).start();
    }

    public void run() {
        String problem = getClass().getName().split("_")[0];
        try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
            solve();
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}
