#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define int ll

template<typename T1,typename T2> inline void chmin(T1 &a, T2 b){ if(a > b) a = b; }
template<typename T1,typename T2> inline void chmax(T1 &a, T2 b){ if(a < b) a = b; }

#define REP(i,n) for(int i=0;i<n;++i)
#define SORT(name) sort(name.begin(), name.end())
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
#if 1
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
const int MOD = 1000000007;
const int MAX_N = 4001;

template< typename T >
class CumulativeSum
{
public:
    CumulativeSum() {}
    CumulativeSum(int sz) : m_Data(sz, T(0)) {};

    void Init(int sz) { m_Data.assign(sz, T(0)); }

    // k に x を加える O(1)
    void Add(int k, T x) {
        assert(static_cast<int>(m_Data.size()) >= k);
        if(static_cast<int>(m_Data.size()) <= k) { m_Data.push_back(x); }
        else { m_Data[k] = (m_Data[k] + x); }
    }

    // 累積和の構築 O(m_Data.size())
    void Build() {
        for(int i = 1; i < static_cast<int>(m_Data.size()); i++) {
            m_Data[i] = (m_Data[i] + m_Data[i - 1]);
        }
    }

    // 区間 [0, k] の和を返す O(1)
    // 閉区間なので k が含まれることに注意
    T Query(int k) {
        if(k < 0) { return T(0); }
        return (m_Data[min(k, static_cast<int>(m_Data.size()) - 1)]);
    }

    // 区間 [l, h] の和を返す O(1)
    // 閉区間なので k が含まれることに注意
    T Query(int l, int h) {
        return (this->Query(h) - this->Query(l-1));
    }
private:
    vector< T > m_Data;
};

int N;
string S;

signed main() {
    cin.tie(0); cout.tie(0);
    ios::sync_with_stdio(false);

    cin >> N >> S;

    CumulativeSum<int> cs_r(N), cs_g(N), cs_b(N);
    REP(i, S.length()) {
        if(S[i] == 'R') { cs_r.Add(i, 1); }
        if(S[i] == 'G') { cs_g.Add(i, 1); }
        if(S[i] == 'B') { cs_b.Add(i, 1); }
    }
    cs_r.Build();
    cs_g.Build();
    cs_b.Build();

    int ans = 0;
    REP(i, S.length()) {
        bool isR = false, isG = false, isB = false;
        if(S[i] == 'R') { isR = true; }
        if(S[i] == 'G') { isG = true; }
        if(S[i] == 'B') { isB = true; }
        for(int j = i + 1; j < N - 1; ++j) {
            int dist = j - i;
            int cand = 0;
            if(isR) {
                if(S[j] == 'G') {
                    cand = cs_b.Query(j + 1, N - 1);
                    if(cand > 0 && j + dist < N && S[j + dist] == 'B') { cand--; }
                }
                else if(S[j] == 'B') {
                    cand = cs_g.Query(j + 1, N - 1);
                    if(cand > 0 && j + dist < N&& S[j + dist] == 'G') { cand--; }
                }
            }
            else if(isG) {
                if(S[j] == 'R') {
                    cand = cs_b.Query(j + 1, N - 1);
                    if(cand > 0 && j + dist < N&& S[j + dist] == 'B') { cand--; }
                }
                else if(S[j] == 'B') {
                    cand = cs_r.Query(j + 1, N - 1);
                    if(cand > 0 && j + dist < N&& S[j + dist] == 'R') { cand--; }
                }
            }
            else {
                if(S[j] == 'R') {
                    cand = cs_g.Query(j + 1, N - 1);
                    if(cand > 0 && j + dist < N&& S[j + dist] == 'G') { cand--; }
                }
                else if(S[j] == 'G') {
                    cand = cs_r.Query(j + 1, N - 1);
                    if(cand > 0 && j + dist < N&& S[j + dist] == 'R') { cand--; }
                }
            }
            ans += cand;
        }
    }
    printf("%lld\n", ans);

    return 0;
}


Measured memory_bytes: 3812