CodeEff/ECCO huggingface dataset:
# Original solution
import sys
sys.setrecursionlimit(10**8)
def ii(): return int(sys.stdin.readline())
def mi(): return list(map(int, sys.stdin.readline().split()))
def li(): return list(map(int, sys.stdin.readline().split()))
def li2(N): return [list(map(int, sys.stdin.readline().split())) for i in range(N)]
def dp2(ini, i, j): return [[ini]*i for i2 in range(j)]
def dp3(ini, i, j, k): return [[[ini]*i for i2 in range(j)] for i3 in range(k)]
#import bisect #bisect.bisect_left(B, a)
#from collections import defaultdict #d = defaultdict(int) d[key] += value
#from collections import Counter # a = Counter(A).most_common()
#from itertools import accumulate #list(accumulate(A))

N, X = mi()
'''
def rec(level):
    if level == 0:
        return 'P'
    return 'B' + rec(level-1) + 'P' + rec(level-1) + 'B'

b = rec(N)
print(b)
'''
X -= 1
cnt = 0
level = N
while True:
    if level == 0:
        cnt += 1
        break
    half = 2**(level+1) - 2
    #print(level, half, cnt)
    if X == 0:
        break
    elif X == half * 2:
        cnt += 2**(level+1) - 1
        break
    elif X > half:
        cnt += 2**(level)
        X -= half + 1
    elif X == half:
        cnt += 2**(level)
        break 
    else:
        X -= 1
    level -= 1
print(cnt)

# Optimized solution
import sys
sys.setrecursionlimit(10**8)
def ii(): return int(sys.stdin.readline())
def mi(): return list(map(int, sys.stdin.readline().split()))
def li(): return list(map(int, sys.stdin.readline().split()))
def li2(N): return [list(map(int, sys.stdin.readline().split())) for i in range(N)]
def dp2(ini, i, j): return [[ini]*i for i2 in range(j)]
def dp3(ini, i, j, k): return [[[ini]*i for i2 in range(j)] for i3 in range(k)]
#import bisect #bisect.bisect_left(B, a)
#from collections import defaultdict #d = defaultdict(int) d[key] += value
#from collections import Counter # a = Counter(A).most_common()
#from itertools import accumulate #list(accumulate(A))

N, X = mi()

def rec(level, pos, score):
    #print(level, pos, score)
    if level == 0:
        return score + 1
    half = 2**(level+1) - 2
    if pos == 0:
        return score
    elif pos == half * 2:
        return score + 2**(level+1) - 1
    elif pos == half:
        return score + 2**(level)
    elif pos > half:
        score += 2**(level)
        pos -= half + 1
    else:
        pos -= 1
    return rec(level-1, pos, score)
    
X -= 1
print((rec(N, X, 0)))
# Original solution
n, x = list(map(int, input().split()))
# レベルごとの全体の枚数、パティの枚数を求める
a, p = [1], [1]
for i in range(n):
    a.append(2*a[i] + 3)
    p.append(2*p[i] + 1)
    
def f(n, x):
    if n == 0:
        return 0 if x <= 0 else 1
    # 3つの場合分け
    mid = (a[n]+1)/2
    if x == mid:
        return 1 + p[n-1]
    elif x < mid:
        return f(n-1, x-1)
    elif x > mid:
        return f(n-1, x-mid) + 1 + p[n-1]

print((f(n, x)))

# Optimized solution
# Lバーガーのパティの数はL-1バーガーのパティ*2 + 1枚
# Lバーガーのバンの数はL-1バーガーのバン*2 + 2枚
n, x = list(map(int, input().split()))
P = [1]
B = [0]
for _ in range(n):
    P.append(P[-1]*2+1)
    B.append(B[-1]*2+2)


# レベルLバーがの下からx層に含まれるパティの数
# B (L-1) P (L-1) B
def dfs(L, x):
    
    if L == 0:  # レベル0バーガーはパティ1枚のみ
        return 1
      
    l = P[L]+B[L]  # 厚さはP[i]+B[i](必ず奇数)
    mid = l//2 + 1
    
    if x == mid:  # どのレベルでも真ん中はパティ
        return 1 + P[L-1]
    elif x == 1:  # どのレベルでも一番下はバン
        return 0
    elif x == l:
        return 1 + P[L-1]*2        
    elif x < mid:
        return dfs(L-1, x-1) 
    elif x > mid:
        return dfs(L-1, x-1-(P[L-1]+B[L-1])-1) + 1 + P[L-1]

