package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var s = bufio.NewScanner(os.Stdin)

func getInt() int {
	s.Scan()
	n, _ := strconv.Atoi(s.Text())
	return n
}

func main() {
	s.Split(bufio.ScanWords)
	n := getInt()

	h := make([]int, n)
	for i := 0; i < n; i++ {
		h[i] = getInt()
	}
	fmt.Println(h)
	count := 0
	ans := 0
	for i := 1; i < n; i++ {
		for j := 0; j < i; j++ {
			if h[i] >= h[j] {

			} else {
				count++
				break
			}
		}
		if count == 0 {
			ans++
		}
		count = 0
	}
	fmt.Println(ans + 1)
}


# b
n = gets.to_i
h = gets.split.map(&:to_i)
m = h[0]

cnt = 0
h.each do |hh|
  if hh >= m
    cnt += 1
    m = hh
  end
end
p cnt


n = gets.to_i
h = gets.chomp.split.map(&:to_i)
res = 1
top = h[0]
(1...n).each do |i|
  res += 1 if top <= h[i]
  top = h[i] if h[i] > top
end
puts res


# frozen_string_literal: true

_ = gets
h = gets.split.map(&:to_i)
max = h[0]
count = 1

h[1..-1].each do |e|
  if e >= max
    count += 1
    max = e
  end
end

puts count


n = gets.to_i
h = gets.split.map(&:to_i)

count = 1
(1..n-1).each do |i|
  if h[0] <= h[i] && h[i-1] <= h[i]
    count += 1
  end
end
puts count


n = gets.to_i
h = gets.split.map(&:to_i)

count = 1
(1..n-1).each do |i|
  if h[0] < h[i] && h[i-1] < h[i]
    count += 1
  end
end
puts count


n = gets.chomp.to_i
h = gets.chomp.split(' ').map(&:to_i)
max = -1
count = 0

h.each do |takasa|
  if (takasa > max)
    count += 1
    max = takasa
  end
end
puts count


// Your code here!

use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().split_whitespace()
        .map(|e| e.parse().ok().unwrap()).collect()
}

fn main(){
    let n: usize = read();
    let hs: Vec<i32> = read_vec();

    let mut cnt:i32 = 0;
    let mut mx:i32 = 0;

    for i in 0..n{
        if mx<=hs[i]{
            cnt+=1;
            mx=hs[i];
        }
    }
    println!("{}",cnt)

}


#![allow(dead_code, unused_variables, unused_macros, unused_imports)]

// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input { (source = $s:expr, $($r:tt)*) => { let mut iter = $s.split_whitespace(); let mut next = || { iter.next().unwrap() }; input_inner!{next, $($r)*} }; ($($r:tt)*) => { let stdin = std::io::stdin(); let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); let mut next = move || -> String{ bytes .by_ref() .map(|r|r.unwrap() as char) .skip_while(|c|c.is_whitespace()) .take_while(|c|!c.is_whitespace()) .collect() }; input_inner!{next, $($r)*} }; }
macro_rules! input_inner { ($next:expr) => {}; ($next:expr, ) => {}; ($next:expr, $var:ident : $t:tt $($r:tt)*) => { let $var = read_value!($next, $t); input_inner!{$next $($r)*} }; ($next:expr, mut $var:ident : $t:tt $($r:tt)*) => { let mut $var = read_value!($next, $t); input_inner!{$next $($r)*} }; }
macro_rules! read_value { ($next:expr, ( $($t:tt),* )) => { ( $(read_value!($next, $t)),* ) }; ($next:expr, [ $t:tt ; $len:expr ]) => { (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>() }; ($next:expr, chars) => { read_value!($next, String).chars().collect::<Vec<char>>() }; ($next:expr, usize1) => { read_value!($next, usize) - 1 }; ($next:expr, $t:ty) => { $next().parse::<$t>().expect("Parse error") }; }

fn main() {
    input! {
        n: usize,
        h: [i32; n],
    }

    let mut ans = 0;
    h.iter().fold(0, |highest, &h| {
        if h >= highest {
            ans += 1;
        }
        std::cmp::max(h, highest)
    });
    println!("{}", ans);
}


use std::io;

fn procon_read<T: std::str::FromStr>() ->  Vec<T> {
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut v: Vec<T> = Vec::new();
	for i in iter {
		v.push(i.parse().ok().unwrap());
	}
	v
}

fn main() {
	let v:Vec<i32> = procon_read();
	let n:i32 = v[0];
	let v:Vec<i32> = procon_read();
	let h:Vec<i32> = v.clone();
	let mut cnt = 1;
	for i in 1..n {
		cnt += 1;
		for j in 0..i {
			if h[i as usize]  < h[j as usize] {
				cnt += -1;
				break;
			}
		}
	}
	println!("{}", cnt);
}


#![allow(unused_imports)]

use text_io::*;
use proconio::*;
use std::collections::*;
use std::process::exit;
use std::cmp::*;
use itertools::Itertools;

fn main() {
    input! {
    a:usize,
    b:[isize;a],
    }
    let mut ans:isize=1;
    for i in 1..a {
        if b[0]<=b[i]&&b[1]<=b[i]&&b[i-1]<=b[i] {ans+=1;}
    }
    println!("{}",ans);
}


use proconio::input;
use std::cmp::*;

fn main() {
    input! {
        n: usize,
        h: [u64;n],
    }

    let ans = h
        .iter()
        .zip(h.iter().scan(0, |m, &now| {
            *m = max(*m, now);
            Some(now >= *m)
        }))
        .filter(|(_, x)| *x)
        .count();

    println!("{}", ans);
}


#![allow(unused)]

//入力マクロここから
//https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules ! input_inner { ( $ next : expr ) => { } ; ( $ next : expr , ) => { } ; ( $ next : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ next , $ t ) ; input_inner ! { $ next $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ next : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ next , $ t ) ) ,* ) } ; ( $ next : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ next , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ next : expr , chars ) => { read_value ! ( $ next , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ next : expr , usize1 ) => { read_value ! ( $ next , usize ) - 1 } ; ( $ next : expr , $ t : ty ) => { $ next ( ) . parse ::<$ t > ( ) . expect ( "Parse error" ) } ; }
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; let mut next = || { iter . next ( ) . unwrap ( ) } ; input_inner ! { next , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let mut bytes = std :: io :: Read :: bytes ( std :: io :: BufReader :: new ( stdin . lock ( ) ) ) ; let mut next = move || -> String { bytes . by_ref ( ) . map ( | r | r . unwrap ( ) as char ) . skip_while ( | c | c . is_whitespace ( ) ) . take_while ( | c |! c . is_whitespace ( ) ) . collect ( ) } ; input_inner ! { next , $ ( $ r ) * } } ; }

use std::cmp::*;

fn main() {
    input! {
        n: usize,
        h: [u64;n],
    }

    let ans = h
        .iter()
        .zip(h.iter().scan(0, |m, &now| {
            *m = max(*m, now);
            Some(now >= *m)
        }))
        .filter(|(_, x)| *x)
        .count();

    println!("{}", ans);
}


var _=readLine(),H=readLine()!.characters.split(" ").map{Int(String($0))!},h=0,a=0;H.forEach{if $0>=h{a++;h=$0}};print(a)


var _=readLine()!,H=readLine()!.characters.split(" ").map{Int(String($0))!},h=0,a=0;for i in H{if i>=h{a++;h=i}};print(a)


var n: Int = Int(readLine()!)!
var arr=readLine()!.characters.split{$0==" "}.map{Int(String($0))!}
var highest: Int = 0
var o: Int = 0

for var i = 0; i < n; i++ {
  if( highest <= arr[i] ) {
    highest = arr[i]
    o+=1
  }
}
print (o)


var _=readLine(),H=readLine()!.characters.split(" ").map{String($0)},h="0",a=0;for i in H{if i>=h{a++;h=i}};print(a)


var _=readLine()!,H=readLine()!.characters.split(" ").map{String($0)},h="0",a=0;for i in H{if i>=h{a++;h=i}};print(a)


let H=readLine()!.characters.split(" ").map{Int(String($0))!};
var h=0,a=0;
for i in H{
  if i>=h{
    a++;
    h=i
  }
};
print(a)


const t={input:require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/),n:(arg:number=0):any=>{if(arg){const a=[];for(let i=0;i<arg;i++){a.push(t.n())}return a}else{const a=t.input[0];t.input.shift();return Number(a)}},s:(arg:number=0):any=>{if(arg){const a=[];for(let i=0;i<arg;i++){a.push(t.s())}return a}else{const a=t.input[0];t.input.shift();return String(a)}},c:(arg:number=0):any=>{if(arg){const a=[];for(let i=0;i<arg;i++){a.push(t.c())}return a}else{let a=t.input[0].split('');const b=a[0];a.shift();if(a.length>0){t.input[0]=a.join('')}else{t.input.shift()}return String(b)}},o:(...arg)=>{console.log(...arg)},abs:(a)=>{return Math.abs(a)},min:(...a)=>{return Math.min(...a)},max:(...a)=>{return Math.max(...a)},floor:(a)=>{return Math.floor(a)},asc:(ar:number[])=>{return ar.sort((a,b)=>{return a-b})},desc:(ar:number[])=>{return ar.sort((a,b)=>{return b-a})},sw:(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length;i+=2){if(eval(a+op+arr[i]))return arr[i+1];}return arr[arr.length-1]}};
const main=()=>{
  let n=t.n()
  let an=t.n(n)
  let max=an[0],c=1
  for(let i=1;i<n;i++){
    if(max<=an[i]){
      c++
      max=an[i]
    }
  }
  t.o(c)
}
main()


