import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0; 
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //

void solve(){
	int n = read.to!int;
	
	S[] ps;
	foreach(i; 0 .. n){
		ps ~= S(read.to!real, read.to!real, read[0]);
	}
	log("ps:", ps);
	
	S[] ls, rs, us, ds;
	S[] lrs, uds;
	foreach(p; ps){
		if(p.d == 'L') ls ~= p, lrs ~= p;
		else if(p.d == 'R') rs ~= p, lrs ~= p;
		else if(p.d == 'U') us ~= p, uds ~= p;
		else ds ~= p, uds ~= p;
	}
	log("ls:", ls);
	log("rs:", rs);
	log("uds:", uds);
	log("us:", us);
	log("ds:", ds);
	log("lrs:", lrs);
	
	ls.sort!"a.x < b.x"();
	rs.sort!"a.x < b.x"();
	uds.sort!"a.x < b.x"();
	us.sort!"a.y < b.y"();
	ds.sort!"a.y < b.y"();
	lrs.sort!"a.y < b.y"();
	
	log("sorted.");
	log("ls:", ls);
	log("rs:", rs);
	log("uds:", uds);
	log("us:", us);
	log("ds:", ds);
	log("lrs:", lrs);
	
	real[] ts = [0];
	
	S[] xs;
	if (ls.length > 0) xs ~= ls[0], xs ~= ls[$ - 1];
	if (rs.length > 0) xs ~= rs[0], xs ~= rs[$ - 1];
	if(uds.length > 0) xs ~= uds[0], xs ~= uds[$ - 1];
	
	log("xs:", xs);
	
	foreach(i; 0 .. xs.length) foreach(j; 0 .. i){
		ts ~= abs(xs[i].x - xs[j].x);
		ts ~= abs(xs[i].x - xs[j].x) / 2;
	}
	
	log("ts:", ts);
	
	S[] ys;
	if (us.length > 0) ys ~= us[0], ys ~= us[$ - 1];
	if (ds.length > 0) ys ~= ds[0], ys ~= ds[$ - 1];
	if(lrs.length > 0) ys ~= lrs[0], ys ~= lrs[$ - 1];
	
	log("ys:", ys);
	
	foreach(i; 0 .. ys.length) foreach(j; 0 .. i){
		ts ~= abs(ys[i].y - ys[j].y);
		ts ~= abs(ys[i].y - ys[j].y) / 2;
	}
	
	log("ts:", ts);
	
	real f(real t){
		real xmin = real.max, xmax = -real.max;
		if(ls.length) xmin = min(xmin, ls[0].x - t), xmax = max(xmax, ls[$ - 1].x - t);
		if(rs.length) xmin = min(xmin, rs[0].x + t), xmax = max(xmax, rs[$ - 1].x + t);
		if(uds.length) xmin = min(xmin, uds[0].x), xmax = max(xmax, uds[$ - 1].x);
		
		real ymin = real.max, ymax = -real.max;
		if(us.length) ymin = min(ymin, us[0].y + t), ymax = max(ymax, us[$ - 1].y + t);
		if(ds.length) ymin = min(ymin, ds[0].y - t), ymax = max(ymax, ds[$ - 1].y - t);
		if(lrs.length) ymin = min(ymin, lrs[0].y), ymax = max(ymax, lrs[$ - 1].y);
		
		log("t:", t, "xmax:", xmax, "xmin:", xmin, "ymax:", ymax, "ymin:", ymin);
		
		return (xmax - xmin) * (ymax - ymin);
	}
	
	real a = 0, b = 100, c = 1e15;
	while(f(c) - f(a) > 0.0000001){
		log("a:", a, "b:", b, "c:", c);
		if(f(a) > f(c)) a = b, b = (a + c) / 2;
		else c = b, b = (a + c) / 2;
	}
	real best = f(b);
	
	foreach(t; ts){
		best = min(best, f(t));
	}
	
	format("%12.12f", best).writeln;
	
	
}

struct S{
	real x, y;
	char d;
}


/*
重要な点は

左に行く点のうち最も左にあるもの・右にあるもの
右に行く点のうち最も左にあるもの・右にあるもの
左右に動かない点のうち最も左にあるもの・右にあるもの

上に行く点のうち最も上にあるもの・下にあるもの
下に行く点のうち最も上にあるもの・下にあるもの
上下に動かない点のうち最も上にあるもの・下にあるもの

これらがすれ違う時刻を候補として全部調べればよい

*/


Measured memory_bytes: 28412