//  [rust]
#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{self, prelude::*};

fn gcd(a: u64, b: u64) -> u64 {
    let mut a = a;
    let mut b = b;
    if a < b {
        let temp = b;
        b = a;
        a = temp
    }
    while b != 0 {
        let r = a%b;
        a = b;
        b = r;
    }
    a
}

fn gcd3 (a: u64, b: u64, c: u64) -> u64 {
    gcd(a,gcd(b,c))
}

#[allow(unused_must_use)]
#[allow(unused_assignments)]
#[allow(unused_variables)]
fn solve<B: BufRead, W: Write>(mut scan: Scanner<B>, mut w: W) {
    let a = ['R','G','B'];
    let n: usize = scan.token();
    let s: Vec<char> = scan.token::<String>().chars().collect();

    let mut ans = 0;
    for i in 1..(n-1) {
        let c = s[i];
        let mut c1 = '0';
        let mut c2 = '0';
        if s[i] == 'R' {
            c1 = 'G'; c2 = 'B';
        } 
        if s[i] == 'G' {
            c1 = 'B'; c2 = 'R';
        } 
        if s[i] == 'B' {
            c1 = 'R'; c2 = 'G';
        } 
        let left = &s[0..i];
        let right = &s[i+1..];
        let mut c1vl: Vec<usize> = Vec::new();
        let mut c2vl: Vec<usize> = Vec::new();
        for (i, &e) in left.iter().rev().enumerate() {
            if e == c1 {
                c1vl.push(i);
            }
            if e == c2 {
                c2vl.push(i);
            }
        }
        let mut c1vr: Vec<usize> = Vec::new();
        let mut c2vr: Vec<usize> = Vec::new();
        for (i, &e) in right.iter().enumerate() {
            if e == c1 {
                c1vr.push(i);
            }
            if e == c2 {
                c2vr.push(i);
            }
        }
        ans += c1vl.len()*c2vr.len() + c2vl.len()* c1vr.len();
        for i in 0..c2vr.len() {
            if c1vl.contains(&c2vr[i]) {
                ans -= 1;
            }
        }
        for i in 0..c2vl.len() {
            if c1vr.contains( &c2vl[i] ) {
                ans -= 1;
            }
        }
    }
    
    writeln!(w, "{}", ans);
}
 
fn main() {
    let stdin = io::stdin();
    let stdout = io::stdout();
    let reader = Scanner::new(stdin.lock());
    let writer = io::BufWriter::new(stdout.lock());
    solve(reader, writer);
}
#[allow(dead_code)]
fn vector_to_str<T: ToString>(vector: &Vec<T>, separator: &str) -> String { 
    use std::fmt::Write;
    let mut ans = String::new();
    for line in vector.iter() {
        write!(&mut ans, "{}{}", line.to_string(), separator).unwrap();
    }
    ans
}
#[allow(dead_code)]
fn matrix_to_str<T: ToString>(matrix: &Vec<Vec<T>>, separator: &str) -> String { 
    use std::fmt::Write;
    let mut ans = String::new();
    for line in matrix.iter() {
        for elem in line.iter() {
            write!(&mut ans, "{}{}", elem.to_string(), separator).unwrap();
        }
        write!(&mut ans, "\n").unwrap();
    }
    ans
}
pub struct Scanner<B> {
    reader: B,
    buf_str: Vec<u8>,
    buf_iter: std::str::SplitWhitespace<'static>,
}
impl<B: BufRead> Scanner<B> {
    pub fn new(reader: B) -> Self {
        Self {
            reader,
            buf_str: Vec::new(),
            buf_iter: "".split_whitespace()
        }
    }
    pub fn token<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buf_iter.next() {
                return token.parse().ok().expect("Failed parse");
            }
            self.buf_str.clear();
            self.reader.read_until(b'\n', &mut self.buf_str).expect("Failed read");
            self.buf_iter = unsafe {
                let slice = std::str::from_utf8_unchecked(&self.buf_str);
                std::mem::transmute(slice.split_whitespace()) }
        }
    }
    pub fn get_matrix<T: std::str::FromStr>(&mut self, m: usize, n: usize) -> Vec<Vec<T>> {
        // m rows and n columns
        let mut ans: Vec<Vec<T>> = Vec::with_capacity(m);
        for i in 0..m {
            ans.push(Vec::with_capacity(n));
            for _ in 0..n {
                ans[i].push(self.token::<T>());
            }
        }
        ans
    }
    pub fn get_vector<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        let mut ans: Vec<T> = Vec::with_capacity(n);
        for _ in 0..n {
            ans.push(self.token::<T>());
        }
        ans
    }
}