function Main(input) {
  const lines = input.trim().split("\n");
  const N = parseInt(lines[0]);
  const H = lines[1].split(" ").map(h => parseInt(h));
  let ans = 0;
  H.forEach((h, i) => {
    let canSeeOcean = true;
    for (let j = 0; j < i; j++) {
      if (h < H[j]) {
        canSeeOcean = false;
      }
    }
    if (canSeeOcean) {
      ans++;
    }
  });
  console.log(ans);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


const solve = (hs) => {
  // ...
  let currMax = 0
  let result = 0
  hs.map((h) => {
    if (h >= currMax) {
      result++
    }
    currMax = Math.max(h, currMax)
  })
  return result
}
const main = (input) => {
  const [n, hs] = input.split("\n")
  return solve(hs.split(" ").map(Number))
}

if (process.env.NODE_ENV !== "test") {
  const input = require("fs").readFileSync("/dev/stdin", "utf8")
  console.log(main(input.trim()))
}


const main = (input: string) => {
  const lines = input.split("\n");
  const H = lines[1].split(" ").map(str => parseInt(str));
  let answer = 0;

  H.forEach((h, i) => {
    if (i === 0 || (H[i - 1] <= h && H[0] <= h)) {
      answer += 1;
    }
  });

  console.log(answer);
};

main(require("fs").readFileSync("/dev/stdin", "utf8"));


const main = (input: string) => {
  const lines = input.split("\n");
  const H = lines[1].split(" ").map(str => parseInt(str));
  let answer = 0;

  H.forEach((h, i) => {
    if (i === 0 || (H[i - 1] < h && H[0] <= h)) {
      answer += 1;
    }
  });

  console.log(answer);
};

main(require("fs").readFileSync("/dev/stdin", "utf8"));


import * as fs from "fs";
const input = fs.readFileSync("/dev/stdin", "utf8").split("\n")[1];

const heights = input.split(" ");
let currH = heights[0];
return currH;


N = int(input())
S = str(input())
X = [0] * N

Sum1 = 0
Sum2 = 0
Sum3 = 0

for i in range(N):
    if S[i] == "R":
        X[i] = 1
        Sum1 += 1
    elif S[i] == "G":
        X[i] = 2
        Sum2 += 1
    elif S[i] == "B":
        X[i] = 4
        Sum3 += 1

Sum = Sum1 * Sum2 * Sum3

for i in range(N):
    for j in range(1, N):
        if i - j < 0 or N <= i + j:
            break
        else:
            if (X[i] + X[i - j] + X[i + j]) == 7:
                Sum -= 1

print(Sum)


# https://atcoder.jp/contests/abc162/submissions/11837869
# tamazooさんを参考に書いた
n = int(input())
s = input()
x = [0] * n
num_r, num_g, num_b = 0, 0, 0
for i in range(n):
    if s[i] == 'R':
        x[i] = 1
        num_r += 1
    elif s[i] == 'G':
        x[i] = 2
        num_g += 1
    elif s[i] == 'B':
        x[i] = 4
        num_b += 1

num = num_r * num_g * num_b

for i in range(n):
    for j in range(1, n):
        if i - j < 0 or n <= i + j:
            break
        else:
            if (x[i - j] + x[i] + x[i + j]) == 7:
                num -= 1
print(num)


D = {"R": 1, "G": 2, "B": 4}
E = {"R": 0, "G": 1, "B": 2}
N = int(input())
T = [E[a] for a in input()]
S = [1 << t for t in T]
s = 0
for i in range(N):
    for j in range(1, min(i+1, N-i)):
        if S[i] + S[i-j] + S[i+j] == 7: s += 1

X = [[0] * N for _ in range(3)]

for i, t in enumerate(T):
    X[t][i] += 1

for i in range(3):
    for j in range(1, N):
        X[i][j] += X[i][j-1]

ans = -s
for i in range(N):
    if T[i] == 0:
        ans += X[1][i] * (X[2][-1] - X[2][i]) + X[2][i] * (X[1][-1] - X[1][i])
    if T[i] == 1:
        ans += X[2][i] * (X[0][-1] - X[0][i]) + X[0][i] * (X[2][-1] - X[2][i])
    if T[i] == 2:
        ans += X[0][i] * (X[1][-1] - X[1][i]) + X[1][i] * (X[0][-1] - X[0][i])
print(ans)


N=int(input())
S=input()
R=[];G=[];B=[]
for i in range(N):
  if S[i]=='R':R.append(i)
  elif S[i]=='G':G.append(i)
  else:B.append(i)
s=len(R)*len(G)*len(B)
RG= [(x+y)/2 for x in R for y in G]
GB= [(x+y)/2 for x in G for y in B]
BR= [(x+y)/2 for x in B for y in R]

for i in RG:
  if i in B:s-=1
for i in GB:
  if i in R:s-=1
for i in BR:
  if i in G:s-=1
print(s);exit()

print(R,G,RG)
exit()
s=len(R)*len(G)*len(B)
for i in R:
  for j in G:
    if (i+j)/2 in B:s-=1
for i in G:
  for j in B:
    if (i+j)/2 in R:s-=1
for i in B:
  for j in R:
    if (i+j)/2 in G:s-=1

print(s)


N=int(input())
S=input()
R=[];G=[];B=[]
for i in range(N):
  if S[i]=='R':R.append(i)
  elif S[i]=='G':G.append(i)
  else:B.append(i)
#print(len(R),len(G),len(B))
s=len(R)*len(G)*len(B)
for i in R:
  for j in G:
    if (i+j)/2 in B:s-=1
for i in G:
  for j in B:
    if (i+j)/2 in R:s-=1
for i in B:
  for j in R:
    if (i+j)/2 in G:s-=1

print(s)


N=int(input())
S=input()
R=[];G=[];B=[]
for i in range(N):
  if S[i]=='R':R.append(i)
  elif S[i]=='G':G.append(i)
  else:B.append(i)

s=0
for i in range(len(R)):
  for j in range(len(G)):
    for k in range(len(B)):
#      print(i,j,k)
#      print(max(R[i],G[j],B[k])+min(R[i],G[j],B[k]),R[i]+G[j]+B[k])
      if (max(R[i],G[j],B[k])+min(R[i],G[j],B[k]))*3/2==R[i]+G[j]+B[k]:continue
      s+=1

print(s)


import java.util.*;
import java.io.*;

public class Main {

	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
	    int n = in.readInt();
	    char s[] = in.readString().toCharArray();
	    long r = 0, g = 0, b = 0;

	    for(int i = 0; i<n; i++) {
	    	if(s[i] == 'R') r++;
	    	if(s[i] == 'G') g++;
	    	if(s[i] == 'B') b++;
	    }
	    long total = r*g*b;
	    int ans = 0;
	    int rgb = (int)'R' + (int)'G' + (int)'B';
	    for(int i = 0; i<n; i++) {
	    	for(int j = i+1; j<n; j++) {
	    		int k = 2*j - i;
	    		if(k < n)
	    			if((int)s[i] + (int)s[j] + (int)s[k] == rgb)
	    				total--;
	    	}
	    }
	    System.out.println(total);
	}
}

class InputReader {

	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public long readLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9') {
				throw new InputMismatchException();
			}
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	public String next() {
		return readString();
	}

	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) {
        FastScanner fs = new FastScanner();
        int n = fs.nextInt();
        String s = fs.next();
        long r=0, b=0, g=0;
        for(char c : s.toCharArray()){
            if(c == 'R') r++;
            else if(c == 'B') b++;
            else g++;
        }
        long total = r*b*g;
        int rgb = (int) 'R' + (int) 'B' + (int) 'G';
        for(int i=0; i<n; ++i){
            char si = s.charAt(i);
            for(int j=i+1; j<n; ++j){
                char sj = s.charAt(j);
                int k = j + (j-i);
                if(k < n){
                    if(((int) si + (int) sj + (int) s.charAt(k)) == rgb)
                        total--;
                }
            }
        }
        System.out.println(total);
    }

    static class FastScanner {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer("");

        String next() {
            while (!st.hasMoreTokens())
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        int[] readArray(int n) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++) a[i] = nextInt();
            return a;
        }

        long nextLong() {
            return Long.parseLong(next());
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedOutputStream;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.util.StringTokenizer;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author mikit
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        LightScanner in = new LightScanner(inputStream);
        LightWriter out = new LightWriter(outputStream);
        DRGBTriplets solver = new DRGBTriplets();
        solver.solve(1, in, out);
        out.close();
    }

    static class DRGBTriplets {
        public void solve(int testNumber, LightScanner in, LightWriter out) {
            int n = in.ints();
            char[] s = in.chars();
            long r = 0, g = 0, b = 0;
            for (int i = 0; i < n; i++) {
                if (s[i] == 'R') r++;
                else if (s[i] == 'G') g++;
                else b++;
            }
            long ans = r * g * b;
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; 2 * j - i < n; j++) {
                    if (s[i] == s[j]) continue;
                    if (s[i] == s[2 * j - i]) continue;
                    if (s[j] == s[2 * j - i]) continue;
                    ans--;
                }
            }
            out.ans(ans).ln();
        }

    }

    static class LightWriter implements AutoCloseable {
        private final Writer out;
        private boolean autoflush = false;
        private boolean breaked = true;

        public LightWriter(Writer out) {
            this.out = out;
        }

        public LightWriter(OutputStream out) {
            this(new OutputStreamWriter(new BufferedOutputStream(out), Charset.defaultCharset()));
        }

        public LightWriter print(char c) {
            try {
                out.write(c);
                breaked = false;
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
            return this;
        }

        public LightWriter print(String s) {
            try {
                out.write(s, 0, s.length());
                breaked = false;
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
            return this;
        }

        public LightWriter ans(String s) {
            if (!breaked) {
                print(' ');
            }
            return print(s);
        }

        public LightWriter ans(long l) {
            return ans(Long.toString(l));
        }

        public LightWriter ln() {
            print(System.lineSeparator());
            breaked = true;
            if (autoflush) {
                try {
                    out.flush();
                } catch (IOException ex) {
                    throw new UncheckedIOException(ex);
                }
            }
            return this;
        }

        public void close() {
            try {
                out.close();
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
        }

    }

    static class LightScanner implements AutoCloseable {
        private BufferedReader reader = null;
        private StringTokenizer tokenizer = null;

        public LightScanner(InputStream in) {
            reader = new BufferedReader(new InputStreamReader(in));
        }

        public String string() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public char[] chars() {
            return string().toCharArray();
        }

        public int ints() {
            return Integer.parseInt(string());
        }

        public void close() {
            try {
                this.reader.close();
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
        }

    }
}


import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        FastScanner fs = new FastScanner();
        int N = fs.nextInt();
        String s = fs.next();
        int len = s.length();
        int r = 0;
        int g = 0;
        int b = 0;

        for (int i = 0; i < len; ++i) {
            if (s.charAt(i) == 'R') {
                ++r;
            } else if (s.charAt(i) == 'G') {
                ++g;
            } else {
                ++b;
            }
        }

        long ans = r*b*g;
        for (int i = 0; i <= len-3; ++i) {
            for (int j = i+1; j < len-1; ++j) {
                if (s.charAt(i) == s.charAt(j)) continue;
                if (j+j-i < len && s.charAt(j+j-i) != s.charAt(i)
                    && s.charAt(j+j-i) != s.charAt(j)) --ans;
            }
        }

        System.out.println(ans);
    }
}

class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;

    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }

    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}

    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }

    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }

    public double nextDouble() { return Double.parseDouble(next());}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        FastScanner fs = new FastScanner();
        int N = fs.nextInt();
        String s = fs.next();
        int len = s.length();
        int r = 0;
        int g = 0;
        int b = 0;

        for (int i = 0; i < len; ++i) {
            if (s.charAt(i) == 'R') {
                ++r;
            } else if (s.charAt(i) == 'G') {
                ++g;
            } else {
                ++b;
            }
        }

        int ans = r*b*g;
        for (int i = 0; i <= len-3; ++i) {
            for (int j = i+1; j < len-1; ++j) {
                if (s.charAt(i) == s.charAt(j)) continue;
                if (j+j-i < len && s.charAt(j+j-i) != s.charAt(i)
                    && s.charAt(j+j-i) != s.charAt(j)) --ans;
            }
        }

        System.out.println(ans);
    }
}

class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;

    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }

    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}

    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }

    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }

    public double nextDouble() { return Double.parseDouble(next());}
}


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String s = sc.next();
        int[] ch = new int[n];
        int r = 0;
        int g = 0;
        int b = 0;
        for(int i = 0; i < n ;i++){
            ch[i] = s.charAt(i);
            if(ch[i] == 'R'){
              r++;
            }else if(ch[i] == 'G'){
              g++;
            }else{
              b++;
            }
        }
        long ans = r * g * b;
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j < n; j++){
              int k = j + j - i;
              if(k < n && ch[i] != ch[j] && ch[i] != ch[k] && ch[j] != ch[k]){
                ans--;
              }
            }
          }
          System.out.println(ans);
    }
}


#include <bits/stdc++.h>

int ri() {
	int n;
	scanf("%d", &n);
	return n;
}

// 3乗で通したお詫びにO(NlogN)で通します
// 参考 : https://twitter.com/SayakaAmemiya/status/1249515024541859842

template<int mod, int proot> struct NTT {
	int get_mod() { return mod; }
	int pow(int a, int b) {
	int res = 1;
		for (; b; b >>= 1) {
			if (b & 1) res = (int64_t) res * a % mod;
			a = (int64_t) a * a % mod;
		}
		return res;
	}
	int inv(int i) { return pow(i, mod - 2); }
	void ntt(std::vector<int> &a, bool inverse) {
		int n = a.size();
		assert((n & -n) == n);
		int h = pow(proot, (mod - 1) / n);
		if (inverse) h = inv(h);

		for (int i = 0, j = 1; j < n - 1; j++) {
			for (int k = n >> 1; k > (i ^= k); k >>= 1);
			if (j < i) std::swap(a[i], a[j]);
		}
		for (int i = 1; i < n; i <<= 1) {
			int base = pow(h, n / i / 2);
			int w = 1;

			std::vector<int> ws(i);
			for (int j = 0; j < i; j++) ws[j] = w, w = (int64_t) w * base % mod;

			for (int j = 0; j < n; j += i << 1) {
				for (int k = 0; k < i; k++) {
					int u = a[k + j];
					int d = (int64_t) a[k + j + i] * ws[k] % mod;
					a[k + j] = u + d >= mod ? u + d - mod : u + d;
					a[k + j + i] = d > u ? u + mod - d : u - d;
				}
			}
		}
		if (inverse) {
			int ninv = inv(a.size());
			for (auto &i : a) i = (int64_t) i * ninv % mod;
		}
	}
};

