Problem:
Score : 1200 points

Problem Statement

In Takahashi's mind, there is always an integer sequence of length 2 \times 10^9 + 1: A = (A_{-10^9}, A_{-10^9 + 1}, ..., A_{10^9 - 1}, A_{10^9}) and an integer P.

Initially, all the elements in the sequence A in Takahashi's mind are 0, and the value of the integer P is 0.

When Takahashi eats symbols +, -, > and <, the sequence A and the integer P will change as follows:

When he eats +, the value of A_P increases by 1;

When he eats -, the value of A_P decreases by 1;

When he eats >, the value of P increases by 1;

When he eats <, the value of P decreases by 1.

Takahashi has a string S of length N. Each character in S is one of the symbols +, -, > and <.
He chose a pair of integers (i, j) such that 1 \leq i \leq j \leq N and ate the symbols that are the i-th, (i+1)-th, ..., j-th characters in S, in this order.
We heard that, after he finished eating, the sequence A became the same as if he had eaten all the symbols in S from first to last.
How many such possible pairs (i, j) are there?

Constraints

1 \leq N \leq 250000

|S| = N

Each character in S is +, -, > or <.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the answer.

Sample Input 1

5
+>+<-

Sample Output 1

3

If Takahashi eats all the symbols in S, A_1 = 1 and all other elements would be 0.
The pairs (i, j) that leads to the same sequence A are as follows:

(1, 5)

(2, 3)

(2, 4)

Sample Input 2

5
+>+-<

Sample Output 2

5

Note that the value of P may be different from the value when Takahashi eats all the symbols in S.

Sample Input 3

48
-+><<><><><>>>+-<<>->>><<><<-+<>><+<<>+><-+->><<

Sample Output 3

475

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using ll=long long;
using R=long double;
const R EPS=1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R& r){return(r > EPS)-(r < -EPS);}
inline R sq(R x){return sqrt(max(x,0.0L));}

const int dx[8]={1,0,-1,0,1,-1,-1,1};
const int dy[8]={0,1,0,-1,1,1,-1,-1};

const pid_t pid = getpid();
// Problem Specific Parameter:

template<unsigned MOD>  class ModInt {
public:
	ModInt(): x(0) {}
	ModInt(signed y) : x(y >= 0 ? y % MOD : MOD - (-y) % MOD) {}
	ModInt(signed long long y) : x(y >= 0 ? y % MOD : MOD - (-y) % MOD) {}


	// Arithmetic Oprators
	ModInt &operator+=(ModInt that) {
		if ((x += that.x) >= MOD) x -= MOD; 
		return *this;
	}
	ModInt &operator-=(ModInt that) {
		if ((x += MOD - that.x) >= MOD) x -= MOD; 
		return *this;
	}
	ModInt &operator*=(ModInt that) {
		x = 1LL * x * that.x % MOD;
		return *this;
	}
	ModInt &operator/=(ModInt that) {
		return *this *= ModInt(get<1>(extgcd(that.x, int(MOD))));
	}
	ModInt &operator%=(ModInt that) {
		x %= that.x;
		return *this;
	}

	ModInt &operator+=(const int that) { return *this += ModInt(that);}
	ModInt &operator-=(const int that) { return *this -= ModInt(that);}
	ModInt &operator*=(const int that) { return *this *= ModInt(that);}
	ModInt &operator/=(const int that) { return *this /= ModInt(that);}
	ModInt &operator%=(const int that) { return *this %= ModInt(that);}

	// Comparators
	bool operator <(ModInt that) const { return x < that.x; }
	bool operator >(ModInt that) const { return x > that.x; }
	bool operator<=(ModInt that) const { return x <= that.x; }
	bool operator>=(ModInt that) const { return x >= that.x; }
	bool operator!=(ModInt that) const { return x != that.x; }
	bool operator==(ModInt that) const { return x == that.x; }

	// Utilities
	unsigned getval() const { return x;}
	ModInt operator+(ModInt that) const { return ModInt(*this) += that;}
	ModInt operator-(ModInt that) const { return ModInt(*this) -= that;}
	ModInt operator*(ModInt that) const { return ModInt(*this) *= that;}
	ModInt operator/(ModInt that) const { return ModInt(*this) /= that;}
	ModInt operator%(ModInt that) const { return ModInt(*this) %= that;}
	ModInt operator+(const int that) const { return ModInt(*this) += that;}
	ModInt operator-(const int that) const { return ModInt(*this) -= that;}
	ModInt operator*(const int that) const { return ModInt(*this) *= that;}
	ModInt operator/(const int that) const { return ModInt(*this) /= that;}
	ModInt operator%(const int that) const { return ModInt(*this) %= that;}
	ModInt operator=(const int that) { return *this = ModInt(that);}
	friend istream &operator>>(istream& is, ModInt &that) {ll tmp; is >> tmp; that = ModInt(tmp);return is;}
	friend ostream &operator<<(ostream& os, const ModInt &that) { return os << that.x; }
	
	ModInt power(ll n) const {
		if(n < 0) return ModInt(1) / power(-n);
		ll b = 1LL, a = x;
		while(n){
			if(n & 1) b = b * a % MOD;
			a = a * a % MOD;
			n >>= 1;
		}
		return ModInt(b);
	}
private:
	unsigned x;
	
	inline auto extgcd(int a, int b) {
		if (b == 0) return make_tuple(a, 1, 0);
		tuple<int, int, int> ret = extgcd(b, a % b);
		swap(get<1>(ret), get<2>(ret));
		get<2>(ret) -= a / b * get<1>(ret);
		return ret;
	}
};

