#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
using namespace std;
using namespace __gnu_pbds;
#ifndef ONLINE_JUDGE
#include "debug.cpp"
#else
#define dbg(...)
#endif
#define endl "\n"
#define FAST ios_base::sync_with_stdio(false); cin.tie(NULL);
#define ll long long
#define pb(n) push_back(n)
#define F first
#define S second
#define mp(x, y) make_pair(x, y)
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
#define nop cout << -1 << endl;
#define ordered_set tree<pair<int, int>, null_type, less<pair<int, int>>, rb_tree_tag, tree_order_statistics_node_update>
const ll sup = 1e18;
const ll inf = -1e18;
const ll mod = 1e9 + 7;
const int N_Max = 2e5 + 7;
const int Nax = 15;
const int LOG = 18;
const int BITS = 30;
const int ALPHA = 26;
ll gcd(ll a , ll b) {return b ? gcd(b , a % b) : a;}
ll lcm(ll a , ll b) {return (a * b) / gcd(a , b);}
ll inv(ll N) {if (N == 1) return 1; return (mod - ((mod / N) * inv(mod % N)) % mod) % mod;}
const ll B = 9973;
ll prefix[N_Max], suffix[N_Max];
int N;
ll binpow(ll a, ll b){
ll res = 1;
while (b > 0) {
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
ll bs2(int i, int p, int re){
int lo = i - re - 1, ro = p + re + 1;
if (lo < 0 || ro >= N) return 0;
int l = 0, r = min(N - 1 - ro, lo), ret = 0;
dbg(l);
dbg(r);
while (l <= r){
int mid = l + (r - l) / 2;
int j = ro + mid, k = lo - mid;
ll hash1 = (prefix[j] - prefix[ro] + mod) % mod * inv(binpow(B, ro) % mod) % mod;
ll hash2 = (suffix[k] - suffix[lo] + mod) % mod * inv(binpow(B, N - 1 - lo) % mod) % mod;
if (hash1 == hash2){
ret = j;
l = mid + 1;
}
else r = mid - 1;
}
dbg(ret);
return ret + 1;
}
ll bs1(int i, int p){
int l = 0, r = min(i, N - 1 - p), ret = 0;
while (l <= r){
int mid = l + (r - l) / 2;
int d = mid - i;
int j = i - mid, k = p + mid;
ll hash1 = (prefix[k] - prefix[p] + mod) % mod * inv(binpow(B, p + 1)) % mod;
ll hash2 = (suffix[j] - suffix[i] + mod) % mod * inv(binpow(B, N - 1 - i)) % mod;
if (hash1 == hash2){
ret = mid;
l = mid + 1;
}
else r = mid - 1;
}
int co = bs2(i, p, ret);
dbg(co);
ret += co;
return ret;
}
void solve(){
string s;
cin >> N >> s;
for (int i = 0; i < N; i++){
ll c = (s[i] - 'a') + 1;
ll pre = (i == 0 ? 0 : prefix[i - 1]);
prefix[i] = (pre + c * binpow(B, i) % mod) % mod;
}
for (int i = N - 1; i >= 0; i--){
ll c = (s[i] - 'a') + 1;
ll nxt = (i == N - 1 ? 0 : suffix[i + 1]);
suffix[i] = (nxt + c * binpow(B, N - 1 - i) % mod) % mod;
}
ll ans = 0;
for (int i = 0; i < N; i++){
ll ret = bs1(i, i);
dbg(i);
dbg(ret);
cout << endl;
ans += ret + 1;
if (i + 1 < N && s[i] == s[i + 1])
ans += bs1(i, i + 1) + 1;
else if (i + 1 < N && s[i] != s[i + 1])
ans += bs2(i + 1, i - 1, 0) + 1;
}
cout << ans << endl;
}
int main(){
FAST
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
int tc = 1;
// cin >> tc;
while (tc--) solve();
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNpbmNsdWRlIDxleHQvcGJfZHMvYXNzb2NfY29udGFpbmVyLmhwcD4gLy8gQ29tbW9uIGZpbGUKI2luY2x1ZGUgPGV4dC9wYl9kcy90cmVlX3BvbGljeS5ocHA+IC8vIEluY2x1ZGluZyB0cmVlX29yZGVyX3N0YXRpc3RpY3Nfbm9kZV91cGRhdGUKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbmFtZXNwYWNlIF9fZ251X3BiZHM7CiNpZm5kZWYgT05MSU5FX0pVREdFCiNpbmNsdWRlICJkZWJ1Zy5jcHAiCiNlbHNlCiNkZWZpbmUgZGJnKC4uLikKI2VuZGlmCiNkZWZpbmUgZW5kbCAiXG4iCiNkZWZpbmUgRkFTVCBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsgY2luLnRpZShOVUxMKTsKI2RlZmluZSBsbCBsb25nIGxvbmcKI2RlZmluZSBwYihuKSBwdXNoX2JhY2sobikKI2RlZmluZSBGIGZpcnN0CiNkZWZpbmUgUyBzZWNvbmQKI2RlZmluZSBtcCh4LCB5KSBtYWtlX3BhaXIoeCwgeSkKI2RlZmluZSB5ZXMgY291dCA8PCAiWUVTIiA8PCBlbmRsOwojZGVmaW5lIG5vIGNvdXQgPDwgIk5PIiA8PCBlbmRsOwojZGVmaW5lIG5vcCBjb3V0IDw8IC0xIDw8IGVuZGw7CiNkZWZpbmUgb3JkZXJlZF9zZXQgdHJlZTxwYWlyPGludCwgaW50PiwgbnVsbF90eXBlLCBsZXNzPHBhaXI8aW50LCBpbnQ+PiwgcmJfdHJlZV90YWcsIHRyZWVfb3JkZXJfc3RhdGlzdGljc19ub2RlX3VwZGF0ZT4KY29uc3QgbGwgc3VwID0gMWUxODsKY29uc3QgbGwgaW5mID0gLTFlMTg7CmNvbnN0IGxsIG1vZCA9IDFlOSArIDc7CmNvbnN0IGludCBOX01heCA9IDJlNSArIDc7CmNvbnN0IGludCBOYXggPSAxNTsKY29uc3QgaW50IExPRyA9IDE4Owpjb25zdCBpbnQgQklUUyA9IDMwOwpjb25zdCBpbnQgQUxQSEEgPSAyNjsKbGwgZ2NkKGxsIGEgLCBsbCBiKSB7cmV0dXJuIGIgPyBnY2QoYiAsIGEgJSBiKSA6IGE7fQpsbCBsY20obGwgYSAsIGxsIGIpIHtyZXR1cm4gKGEgKiBiKSAvIGdjZChhICwgYik7fQpsbCBpbnYobGwgTikge2lmIChOID09IDEpIHJldHVybiAxOyByZXR1cm4gKG1vZCAtICgobW9kIC8gTikgKiBpbnYobW9kICUgTikpICUgbW9kKSAlIG1vZDt9Cgpjb25zdCBsbCBCID0gOTk3MzsKbGwgcHJlZml4W05fTWF4XSwgc3VmZml4W05fTWF4XTsKaW50IE47CgpsbCBiaW5wb3cobGwgYSwgbGwgYil7CiAgICBsbCByZXMgPSAxOwogICAgd2hpbGUgKGIgPiAwKSB7CiAgICAgICAgaWYgKGIgJiAxKQogICAgICAgICAgICByZXMgPSByZXMgKiBhICUgbW9kOwogICAgICAgIGEgPSBhICogYSAlIG1vZDsKICAgICAgICBiID4+PSAxOwogICAgfQogICAgcmV0dXJuIHJlczsKfQoKbGwgYnMyKGludCBpLCBpbnQgcCwgaW50IHJlKXsKICAgIGludCBsbyA9IGkgLSByZSAtIDEsIHJvID0gcCArIHJlICsgMTsKICAgIGlmIChsbyA8IDAgfHwgcm8gPj0gTikgcmV0dXJuIDA7CiAgICBpbnQgbCA9IDAsIHIgPSBtaW4oTiAtIDEgLSBybywgbG8pLCByZXQgPSAwOwogICAgZGJnKGwpOwogICAgZGJnKHIpOwogICAgd2hpbGUgKGwgPD0gcil7CiAgICAgICAgaW50IG1pZCA9IGwgKyAociAtIGwpIC8gMjsKICAgICAgICBpbnQgaiA9IHJvICsgbWlkLCBrID0gbG8gLSBtaWQ7CiAgICAgICAgbGwgaGFzaDEgPSAocHJlZml4W2pdIC0gcHJlZml4W3JvXSArIG1vZCkgJSBtb2QgKiBpbnYoYmlucG93KEIsIHJvKSAlIG1vZCkgJSBtb2Q7CiAgICAgICAgbGwgaGFzaDIgPSAoc3VmZml4W2tdIC0gc3VmZml4W2xvXSArIG1vZCkgJSBtb2QgKiBpbnYoYmlucG93KEIsIE4gLSAxIC0gbG8pICUgbW9kKSAlIG1vZDsKICAgICAgICBpZiAoaGFzaDEgPT0gaGFzaDIpewogICAgICAgICAgICByZXQgPSBqOwogICAgICAgICAgICBsID0gbWlkICsgMTsKICAgICAgICB9CiAgICAgICAgZWxzZSByID0gbWlkIC0gMTsKICAgIH0KICAgIGRiZyhyZXQpOwogICAgcmV0dXJuIHJldCArIDE7Cn0KCmxsIGJzMShpbnQgaSwgaW50IHApewogICAgaW50IGwgPSAwLCByID0gbWluKGksIE4gLSAxIC0gcCksIHJldCA9IDA7CiAgICB3aGlsZSAobCA8PSByKXsKICAgICAgICBpbnQgbWlkID0gbCArIChyIC0gbCkgLyAyOwogICAgICAgIGludCBkID0gbWlkIC0gaTsKICAgICAgICBpbnQgaiA9IGkgLSBtaWQsIGsgPSBwICsgbWlkOwogICAgICAgIGxsIGhhc2gxID0gKHByZWZpeFtrXSAtIHByZWZpeFtwXSArIG1vZCkgJSBtb2QgKiBpbnYoYmlucG93KEIsIHAgKyAxKSkgJSBtb2Q7CiAgICAgICAgbGwgaGFzaDIgPSAoc3VmZml4W2pdIC0gc3VmZml4W2ldICsgbW9kKSAlIG1vZCAqIGludihiaW5wb3coQiwgTiAtIDEgLSBpKSkgJSBtb2Q7CiAgICAgICAgaWYgKGhhc2gxID09IGhhc2gyKXsKICAgICAgICAgICAgcmV0ID0gbWlkOwogICAgICAgICAgICBsID0gbWlkICsgMTsKICAgICAgICB9CiAgICAgICAgZWxzZSByID0gbWlkIC0gMTsKICAgIH0KICAgIGludCBjbyA9IGJzMihpLCBwLCByZXQpOwogICAgZGJnKGNvKTsKICAgIHJldCArPSBjbzsKICAgIHJldHVybiByZXQ7Cn0KCnZvaWQgc29sdmUoKXsKICAgIHN0cmluZyBzOwogICAgY2luID4+IE4gPj4gczsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKXsKICAgICAgICBsbCBjID0gKHNbaV0gLSAnYScpICsgMTsKICAgICAgICBsbCBwcmUgPSAoaSA9PSAwID8gMCA6IHByZWZpeFtpIC0gMV0pOwogICAgICAgIHByZWZpeFtpXSA9IChwcmUgKyBjICogYmlucG93KEIsIGkpICUgbW9kKSAlIG1vZDsKICAgIH0KICAgIGZvciAoaW50IGkgPSBOIC0gMTsgaSA+PSAwOyBpLS0pewogICAgICAgIGxsIGMgPSAoc1tpXSAtICdhJykgKyAxOwogICAgICAgIGxsIG54dCA9IChpID09IE4gLSAxID8gMCA6IHN1ZmZpeFtpICsgMV0pOwogICAgICAgIHN1ZmZpeFtpXSA9IChueHQgKyBjICogYmlucG93KEIsIE4gLSAxIC0gaSkgJSBtb2QpICUgbW9kOwogICAgfQogICAgbGwgYW5zID0gMDsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKXsKICAgICAgICBsbCByZXQgPSBiczEoaSwgaSk7CiAgICAgICAgZGJnKGkpOwogICAgICAgIGRiZyhyZXQpOwogICAgICAgIGNvdXQgPDwgZW5kbDsKICAgICAgICBhbnMgKz0gcmV0ICsgMTsKICAgICAgICBpZiAoaSArIDEgPCBOICYmIHNbaV0gPT0gc1tpICsgMV0pCiAgICAgICAgICAgIGFucyArPSBiczEoaSwgaSArIDEpICsgMTsKICAgICAgICBlbHNlIGlmIChpICsgMSA8IE4gJiYgc1tpXSAhPSBzW2kgKyAxXSkKICAgICAgICAgICAgYW5zICs9IGJzMihpICsgMSwgaSAtIDEsIDApICsgMTsKICAgIH0KICAgIGNvdXQgPDwgYW5zIDw8IGVuZGw7Cn0KCmludCBtYWluKCl7CiAgICBGQVNUCiAgICAjaWZuZGVmIE9OTElORV9KVURHRQogICAgZnJlb3BlbigiaW5wdXQudHh0IiwiciIsc3RkaW4pOwogICAgZnJlb3Blbigib3V0cHV0LnR4dCIsInciLHN0ZG91dCk7CiAgICAjZW5kaWYKICAgIGludCB0YyA9IDE7CiAgICAvLyBjaW4gPj4gdGM7CiAgICB3aGlsZSAodGMtLSkgc29sdmUoKTsKICAgIHJldHVybiAwOwp9