int main() {
	int n = ri();
	int back[3] = { 0 };
	int forward[3] = { 0 };
	std::vector<int> a(n);
	{
		char tmp[4096];
		scanf("%s", tmp);
		for (int i = 0; i < n; i++) {
			a[i] = tmp[i] == 'R' ? 0 : tmp[i] == 'G' ? 1 : 2;
			back[a[i]]++;
		}
	}

	int64_t res = 0;
	// j - i != k - jを無視したの
	for (int j = 0; j < n; j++) {
		back[a[j]]--;
		res += forward[(a[j] + 1) % 3] * back[(a[j] + 2) % 3];
		res += forward[(a[j] + 2) % 3] * back[(a[j] + 1) % 3];
		forward[a[j]]++;
	}
	// j - i == k - jで相異なるものを引く
	int n2 = 1;
	for (; n2 < n + n - 1; n2 <<= 1);
	NTT<40961, 3> ntt;
	std::vector<int> count[3];
	for (auto &i : count) i.resize(n2);
	for (int i = 0; i < n; i++) count[a[i]][i]++;
	for (auto &i : count) ntt.ntt(i, false);

	std::vector<int> conved[3]; // conved count[i], count[(i + 1) % 3]
	for (int i = 0; i < 3; i++) {
		auto &cur = conved[i];
		cur.resize(n2);
		for (int j = 0; j < n2; j++) cur[j] = (int64_t) count[i][j] * count[(i + 1) % 3][j] % 40961;
		ntt.ntt(cur, true);
	}
	for (int j = 0; j < n; j++) res -= conved[(a[j] + 1) % 3][j + j];

	printf("%" PRId64 "\n", res);

	return 0;
}


#include <bits/stdc++.h>

int ri() {
	int n;
	scanf("%d", &n);
	return n;
}

// 3乗で通したお詫びにO(NlogN)で通します
// 参考 : https://twitter.com/SayakaAmemiya/status/1249515024541859842

template<int mod, int proot> struct NTT {
	int get_mod() { return mod; }
	int pow(int a, int b) {
	int res = 1;
		for (; b; b >>= 1) {
			if (b & 1) res = (int64_t) res * a % mod;
			a = (int64_t) a * a % mod;
		}
		return res;
	}
	int inv(int i) { return pow(i, mod - 2); }
	void ntt(std::vector<int> &a, bool inverse) {
		int n = a.size();
		assert((n & -n) == n);
		int h = pow(proot, (mod - 1) / n);
		if (inverse) h = inv(h);

		for (int i = 0, j = 1; j < n - 1; j++) {
			for (int k = n >> 1; k > (i ^= k); k >>= 1);
			if (j < i) std::swap(a[i], a[j]);
		}
		for (int i = 1; i < n; i <<= 1) {
			int base = pow(h, n / i / 2);
			int w = 1;

			std::vector<int> ws(i);
			for (int j = 0; j < i; j++) ws[j] = w, w = (int64_t) w * base % mod;

			for (int j = 0; j < n; j += i << 1) {
				for (int k = 0; k < i; k++) {
					int u = a[k + j];
					int d = (int64_t) a[k + j + i] * ws[k] % mod;
					a[k + j] = u + d >= mod ? u + d - mod : u + d;
					a[k + j + i] = d > u ? u + mod - d : u - d;
				}
			}
		}
		if (inverse) {
			int ninv = inv(a.size());
			for (auto &i : a) i = (int64_t) i * ninv % mod;
		}
	}
};

int main() {
	int n = ri();
	int back[3] = { 0 };
	int forward[3] = { 0 };
	std::vector<int> a(n);
	{
		char tmp[4096];
		scanf("%s", tmp);
		for (int i = 0; i < n; i++) {
			a[i] = tmp[i] == 'R' ? 0 : tmp[i] == 'G' ? 1 : 2;
			back[a[i]]++;
		}
	}

	int64_t res = 0;
	// j - i != k - jを無視したの
	for (int j = 0; j < n; j++) {
		back[a[j]]--;
		res += forward[(a[j] + 1) % 3] * back[(a[j] + 2) % 3];
		res += forward[(a[j] + 2) % 3] * back[(a[j] + 1) % 3];
		forward[a[j]]++;
	}
	// j - i == k - jで相異なるものを引く
	int n2 = 1;
	for (; n2 < n + n - 1; n2 <<= 1);
	NTT<998244353, 3> ntt;
	std::vector<int> count[3];
	for (auto &i : count) i.resize(n2);
	for (int i = 0; i < n; i++) count[a[i]][i]++;
	for (auto &i : count) ntt.ntt(i, false);

	std::vector<int> conved[3]; // conved count[i], count[(i + 1) % 3]
	for (int i = 0; i < 3; i++) {
		auto &cur = conved[i];
		cur.resize(n2);
		for (int j = 0; j < n2; j++) cur[j] = (int64_t) count[i][j] * count[(i + 1) % 3][j] % 998244353;
		ntt.ntt(cur, true);
	}
	for (int j = 0; j < n; j++) res -= conved[(a[j] + 1) % 3][j + j];

	printf("%" PRId64 "\n", res);

	return 0;
}


#include <bits/stdc++.h>

int ri() {
	int n;
	scanf("%d", &n);
	return n;
}

// 3乗で通したお詫びにO(NlogN)で通します
// 参考 : https://twitter.com/SayakaAmemiya/status/1249515024541859842

template<int mod, int proot> struct NTT {
	int get_mod() { return mod; }
	int pow(int a, int b) {
	int res = 1;
		for (; b; b >>= 1) {
			if (b & 1) res = (int64_t) res * a % mod;
			a = (int64_t) a * a % mod;
		}
		return res;
	}
	int inv(int i) { return pow(i, mod - 2); }
	void ntt(std::vector<int> &a, bool inverse) {
		int n = a.size();
		assert((n & -n) == n);
		int h = pow(proot, (mod - 1) / n);
		if (inverse) h = inv(h);

		for (int i = 0, j = 1; j < n - 1; j++) {
			for (int k = n >> 1; k > (i ^= k); k >>= 1);
			if (j < i) std::swap(a[i], a[j]);
		}
		for (int i = 1; i < n; i <<= 1) {
			int base = pow(h, n / i / 2);
			int w = 1;

			std::vector<int> ws(i);
			for (int j = 0; j < i; j++) ws[j] = w, w = (int64_t) w * base % mod;

			for (int j = 0; j < n; j += i << 1) {
				for (int k = 0; k < i; k++) {
					int u = a[k + j];
					int d = (int64_t) a[k + j + i] * ws[k] % mod;
					a[k + j] = u + d >= mod ? u + d - mod : u + d;
					a[k + j + i] = d > u ? u + mod - d : u - d;
				}
			}
		}
		if (inverse) {
			int ninv = inv(a.size());
			for (auto &i : a) i = (int64_t) i * ninv % mod;
		}
	}
};

char inputbuf[4096];
char *ptr = inputbuf;

