//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("O2")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//
//#pragma GCC target("ssse3,sse4,popcnt,abm,mmx")
#include <bits/stdc++.h>

#include <utility>

#define all(x) (x).begin(), (x).end()
#define allp(x) (x)->begin(), (x)->end()

#define pb push_back
#define GLIBCDEBUG

using namespace std;
void dout() { cerr << endl; }
//typedef long long ll;
template <typename Head, typename... Tail>
void dout(Head H, Tail... T) {
    cerr << H << ' ';
    dout(T...);
}

using ll = long long;
//#ifdef __int128
//using hll = __int128;
//#endif
using pii = pair<ll, ll>;
using ld = long double;

template <typename T>
void do_uniq(vector<T> &vec){
    sort(all(vec));
    vec.resize(unique(all(vec)) - vec.begin());
}

#ifndef ONLINE_JUDGE
clock_t timestamp_start = clock();
void time_calc()
{
    cerr << (ld)(clock() - timestamp_start) / CLOCKS_PER_SEC << "\n";
}
#endif


#ifdef _getchar_nolock
#else
#    define _getchar_nolock getchar_unlocked
#endif

#define integer int

 integer mod = 1e9 + 7;

integer ml(integer a, integer b) {
    return (a * 1ll * b) % mod;
}

integer add(integer a, integer b) {
    integer rt = a + b;
    if (rt < mod) return rt;
    return rt - mod;
}

integer sub(integer a, integer b) {
    return add(a, mod - b);
}

integer sq(integer a) {
    return ml(a, a);
}

integer b_p(integer b, ll p) {
    if (p == 0) return 1;
    if (p & 1) return ml(b, b_p(b, p - 1));
    return sq(b_p(b, p >> 1));
}

integer divv(integer a, integer b) {
    return ml(a, b_p(b, mod - 2));
}

const ll inf = 1e9 + 231;

#define solvsh
//#define multi

//#define GLIBCXX_DEBUG

//#define STRESS
#ifdef solvsh

const int MAXN = 20;

int tables[MAXN][MAXN];

int lenn[MAXN];

int wss[26];

void solve() {

    ll answr = 0;
    string s;
    cin >> s;

    int n = s.size();

    int ptr = n  - 1;

    while (ptr > 0) {
        if (s[ptr - 1] == s[ptr]) {

            answr += n - 1 - ptr - wss[s[ptr] - 'a'];


            for (int i = 0; i < 26; ++i) wss[i] = 0;
            wss[s[ptr] - 'a'] = n + 1 - ptr;
            --ptr;
            --ptr;

        } else {
            wss[s[ptr] - 'a']++;
            --ptr;
        }
    }

    cout << answr << "\n";
}


#else

#endif
#ifndef STRESS

void multisolve() {
//    precalc();
    int t;
    cin >> t;


    int i = 1;
    while (t--) {
        solve();
        i++;
    }

}


void singlesolve (){
//    precalc();
    solve();

//    cerr << cnt << "\n";
}

#else

#endif

#ifndef ONLINE_JUDGE

#endif


#define int int
signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    cout << fixed << setprecision(20);



#ifdef multi
    //            gen();

    multisolve();
#else
    singlesolve();
//    gen();
#endif

}
#include <bits/stdc++.h>
#define rep(a,n) for (ll a = 0; a < (n); ++a)
using namespace std;
//using namespace atcoder;
using ll = long long;
typedef pair<ll,ll> P;
typedef pair<ll,P> PP;
typedef vector<vector<int> > Graph;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a >= b) { a = b; return 1; } return 0; }
const ll INF = 1e18;
#define SZ(x) ((int)(x).size())

#define debug(v) cout<<#v<<": ",prt(v);
template <typename A,typename B>
inline void prt(pair<A,B> p){cout<<"("<<p.first<<", "<<p.second<<")\n";}
template <typename A,typename B,typename C>
inline void prt(tuple<A,B,C> p){cout<<"("<<get<0>(p)<<", "<<get<1>(p)<<", "<<get<2>(p)<<")\n";}
inline void prt(bool p){if(p)cout<<"True"<<'\n';else cout<<"False"<<'\n';}
template <typename T> 
inline void prt(vector<T> v){cout<<'{';for(ll i=0;i<v.size();i++){cout<<v[i];if(i<v.size()-1)cout<<", ";}cout<<'}'<<'\n';}
template<typename T> 
inline void prt(vector<vector<T> >& vv){ for(const auto& v : vv){ prt(v); } }
template <typename T> 
inline void prt(deque<T> v){cout<<'{';for(ll i=0;i<v.size();i++){cout<<v[i];if(i<v.size()-1)cout<<", ";}cout<<'}'<<'\n';}
template <typename A,typename B>
inline void prt(map<A,B> v){cout<<'{';ll c=0;for(auto &p: v){cout<<p.first<<":"<<p.second;c++;if(c!=v.size())cout<<", ";}cout<<'}'<<'\n';}
template <typename A,typename B>
inline void prt(unordered_map<A,B> v){cout<<'{';ll c=0;for(auto &p: v){cout<<p.first<<":"<<p.second;c++;if(c!=v.size())cout<<", ";}cout<<'}'<<'\n';}
template <typename T> 
inline void prt(set<T> v){cout<<'{';for(auto i=v.begin();i!=v.end();i++){cout<<*i;if(i!=--v.end())cout<<", ";}cout<<'}'<<'\n';}
template <typename T> 
inline void prt(multiset<T> v){cout<<'{';for(auto i=v.begin();i!=v.end();i++){cout<<*i;if(i!=--v.end())cout<<", ";}cout<<'}'<<'\n';}

/*
l = s.size()
各文字の出現回数について累積和を取っておく
lが大きい方から見ていく
s[i]==s[i+1]!=s[i+2]ならひっくり返す
前回ひっくり返した文字と違う文字なら全部ひっくり返して、同じ文字なら途中までひっくり返す

*/

int main(){
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	string s;
	cin >> s;
	ll l = s.size();
	vector<vector<ll> >cnt(26,vector<ll>(l+1,0));
	for(int i=1;i<=l;i++){
		rep(j,26)cnt[j][i]=cnt[j][i-1];
		int id = s[i-1]-'a';
		cnt[id][i]++;
	}
	ll last_id = l+1;
	ll last_char = '.';
	ll ans = 0;
	//debug(cnt[2]);
	for(int i=l-2;i>=1;i--){
		if(s[i-1]==s[i]&&s[i+1]!=s[i-1]){
			ans += (last_id-i)-(cnt[s[i-1]-'a'][last_id-1]-cnt[s[i-1]-'a'][i-1]);
			//cout << (last_id-i) << endl;
			//cout << (cnt[s[i]-'a'][last_id-1]-cnt[s[i]-'a'][i-1]) << endl;
			if(last_char!=s[i-1]){
				ans += l-last_id+1;
				//cout << ans << endl;
			}
			last_char = s[i-1];
			last_id = i+2;
		}
	}
	cout << ans << endl;
	return 0;
}