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

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,a,b) for(int i=(a);i<(b);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second

using vint=vector<int>;
using pint=pair<int,int>;
using vpint=vector<pint>;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
    ost<<"{"<<p.first<<","<<p.second<<"}";
    return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
    ost<<"{";
    for(int i=0;i<v.size();i++){
        if(i)ost<<",";
        ost<<v[i];
    }
    ost<<"}";
    return ost;
}

struct ModX{
    using ull=uint64_t;
    static const ull mod=(1ll<<61)-1;
    static const ull MASK30=(1ll<<30)-1;
    static const ull MASK31=(1ll<<31)-1;

    ull a;

    ModX& s(ull vv){
        a=vv<mod?vv:vv-mod;
        return *this;
    }
    ModX(ull a=0):a(a%mod){}
    
    ModX& operator+=(const ModX& x){return s(a+x.a);}
    ModX& operator-=(const ModX& x){return s(a+mod-x.a);}
    ModX& operator*=(const ModX& x){
        const ull au=a>>31;
        const ull ad=a&MASK31;
        const ull bu=x.a>>31;
        const ull bd=x.a&MASK31;
        const ull mid=ad*bu+au*bd;
        const ull midu=mid>>30;
        const ull midd=mid&MASK30;
        const ull z=au*bu*2+midu+(midd<<31)+ad*bd;
        return s((z&mod)+(z>>61));
    }

    ModX operator+(const ModX &x)const{return ModX(*this)+=x;}
    ModX operator-(const ModX &x)const{return ModX(*this)-=x;}
    ModX operator*(const ModX &x)const{return ModX(*this)*=x;}

    bool operator==(const ModX &x)const{return a==x.a;}
    bool operator!=(const ModX &x)const{return a!=x.a;}
    bool operator<(const ModX &x)const{return a<x.a;}

    ModX operator-()const{return ModX()-*this;}

    ModX pow(int m){
        ModX ret=1;
        ModX n=*this;
        while(m){
            if(m&1)ret=ret*n;
            n=n*n;
            m>>=1;
        }
        return ret;
    }
    ModX inv(){
        return pow(mod-2);
    }
};

istream& operator>>(istream& in,const ModX& a){
    return (in>>a.a);
}

ostream& operator<<(ostream& out,const ModX& a){
    return (out<<a.a);
}
using xint=ModX;
const xint base(119);
const int RHSIZE=1111111;
xint basepow[RHSIZE];
struct RHInit{
    RHInit(){
        basepow[0]=1;
        for(int i=1;i<RHSIZE;i++)basepow[i]=basepow[i-1]*base;
    }
}RHInitDummy;


int N;
string S;
xint H[333333];
int pos[333333];

inline xint po(int k){
    if(k>=0)return basepow[k];
    return basepow[-k].inv();
}
signed main(){
    cin>>N>>S;
    H[0]=0;
    for(int i=0;i<N;i++){
        if(S[i]=='+'){
            H[i+1]=H[i]+po(pos[i]);
            pos[i+1]=pos[i];
        }
        else if(S[i]=='-'){
            H[i+1]=H[i]-po(pos[i]);
            pos[i+1]=pos[i];
        }
        else if(S[i]=='>'){
            H[i+1]=H[i];
            pos[i+1]=pos[i]+1;
        }
        else{
            H[i+1]=H[i];
            pos[i+1]=pos[i]-1;
        }
    }

    map<xint,int>cnt;
    int ans=0;
    cnt[H[N]]++;
    for(int i=N-1;i>=0;i--){
        // (b-a)*po[-pos[i]]==H[N];
        ans+=cnt[H[N]*po(pos[i])+H[i]];
        cnt[H[i]]++;
    }
    cout<<ans<<endl;
    return 0;
}

Measured memory_bytes: 45572