int main() {
	fread(inputbuf, 1, sizeof(inputbuf), stdin);
	int n = 0;
	while (*ptr >= '0' && *ptr <= '9') n = n * 10 + *ptr++ - '0';
	while (*ptr != 'R' && *ptr != 'G' && *ptr != 'B') ptr++;

	int back[3] = { 0 };
	int forward[3] = { 0 };
	std::vector<int> a(n);
	{
		for (int i = 0; i < n; i++) {
			a[i] = *ptr == 'R' ? 0 : *ptr == 'G' ? 1 : 2;
			back[a[i]]++;
			ptr++;
		}
	}

	int64_t res = 0;
	// j - i != k - jを無視したの
	for (int j = 0; j < n; j++) {
		back[a[j]]--;
		res += forward[(a[j] + 1) % 3] * back[(a[j] + 2) % 3];
		res += forward[(a[j] + 2) % 3] * back[(a[j] + 1) % 3];
		forward[a[j]]++;
	}
	// j - i == k - jで相異なるものを引く
	int n2 = 1;
	for (; n2 < n + n - 1; n2 <<= 1);
	NTT<40961, 3> ntt;
	std::vector<int> count[3];
	for (auto &i : count) i.resize(n2);
	for (int i = 0; i < n; i++) count[a[i]][i]++;
	for (auto &i : count) ntt.ntt(i, false);

	std::vector<int> conved[3]; // conved count[i], count[(i + 1) % 3]
	for (int i = 0; i < 3; i++) {
		auto &cur = conved[i];
		cur.resize(n2);
		for (int j = 0; j < n2; j++) cur[j] = (int64_t) count[i][j] * count[(i + 1) % 3][j] % 40961;
		ntt.ntt(cur, true);
	}
	for (int j = 0; j < n; j++) res -= conved[(a[j] + 1) % 3][j + j];

	printf("%" PRId64 "\n", res);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main(){
  long long n;
  cin >> n;

  string s;
  cin >> s;
  int r=0,g=0,b=0;

  for(int i=0;i<n;i++){
    if(s[i] == 'R')r++;
    if(s[i] == 'G')g++;
    if(s[i] == 'B')b++;
  }

  int cnt = 0;
  for(int i=0;i<=n-3;i++){
    for(int j=i+1;j<=n-2;j++){
      int k = j+(j-i);
      if(k>=n)break;
      if(s[i] != s[j] && s[j] != s[k] && s[k] != s[i])cnt++;
    }
  }
  cout << r*g*b - cnt << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  string s;
  cin >> n >> s;

  int r = 0, g = 0, b = 0;
  for (int i = 0; i < n; i++) {
    if (s[i] == 'R') r++;
    else if (s[i] == 'G') g++;
    else if (s[i] == 'B') b++;
  }

  int cnt = 0;

  for (int i = 0; i < n-2; i++) {
    for (int j = i+1; j < n-1; j++) {
      int k = j + j-i;
      if (k >= n) break;
      if (s[i] != s[j] && s[i] != s[k] && s[j] != s[k]) cnt++;
    }
  }

  cout << r*g*b - cnt;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  string s;
  cin >> n >> s;

  int r = 0, g = 0, b = 0;
  for (int i = 0; i < n; i++) {
    if (s[i] == 'R') r++;
    else if (s[i] == 'G') g++;
    else if (s[i] == 'B') b++;
  }

  int cnt = 0;

  for (int i = 0; i <= n-3; i++) {
    for (int j = i+1; j <= n-2; j++) {
      int k = j + j-i;
      if (k >= n) break;
      if (s[i] != s[j] && s[i] != s[k] && s[j] != s[k]) cnt++;
    }
  }

  cout << r*g*b - cnt;

  return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h> // uint64_t

#define STR_MAX 4000
#define BUF_SIZE (STR_MAX+10)

// size: specify sizeof(str)
int get_str(char *str, int size) {
    if(!fgets(str, size, stdin)) return -1;
    return 0;
}

int get_int(void) {
  int num;
#ifdef BUF_SIZE
  char line[BUF_SIZE];
  if(!fgets(line, BUF_SIZE, stdin)) return 0;
  sscanf(line, "%d", &num);
#else
#error
#endif
  return num;
}

enum {
    ENUM_RED,
    ENUM_GREEN,
    ENUM_BLUE,
    ENUM_ALL
};

int table[256] = {
    ['R'] = 1<<ENUM_RED,
    ['G'] = 1<<ENUM_GREEN,
    ['B'] = 1<<ENUM_BLUE,
};

#define ALL_TYPE ((1<<ENUM_ALL) - 1)

int main(void) {
    int len = get_int(); // length
    char str[BUF_SIZE];
    get_str(str, BUF_SIZE);
    char type[BUF_SIZE] = {0};
    int i;
    for(i = 0; i < len; i++) {
        type[i] = table[str[i]];
    }
    static uint64_t dp[STR_MAX+1][1<<ENUM_ALL] = {0};
    dp[0][0] = 1;
    int pat;
    for(i = 1; i <= len; i++) {
        int tp = type[i-1];
        for(pat = 0; pat < (1<<ENUM_ALL); pat++) {
            dp[i][pat] = dp[i-1][pat];
            if(!(tp & pat)) { continue; }
            int prev_tp = pat & (~(tp));
            dp[i][pat] += dp[i-1][prev_tp];
#ifdef DEBUG
            printf("[%d]: dp[%d][%d -> %d] = %llu\n",tp, i,prev_tp, pat, dp[i][pat]);
#endif
        }
    }
    uint64_t exclude = 0;
    int dist;
    for(dist = 1; dist < len; dist++) {
        for(i = 0; i < len; i++) {
            if(i + 2*dist >= len) break;
            if((type[i] | type[i+dist] | type[i+dist*2]) == ALL_TYPE) exclude++;
        }
    }
#ifdef DEBUG
    printf("%llu %llu\n", dp[len][ALL_TYPE], exclude);
#endif
    printf("%llu\n", dp[len][ALL_TYPE]-exclude);
    return 0;
}


char S[4040];
i,j;c[99],t;
main(N)
{
	for(scanf("%d%s",&N,S);i<N;c[S[i++]]++)for(j=i;j>=0;j-=2)t-=(S[i]^S[i+j>>1]^S[j])==87;
	printf("%ld",1L*c[66]*c[71]*c[82]+t);
}


char S[4040];
i,j;c[99],t;
main(N)
{
	for(scanf("%d%s",&N,S);i<N;c[S[i++]]++)for(j=N-i+1>>1;j--;)t-=(S[i]^S[i+j]^S[i+j+j])==87;
	printf("%ld",1L*c[66]*c[71]*c[82]+t);
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<time.h>
#define FOR(i,n) for(int i=0;i<n;i++)
#define PRN(n) printf("%d\n",n)
#define PRF(n) printf("%lf\n",n)
#define PRL(n) printf("%lld\n",n)
#define PRS(s) printf("%s\n",s)
#define PRC(c) printf("%c",c)
#define INI(n) scanf("%d",&n)
#define INL(n) scanf("%lld",&n)
#define INF 10000000000
#define mod 1000000007
#define X 100000
#define N 20
#define M 46
typedef long long int ll;
ll finv[X];
ll fac[X];
ll inv[X];
ll usort(const void *a, const void *b){return *(ll*)a-*(ll*)b;}
ll dsort(const void *a, const void *b){return *(ll*)b-*(ll*)a;}
ll ssort(const void *a, const void *b){return strcmp((char*)a,(char*)b);}
void Iswap(int *a,int *b){
  int t=*a;
  *a=*b;
  *b=t;
}
void Fswap(double *a,double *b){
  double t=*a;
  *a=*b;
  *b=t;
}
void Lswap(ll *a,ll *b){
  ll t=*a;
  *a=*b;
  *b=t;
}
ll min(ll a,ll b){
  if(a>b)return b;
  return a;
}
ll max(ll a,ll b){
  if(a>b)return a;
  return b;
}
ll z(ll a){return max(a,-a);}
ll gcd(ll a,ll b){if(!b){return a;}else{return gcd(b,a%b);}}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
ll kt(ll a){
  ll sum=0;
  while(a){
    a/=10;
    sum++;
  }
  return sum;
}
ll ks(ll a){
  ll sum=0;
  while(a){
    sum+=a%10;
    a/=10;
  }
  return sum;
}
void nCrReady(){
  fac[0]=fac[1]=1;
  finv[0]=finv[1]=1;
  inv[1]=1;
  for (ll i=2;i<X;i++){
    fac[i]=fac[i-1]*i%mod;
    inv[i]=mod-inv[mod%i]*(mod/i)%mod;
    finv[i]=finv[i-1]*inv[i]%mod;
  }
}
ll nCr(ll n,ll k){return fac[n]*(finv[k]*finv[n-k]%mod)%mod;}

int main(void){
  int n;
  scanf("%d",&n);
  char s[n+1];
  int a[n];
  scanf("%s",s);
  int r=0,b=0,g=0;
  FOR(i,n){
    if(s[i]=='R'){
      r++;
      a[i]=2;
    }else if(s[i]=='B'){
      b++;
      a[i]=3;
    }else{
      g++;
      a[i]=5;
    }
  }
  ll ans=r*b*g;
  FOR(i,n){
    FOR(j,n){
      if(i+j*2<n){
        if(a[i]*a[i+j]*a[i+2*j]==30)ans--;
      }else{
        break;
      }
    }
  }
  PRL(ans);
  return 0;
}


#include <stdio.h>                                                                         int main(void){
  int N,r=0,g=0,b=0,i,j;
  long res=0;
  char S[5000];
  scanf("%d%s",&N,S);
  for(i=0;i<N;i++){
    if(S[i]=='R') r++;
    if(S[i]=='G') g++;
    if(S[i]=='B') b++;
  }
  res=r*g;
  res*=b;
  for(i=0;i<N-2;i++){
    for(j=i+1;j<N-1;j++){
      int k=2*j-i;
      if(S[i]!=S[j]&&S[i]!=S[k]&&S[j]!=S[k]&&k<N){
        res--;
      }
    }
  }
  printf("%ld",res);
  return 0;
}


#include  <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
  int n,i,j,k,r=0, g=0 ,b=0;
  long long count=0;
  char s[4005];
  scanf("%d",&n);
  scanf("%s",s);
  n=strlen(s);
  for(int l=0;l<n;l++){
    if(s[l]=='R') r++;
    if(s[l]=='G') g++;
    if(s[l]=='B') b++;
  }
  count=r*g*b;
  for(int i=0;i<n-2;i++){
    for(int j=i+1;j<n-1;j++){
      k=2*j-i;
        if(s[i]!=s[j]&&s[i]!=s[k]&&s[j]!=s[k]&&k<n){
          count--;

      }
    }
  }
  printf("%lld",count);

  return 0;
}


"use strict";

const main = arg => {
    const input = arg.trim().split("\n");

    const n = parseInt(input[0]);
    const s = input[1];
    let rs = []
    let gs = []
    let bs = []
    for(let i = 0; i<s.length;i++){
        if(s[i] === "R") rs.push(i)
        else if(s[i] === "G") gs.push(i)
        else if(s[i] === "B") bs.push(i)
    }
    let num = rs.length * gs.length * bs.length
    for(let i = 0; i< n; i++){
        for(let j = i+1; j<n; j++){
            let k = j + j - i
            if (k >= n) break
            if( s[i] !== s[j] && s[j] !== s[k] && s[k] !== s[i]){
                num--
            }
        }
    }
    console.log(num)
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


        // if (j - i === k - j) {
        //   continue
        // }
        // if (S[i] !== S[j] && S[j] !== S[k] && S[i] !== S[k]) {
        //   count++
        // }

function main(input) {
  const inputs = input.split('\n')
  const N = Number(inputs[0])
  const S = inputs[1]
  const R = [], G = [], B = []
  S.split('').forEach((e, i) => {
    if (e === 'R') {
      R.push(i)
    }
    if (e === 'G') {
      G.push(i)
    }
    if (e === 'B') {
      B.push(i)
    }
  })
  // console.log(R, G, B)

  // 貪欲
  // {
  //   let count = 0
  //   for(let i = 0; i < N - 2; i++) {
  //     for(let j = i + 1; j < N - 1; j++) {
  //       if (S[i] === S[j]) continue
  //       const ji = j - i
  //       for (let k = j + 1; k < N; k++) {
  //         if (S[j] === S[k]) continue
  //         if (k - j === ji) continue
  //         if (S[i] === S[k]) continue
  //         console.log('rgb:', i, j, k)
  //         count++
  //       }
  //     }
  //   }
  //   console.log('greedy:', count)
  // }

  let count = R.length * B.length * G.length
  // console.log(count)
  let notCount = 0
  for(let i = 0; i < N; i++) {
    for(let j = i + 1; j < N-1; j++) {
      const k = j * 2 - i
      if (k < N) {
        // console.log(i, j, k, S[i], S[j], S[k])
        if (S[i] !== S[j] && S[j] !== S[k] && S[i] !== S[k]) {
          // console.log('not count')
          notCount++
        }
      }
    }
  }

  console.log(count - notCount)

}
main(require("fs").readFileSync("/dev/stdin", "utf8"));


function main(input) {
  const tmp = input.trim().split('\n')
  const n = parseInt(tmp[0], 10)
  const s = tmp[1]

  let r = 0
  let g = 0
  let b = 0

  for (let i = 0; i < n; i++) {
    if (s[i] == 'R') {
      r++
    } else if (s[i] == 'G') {
      g++
    } else {
      b++
    }
  }

  let answer = r * g * b
  for (let i = 0; i < n - 1; i++) {
    for (let j = i + 1; 2 * j - i < n; j++) {
      const k = 2 * j - i
      if (s[i] != s[j] && s[j] != s[k] && s[k] != s[i]) {
        answer--
      }
    }
  }

  console.log(answer)
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'))


function Main(input) {
  input = input.trim().split("\n").map(function(x) { return x.split(" ")});
  var N = parseInt(input[0],10);
  var S = input[1][0];
  console.log(S.substr(0,1));
  var vec_R = Array.from({length: N + 1}, () => 0);
  var vec_G = Array.from({length: N + 1}, () => 0);
  var vec_B = Array.from({length: N + 1}, () => 0);
  var arr_chr = [vec_R,vec_G,vec_B];
  var ans = 0;
  for(var i = S.length - 1; i >= 0; i--){
    if(S.substr(i, 1) === 'R') {
      vec_R[i] = vec_R[i + 1] + 1;
      vec_G[i] = vec_G[i + 1];
      vec_B[i] = vec_B[i + 1];
    }
    if(S.substr(i, 1) === 'G') {
      vec_R[i] = vec_R[i + 1];
      vec_G[i] = vec_G[i + 1] + 1;
      vec_B[i] = vec_B[i + 1];
    }
    if(S.substr(i, 1) === 'B') {
      vec_R[i] = vec_R[i + 1];
      vec_G[i] = vec_G[i + 1];
      vec_B[i] = vec_B[i + 1] + 1;
    }
  }
  vec_R = vec_R.pop();
  vec_G = vec_G.pop();
  vec_B = vec_B.pop();
  var a, b, c;
  var tmp = 0;
  for (var i = 0; i < (S.length - 3); i++){
    a = S.substr(i, 1);
    for (var j = i + 1; j < (S.length - 1); j++){
      b = S.substr(j, 1);
      if (a !== b){
        ans += arr_chr[chrSk_i(S, a, b)][j + 1];
        if (j+(j-i) < N && S.substr(j+(j-i), 1) !== a && S.substr(j+(j-i), 1) !== b) {
          ans --;
          tmp ++;
        }
      }
    }
  }
  function chrSk_i(S, a, b){
    if (a !== 'R' && b !== 'R') return 0;
    if (a !== 'G' && b !== 'G') return 1;
    if (a !== 'B' && b !== 'B') return 2;
  }
  console.log(ans);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function main(input) {
  const inputs = input.split('\n')
  const N = Number(inputs[0])
  const S = inputs[1]

  // 貪欲

  let count = 0
  for(let i = 0; i < N - 2; i++) {
    for(let j = i + 1; j < N - 1; j++) {
      if (S[i] === S[j]) continue
      const ji = j - i
      for (let k = j + 1; k < N; k++) {
        if (S[j] === S[k]) continue
        if (k - j === ji) continue
        if (S[i] === S[k]) continue
        count++
      }
    }
  }
  console.log(count)
}
main(require("fs").readFileSync("/dev/stdin", "utf8"));


function main(input) {
  const inputs = input.split('\n')
  const N = Number(inputs[0])
  const S = inputs[1]

  // 貪欲

  let count = 0
  for(let i = 0; i < N - 2; i++) {
    for(let j = i + 1; j < N - 1; j++) {
      for (let k = j + 1; k < N; k++) {
        // console.log(i, j, k)
        if (j - i === k - j) {
          continue
        }
        if (S[i] !== S[j] && S[j] !== S[k] && S[i] !== S[k]) {
          count++
        }
      }
    }
  }
  console.log(count)
}
main(require("fs").readFileSync("/dev/stdin", "utf8"));


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var stdin = bufio.NewScanner(os.Stdin)

func main() {
	stdin.Split(bufio.ScanWords)
	N := nextInt()
	S := nextStr()
	sum := 0
	Rs := make([]int, 0, N)
	Gs := make([]int, 0, N)
	Bs := make([]int, 0, N)
	for i, c := range S {
		if c == 'R' {
			Rs = append(Rs, i)
		}
		if c == 'G' {
			Gs = append(Gs, i)
		}
		if c == 'B' {
			Bs = append(Bs, i)
		}
	}

	runes := []rune(S)
	for _, r := range Rs {
		for _, g := range Gs {
			var bindex int
			// right
			if r > g {
				bindex = 2*r - g
			} else {
				bindex = 2*g - r
			}
			if bindex < N && runes[bindex] == 'B' {
				sum++
			}
			// left
			if r > g {
				bindex = 2*g - r
			} else {
				bindex = 2*r - g
			}
			if bindex >= 0 && runes[bindex] == 'B' {
				sum++
			}
			// mid
			if (r+g)%2 == 0 && runes[(r+g)/2] == 'B' {
				sum++
			}
		}
	}

	// for i := 0; i < N-2; i++ {
	// 	for j := i + 1; j < N-1; j++ {
	// 		if S[i] == S[j] {
	// 			continue
	// 		}
	// 		for k := j + 1; k < N; k++ {
	// 			if j-i != k-j && S[i] != S[k] && S[j] != S[k] {
	// 				sum++
	// 			}
	// 		}
	// 	}
	// }
	fmt.Println(len(Rs)*len(Gs)*len(Bs) - sum)
}

func nextInt() int {
	stdin.Scan()
	i, err := strconv.Atoi(stdin.Text())
	if err != nil {
		panic(err)
	}
	return i
}

func nextStr() string {
	stdin.Scan()
	i := stdin.Text()
	// if err != nil {
	// 	panic(err)
	// }
	return i
}


package main

import "fmt"

var (
	N          int
	S          string
	rs, gs, bs []int
)

func main() {
	fmt.Scan(&N, &S)
	rs = make([]int, 0, N)
	gs = make([]int, 0, N)
	bs = make([]int, 0, N)

	for i, c := range S {
		if c == 'R' {
			rs = append(rs, i)
		}
		if c == 'G' {
			gs = append(gs, i)
		}
		if c == 'B' {
			bs = append(bs, i)
		}
	}

	runes := []rune(S)
	ans := len(rs) * len(gs) * len(bs)
	for _, r := range rs {
		for _, g := range gs {
			k1 := max(r, g) + abs(r-g)
			k2 := min(r, g) - abs(r-g)
			if k1 > 0 && k1 < N && runes[k1] == 'B' {
				ans--
			}
			if k2 > 0 && k2 < N && runes[k2] == 'B' {
				ans--
			}
			if (r-g)%2 == 0 && runes[(r+g)/2] == 'B' {
				ans--
			}
		}
	}
	fmt.Println(ans)
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func search(i int, c rune) int {
	var x, y []int
	if c == 'R' {
		x, y = gs, bs
	} else if c == 'G' {
		x, y = rs, bs
	} else {
		x, y = rs, gs
	}
	ans := 0
	for _, j := range x {
		for _, k := range y {
			if j <= i || k <= i {
				continue
			}
			if max(j, k)-min(j, k) != min(j, k)-i {
				ans++
			}
		}
	}
	return ans
}

func min(a, b int) int {
	if a > b {
		return b
	}
	return a
}
func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc, wr = bufio.NewScanner(os.Stdin), bufio.NewWriter(os.Stdout)

func scanString() string   { sc.Scan(); return sc.Text() }
func scanRunes() []rune    { return []rune(scanString()) }
func scanInt() int         { a, _ := strconv.Atoi(scanString()); return a }
func scanInt64() int64     { a, _ := strconv.ParseInt(scanString(), 10, 64); return a }
func scanFloat64() float64 { a, _ := strconv.ParseFloat(scanString(), 64); return a }

func scanInts(n int) []int {
	res := make([]int, n)
	for i := 0; i < n; i++ {
		res[i] = scanInt()
	}
	return res
}

func debug(a ...interface{}) { fmt.Fprintln(os.Stderr, a...) }

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

//•*¨*•.¸¸♪main•*¨*•.¸¸♪(　-ω-)ノ　(　・ω・)
func main() {
	defer wr.Flush()
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, 10000), 1001001)

	n := scanInt()
	s := scanString()

	rc := 0
	gc := 0
	bc := 0

	for i := 0; i < n; i++ {
		if s[i] == 'R' {
			rc++
		} else if s[i] == 'G' {
			gc++
		} else {
			bc++
		}
	}

	ans := rc*gc*bc
	for i := 0; i < n; i++ {
		for j := 1; j < n; j++ {
			if i+j >= n || i+2*j >= n {
				break
			}
			if s[i] != s[i+j] && s[i+j] != s[i+2*j] && s[i] != s[i+2*j] {
				ans--
			}
		}
	}

	fmt.Fprintln(wr, ans)

}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

func main() {
	io := NewIo(os.Stdin, os.Stdout)
	defer io.Flush()
	_ = io.NextInt()
	s := io.Next()
	r, g, b := []int{}, []int{}, []int{}
	for i := range s {
		switch s[i] {
		case 'R':
			r = append(r, i)
		case 'G':
			g = append(g, i)
		case 'B':
			b = append(b, i)
		}
	}
	//logger.Println(r, g, b)
	ans := len(r) * len(g) * len(b)
	for i := range r {
		for j := range g {
			for k := range b {
				x, y, z := sort3(r[i], g[j], b[k])
				if x-2*y+z == 0 {
					//logger.Println(r[i], g[j], b[k])
					ans--
				}
			}
			/*
				k := sort.Search(len(b), func(k int) bool {
					x, y, z := sort3(r[i], g[j], b[k])
					return x-2*y+z >= 0
				})
				if k == len(b) {
					continue
				}
				x, y, z := sort3(r[i], g[j], b[k])
				if x-2*y+z == 0 {
					ans--
				}
			*/
		}
	}
	io.Println(ans)
}

func sort3(x, y, z int) (int, int, int) {
	if x > y {
		x, y = y, x
	}
	if y > z {
		y, z = z, y
	}
	if x > y {
		x, y = y, x
	}
	return x, y, z
}

// Io is I/O object
type Io struct {
	reader    *bufio.Reader
	writer    *bufio.Writer
	tokens    []string
	nextToken int
}

// NewIo returns a new Io instance
func NewIo(r io.Reader, w io.Writer) *Io {
	return &Io{
		reader: bufio.NewReader(r),
		writer: bufio.NewWriter(w),
	}
}

// Flush flushes writer
func (io *Io) Flush() {
	err := io.writer.Flush()
	if err != nil {
		panic(err)
	}
}

// NextLine scans a line from stdin
func (io *Io) NextLine() string {
	var buffer []byte
	for {
		line, isPrefix, err := io.reader.ReadLine()
		if err != nil {
			panic(err)
		}
		buffer = append(buffer, line...)
		if !isPrefix {
			break
		}
	}
	return string(buffer)
}

// Next return a word from stdin
func (io *Io) Next() string {
	for io.nextToken >= len(io.tokens) {
		line := io.NextLine()
		io.tokens = strings.Fields(line)
		io.nextToken = 0
	}
	r := io.tokens[io.nextToken]
	io.nextToken++
	return r
}

// NextInt returns an integer from stdin
func (io *Io) NextInt() int {
	i, err := strconv.Atoi(io.Next())
	if err != nil {
		panic(err)
	}
	return i
}

// Println is a wrapper of fmt.Fprintln
func (io *Io) Println(a ...interface{}) {
	fmt.Fprintln(io.writer, a...)
}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

const mod = 998244353
const facNum = 300001

func main() {
	sc := newScanner(os.Stdin)
	N := sc.i()
	S := sc.s()
	cnt := 0
	for i := 1; i <= N-2; i++ {
		for j := i + 1; j <= N-1; j++ {
			a := S[i-1]
			b := S[j-1]
			if a == b {
				continue
			}
			for k := j + 1; k <= N; k++ {
				if j-i == k-j {
					continue
				}
				c := S[k-1]
				if b == c || a == c {
					continue
				}
				cnt += 1
			}
		}
	}
	fmt.Println(cnt)
}

// fmt.Println("Yes")
// fmt.Println("No")

// I/O
type scanner struct {
	sc *bufio.Scanner
}

func newScanner(input io.Reader) *scanner {
	sc := bufio.NewScanner(input)
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, 1024), int(1e+9))
	return &scanner{sc}
}

func (s *scanner) s() string {
	s.sc.Scan()
	return s.sc.Text()
}

func (s *scanner) i() int {
	i, e := strconv.Atoi(s.s())
	if e != nil {
		panic(e)
	}
	return i
}

func (s *scanner) f() float64 {
	f, e := strconv.ParseFloat(s.s(), 64)
	if e != nil {
		panic(e)
	}
	return f
}

func (s *scanner) bs() []byte {
	return []byte(s.s())
}

func (s *scanner) is(n int) []int {
	res := make([]int, n)
	for i := 0; i < n; i++ {
		res[i] = s.i()
	}
	return res
}

func (s *scanner) fs(n int) []float64 {
	res := make([]float64, n)
	for i := 0; i < n; i++ {
		res[i] = s.f()
	}
	return res
}

//const factorial = new
func Pow(a, n int) int {
	ans := 1
	for n > 0 {
		if (n & 1) == 1 {
			ans = ans * a % mod
		}
		a = a * a % mod
		n = n >> 1
	}
	return ans
}

func Gcd(a, b int) int {
	if a < b {
		return Gcd(b, a)
	}
	for b != 0 {
		a, b = b, a%b
	}
	return a
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func combination(n, k int, fac, ifac []int) int {
	if n < k || n < 0 {
		return 0
	}
	if k == 0 {
		return 1
	}
	//while n != 0
	ans := ifac[k] * ifac[n-k] % mod
	return ans * fac[n] % mod
}

// 階乗: factorial
// コンビネーションを計算する際に前もって計算しておく
// fac[k] => k! (mod M)
// ifac[k] => k!^(M-2) (mod M)
// n: ex. 2 * 10^5 => 200001
// fac, ifac := factorial()
func factorial() (fac []int, ifac []int) {
	fac = make([]int, facNum)
	fac[0] = 1
	ifac = make([]int, facNum)
	ifac[0] = 1
	for i := 1; i < facNum; i++ {
		fac[i] = fac[i-1] * i % mod
		ifac[i] = ifac[i-1] * Pow(i, mod-2) % mod
	}
	return
}

// vs: sorted slice int value
func lowerBound(vs []int, v int) (index int) {
	n := len(vs) / 2
	m := len(vs)
	for m != n {
		if vs[n] < v {
			n = (m-n+1)/2 + n
			//m = m
		} else {
			m = n
			n = n / 2
		}
	}
	return n
}

func IntSlice(n, init int) []int {
	r := make([]int, n)
	for i := range r {
		r[i] = init
	}
	return r
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func scanInt() int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return i
}

func scanInt64() int64 {
	sc.Scan()
	i, _ := strconv.ParseInt(sc.Text(), 10, 64)
	return i
}

func scanInts(n int) []int {
	res := make([]int, n)
	for i := 0; i < n; i++ {
		res[i] = scanInt()
	}
	return res
}

func scanInts64(n int) []int64 {
	res := make([]int64, n)
	for i := range res {
		res[i] = scanInt64()
	}
	return res
}

func scanText() string {
	sc.Scan()
	return sc.Text()
}

var sc = bufio.NewScanner(os.Stdin)

func main() {
	sc.Split(bufio.ScanWords)
	n := scanInt()
	s := scanText()

	r := strings.Count(s, "R")
	g := strings.Count(s, "G")
	b := strings.Count(s, "B")

	ans := r * g * b

	for i := 1; i < n; i++ {
		for j := 1; j <= n; j++ {
			gi := i + j
			bi := gi + j
			if bi > n {
				break
			}
			if s[i-1:i] != s[gi-1:gi] && s[bi-1:bi] != s[gi-1:gi] && s[i-1:i] != s[bi-1:bi] {
				fmt.Println(i, gi, bi)
				ans--
			}
		}
	}
	fmt.Println(ans)
}


$n = gets.to_i
colors = gets.chomp.split("")
color_array = Array.new(3) { Array.new }
colors.each.with_index(1) do |color, index|
  case color
  when "R"
    color_array[0] << index
  when "G"
    color_array[1] << index
  when "B"
    color_array[2] << index
  end
end

$ngs = Array.new($n + 1, 0)

def count_ngs(a, b)
  gap = b - a
  $ngs[((a + b) / 2)] += 1 if gap.even?
  $ngs[a - gap] += 1 if (a - gap) > 0
  $ngs[b + gap] += 1 if (b + gap) <= $n
end

color_array[0].each do |i1|
  color_array[1].each do |i2|
    if i1 > i2
      count_ngs(i2, i1)
    else
      count_ngs(i1, i2)
    end
  end
end

ans = color_array[0].size * color_array[1].size * color_array[2].size

color_array[2].each do |i|
  ans -= $ngs[i]
end

puts ans


n = gets.to_i
s = gets.chomp.bytes

cnt = 0
(n-2).times do |i|
 j = i + 1
 k = j + 1
 while k < n
  cnt += 1 if s[i] != s[j] && s[i] != s[k] && s[j] != s[k]
  j += 1
  k += 2
 end
end

puts s.count(82) * s.count(71) * s.count(66) - cnt


n = gets.to_s.to_i
s = gets.to_s.chomp.bytes

cnt = 0
n.times do |i|
  j = i + 1
  k = i + 2
  while k < n
    cnt += 1 if (s[i] != s[j] && s[j] != s[k] && s[i] != s[k])
    j += 1
    k += 2
  end
end

# p "RGB".bytes #=> [82, 71, 66]
puts s.count(82) * s.count(71) * s.count(66) - cnt


use std::io;

fn read() -> String {
    let mut buff = String::new();
    io::stdin().read_line(&mut buff).unwrap();
    buff.trim().to_string()
}

fn main() {
    let n: i32 = read().parse().unwrap();
    let chars: Vec<char> = read().chars().collect();

    let r_count = chars.iter().filter(|c| c == &&'R').count();
    let g_count = chars.iter().filter(|c| c == &&'G').count();
    let b_count = chars.iter().filter(|c| c == &&'B').count();

    let mut ans = r_count * g_count * b_count;

    for i in 0..n {
        for j in (i + 1)..n {
            let k = 2 * j - i;
            if k < n {
                let ci = chars[i as usize];
                let cj = chars[j as usize];
                let ck = chars[k as usize];
                if ci != cj && ci != ck && cj != ck {
                    ans -= 1;
                }
            }
        }
    }

    println!("{}", ans);
}


n = gets.to_i
cs = gets.strip.chars

r_count = cs.count("R")
g_count = cs.count("G")
b_count = cs.count("B")

miss = 0

n.times do |i|
  ((i + 1)..n).each do |j|
    k = 2 * j - i
    rest = (["R", "G", "B"] - [cs[i], cs[j]])
    if rest.length == 1
      if cs[k]
        if cs[k] == rest.first
          miss += 1
        end
      end
    end
  end
end

puts(r_count * g_count * b_count - miss)


n = gets.to_i
s = gets.chomp

tally = s.chars.tally
tally.default = 0
answer = tally['R'] * tally['G'] * tally['B']

(0...n).each do |i|
  (1...n / 3).each do |d|
    break if (i + 2 * d) > n - 1

    if s[i] != s[i + d] && s[i + d] != s[i + 2 * d] && s[i + 2 * d] != s[i + d]
      answer -= 1
    end
  end
end

puts answer


macro_rules! get_one {
    ($t:ty) => {{
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        line.trim().parse::<$t>().unwrap()
    }};

    ($t:ty; $n:expr) => {
        (0..$n).map(|_| get_one!($t)).collect::<Vec<_>>()
    };
}

fn main() {
    let _ = get_one!(usize);
    let v_s: Vec<char> = get_one!(String).chars().collect();
    let r_pos = pos('R', &v_s);
    let g_pos = pos('G', &v_s);
    let b_pos = pos('B', &v_s);

    let mut except = 0;
    for &r in r_pos.iter() {
        for &g in g_pos.iter() {
            if let Some('B') = v_s.get((2 * r - g) as usize) {
                except += 1;
            }
            if let Some('B') = v_s.get((2 * g - r) as usize) {
                except += 1;
            }
            if (r + g) % 2 == 0 && v_s[((r + g) / 2) as usize] == 'B' {
                except += 1;
            }
        }
    }

    let r_num = r_pos.len();
    let g_num = g_pos.len();
    let b_num = b_pos.len();

    println!("{}", r_num * g_num * b_num - except);
}

fn pos(chr: char, v: &Vec<char>) -> Vec<i32> {
    v.iter().enumerate().filter_map(|(i, &c)| if c == chr {Some(i as i32)} else {None}).collect()
}


use proconio;

fn disj3(x: char, y: char, z: char) -> bool {
    x != y && y != z && z != x
}

fn count_bad(s: &Vec<char>, step: usize) -> usize {
    let mut count = 0;
    for i in 0..s.len() {
        if i + step * 2 >= s.len() {
            break;
        }
        if disj3(s[i], s[i+step], s[i+step*2]) {
            count += 1;
        }

    }
    count
}

fn main() {
    proconio::input! {
        _n: usize,
        s: String,
    }
    let s: Vec<char> = s.chars().collect();

    let mut r: usize = 0;
    let mut g: usize = 0;
    let mut b: usize = 0;

    for c in s.iter() {
        if c == &'R' {
            r += 1;
        }
        if c == &'G' {
            g += 1;
        }
        if c == &'B' {
            b += 1;
        }
    }

    let mut bad = 0;
    for i in 1..=s.len() {
        bad += count_bad(&s, i);
    }
    println!("{}", r * g * b - bad);
}


#![allow(non_snake_case)]
#![allow(unused_imports)]

use proconio::{input, fastout};
use proconio::marker::*;
use whiteread::parse_line;
use std::collections::*;
use num::*;
use num_traits::*;
use superslice::*;
use std::ops::*;

use itertools::Itertools;
use itertools_num::ItertoolsNum;

fn main() {
    input!{
        n: usize,
        s: Chars,
    }

    let mut ans = 0;
    for i in 0..n-2 {
        for j in i+1..n-1 {
            if s[i] == s[j] { continue; }
            for k in (j+1..n).filter(|&x| x != 2*j - i) {
                if j-i == k-j { continue; }
                if s[i] != s[j] && s[j] != s[k] && s[k] != s[i] {
                    ans += 1;
                }
            }
        }
    }

    println!("{}", ans)
}


#![allow(non_snake_case)]
#![allow(unused_imports)]

use proconio::{input, fastout};
use proconio::marker::*;
use whiteread::parse_line;
use std::collections::*;
use num::*;
use num_traits::*;
use superslice::*;
use std::ops::*;

use itertools::Itertools;
use itertools_num::ItertoolsNum;

fn main() {
    input!{
        n: usize,
        s: Chars,
    }

    let mut ans = 0;
    for i in 0..n-2 {
        for j in i+1..n-1 {
            if s[i] == s[j] { continue; }
            for k in j+1..n {
                if j-i == k-j { continue; }
                if s[j] != s[k] && s[k] != s[i] {
                    ans += 1;
                }
            }
        }
    }

    println!("{}", ans)
}


#![allow(non_snake_case)]
#![allow(unused_imports)]

use proconio::{input, fastout};
use proconio::marker::*;
use whiteread::parse_line;
use std::collections::*;
use num::*;
use num_traits::*;
use superslice::*;
use std::ops::*;

use itertools::Itertools;
use itertools_num::ItertoolsNum;

fn main() {
    input!{
        n: usize,
        s: Chars,
    }

    let mut ans = 0;
    for i in 0..n-2 {
        for j in i+1..n-1 {
            for k in j+1..n {
                if j-i == k-j { continue; }
                if s[i] != s[j] && s[j] != s[k] && s[k] != s[i] {
                    ans += 1;
                }
            }
        }
    }

    println!("{}", ans)
}


func main() {
    let N = Int(readLine()!)!
    let S = Array(readLine()!)

    var count: [Character: Int] = ["R": 0, "G": 0, "B": 0]
    for c in S {
        count[c]! += 1
    }

    var ans = 1
    for c in "RGB" {
        ans *= count[c]!
    }

    for i in 1...((N - 1) / 2) {
        var first = 0
        while first + 2 * i < N {
            let mid = first + i
            let last = first + 2 * i
            if S[first] != S[mid] && S[mid] != S[last] && S[first] != S[last] {
                ans -= 1
            }
            first += 1
        }
    }

    print(ans)
}

main()


let n = Int(readLine()!)!
let s = Array(readLine()!)

var d: [Character: Int] = ["R": 0, "G": 0, "B": 0]

for char in s {
    d[char]! += 1
}

var result = d["R"]! * d["G"]! * d["B"]!
for i in 0..<n {
    for j in i+1..<n {
        let k = 2 * j - i
        if k >= n {break}
        if s[i] != s[j] && s[j] != s[k] && s[k] != s[i] {
            result -= 1
        }
    }
}

print(result)


let N = Int(readLine()!) ?? 0
let rgbArray = Array(readLine()!)
var count = 0
var rgbIndex = Array(repeating: Array(repeating: 0, count: 0), count: 3)

rgbArray.enumerated().forEach{
    if $0.1 == "R"{
        rgbIndex[0].append($0.0)
    }
    if $0.1 == "G"{
        rgbIndex[1].append($0.0)
    }
    if $0.1 == "B"{
        rgbIndex[2].append($0.0)
    }

}
var total = rgbIndex[2].count*rgbIndex[1].count*rgbIndex[0].count

for i in 0 ..< N {
    for j in i+1 ..< N {
        let k = 2 * j - i
        if k >= N {
          break
        }
        if rgbArray[i] != rgbArray[j] && rgbArray[j] != rgbArray[k] && rgbArray[k] != rgbArray[i] {
            total -= 1
        }
    }
}

print(total)


import Foundation

let main: () = {
    let N = nextInt()
    let S = next()
    var R = 0, G = 0, B = 0
    S.forEach {
        switch ($0) {
        case "R": R += 1
        case "G": G += 1
        case "B": B += 1
        default: break
        }
    }
    let total = R * G * B
    var exc = 0
    for n in 0 ..< N - 2 {
        for m in n + 1 ..< N - 1 {
            let k = m + (m - n)
            if k >= N { break }
            if S[n] != S[m] && S[n] != S[k] && S[m] != S[k] { exc += 1 }
        }
    }
    let ans = total - exc
    print(ans)
}()

//----------------------------------

let dx = [1, 0, -1, 0] //[1, 0, -1, 0, -1,  1, -1, 1]
let dy = [0, 1, 0, -1] //[0, 1, 0, -1, -1, -1,  1, 1]

@inlinable func gcd(_ a: Int, _ b: Int) -> Int { (b > 0) ? gcd(b, a % b) : a }
@inlinable func lcm(_ a: Int, _ b: Int) -> Int { a / gcd(a, b) * b }

//----------------------------------

infix operator  =~ : ComparisonPrecedence
infix operator !=~ : ComparisonPrecedence
func =~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { !(right ~= left) }
func =~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { !(right ~= left) }

func =~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { right.contains(left) }
func !=~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { !right.contains(left) }

infix operator /^ : MultiplicationPrecedence
infix operator /^= : AssignmentPrecedence
func /^ <T: FixedWidthInteger>(left: T, right: T) -> T { (left + (right - 1)) / right }
func /^= <T: FixedWidthInteger>(left: inout T, right: T) { left = (left + (right - 1)) / right }

@inlinable func chmax<T: Comparable>(_ m: inout T, _ q: T) { if (m < q) { m = q } }
@inlinable func chmin<T: Comparable>(_ m: inout T, _ q: T) { if (m > q) { m = q } }
@inlinable func chRmax<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m < q) { m = q; return true } else { return false } }
@inlinable func chRmin<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m > q) { m = q; return true } else { return false } }

