#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <numeric>
#include <functional>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <memory>
#include <thread>
#include <tuple>
#include <limits>

using namespace std;

struct UpperHull {
    typedef double coord_t;
    struct Line {
        // y = mx + b
        coord_t b;
        coord_t m;

        bool isEvaluation;
        mutable coord_t s, e; // [s, e)

        Line() : b(0), m(0), isEvaluation(false), s(numeric_limits<coord_t>::lowest()), e(numeric_limits<coord_t>::max()) { }

        bool operator <(const Line &other) const {
            if (isEvaluation) {
                coord_t x = b;
                if (other.s <= x && x < other.e) {
                    return false; // equals
                } else {
                    return x < other.e;
                }
            }
            if (other.isEvaluation) {
                coord_t x = other.b;
                if (s <= x && x < e) {
                    return false; // equals
                } else {
                    return s <= x;
                }
            }
            return m < other.m;
        }

        coord_t evaluate(coord_t xp) const {
            return b + m * xp;
        }

        coord_t cross_point(const Line &other) const {
            // b1 + m1 * x == b2 + m2 * x
            // (b1 - b2) / (m2 - m1) = x
            coord_t up = b - other.b;
            coord_t down = other.m - m;
            return up / down;
        }
    };

    set<Line> hull;

    bool ok(const Line &a, const Line &b, const Line &c) const {
        coord_t x1 = a.cross_point(b);
        coord_t x2 = b.cross_point(c);
        return x1 < x2;
    }

    coord_t evaluate(coord_t x) const {
        Line evaluation;
        evaluation.b = x;
        evaluation.m = x;
        evaluation.isEvaluation = true;
        return hull.find(evaluation)->evaluate(x);
    }

    void addLine(coord_t x, coord_t y, coord_t incline) {
        Line cand;
        cand.b = y - x * incline;
        cand.m = incline;
        auto Next = hull.lower_bound(cand);
        // same incline, so higher b wins
        if (Next != hull.end() && Next->m == cand.m) {
            if (Next->b >= cand.b) {
                // higher one is there.
                return;
            } else {
                // lower one, remove first.
                Next = hull.erase(Next);
            }
        }
        if (Next != hull.begin() && Next != hull.end()) {
            auto Prev = Next; --Prev;
            if (ok(*Prev, cand, *Next)) {
                // can be added
            } else {
                return;
            }
        }
        for (;;) {
            auto Prev = Next;
            if (Prev == hull.begin()) break;
            --Prev;
            auto PPrev = Prev;
            if (PPrev == hull.begin()) break;
            --PPrev;
            if (ok(*PPrev, *Prev, cand)) {
                break;
            }
            hull.erase(Prev);
        }
        for (;;) {
            if (Next == hull.end()) break;
            auto NNext = Next; ++NNext;
            if (NNext == hull.end()) break;
            if (ok(cand, *Next, *NNext)) {
                break;
            }
            Next = hull.erase(Next);
        }
        insertAndAssign(cand);
    }

private:
    void insertAndAssign(const Line &l) {
        auto iter = hull.insert(l).first;
        auto N = iter; ++N;
        if (N != hull.end()) {
            coord_t x = iter->cross_point(*N);
            iter->e = x;
            N->s = x;
        }
        auto P = iter;
        if (P != hull.begin()) {
            --P;
            coord_t x = P->cross_point(*iter);
            iter->s = x;
            P->e = x;
        }
    }
};


void addEvents(const UpperHull& hull, set<double>& event_time) {
  for (auto I = hull.hull.begin(), IEnd = hull.hull.end(); I != IEnd; ++I) {
    auto cand_time = I->s;
    if (cand_time >= 0) {
      event_time.insert(cand_time);
    }
  }
}

int main() {
  UpperHull xup, xdown, yup, ydown;
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    int x, y;
    char d[20];
    scanf("%d%d%1s", &x, &y, d);
    if (*d == 'R') {
      xup.addLine(0, x, 1);
      xdown.addLine(0, -x, -1);
      yup.addLine(0, y, 0);
      ydown.addLine(0, -y, 0);
    }
    else if (*d == 'L') {
      xup.addLine(0, x, -1);
      xdown.addLine(0, -x, 1);
      yup.addLine(0, y, 0);
      ydown.addLine(0, -y, 0);
    }
    else if (*d == 'U') {
      xup.addLine(0, x, 0);
      xdown.addLine(0, -x, 0);
      yup.addLine(0, y, 1);
      ydown.addLine(0, -y, -1);
    }
    else if (*d == 'D') {
      xup.addLine(0, x, 0);
      xdown.addLine(0, -x, 0);
      yup.addLine(0, y, -1);
      ydown.addLine(0, -y, 1);
    }
  }
  set<double> event_time;
  event_time.insert(0);
  addEvents(xup, event_time);
  addEvents(xdown, event_time);
  addEvents(yup, event_time);
  addEvents(ydown, event_time);
  double ans = (double)(xup.evaluate(0) + xdown.evaluate(0)) * (double)(yup.evaluate(0) + ydown.evaluate(0));
  for (auto I = event_time.begin(), IEnd = event_time.end(); I != IEnd; ++I) {
    auto J = I; ++J;
    if (J != IEnd) {
      double s = *I, e = (*J);
      for (int magic = 0; magic < 100; magic++) {
        double m1 = s + (e - s) / 3;
        double m2 = m1 + (e - m1) / 2;
        double a1 = (double)(xup.evaluate(m1) + xdown.evaluate(m1)) * (double)(yup.evaluate(m1) + ydown.evaluate(m1));
        double a2 = (double)(xup.evaluate(m2) + xdown.evaluate(m2)) * (double)(yup.evaluate(m2) + ydown.evaluate(m2));
        ans = min(ans, a1);
        ans = min(ans, a2);
        if (a1 < a2) {
          e = m2;
        }
        else {
          s = m1;
        }
      }
    }
    else {
      double a1 = (double)(xup.evaluate(*I) + xdown.evaluate(*I)) * (double)(yup.evaluate(*I) + ydown.evaluate(*I));
      ans = min(ans, a1);
    }
  }
  printf("%.10f\n", ans);
  return 0;
}


Measured memory_bytes: 384