using mint = ModInt<1000000007>;
using mint2 = ModInt<1000000009>;
using mint3 = ModInt<1000000021>;
using mint4 = ModInt<1000000033>;
using mint5 = ModInt<1000000087>;
using mint6 = ModInt<1000000093>;


uniform_int_distribution<int> rng(1 << 20, 1 << 28); // [lower,upper] 
mt19937 mt(pid);

const int limit = 500010;
const int offset = 250000;

using H = tuple<mint,mint2,mint3,mint4,mint5,mint6>;
const H B = H(mint(rng(mt)),mint2(rng(mt)),mint3(rng(mt)),mint4(rng(mt)),mint5(rng(mt)),mint6(rng(mt)));
const H ZERO = H(mint(0),mint2(0),mint3(0),mint4(0),mint5(0),mint6(0));
const H ONE = H(mint(1),mint2(1),mint3(1),mint4(1),mint5(1),mint6(1));


void add(H &cur,H tar){
	get<0>(cur) += get<0>(tar);  
	get<1>(cur) += get<1>(tar);  
	get<2>(cur) += get<2>(tar);  
	get<3>(cur) += get<3>(tar);  
	get<4>(cur) += get<4>(tar);  
	get<5>(cur) += get<5>(tar);  
}

void sub(H &cur,H tar){
	get<0>(cur) -= get<0>(tar);  
	get<1>(cur) -= get<1>(tar);  
	get<2>(cur) -= get<2>(tar);  
	get<3>(cur) -= get<3>(tar);  
	get<4>(cur) -= get<4>(tar);  
	get<5>(cur) -= get<5>(tar);  
}

void mul(H &cur,H tar){
	get<0>(cur) *= get<0>(tar);  
	get<1>(cur) *= get<1>(tar);  
	get<2>(cur) *= get<2>(tar);  
	get<3>(cur) *= get<3>(tar);  
	get<4>(cur) *= get<4>(tar);  
	get<5>(cur) *= get<5>(tar);  
}

H power(H cur,int n){
	H ret;
	get<0>(ret) = get<0>(B).power(n);  
	get<1>(ret) = get<1>(B).power(n);
	get<2>(ret) = get<2>(B).power(n);
	get<3>(ret) = get<3>(B).power(n);
	get<4>(ret) = get<4>(B).power(n);
	get<5>(ret) = get<5>(B).power(n);
	return ret;
}

H shash[limit],csum[limit];
int cpos[limit];


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

	shash[0] = ONE;
	rep(i,1,limit){
		shash[i] = ONE;
		mul(shash[i],shash[i-1]);
		mul(shash[i],B);
	}

	H cur = ZERO;
	int pos = 0;
	rep(i,n+1){
		cpos[i] = pos;
		csum[i] = cur;
		if(i == n) break;

		if(s[i] == '+') add(cur,shash[pos + offset]);
		if(s[i] == '-') sub(cur,shash[pos + offset]);
		if(s[i] == '>') pos++;
		if(s[i] == '<') pos--;
	}

	map<H,int> num;
	num[csum[n]]++;

	ll ans = 0LL;
	rrep(i,n){
		H tar = csum[n];
		mul(tar,power(B,cpos[i])); 
		add(tar,csum[i]);
		if(num.find(tar) != end(num)) ans += num[tar];
		num[csum[i]]++;
	}

	cout << ans << endl;


	return 0;
}