prefix operator *
prefix func * <T> (a: [T]) -> (T, T) { (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T) { (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T) { (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4], a[5]) }

func printErr(_ str: String, terminator: String = "\n") {
    let s = str + terminator
    FileHandle.standardError.write(s.data(using: .utf8)!)
    FileHandle.standardError.synchronizeFile()
}

@inlinable func next() -> String { readLine()! }
@inlinable func nextInt() -> Int { Int(next())! }
@inlinable func nextDouble() -> Double { Double(next())! }
@inlinable func listOfString() -> [String] { next().split(separator: " ").map(String.init) }
@inlinable func listOfInt() -> [Int] { listOfString().map { Int($0)! } }
@inlinable func listOfInt(_ offset: Int = 0) -> [Int] { listOfString().map { Int($0)! + offset } }
@inlinable func listOfInt(_ offsets: Int ...) -> [Int] { listOfString().enumerated().map { Int($0.element)! + offsets[$0.offset % offsets.count] } }
@inlinable func listOfDouble(_ offset: Double = 0.0) -> [Double] { listOfString().map { Double($0)! + offset } }
@inlinable func listOfDouble(_ offsets: Double ...) -> [Double] { listOfString().enumerated().map { Double($0.element)! + offsets[$0.offset % offsets.count] } }

extension Int {
    init(s: String) { self.init(s)! }
    var isEven: Bool { self.isMultiple(of: 2) }
    var isOdd: Bool { !self.isEven }
    var isTrue: Bool { self != 0 }
    var isFalse: Bool { !self.isTrue }
    var toString: String { String(self) }
    var toChar: Character { Character(UnicodeScalar(UInt8(self))) }
}
func + (left: Int, right: Bool) -> Int { left + (right ? 1 : 0) }
extension Character {
    var asciiCode: Int { Int(self.asciiValue!) }
    var string: String { String(self) }
}
extension String {
    @inlinable subscript (position: Int) -> Character { self[self.index(self.startIndex, offsetBy: position)] }
    @inlinable func repeate(_ times: Int) -> String { String(repeating: self, count: times) }
    //  @inlinable subscript (n: Int) -> String { String(self[self.index(self.startIndex, offsetBy: n)]) }
    //  @inlinable subscript (n: Int) -> Int { Int(self[self.index(self.startIndex, offsetBy: n)].asciiValue!) }
    var toInt: Int { Int(self)! }
}
extension String { // VB like
    @inlinable func _index(_ position: Int) -> String.Index! {
        if !(0 ..< self.count ~= position) { return nil }
        return self.index(self.startIndex, offsetBy: position)
    }
    @inlinable func mid(from index: Int, length: Int) -> String! {
        if let startPosition = self._index(index) {
            if let endPosition = self._index(index + length - 1) {
                return String(self[startPosition...endPosition])
            } else {
                let endPosition = self.index(before: self.endIndex)
                return String(self[startPosition...endPosition])
            }
        }
        return ""
    }
    @inlinable func left(_ length: Int) -> String { String(self.prefix(length)) }
    @inlinable func right(_ length: Int) -> String { String(self.suffix(length)) }
}

extension Dictionary {
    @inlinable mutating func getOrSet(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored }
        else {
            let newValue = defaultValue()
            self[key] = newValue
            return newValue
        }
    }
    @inlinable mutating func getOrElse(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored } else { return defaultValue() }
    }
    @inlinable func containsKey(_ key: Key) -> Bool { self.keys.contains(key) }
}

