#include<bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define INF 1000000000
#define mod 1000000007
using ll=long long;
const ll LINF=1001002003004005006ll;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}

/*
候補を列挙するときは候補じゃない点も多めに入っちゃっててもそんな問題ないんだから
無駄がまぎれちゃっててもざっくり集める．

単調増加*単調減少の時はどっちかの端点を調べればよい．
微分したら上凸に決まってんだから．
だからもうこの端点は必ず覆えるようにおおげさに候補点を集めれればいい
*/




struct node{
    long double x,y;char d;
    node(long double x,long double y,char d):x(x),y(y),d(d){}
    node(){}
};

signed main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    cout<<fixed<<setprecision(12);

    int n;cin>>n;
    vector<node> v(n);
    rep(i,n){
        long double x,y;char c;cin>>x>>y>>c;
        v[i]=node(x,y,c);
    }

    auto fx=[&](double T){
        long double minx=INF,maxx=-INF;
        rep(i,n){
            if(v[i].d=='U' or v[i].d=='D') chmin(minx,v[i].x),chmax(maxx,v[i].x);
            else{
                long double p;
                if(v[i].d=='R') p=v[i].x+T;
                else            p=v[i].x-T;
                chmin(minx,p);
                chmax(maxx,p);
            }
        }
        return maxx-minx;
    };

    auto fy=[&](long double T){
        long double miny=INF,maxy=-INF;
        rep(i,n){
            if(v[i].d=='R' or v[i].d=='L') chmin(miny,v[i].y),chmax(maxy,v[i].y);
            else{
                long double p;
                if(v[i].d=='U') p=v[i].y+T;
                else            p=v[i].y-T;
                chmin(miny,p);
                chmax(maxy,p);
            }
        }
        return maxy-miny;
    };

    vector<long double> cand;
    cand.push_back(0);

    {
        long double mud=INF,ml=INF,mr=INF;
        rep(i,n){
            if(v[i].d=='U' or v[i].d=='D') chmin(mud,v[i].x);
            if(v[i].d=='L') chmin(ml,v[i].x);
            if(v[i].d=='R') chmin(mr,v[i].x);
        }
        cand.push_back(abs(mud-ml));
        cand.push_back(0.5*abs(ml-mr));
        cand.push_back(abs(mud-mr));
    }

    {
        long double mud=-INF,ml=-INF,mr=-INF;
        rep(i,n){
            if(v[i].d=='U' or v[i].d=='D') chmax(mud,v[i].x);
            if(v[i].d=='L') chmax(ml,v[i].x);
            if(v[i].d=='R') chmax(mr,v[i].x);
        }
        cand.push_back(abs(mud-ml));
        cand.push_back(0.5*abs(ml-mr));
        cand.push_back(abs(mud-mr));
    }

    {
        long double mrl=-INF,md=-INF,mu=-INF;
        rep(i,n){
            if(v[i].d=='L' or v[i].d=='R') chmax(mrl,v[i].y);
            if(v[i].d=='U') chmax(mu,v[i].y);
            if(v[i].d=='D') chmax(md,v[i].y);
        }
        cand.push_back(abs(mrl-mu));
        cand.push_back(0.5*abs(mu-md));
        cand.push_back(abs(mrl-md));
    }

    {
        long double mrl=INF,md=INF,mu=INF;
        rep(i,n){
            if(v[i].d=='L' or v[i].d=='R') chmin(mrl,v[i].y);
            if(v[i].d=='U') chmin(mu,v[i].y);
            if(v[i].d=='D') chmin(md,v[i].y);
        }
        cand.push_back(abs(mrl-mu));
        cand.push_back(0.5*abs(mu-md));
        cand.push_back(abs(mrl-md));
    }

    long double ans=LINF;
    for(auto T:cand){
        chmin(ans,fx(T)*fy(T));
    }
    cout<<ans<<endl;
    return 0;
}


Measured memory_bytes: 4992