#include "bits/stdc++.h"
using namespace std;
template<typename dataT>
struct nodeT{
    dataT val;
    nodeT<dataT> *left, *right;
    nodeT(){
        left = nullptr;
        right = nullptr;
        val = dataT();
    }
    nodeT(dataT v){
        nodeT();
        val = v;
    }
    dataT get_val(){
        return val;
    }
    void set_val(dataT x){
        val = x;
    }
    void add_to_val(dataT x){
        val = val + x;
    }
    void update(){
        val = dataT();
        if(left) val = val + left->get_val();
        if(right) val = val + right->get_val();
    }
};
template<typename dataT, typename boundT = int, boundT leftBound = 0, boundT rightBound = 100100>
struct dynamic_tree{
    using node = nodeT<dataT>;
    virtual node * get_node(node * before){
        if(before) return before;
        node * new_node = new node();
        return new_node;
    }
    node * root;
    void clear(){
        root = nullptr;
    }
    dynamic_tree(){
        clear();
    }
    node * get_root(){
        return root;
    }
    node * set_pos(node * cur, boundT l, boundT r, boundT pos, dataT val){
        cur = get_node(cur);
        if(l == r) cur->set_val(val);
        else{
            boundT mid = (l + r)>>1;
            if(pos <= mid) cur->left = set_pos(cur->left, l, mid, pos, val);
            else cur->right = set_pos(cur->right, mid + 1, r, pos, val);
            cur->update();
        }
        return cur;
    }
    node * set_pos(boundT pos, dataT val){
        root = set_pos(root, leftBound, rightBound, pos, val);
        return root;
    }
    node * set_pos(node * rt, boundT pos, dataT val){
        return set_pos(rt, leftBound, rightBound, pos, val);
    }
    node * add_to_pos(node * cur, boundT l, boundT r, boundT pos, dataT val){
        cur = get_node(cur);
        if(l == r) cur->add_to_val(val);
        else{
            boundT mid = (l + r)>>1;
            if(pos <= mid) cur->left = add_to_pos(cur->left, l, mid, pos, val);
            else cur->right = add_to_pos(cur->right, mid + 1, r, pos, val);
            cur->update();
        }
        return cur;
    }
    node * add_to_pos(boundT pos, dataT val){
        root = add_to_pos(root, leftBound, rightBound, pos, val);
        return root;
    }
    node * add_to_pos(node * rt, boundT pos, dataT val){
        return add_to_pos(rt, leftBound, rightBound, pos, val);
    }
    dataT query(node * cur, boundT l, boundT r, boundT x, boundT y){
        if(cur == nullptr || l > y || r < x) return dataT();
        if(x <= l && r <= y) return cur->get_val();
        boundT mid = (l + r)>>1;
        if(y <= mid) return query(cur->left, l, mid, x, y);
        if(x > mid) return query(cur->right, mid + 1, r, x, y);
        return query(cur->left, l, mid, x, y) + query(cur->right, mid + 1, r, x, y);
    }
    dataT query(boundT x, boundT y){
        return query(root, leftBound, rightBound, x, y);
    }
    dataT query(node * rt, boundT x, boundT y){
        return query(rt, leftBound, rightBound, x, y);
    }
};
template<typename dataT, typename boundT = int, boundT leftBound = 0, boundT rightBound = 100100>
struct persistent_tree : dynamic_tree<dataT, boundT, leftBound, rightBound>{
    using node = nodeT<dataT>;
    node * get_node(node * before) override {
        node * new_node = new node();
        if(before){
            new_node->left = before->left;
            new_node->right = before->right;
            new_node->val = before->val;
        }
        return new_node;
    }
    persistent_tree(): dynamic_tree<dataT, boundT, leftBound, rightBound> (){
    }
};
const int maxn = 4222;
using tree = persistent_tree<int, int, 0, maxn>;
tree rts[2][maxn];
char ty[maxn];
int val[maxn], pos[2][maxn];
int dp[maxn][maxn];
int n;
int solve(int cur, int wh){
	if(cur == 2 * n) return 0;
	if(dp[cur][wh] != -1) return dp[cur][wh];
	int bl = cur - wh;
	int res = maxn * maxn + 200;
	if(wh != n){
		int npos = pos[0][wh+1]
				+ rts[0][wh].query(pos[0][wh+1], maxn - 1)
				+ rts[1][bl].query(pos[0][wh+1], maxn - 1);
		res = min(res, npos - cur + solve(cur + 1, wh + 1));
	}
	if(bl != n){
		int npos = pos[1][bl+1]
				+ rts[0][wh].query(pos[1][bl+1], maxn - 1)
				+ rts[1][bl].query(pos[1][bl+1], maxn - 1);
		res = min(res, npos - cur + solve(cur + 1, wh));
	}
	return dp[cur][wh] = res;
}
int main(){
	cin >> n;
	for(int e = 0; e < 2 * n; e++){
		cin >> ty[e] >> val[e];
		ty[e] = ty[e] == 'B';
		pos[ty[e]][val[e]] = e;
	}
	for(int f = 0; f < 2; f++)
		for(int e = 1; e <= n; e++){
			rts[f][e].root = rts[f][e-1].get_root();
			rts[f][e].set_pos(pos[f][e], 1);
		}
	memset(dp, -1, sizeof(dp));
	cout << solve(0, 0) << endl;
    return 0;
}


Measured memory_bytes: 72704