extension Set {
    static func += (left: inout Set<Element>, right: Element) { left.insert(right) }
    static func -= (left: inout Set<Element>, right: Element) { left.remove(right) }
}

extension Array {
    static func += (left: inout Array<Element>, right: Element) { left.append(right) }
    init(_ size: Int, _ initValue: ((Int) -> Element)) {
        self = [Element]()
        for index in 0 ..< size {
            let value = initValue(index)
            self.append(value)
        }
    }
    init(_ size: Int, _ initValue: (() -> Element)) {
        self = [Element]()
        for _ in 0 ..< size {
            let value = initValue()
            self.append(value)
        }
    }
}
typealias IntArray = Array<Int>
typealias DoubleArray = Array<Double>
typealias BoolArray = Array<Bool>
typealias StringArray = Array<String>

extension Array where Element == Int {
    init(_ size: Int) {
        self = [Element](repeating: 0, count: size)
    }
}
extension Array where Element == Double {
    init(_ size: Int) {
        self = [Element](repeating: 0.0, count: size)
    }
}
extension Array where Element == Bool {
    init(_ size: Int) {
        self = [Element](repeating: false, count: size)
    }
}
extension Array where Element == String {
    init(_ size: Int) {
        self = [Element](repeating: "", count: size)
    }
}

