/*Bismillahir Rahmanir Rahim*///{
#include <bits/stdc++.h>
using namespace std;
using ll = long long; using ull = unsigned long long; using ld = long double;
const ll llinf = (1ll<<61)-1;
const double eps = 1e-6, ldeps = 1e-9;
struct Dbg {
static constexpr auto &os = cout;   // replace by cerr in interactive.
template<class C> static auto dud(C *x)->decltype(os << *x, 0);
template<class C> static char dud(...);
template<class C> typename enable_if<sizeof dud<C>(0)!=1, Dbg&>::type operator<<(const C &x) { os << x; return *this; }
template<class C> Dbg &dump(C b, C e) {
    *this << "\n[";
    int cur = 0;
    for (C i = b; i!=e and cur<26; i++, cur++) *this << ", "+2*(i==b) << *i;
    return *this << ']';
}
template<class C> typename enable_if<sizeof dud<C>(0)==1, Dbg&>::type operator<<(const C &x) {
    return dump(begin(x), end(x));
}
template<class C, size_t X> typename enable_if<!is_same<C, const char>::value, Dbg&>::type operator <<(C (&x)[X]) {
    return dump(begin(x), end(x));
}
template<class B, class C> Dbg &operator <<(const pair<B, C> &x) {
    return *this << '{' << x.first << ", " << x.second << '}';
}
template<class C, size_t Y> struct TP {
    void operator()(Dbg& os, const C &t) { TP<C, Y-1>()(os, t); os << ", " << get<Y-1>(t); }
};
template<class C> struct TP<C, 1> { void operator()(Dbg& os, const C &t) { os << get<0>(t); } };
template<class... C> Dbg& operator<<(const tuple<C...> &t) {
    os << '{', TP<decltype(t), sizeof...(C)>()(*this, t); return *this << '}';
}
Dbg &operator<<(ostream&(*x)(std::ostream&)) { os << x; return *this; }
} dbg;
void err(istringstream *iss) { delete iss; }
template<class C, class... Args> void err(istringstream *iss, const C &val, const Args &... args) {
    string name; *iss >> name; if (name.back()==',') name.pop_back();
    dbg << name << " = " << val << "; ", err(iss, args ...);
}
#define bug(args...) dbg << __LINE__ << ": ", err(new istringstream(string(#args)), args), dbg << endl
#define ASSERT(a, o, b) { if (!((a) o (b))) bug(a, b), assert((a) o (b)); }
#define sl(a) int(strlen(a))
#define sz(a) int(a.size())
int T, Q, cn;//}
const int inf = 1000000007, mxn = 2005;

template <class T> class BIT//{
{
    vector<T> tree;
public:
    int N, mnIdx;
    BIT(int _n, int _mnIdx) : N(_n), mnIdx(_mnIdx) {   // mnIdx<actual & N>actual hole no problem
        tree.resize(N+2);
    }

    void reset() {fill_n(tree.begin(), N+2, 0);}

    void addAtIdx(int idx, T val) {idx+=1-mnIdx;
        while (idx<=N) tree[idx] += val, idx += (idx & -idx);
    }

    T prefixSum(int idx) {idx+=1-mnIdx;
        T sum = 0;
        while (idx>0) sum += tree[idx], idx -= (idx & -idx);
        return sum;
    }

    T rangeSum(int l, int r) {
        return prefixSum(r)-prefixSum(l-1);
    }

    // upper_bound(x)==lower_bound(x+1) in non-fraction.
    int lower_bound(T x) { // returns mnIdx+N if no >= found
        int idx = 0, mask = 1<<(31^__builtin_clz(N)), ret = N+1, tIdx;
        while (mask) {
            tIdx = idx+mask, mask >>= 1;
            if (tIdx>=N || tIdx<=0) continue;
            if (tree[tIdx]>=x) ret = min(ret, tIdx); else idx = tIdx, x -= tree[tIdx];
        }ret-=1-mnIdx;
        return ret;
    }

    void multiplyAll(T c) {   // to divide all replace * by /
        for (int i = 1; i <= N; i++) tree[i] *= c;
    }
};//}

vector<BIT<int>> ft(2, BIT<int>(mxn, 0));

int n, a[mxn<<1|1], pos[2][mxn], cnt[2][mxn][mxn<<1|1], dp[mxn][mxn];
char c[mxn<<1|1];

signed main() { ios::sync_with_stdio(0); cin.tie(NULL); cout.precision(11);
/* We can count inversion between same color easily, which we will have to eliminate any way. After that: Easy to find
dp[whiteTaken][blackTaken] with only caring about swapping between different colors: When x whiteBalls have been taken,
in order to take the yth blackBall, we need to cross (number of whiteBalls to its left - number of whiteBalls<=x to its left),
both of which can be precalced.*/

    cin >> n;
    int inversionSameColor = 0;
    for (int i = 1; i <= n<<1; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < mxn; k++) {
                cnt[j][k][i] = cnt[j][k][i-1];
            }
        }
        cin >> c[i] >> a[i];
        bool o = c[i]=='B';
        for (int j = a[i]; j <= mxn-1; j++) {
            cnt[o][j][i]++;
        }
        pos[o][a[i]] = i;
        inversionSameColor += ft[o].rangeSum(a[i]+1, mxn-1);
        ft[o].addAtIdx(a[i], 1);
    }
    for (int i = n; i >= 0; i--) {
        for (int j = n; j >= 0; j--) {
            int at = i+j+1;
            if (at>n<<1) {dp[i][j] = 0; continue;}
            dp[i][j] = inf;
            if (i<n) dp[i][j] = min(dp[i][j], max(cnt[1][n][pos[0][i+1]]-cnt[1][j][pos[0][i+1]], 0)+dp[i+1][j]);
            if (j<n) dp[i][j] = min(dp[i][j], max(cnt[0][n][pos[1][j+1]]-cnt[0][i][pos[1][j+1]], 0)+dp[i][j+1]);
        }
    }
    cout << inversionSameColor+dp[0][0] << '\n';
}

Measured memory_bytes: 78848