print((dfs(n, x)))
# Original solution
import sys
from functools import lru_cache


@lru_cache(maxsize=None)
def alg_memoization_recursion(lv, n, m):
    if lv == 0:
        if m <= 0:
            return 0
        else:
            return 1
    else:
        if (n + 1) // 2 == m:
            return alg_memoization_recursion(lv - 1, n // 2 - 1, m - 1) + 1
        elif (n + 1) // 2 > m:
            return alg_memoization_recursion(lv - 1, n // 2 - 1, m - 1)
        elif n == m:
            return alg_memoization_recursion(lv - 1, n // 2 - 1, n // 2 - 1) + alg_memoization_recursion(lv - 1, n // 2 - 1, m - (n // 2) - 1) + 1
        else:
            return alg_memoization_recursion(lv - 1, n // 2 - 1, n // 2 - 1) + alg_memoization_recursion(lv - 1, n // 2 - 1, m - (n // 2) - 1) + 1


def solve():
    input = sys.stdin.readline
    mod = 10 ** 9 + 7
    n, x = list(map(int, input().rstrip('\n').split()))
    t = 1
    for i in range(1, n + 1):
        t = 1 + t + 1 + t + 1
    print((alg_memoization_recursion(n, t, x)))


if __name__ == '__main__':
    solve()


# Optimized solution
import sys
from functools import lru_cache


@lru_cache(maxsize=None)
def func(num, pos):
    if num == 1:
        return 1
    elif pos == 1:
        return 0
    elif 1 < pos < (num + 2 - 1) // 2:
        return func((num - 3) // 2, pos - 1)
    elif pos == (num + 2 - 1) // 2:
        return func((num - 3) // 2, (num - 3) // 2) + 1
    elif (num + 2 - 1) // 2 < pos < num:
        return func((num - 3) // 2, (num - 3) // 2) + func((num - 3) // 2, pos - (num - 3) // 2 - 2) + 1
    elif pos == num:
        return func((num - 3) // 2, (num - 3) // 2) * 2 + 1


def solve():
    input = sys.stdin.readline
    mod = 10 ** 9 + 7
    n, x = list(map(int, input().rstrip('\n').split()))
    t = 1
    for i in range(n):
        t = t * 2 + 3
    print((func(t, x)))


if __name__ == '__main__':
    solve()
# Original solution
n,x=list(map(int,input().split()))
def b(j):
    return 2**(j+2)-3
def p(j):
    return 2**(j+1)-1
def f(n,x):
    if n==0:
        return 0 if x<=0 else 1
    elif x<=b(n-1)+1:
        return f(n-1,x-1)
    elif x==b(n-1)+2:
        return p(n-1)+1
    elif 2+b(n-1)<x<=2*b(n-1)+2:
        return p(n-1)+1+f(n-1,x-b(n-1)-2)
    else:
        return 2*p(n-1)+1
print((f(n,x)))

# Optimized solution
n,x=list(map(int,input().split()))
def b(j):
    return 2**(j+2)-3
def p(j):
    return 2**(j+1)-1
def f(n,x):
    if n==0:
        if x<=0:
            return 0
        else:
            return 1
    elif x<=b(n-1)+1:
        return f(n-1,x-1)
    elif x==b(n-1)+2:
        return p(n-1)+1
    elif 2+b(n-1)<x<=2*b(n-1)+2:
        return p(n-1)+1+f(n-1,x-b(n-1)-2)
    else:
        return 2*p(n-1)+1
print((f(n,x)))
# Original solution
n, x = list(map(int, input().split()))

A = [1] * (n + 1)
P = [1] * (n + 1)
for i in range(1, n + 1):
    A[i] = A[i - 1] * 2 + 3
    P[i] = P[i - 1] * 2 + 1


def pate(m, y):
    if m == 0:
        return 1
    else:
        c = 0

        if y >= 1:
            y -= 1

        if y >= 1:
            if y >= A[m - 1]:
                y -= A[m - 1]
                c += P[m - 1]
            else:
                c += pate(m - 1, y)
                y = 0

        if y >= 1:
            y -= 1
            c += 1

        if y >= 1:
            if y >= A[m - 1]:
                y -= A[m - 1]
                c += P[m - 1]
            else:
                c += pate(m - 1, y)
                y = 0

        if y >= 1:
            y -= 1

        return c


print((pate(n, x)))


# Optimized solution
n, x = list(map(int, input().split()))

A = [1] * (n + 1)
P = [1] * (n + 1)
for i in range(1, n + 1):
    A[i] = A[i - 1] * 2 + 3
    P[i] = P[i - 1] * 2 + 1

c = 0
for i in list(range(n+1))[::-1]:
    if i == 0:
        c += 1

    elif x == 1:
        break

    elif x <= A[i - 1] + 1:
        x -= 1

    elif x == A[i - 1] + 2:
        c += P[i - 1] + 1
        break

    elif x <= A[i] - 1:
        c += P[i - 1] + 1
        x -= A[i - 1] + 2

    elif x == A[i]:
        c += P[i]
        break

print(c)
# Original solution
n,x=list(map(int,input().split()))

a,p=[1],[1]
for i in range(n):
    a.append(a[i]*2+3)
    p.append(p[i]*2+1)


def f(n,x):
    if n==0:return 0 if x<=0 else 1
    elif x<=1+a[n-1]:
        return f(n-1,x-1)
    else:
        return p[n-1]+1+f(n-1,x-2-a[n-1])


print((f(n,x)))

# Optimized solution
def f(n,x):
    if n==0:return 0 if x<=0 else 1
    elif x<=1+a[n-1]:
        return f(n-1,x-1)
    else:
        return p[n-1]+1+f(n-1,x-2-a[n-1])


n,x=list(map(int,input().split()))
a,p=[1],[1]

for i in range(n):
    a.append(a[i]*2+3)
    p.append(p[i]*2+1)

print((f(n,x)))
# Original solution
def DFS(N,X):
    if N==0:return 0 if X<=0 else 1
    elif X<=1+B[N-1]:
        return DFS(N-1,X-1)
    else:
        return P[N-1]+1+DFS(N-1,X-2-B[N-1])


n,x=list(map(int,input().split()))
B,P=[1],[1]

for i in range(n):
    P.append(P[i]*2+1)
    B.append(B[i]*2+3)

print((DFS(n,x)))

# Optimized solution
def DFS(N,X):
    if N==0:return 1
    elif X==1:return 0
    elif 1<X<=1+B[N-1]:return DFS(N-1,X-1)
    elif X==2+B[N-1]:return P[N-1]+1
    elif 2+B[N-1]<X<=2+2*B[N-1]:return P[N-1]+1+DFS(N-1,X-2-B[N-1])
    elif X==2*B[N-1]+3:return 2*P[N-1]+1


n,x=list(map(int,input().split()))

P,B=[1],[1]
for i in range(n):
    P.append(P[i]*2+1)
    B.append(B[i]*2+3)

print((DFS(n,x)))
# Original solution
n, k = list(map(int, input().split(' ')))
lens = {}
lens[0] = 1
for i in range(1, 51):
  lens[i] = lens[i-1] * 2 + 3
memo = {}
def sumP(level, index):
  key = (level, index)
  if key in memo:
    return memo[key]
  if level == 0:
    if index == 1:
      memo[key] = 1
    else:
      memo[key] = 0
  elif index < lens[level] // 2 + 1:  # レベル一つ下の奴の一部分のみ
    memo[key] = sumP(level-1, index-1)
  elif index == lens[level] // 2 + 1:  # ど真ん中のPを入れて一つ下全部(index-1は左端のB)
    memo[key] = 1 + sumP(level-1, lens[level-1])
  else: # レベル一つ下の奴の丸々1つ + P + レベル一つ下の奴の一部分もしくは全部, minは最後のBを捨てるため
    memo[key] = sumP(level-1, lens[level-1]) + 1 + sumP(level-1, min(lens[level-1], index-lens[level-1]-2))
  return memo[key]

print((sumP(n, k)))

  

# Optimized solution
n, k = list(map(int, input().split(' ')))
lens = {0: 1}
for i in range(1, 51):
  lens[i] = lens[i-1] * 2 + 3
memo = {}
def sumP(level, index):
  key = (level, index)
  if key in memo:
    return memo[key]
  if level == 0:
    if index == 1:
      memo[key] = 1
    else:
      memo[key] = 0
  elif index < lens[level] // 2 + 1:  # レベル一つ下の奴の一部分のみ
    memo[key] = sumP(level-1, index-1)
  elif index == lens[level] // 2 + 1:  # ど真ん中のPを入れて一つ下全部(index-1は左端のB)
    memo[key] = 1 + sumP(level-1, lens[level-1])
  else: # レベル一つ下の奴の丸々1つ + P + レベル一つ下の奴の一部分もしくは全部, minは最後のBを捨てるため
    memo[key] = sumP(level-1, lens[level-1]) + 1 + sumP(level-1, min(lens[level-1], index-lens[level-1]-2))
  return memo[key]
 
print((sumP(n, k)))
# Original solution
#!/usr/bin/env python3
import sys
import functools
INF = float("inf")


@functools.lru_cache(None)
def hight(n):
    return 2**(n+2)-3


@functools.lru_cache(None)
def paty(n):
    return 2**(n+1)-1


def rec(n, x):
    # print(n, x)
    if n == 0:
        if x == 0:
            return 0
        else:
            return 1

    if x == 0:
        return 0
    elif x == 1:
        return 0
    elif x < hight(n-1)+2:
        return rec(n-1, x-1)
    elif x == hight(n-1)+2:
        return paty(n-1) + 1
    else:
        # print(paty(n-1)+1)
        return paty(n-1)+1 + rec(n-1, x-(hight(n-1)+2))


def solve(N: int, X: int):
    print((rec(N, X)))

    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    X = int(next(tokens))  # type: int
    solve(N, X)


if __name__ == '__main__':
    main()


# Optimized solution
#!/usr/bin/env python3
import sys
import functools
INF = float("inf")


@functools.lru_cache(None)
def hight(n):
    if n == 0:
        return 1
    else:
        return 2*hight(n-1)+3


@functools.lru_cache(None)
def paty(n):
    if n == 0:
        return 1
    else:
        return 2*paty(n-1)+1


def rec(n, x):
    # print(n, x)
    if n == 0:
        if x == 0:
            return 0
        else:
            return 1

    if x == 0:
        return 0
    elif x == 1:
        return 0
    elif x < hight(n-1)+2:
        return rec(n-1, x-1)
    elif x == hight(n-1)+2:
        return paty(n-1) + 1
    else:
        # print(paty(n-1)+1)
        return paty(n-1)+1 + rec(n-1, x-(hight(n-1)+2))


def solve(N: int, X: int):
    print((rec(N, X)))

    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    X = int(next(tokens))  # type: int
    solve(N, X)


if __name__ == '__main__':
    main()
# Original solution
n, x = list(map(int, input().split()))
 
P = [0] * (n + 1)
P[0] = 1
for i in range(1, n + 1):
    P[i] = P[i - 1] * 2 + 1

A = [0] * (n + 1)
A[0] = 1
for i in range(1, n + 1):
    A[i] = A[i - 1] * 2 + 3

#print(P)
#print(A)
 
def dfs(n, x):
    if n == 0:
        return 1
    if x == 1:
        return 0
    elif x <= 1 + A[n - 1]:
        return dfs(n - 1, x - 1)
    elif x == 1 + A[n - 1] + 1:
        return P[n - 1] + 1
    elif 1 + A[n - 1] + 1 < x < 1 + A[n - 1] + 1 + A[n - 1] + 1:
        return P[n - 1] + 1 + dfs(n - 1, x - 1 - A[n - 1] - 1)
    elif x >= 1 + A[n - 1] + 1 + A[n - 1] + 1:
        return P[n - 1] + 1 + P[n - 1]
    
print((dfs(n, x)))    

# Optimized solution
n, x = list(map(int, input().split()))
 
P = [0] * (n + 1)
P[0] = 1
for i in range(1, n + 1):
    P[i] = P[i - 1] * 2 + 1

A = [0] * (n + 1)
A[0] = 1
for i in range(1, n + 1):
    A[i] = A[i - 1] * 2 + 3

#print(P)
#print(A)
 
def dfs(n, x):
    if n == 0:
        return 1
    if x == 1:
        return 0
    elif 1 < x <= 1 + A[n - 1]:
        return dfs(n - 1, x - 1)
    elif x == 1 + A[n - 1] + 1:
        return P[n - 1] + 1
    elif 1 + A[n - 1] + 1 < x < 1 + A[n - 1] + 1 + A[n - 1] + 1:
        return P[n - 1] + 1 + dfs(n - 1, x - 1 - A[n - 1] - 1)
    elif x >= 1 + A[n - 1] + 1 + A[n - 1] + 1:
        return P[n - 1] + 1 + P[n - 1]
    
print((dfs(n, x)))
# Original solution
from bisect import bisect
N = int(eval(input()))
B = []
BW = []; BB = []
MB = {}; MW = {}
for i in range(2*N):
    c, a = input().split()
    a = int(a)
    c = "BW".index(c)
    B.append((c, a))
    if c:
        MW[a-1] = i
    else:
        MB[a-1] = i

P = [[0]*(N+1) for i in range(N+1)]
Q = [[0]*(N+1) for i in range(N+1)]

for p in range(N):
    cnt = MW[p] - sum(MW[p0] < MW[p] for p0 in range(p))

    P[p][0] = cnt
    for q in range(N):
        if MB[q] < MW[p]:
            cnt -= 1
        P[p][q+1] = cnt

for q in range(N):
    cnt = MB[q] - sum(MB[q0] < MB[q] for q0 in range(q))

    Q[q][0] = cnt
    for p in range(N):
        if MW[p] < MB[q]:
            cnt -= 1
        Q[q][p+1] = cnt

dist = [[10**9]*(N+1) for i in range(N+1)]
dist[0][0] = 0
que = [(0, 0, 0)]
for i in range(N):
    dist[i+1][0] = dist[i][0] + P[i][0]
for i in range(N):
    dist[0][i+1] = dist[0][i] + Q[i][0]
for i in range(N):
    for j in range(N):
        dist[i+1][j+1] = min(dist[i][j+1] + P[i][j+1], dist[i+1][j] + Q[j][i+1])
print((dist[N][N]))


# Optimized solution
N = int(eval(input()))
MB = {}; MW = {}
for i in range(2*N):
    c, a = input().split()
    c = "BW".index(c); a = int(a)
    if c:
        MW[a-1] = i
    else:
        MB[a-1] = i

P = [[0]*(N+1) for i in range(N+1)]
Q = [[0]*(N+1) for i in range(N+1)]

for p in range(N):
    cnt = MW[p] - sum(MW[p0] < MW[p] for p0 in range(p))

    P[p][0] = cnt
    for q in range(N):
        if MB[q] < MW[p]:
            cnt -= 1
        P[p][q+1] = cnt

for q in range(N):
    cnt = MB[q] - sum(MB[q0] < MB[q] for q0 in range(q))

    Q[q][0] = cnt
    for p in range(N):
        if MW[p] < MB[q]:
            cnt -= 1
        Q[q][p+1] = cnt

dp = [[10**9]*(N+1) for i in range(N+1)]
dp[0][0] = 0
for i in range(N):
    dp[i+1][0] = dp[i][0] + P[i][0]
for i in range(N):
    dp[0][i+1] = dp[0][i] + Q[i][0]
for i in range(N):
    for j in range(N):
        dp[i+1][j+1] = min(dp[i][j+1] + P[i][j+1], dp[i+1][j] + Q[j][i+1])
print((dp[N][N]))
# Original solution
from itertools import accumulate


def solve(n, rev):
    def existence_right(rev_c):
        n2 = n * 2
        acc = [[0] * n2]
        row = [0] * n2
        for x in rev_c:
            row[n2 - x - 1] += 1
            acc.append(list(reversed(list(accumulate(row)))))
        return acc

    # How many white/black ball lower than 'k' righter than index x? (0<=x<=2N-1)
    # cost[color][k][x]
    cost = list(map(existence_right, rev))

    dp = [0] + list(accumulate(c[y] for y, c in zip(rev[1], cost[1])))
    for x, cw0, cw1 in zip(rev[0], cost[0], cost[0][1:]):
        ndp = [0] * (n + 1)
        cw0x = cw0[x]
        ndp[0] = prev = dp[0] + cw0x
        for b, (y, cb0, cb1) in enumerate(zip(rev[1], cost[1], cost[1][1:])):
            ndp[b + 1] = prev = min(dp[b + 1] + cw0x + cb1[x], prev + cw1[y] + cb0[y])
        dp = ndp
    return dp[n]


n = int(eval(input()))
# White/Black 'k' ball is what-th in whole row?
rev = [[0] * n, [0] * n]
for i in range(n * 2):
    c, a = input().split()
    a = int(a) - 1
    rev[int(c == 'B')][a] = i
print((solve(n, rev)))


# Optimized solution
from itertools import accumulate


def solve(n, rev):
    def existence_right(rev_c):
        n2 = n * 2
        acc = [[0] * n2]
        row = [0] * n2
        for x in rev_c:
            row[n2 - x - 1] += 1
            acc.append(list(reversed(list(accumulate(row)))))
        return acc

    # How many white/black ball lower than 'k' righter than index x? (0<=x<=2N-1)
    # cost[color][k][x]
    cost_w, cost_b = list(map(existence_right, rev))

    dp = [0] + list(accumulate(c[y] for y, c in zip(rev[1], cost_b)))
    for w, x in enumerate(rev[0]):
        ndp = [0] * (n + 1)
        cwx = cost_w[w][x]
        ndp[0] = prev = dp[0] + cwx
        for b, y in enumerate(rev[1]):
            ndp[b + 1] = prev = min(dp[b + 1] + cwx + cost_b[b + 1][x],
                                    prev + cost_w[w + 1][y] + cost_b[b][y])
        dp = ndp
    return dp[n]


n = int(eval(input()))
# White/Black 'k' ball is what-th in whole row?
rev = [[0] * n, [0] * n]
for i in range(n * 2):
    c, a = input().split()
    a = int(a) - 1
    rev[int(c == 'B')][a] = i
print((solve(n, rev)))
# Original solution
def main():
    from sys import stdin
    input = stdin.readline

    n = int(eval(input()))
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a, int(b)-1) for a, b in ab]
    dct = {(a, b): i for i, (a, b) in enumerate(ab)}

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a == "B":
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct[("B", i)]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct[("W", j)]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print((dp[n][n]))


main()


# Optimized solution
def main():
    from sys import stdin
    input = stdin.readline

    n = int(eval(input()))
    ab = [list(input().split()) for _ in [0]*(2*n)]
    ab = [(a == "B", int(b)-1) for a, b in ab]
    dct_b = [0]*n
    dct_w = [0]*n
    for i, (a, b) in enumerate(ab):
        if a:
            dct_b[b] = i
        else:
            dct_w[b] = i

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    # 左i個にあるj以上のボールの数
    lb = [[0]*(n+1) for _ in [0]*(2*n)]
    lw = [[0]*(n+1) for _ in [0]*(2*n)]

    for j in range(n):
        cnt1, cnt2 = 0, 0
        for i, (a, b) in enumerate(ab):
            lb[i][j] = cnt1
            lw[i][j] = cnt2
            if a:
                if b >= j:
                    cnt1 += 1
            else:
                if b >= j:
                    cnt2 += 1

    dp = [[10**9]*(n+1) for _ in [0]*(n+1)]  # dp[i][j] = Bをi個、Wをj個置くための最小手数
    dp[0][0] = 0

    for i in range(n+1):
        dp1 = dp[i]
        if i < n:
            dp2 = dp[i+1]
            t = dct_b[i]
        for j in range(n+1):
            d = dp1[j]
            if i < n:
                dp2[j] = min(dp2[j], d+lb[t][i]+lw[t][j])
            if j < n:
                t2 = dct_w[j]
                dp1[j+1] = min(dp1[j+1], d+lb[t2][i]+lw[t2][j])
    print((dp[n][n]))


main()
# Original solution
n = int(eval(input()))
INF = 10 ** 9
info = [list(input().split()) for i in range(2 * n)]

ind = {}
for i in range(2 * n):
    info[i] = (info[i][0], int(info[i][1]))
    ind[info[i]] = i

ru_b = [[0] * (2 * n + 1) for i in range(n + 1)]
ru_w = [[0] * (2 * n + 1) for i in range(n + 1)]
for i in range(n + 1):
    for j in range(2 * n):
        col, num = info[j]
        if col == "B" and num > i:
            ru_b[i][j + 1] += 1
        if col == "W" and num > i:
            ru_w[i][j + 1] += 1
    for j in range(2 * n):
        ru_b[i][j + 1] += ru_b[i][j]
        ru_w[i][j + 1] += ru_w[i][j]    


dp = [[INF] * (n + 1) for i in range(n + 1)]
dp[0][0] = 0
for i in range(n + 1):
    for j in range(n + 1):
        if i + 1 <= n and j <= n:
            bi = ind[("B", i + 1)]
            dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + ru_b[i][bi] + ru_w[j][bi])
        if i <= n and j + 1 <= n:
            wi = ind[("W", j + 1)]
            dp[i][j + 1] = min(dp[i][j + 1], dp[i][j] + ru_w[j][wi] + ru_b[i][wi])

print((dp[-1][-1]))

# Optimized solution
import sys
input = sys.stdin.readline


n = int(eval(input()))
INF = 10 ** 9
info = [list(input().split()) for i in range(2 * n)]

ind = {}
for i in range(2 * n):
    if info[i][0] == "B":
        info[i] = (0, int(info[i][1]))
    else:
        info[i] = (1, int(info[i][1]))
    ind[info[i][0] * 10 ** 5 + info[i][1]] = i

ru_b = [[0] * (2 * n + 1) for i in range(n + 1)]
ru_w = [[0] * (2 * n + 1) for i in range(n + 1)]
for i in range(n + 1):
    for j in range(2 * n):
        col, num = info[j]
        if col == 0 and num > i:
            ru_b[i][j + 1] += 1
        elif col == 1 and num > i:
            ru_w[i][j + 1] += 1
    for j in range(2 * n):
        ru_b[i][j + 1] += ru_b[i][j]
        ru_w[i][j + 1] += ru_w[i][j]    


dp = [[INF] * (n + 1) for i in range(n + 1)]
dp[0][0] = 0
for i in range(n + 1):
    for j in range(n + 1):
        if i + 1 <= n and j <= n:
            bi = ind[i + 1]
            dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + ru_b[i][bi] + ru_w[j][bi])
        if i <= n and j + 1 <= n:
            wi = ind[10 ** 5 + j + 1]
            dp[i][j + 1] = min(dp[i][j + 1], dp[i][j] + ru_w[j][wi] + ru_b[i][wi])

print((dp[-1][-1]))
# Original solution
p = 10**9+7
N = int(eval(input()))
S1 = input().strip()
S2 = input().strip()
cnt = 1
cur = 0
if N>=2 and S1[0]==S1[1]:
    cnt = cnt*6
    cur = 2
else:
    cnt = cnt*3
    cur = 1
while cur<N:
    if cur<N-1 and S1[cur]==S1[cur+1]:
        if S1[cur-1]==S2[cur-1]:
            cnt = (cnt*2)%p
            cur += 2
        else:
            cnt = (cnt*3)%p
            cur += 2
    elif S1[cur-1]==S2[cur-1]:
        cnt = (cnt*2)%p
        cur += 1
    elif cur>=2 and S1[cur-2]==S1[cur-1]:
        cur += 1
print(cnt)    

# Optimized solution
p = 10**9+7
N = int(eval(input()))
S1 = input().strip()
S2 = input().strip()
cnt = 1
cur = 0
if S1[0]==S2[0]:
    cnt = 3
    cur += 1
else:
    cnt = 6
    cur += 2
while cur<N:
    if S1[cur]==S2[cur]:
        if S1[cur-1]==S2[cur-1]:
            cnt = (cnt*2)%p
        cur += 1
    else:
        if S1[cur-1]==S2[cur-1]:
            cnt = (cnt*2)%p
        else:
            cnt = (cnt*3)%p
        cur += 2
print(cnt)