extension Array {
    @inlinable func count(_ predicate: ((Element) -> Bool)) -> Int {
        var cnt = 0; for e in self { if (predicate(e)) { cnt += 1 } }
        return cnt
    }
    @inlinable func groupBy<K>(_ keySelector: (Element) -> K) -> [K : [Element]] {
        var destination = [K : [Element]]()
        for element in self {
            let key = keySelector(element)
            var list = destination.getOrSet(key) { [Element]() }
            list.append(element)
            destination[key] = list
        }
        return destination
    }
    @inlinable func groupByIndexed<K>(_ keySelector: (Element) -> K) -> [K : [Int]] {
        var destination = [K : [Int]]()
        for element in self.enumerated() {
            let key = keySelector(element.element)
            var list = destination.getOrSet(key) { [Int]() }
            list.append(element.offset)
            destination[key] = list
        }
        return destination
    }
}

extension Array {
    func binarySearch(_ element: Element, by compare: (Element, Element) -> Int, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            let cmp = compare(midVal, element)
            if (cmp < 0) { low = mid + 1 }          //-1
            else if (0 < cmp) { high = mid - 1 }    // 1
            else { return mid } // key found        // 0
        }
        return -(low + 1)  // key not found
    }
}
extension Array where Element : Comparable {
    func binarySearch(_ element: Element, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            if (midVal < element) { low = mid + 1 }
            else if (midVal > element) { high = mid - 1 }
            else { return mid } // key found
        }
        return -(low + 1)  // key not found
    }
}

extension Array where Element == Int {
    @inlinable func distinct() -> [Element] {
        var set = Set<Element>(), ary = [Element]()
        for n in self.indices { if !set.contains(self[n]) { ary.append(self[n]); set.insert(self[n]) } }
        return ary
    }
    @inlinable func any(_ predicate: (Element) -> Bool) -> Bool {
        var any = false; for element in self { if predicate(element) { any = true } }
        return any
    }
    @inlinable func all(_ predicate: (Element) -> Bool) -> Bool {
        self.allSatisfy(predicate)
    }
    @inlinable func sum() -> Element { self.reduce(0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}

extension Array where Element == Double {
    @inlinable func sum() -> Element { self.reduce(0.0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0.0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}
extension Array where Element == String {
    @inlinable func toIntDouble() -> (Int, Double) { (Int(self[0])!, Double(self[1])!) }
    @inlinable func toIntString() -> (Int, String) { (Int(self[0])!, self[1]) }
    @inlinable func toIntIntString() -> (Int, Int, String) { (Int(self[0])!, Int(self[1])!, self[2]) }
}

@inlinable func block( _ action: () -> Void) {
    action()
}
@inlinable func repeate(_ times1: Int, _ action: () -> Void) {
    for _ in 0 ..< times1 { action() }
}
@inlinable func repeate(_ times1: Int, _ action: (Int) -> Void) {
    for index1 in 0 ..< times1 {
        action(index1)
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ action: (Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            action(index1, index2)
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ action: (Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                action(index1, index2, index3)
            }
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ times4: Int, _ action: (Int, Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                for index4 in 0 ..< times4 {
                    action(index1, index2, index3, index4)
                }
            }
        }
    }
}

func measureTimeSeconds(block: (() -> Void)) -> Double {
    let startTime = Date()
    block()
    let duration = -startTime.timeIntervalSinceNow
    return duration
}

public class PriorityQueue<T> {
    private final var _heap: [T]
    private let compare: (T, T) -> Bool
    public init(_ compare: @escaping (T, T) -> Bool) {
        _heap = []
        self.compare = compare
    }
    public func push(_ newElement: T) {
        _heap.append(newElement)
        _ = siftUp(index: _heap.endIndex - 1)
    }
    public func peek() -> T? {
        if _heap.count == 0 { return nil }
        return _heap[0]
    }
    public func pop() -> T? {
        if _heap.count == 0 { return nil }
        _heap.swapAt(0, _heap.endIndex - 1)
        let pop = _heap.removeLast()
        _ = siftDown(index: 0)
        return pop
    }
    private func siftDown(index: Int) -> Bool {
        let left = index * 2 + 1
        let right = index * 2 + 2
        var smallest = index
        if left < _heap.count && compare(_heap[left], _heap[smallest]) { smallest = left }
        if right < _heap.count && compare(_heap[right], _heap[smallest]) { smallest = right }
        if smallest != index {
            _heap.swapAt(index, smallest)
            _ = siftDown(index: smallest)
            return true
        }
        return false
    }
    private func siftUp(index: Int) -> Bool {
        if index == 0 { return false }
        let parent = (index - 1) >> 1
        if compare(_heap[index], _heap[parent]) {
            _heap.swapAt(index, parent)
            _ = siftUp(index: parent)
            return true
        }
        return false
    }
}
extension PriorityQueue {
    public var count: Int { return _heap.count }
    public var isEmpty: Bool { return _heap.isEmpty }
    public func update<T2>(element: T2) -> T? where T2: Equatable {
        assert(element is T)  // How to enforce this with type constraints?
        for (index, item) in _heap.enumerated() {
            if (item as! T2) == element {
                _heap[index] = element as! T
                if siftDown(index: index) || siftUp(index: index) { return item }
            }
        }
        return nil
    }
    public func remove<T2>(element: T2) -> T? where T2: Equatable {
        assert(element is T)  // How to enforce this with type constraints?
        for (index, item) in _heap.enumerated() {
            if (item as! T2) == element {
                _heap.swapAt(index, _heap.endIndex - 1)
                _heap.removeLast()
                _ = siftDown(index: index)
                return item
            }
        }
        return nil
    }
    public var heap: [T] { return _heap }
    public func removeAll() { _heap.removeAll() }
    public func addAll(_ elements: [T]) { for e in elements { self.push(e) } }
}


import Foundation

let main: () = {
    let N = nextInt()
    let S = next()
    var R = 0, G = 0, B = 0
    S.forEach {
        switch ($0) {
        case "R": R += 1
        case "G": G += 1
        case "B": B += 1
        default: break
        }
    }
    let total = R * G * B
    var exc = 0
    for n in 0 ..< N - 2 {
        for m in n + 1 ..< N - 1 {
            let k = m + (m - n)
            if k >= N { continue }
            if S[n] != S[m] && S[n] != S[k] && S[m] != S[k] { exc += 1 }
        }
    }
    let ans = total - exc
    print(ans)
}()

//----------------------------------

let dx = [1, 0, -1, 0] //[1, 0, -1, 0, -1,  1, -1, 1]
let dy = [0, 1, 0, -1] //[0, 1, 0, -1, -1, -1,  1, 1]

@inlinable func gcd(_ a: Int, _ b: Int) -> Int { (b > 0) ? gcd(b, a % b) : a }
@inlinable func lcm(_ a: Int, _ b: Int) -> Int { a / gcd(a, b) * b }

//----------------------------------

infix operator  =~ : ComparisonPrecedence
infix operator !=~ : ComparisonPrecedence
func =~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { !(right ~= left) }
func =~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { !(right ~= left) }

func =~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { right.contains(left) }
func !=~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { !right.contains(left) }

infix operator /^ : MultiplicationPrecedence
infix operator /^= : AssignmentPrecedence
func /^ <T: FixedWidthInteger>(left: T, right: T) -> T { (left + (right - 1)) / right }
func /^= <T: FixedWidthInteger>(left: inout T, right: T) { left = (left + (right - 1)) / right }

@inlinable func chmax<T: Comparable>(_ m: inout T, _ q: T) { if (m < q) { m = q } }
@inlinable func chmin<T: Comparable>(_ m: inout T, _ q: T) { if (m > q) { m = q } }
@inlinable func chRmax<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m < q) { m = q; return true } else { return false } }
@inlinable func chRmin<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m > q) { m = q; return true } else { return false } }

