Problem:
Score : 600 points

Problem Statement

There are N points in a two-dimensional plane. The initial coordinates of the i-th point are (x_i, y_i). Now, each point starts moving at a speed of 1 per second, in a direction parallel to the x- or y- axis. You are given a character d_i that represents the specific direction in which the i-th point moves, as follows:

If d_i = R, the i-th point moves in the positive x direction;

If d_i = L, the i-th point moves in the negative x direction;

If d_i = U, the i-th point moves in the positive y direction;

If d_i = D, the i-th point moves in the negative y direction.

You can stop all the points at some moment of your choice after they start moving (including the moment they start moving).
Then, let x_{max} and x_{min} be the maximum and minimum among the x-coordinates of the N points, respectively. Similarly, let y_{max} and y_{min} be the maximum and minimum among the y-coordinates of the N points, respectively.

Find the minimum possible value of (x_{max} - x_{min}) \times (y_{max} - y_{min}) and print it.

Constraints

1 \leq N \leq 10^5

-10^8 \leq x_i,\ y_i \leq 10^8

x_i and y_i are integers.

d_i is R, L, U, or D.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1 d_1
x_2 y_2 d_2
.
.
.
x_N y_N d_N

Output

Print the minimum possible value of (x_{max} - x_{min}) \times (y_{max} - y_{min}).

The output will be considered correct when its absolute or relative error from the judge's output is at most 10^{-9}.

Sample Input 1

2
0 3 D
3 0 L

Sample Output 1

0

After three seconds, the two points will meet at the origin. The value in question will be 0 at that moment.

Sample Input 2

5
-7 -10 U
7 -6 U
-8 7 D
-3 3 D
0 -6 R

Sample Output 2

97.5

The answer may not be an integer.

Sample Input 3

20
6 -10 R
-4 -9 U
9 6 D
-3 -2 R
0 7 D
4 5 D
10 -10 U
-1 -8 U
10 -6 D
8 -5 U
6 4 D
0 3 D
7 9 R
9 -4 R
3 10 D
1 9 U
1 -6 U
9 -8 R
6 7 D
7 -3 D

Sample Output 3

273

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {
	private static List<Point> points;

	public static void main(String[] args) {

		Scanner sysin = new Scanner(System.in);
		final int n = sysin.nextInt();
		points = IntStream.range(0, n)
			.mapToObj(i -> new Point(sysin.nextLong(), sysin.nextLong(), Vector.get(sysin.next().charAt(0))))
			.collect(Collectors.toList());
		sysin.close();

		double min = Double.MAX_VALUE;
		for (Dimention dim : Dimention.values()) {
			double maxAbs = points.stream().mapToDouble(p -> Math.abs(p.get(dim, 0.0d))).max().getAsDouble();
			Pair<Double, Double> d1 = binSearch(dim, calc(dim, 0.0d), calc(dim, maxAbs * 2));
			Pair<Double, Double> d2 = calc(dim == Dimention.X ? Dimention.Y : Dimention.X, d1.getKey());

			//System.out.printf("%s d1 = %f, %f\n", dim, d1.getKey(), d1.getValue());
			//System.out.printf("%s d2 = %f, %f\n", dim, d2.getKey(), d2.getValue());
			min = Math.min(min, d1.getValue() * d2.getValue());
		}

		System.out.println(min);

	}

	private static Pair<Double, Double> calc(Dimention dim, double time) {
		double[] values = points.stream().mapToDouble(p -> p.get(dim, time)).toArray();
		double max = Arrays.stream(values).max().getAsDouble();
		double min = Arrays.stream(values).min().getAsDouble();
		double value = max - min;
		//System.out.printf("(%s, %f) = %f = %f - %f\n", dim, time, value, max, min);
		return (new Pair<>(time, value));
	}

	private static Pair<Double, Double> binSearch(Dimention dim, Pair<Double, Double> start, Pair<Double, Double> end) {
		double midt = (start.getKey() + end.getKey()) / 2;
		Pair<Double, Double> mid = calc(dim, midt);

		double stv = start.getValue();
		double cev = mid.getValue();
		double env = end.getValue();

		double left = Math.abs(stv - cev);
		double right = Math.abs(env - cev);

		//System.out.printf("%s ... (%f, %f), (%f, %f), (%f, %f)\n", dim, start.getKey(), stv, midt, cev, end.getKey(), env);

		if (left == right) {
			if (stv == env) return mid; // ずっと同じ値
			if (stv < cev) return start; // 右肩上がり
			if (env < cev) return end; // 右肩下がり)
			return mid; // 中央凹み
		} else if (left <  right) {
			 return binSearch(dim, start, mid);
		} else {
			return binSearch(dim, mid, end);
		}
	}

	@SuppressWarnings("serial")
	private static class Pair<K, V> extends SimpleImmutableEntry<K, V> {
		public Pair(final K key, final V value) {
			super(key, value);
		}
	}

	private static class Point {
		private final long x, y;
		private final Vector vector;

		public Point(long x, long y, Vector v) {
			this.x = x;
			this.y = y;
			this.vector = v;
		}

		public double get(Dimention d, double time) {
			switch (d) {
			case X : return (time * vector.x) + x;
			case Y : return (time * vector.y) + y;
			}
			return 0.0d;
		}
	}

	private static enum Vector {
		RIGHT( 1,  0),
		LEFT (-1,  0),
		UP   ( 0,  1),
		DOWN ( 0, -1);

		public final int x, y;
		private Vector(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public static Vector get(char c) {
			switch(c) {
			case 'R' :
				return RIGHT;
			case 'L' :
				return LEFT;
			case 'U' :
				return UP;
			case 'D' :
				return DOWN;
			default  :
				throw new IllegalArgumentException();
			}
		}
	}

	private static enum Dimention {
		X, Y;
	}
}