/*
* Problem :: 12026 / BOJ 거
*
* Kind :: Dynamic Programming
*
* Insight
* - dp[i] = i 번째 칸으로 이동하는데 필요한 에너지 양의 최솟값
* + 이를 구하기 위해서는 0 ~ (i-1) 번째 칸을 살펴보며
* 그 칸부터 점프해서 dp[i] 칸에 도착할 때 드는 에너지 양의 최솟값을 찾으면 된다
* # 시간복잡도는 O(N^2) 이니 충분히 시간 제한 내에 풀 수 있다
* -> B, O, J, B, O, J, ... 순서로 보도블록을 밟는 조건을 고려하고
* 0 ~ (i-1) 번째 칸에서 i 번째 칸으로 이동할 때,
* 사전에 0 ~ (i-1) 번째 칸이 도착가능한 칸인지 확인해주자
*
* Point
* - dp 배열을 -1 로 초기화시켜서
* dp[i] 가 -1 이면 도착이 불가능한 칸으로 간주했다
*
* - 편의상 다음과 같이 생각했다.
* 1번 칸 = 0 번째 칸
* 2번 칸 = 1 번째 칸
* ...
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N; cin >> N;
string R; cin >> R;
// Process
map<char,char> P;
P['B'] = 'J'; /* 현재 보도블록이 'B' 이면 이전에 밟아야 하는 보도블록은 'J' 임 */
P['O'] = 'B'; /* 현재 보도블록이 'O' 이면 이전에 밟아야 하는 보도블록은 'B' 임 */
P['J'] = 'O'; /* 현재 보도블록이 'J' 이면 이전에 밟아야 하는 보도블록은 'O' 임 */
int dp[N]; /* dp[i] = i 번째 칸으로 이동하는데 필요한 에너지 양의 최솟값 */
fill(dp, dp+N, -1); /* dp 를 -1 로 초기화 */
dp[0] = 0; /* 0번째 칸 = 1번 칸 */
for (int i=1; i<N; i++) {
for (int j=0; j<i; j++) {
/* 현재 보도블록 기준 이전에 밟아야 하는 보도블록을 확인하고
* 그 보도블록 칸이 도착가능하다면 */
if (R[j] == P[R[i]] && dp[j] != -1) {
/* dp[i] 값이 한번도 갱신된 적 없거나 있더라도
* 그보다 더 적은 에너지만으로 i 번째 칸으로 이동할 수 있다면 */
if (dp[i] == -1 || dp[i] > dp[j] + (i-j)*(i-j)) {
dp[i] = dp[j] + (i-j)*(i-j); /* dp[i] 갱신 */
}
}
}
}
// Control : Output
cout << dp[N-1] << endl;
}
// Helper Functions
/* None */