prefix operator *
prefix func * <T> (a: [T]) -> (T, T) { (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T) { (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T) { (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4], a[5]) }

func printErr(_ str: String, terminator: String = "\n") {
    let s = str + terminator
    FileHandle.standardError.write(s.data(using: .utf8)!)
    FileHandle.standardError.synchronizeFile()
}

@inlinable func next() -> String { readLine()! }
@inlinable func nextInt() -> Int { Int(next())! }
@inlinable func nextDouble() -> Double { Double(next())! }
@inlinable func listOfString() -> [String] { next().split(separator: " ").map(String.init) }
@inlinable func listOfInt() -> [Int] { listOfString().map { Int($0)! } }
@inlinable func listOfInt(_ offset: Int = 0) -> [Int] { listOfString().map { Int($0)! + offset } }
@inlinable func listOfInt(_ offsets: Int ...) -> [Int] { listOfString().enumerated().map { Int($0.element)! + offsets[$0.offset % offsets.count] } }
@inlinable func listOfDouble(_ offset: Double = 0.0) -> [Double] { listOfString().map { Double($0)! + offset } }
@inlinable func listOfDouble(_ offsets: Double ...) -> [Double] { listOfString().enumerated().map { Double($0.element)! + offsets[$0.offset % offsets.count] } }

extension Int {
    init(s: String) { self.init(s)! }
    var isEven: Bool { self.isMultiple(of: 2) }
    var isOdd: Bool { !self.isEven }
    var isTrue: Bool { self != 0 }
    var isFalse: Bool { !self.isTrue }
    var toString: String { String(self) }
    var toChar: Character { Character(UnicodeScalar(UInt8(self))) }
}
func + (left: Int, right: Bool) -> Int { left + (right ? 1 : 0) }
extension Character {
    var asciiCode: Int { Int(self.asciiValue!) }
    var string: String { String(self) }
}
extension String {
    @inlinable subscript (position: Int) -> Character { self[self.index(self.startIndex, offsetBy: position)] }
    @inlinable func repeate(_ times: Int) -> String { String(repeating: self, count: times) }
    //  @inlinable subscript (n: Int) -> String { String(self[self.index(self.startIndex, offsetBy: n)]) }
    //  @inlinable subscript (n: Int) -> Int { Int(self[self.index(self.startIndex, offsetBy: n)].asciiValue!) }
    var toInt: Int { Int(self)! }
}
extension String { // VB like
    @inlinable func _index(_ position: Int) -> String.Index! {
        if !(0 ..< self.count ~= position) { return nil }
        return self.index(self.startIndex, offsetBy: position)
    }
    @inlinable func mid(from index: Int, length: Int) -> String! {
        if let startPosition = self._index(index) {
            if let endPosition = self._index(index + length - 1) {
                return String(self[startPosition...endPosition])
            } else {
                let endPosition = self.index(before: self.endIndex)
                return String(self[startPosition...endPosition])
            }
        }
        return ""
    }
    @inlinable func left(_ length: Int) -> String { String(self.prefix(length)) }
    @inlinable func right(_ length: Int) -> String { String(self.suffix(length)) }
}

extension Dictionary {
    @inlinable mutating func getOrSet(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored }
        else {
            let newValue = defaultValue()
            self[key] = newValue
            return newValue
        }
    }
    @inlinable mutating func getOrElse(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored } else { return defaultValue() }
    }
    @inlinable func containsKey(_ key: Key) -> Bool { self.keys.contains(key) }
}

extension Set {
    static func += (left: inout Set<Element>, right: Element) { left.insert(right) }
    static func -= (left: inout Set<Element>, right: Element) { left.remove(right) }
}

extension Array {
    static func += (left: inout Array<Element>, right: Element) { left.append(right) }
    init(_ size: Int, _ initValue: ((Int) -> Element)) {
        self = [Element]()
        for index in 0 ..< size {
            let value = initValue(index)
            self.append(value)
        }
    }
    init(_ size: Int, _ initValue: (() -> Element)) {
        self = [Element]()
        for _ in 0 ..< size {
            let value = initValue()
            self.append(value)
        }
    }
}
typealias IntArray = Array<Int>
typealias DoubleArray = Array<Double>
typealias BoolArray = Array<Bool>
typealias StringArray = Array<String>

extension Array where Element == Int {
    init(_ size: Int) {
        self = [Element](repeating: 0, count: size)
    }
}
extension Array where Element == Double {
    init(_ size: Int) {
        self = [Element](repeating: 0.0, count: size)
    }
}
extension Array where Element == Bool {
    init(_ size: Int) {
        self = [Element](repeating: false, count: size)
    }
}
extension Array where Element == String {
    init(_ size: Int) {
        self = [Element](repeating: "", count: size)
    }
}

extension Array {
    @inlinable func count(_ predicate: ((Element) -> Bool)) -> Int {
        var cnt = 0; for e in self { if (predicate(e)) { cnt += 1 } }
        return cnt
    }
    @inlinable func groupBy<K>(_ keySelector: (Element) -> K) -> [K : [Element]] {
        var destination = [K : [Element]]()
        for element in self {
            let key = keySelector(element)
            var list = destination.getOrSet(key) { [Element]() }
            list.append(element)
            destination[key] = list
        }
        return destination
    }
    @inlinable func groupByIndexed<K>(_ keySelector: (Element) -> K) -> [K : [Int]] {
        var destination = [K : [Int]]()
        for element in self.enumerated() {
            let key = keySelector(element.element)
            var list = destination.getOrSet(key) { [Int]() }
            list.append(element.offset)
            destination[key] = list
        }
        return destination
    }
}

extension Array {
    func binarySearch(_ element: Element, by compare: (Element, Element) -> Int, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            let cmp = compare(midVal, element)
            if (cmp < 0) { low = mid + 1 }          //-1
            else if (0 < cmp) { high = mid - 1 }    // 1
            else { return mid } // key found        // 0
        }
        return -(low + 1)  // key not found
    }
}
extension Array where Element : Comparable {
    func binarySearch(_ element: Element, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            if (midVal < element) { low = mid + 1 }
            else if (midVal > element) { high = mid - 1 }
            else { return mid } // key found
        }
        return -(low + 1)  // key not found
    }
}

extension Array where Element == Int {
    @inlinable func distinct() -> [Element] {
        var set = Set<Element>(), ary = [Element]()
        for n in self.indices { if !set.contains(self[n]) { ary.append(self[n]); set.insert(self[n]) } }
        return ary
    }
    @inlinable func any(_ predicate: (Element) -> Bool) -> Bool {
        var any = false; for element in self { if predicate(element) { any = true } }
        return any
    }
    @inlinable func all(_ predicate: (Element) -> Bool) -> Bool {
        self.allSatisfy(predicate)
    }
    @inlinable func sum() -> Element { self.reduce(0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}

extension Array where Element == Double {
    @inlinable func sum() -> Element { self.reduce(0.0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0.0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}
extension Array where Element == String {
    @inlinable func toIntDouble() -> (Int, Double) { (Int(self[0])!, Double(self[1])!) }
    @inlinable func toIntString() -> (Int, String) { (Int(self[0])!, self[1]) }
    @inlinable func toIntIntString() -> (Int, Int, String) { (Int(self[0])!, Int(self[1])!, self[2]) }
}

@inlinable func block( _ action: () -> Void) {
    action()
}
@inlinable func repeate(_ times1: Int, _ action: () -> Void) {
    for _ in 0 ..< times1 { action() }
}
@inlinable func repeate(_ times1: Int, _ action: (Int) -> Void) {
    for index1 in 0 ..< times1 {
        action(index1)
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ action: (Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            action(index1, index2)
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ action: (Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                action(index1, index2, index3)
            }
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ times4: Int, _ action: (Int, Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                for index4 in 0 ..< times4 {
                    action(index1, index2, index3, index4)
                }
            }
        }
    }
}

func measureTimeSeconds(block: (() -> Void)) -> Double {
    let startTime = Date()
    block()
    let duration = -startTime.timeIntervalSinceNow
    return duration
}

public class PriorityQueue<T> {
    private final var _heap: [T]
    private let compare: (T, T) -> Bool
    public init(_ compare: @escaping (T, T) -> Bool) {
        _heap = []
        self.compare = compare
    }
    public func push(_ newElement: T) {
        _heap.append(newElement)
        _ = siftUp(index: _heap.endIndex - 1)
    }
    public func peek() -> T? {
        if _heap.count == 0 { return nil }
        return _heap[0]
    }
    public func pop() -> T? {
        if _heap.count == 0 { return nil }
        _heap.swapAt(0, _heap.endIndex - 1)
        let pop = _heap.removeLast()
        _ = siftDown(index: 0)
        return pop
    }
    private func siftDown(index: Int) -> Bool {
        let left = index * 2 + 1
        let right = index * 2 + 2
        var smallest = index
        if left < _heap.count && compare(_heap[left], _heap[smallest]) { smallest = left }
        if right < _heap.count && compare(_heap[right], _heap[smallest]) { smallest = right }
        if smallest != index {
            _heap.swapAt(index, smallest)
            _ = siftDown(index: smallest)
            return true
        }
        return false
    }
    private func siftUp(index: Int) -> Bool {
        if index == 0 { return false }
        let parent = (index - 1) >> 1
        if compare(_heap[index], _heap[parent]) {
            _heap.swapAt(index, parent)
            _ = siftUp(index: parent)
            return true
        }
        return false
    }
}
extension PriorityQueue {
    public var count: Int { return _heap.count }
    public var isEmpty: Bool { return _heap.isEmpty }
    public func update<T2>(element: T2) -> T? where T2: Equatable {
        assert(element is T)  // How to enforce this with type constraints?
        for (index, item) in _heap.enumerated() {
            if (item as! T2) == element {
                _heap[index] = element as! T
                if siftDown(index: index) || siftUp(index: index) { return item }
            }
        }
        return nil
    }
    public func remove<T2>(element: T2) -> T? where T2: Equatable {
        assert(element is T)  // How to enforce this with type constraints?
        for (index, item) in _heap.enumerated() {
            if (item as! T2) == element {
                _heap.swapAt(index, _heap.endIndex - 1)
                _heap.removeLast()
                _ = siftDown(index: index)
                return item
            }
        }
        return nil
    }
    public var heap: [T] { return _heap }
    public func removeAll() { _heap.removeAll() }
    public func addAll(_ elements: [T]) { for e in elements { self.push(e) } }
}


let N = 39

let rgbArray = Array(" RBRBGRBGGBBRRGBBRRRBGGBRBGBRBGBRBBBGBBB")
print(rgbArray)
var count = 0

var rgbIndex = Array(repeating: Array(repeating: 0, count: 0), count: 3)

rgbArray.enumerated().forEach{
    if $0.1 == "R"{
        rgbIndex[0].append($0.0)
    }
    if $0.1 == "G"{
        rgbIndex[1].append($0.0)
    }
    if $0.1 == "B"{
        rgbIndex[2].append($0.0)
    }

}
var total = rgbIndex[2].count*rgbIndex[1].count*rgbIndex[0].count

for i in 1...(N-2) {
    for j in (i+1)...(N-1) {
        let x = j - i
        let k = j + x
        if k <= N && rgbArray[i] != rgbArray[j] && rgbArray[i] != rgbArray[k] && rgbArray[j] != rgbArray[k]{
            total -= 1
        }

    }
}

print(total)


export class Main {
  static main(input: string): string {
    const tmp: string[] = input.split("\n");
    const [n]: number[] = tmp.shift().split(" ").map(int => parseInt(int));
    const [s]: string[] = tmp.shift().split(" ");
    const sList = s.split("").slice(0, n);
    let rCount = 0;
    let gCount = 0;
    let bCount = 0;
    for (let i = 0, leni = n; i < leni; i++) {
      switch (sList[i]) {
        case "R":
          rCount++;
          break;
        case "G":
          gCount++;
          break;
        default:
          bCount++;
      }
    }
    let allCount = rCount * gCount * bCount;
    let noCount = 0;
    for (let j = 1, lenj = n - 1; j < lenj; j++) {
      for (let d = 1, len = Math.min(j, n - (j + 1)); d <= len; d++) {
        let si = sList[j - d];
        let sj = sList[j];
        let sk = sList[j + d];
        if (si != sj && sj != sk && sk != si) {
          noCount++;
        }
      }
    }
    return `${allCount - noCount}`;
  }
}
console.log(Main.main(require("fs").readFileSync("/dev/stdin", "utf8")));