#include<random>
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<string.h>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...) do {} while (0)
#endif
#include<cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)

template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
    for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
    putchar('\n');
}
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef unsigned long long ULL;
using HashMap = gp_hash_table<ULL, int>;

ULL add(ULL x, ULL y, ULL m) {
    if ((x += y) >= m) x -= m;
    return x;
}
ULL mul(ULL x, ULL y, ULL m) {
    (x *= y) %= m;
    return x;
}

ULL gcd(ULL x, ULL y) {
    while (1) {
	if (x) y %= x; else return y;
	if (y) x %= y; else return x;
    }
}

// xs + yt = gcd(x, y), xu + yv = 0
// abs(s) < abs(y / gcd(x, y));
// abs(t) < abs(x / gcd(x, y));
LL extgcd(LL x, LL y, LL&s, LL&t) {
    for (LL u=t=1, v=s=0; x; ) {
	LL q = y / x;
	swap(s -= q * u, u);
	swap(t -= q * v, v);
	swap(y -= q * x, x);
    }
    return y;
}

LL invMod(LL a, LL mod) {
    LL x, y;
    if (extgcd(a, mod, x, y) == 1) return (x + mod) % mod;
    return 0; // unsolvable
}
int N;
char S[250011];

const int SIZE = 3;
ULL MOD[SIZE];
ULL B[SIZE];
ULL INV_B[SIZE];
ULL C[SIZE];
ULL VAL[SIZE];
ULL WHOLE[SIZE];
HashMap mp[SIZE];

mt19937 engine(285694);

void MAIN() {
    scanf("%d%s", &N, S);

    REP (t, SIZE) {
	C[t] = 1;
	while (1) {
	    MOD[t] = engine() % 1000000009;
	    if (MOD[t] == 0) continue;
	    B[t] = engine() % MOD[t];
	    ULL g = gcd(MOD[t], B[t]);
	    MOD[t] /= g;
	    B[t] /= g;
	    if (B[t] <= 1 || B[t] == MOD[t]-1) continue;
	    INV_B[t] = invMod(B[t], MOD[t]);
	    break;
	}
    }

    REP (i, N) {
	REP (t, SIZE) {
	    ULL &val = VAL[t];
	    ULL &c = C[t];
	    const ULL mod = MOD[t];
	    const ULL b = B[t];
	    const ULL invB = INV_B[t];

	    if (false) {
	    } else if (S[i] == '>') {
		c = mul(c, b, mod);
	    } else if (S[i] == '<') {
		c = mul(c, invB, mod);
	    } else if (S[i] == '+') {
		val = add(val, c, mod);
	    } else if (S[i] == '-') {
		val = add(val, mod-c, mod);
	    }
	}
    }

    REP (t, SIZE) WHOLE[t] = VAL[t];

    LL ans = 0;
    for (int i=N; i--;) {
	int z = N;
	REP (t, SIZE) {
	    ULL &val = VAL[t];
	    ULL &c = C[t];
	    const ULL mod = MOD[t];
	    const ULL b = B[t];
	    const ULL invB = INV_B[t];
	    const ULL whole = WHOLE[t];
	    mp[t][val]++;

	    if (false) {
	    } else if (S[i] == '>') {
		c = mul(c, invB, mod);
	    } else if (S[i] == '<') {
		c = mul(c, b, mod);
	    } else if (S[i] == '+') {
		val = add(val, mod-c, mod);
	    } else if (S[i] == '-') {
		val = add(val, c, mod);
	    }

	    //EACH (e, mp[t]) {
	    //    eprintf("(%llu %d)", e->first, e->second);
	    //}
	    ULL key = add(val, mul(c, whole, mod), mod);
	    //eprintf(": %llu\n", key);
	    auto it = mp[t].find(key);
	    if (it == mp[t].end()) {
		z = 0;
	    } else {
		amin(z, it->second);
	    }
	}

	ans += z;
    }

    printf("%lld\n", ans);
}

int main() {
    int TC = 1;
//    scanf("%d", &TC);
    REP (tc, TC) MAIN();
    return 0;
}



Measured memory_bytes: 43644