#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long lint;

lint modpow(lint x, lint y, lint mod) {
  lint ret = 1 % mod, x2p = x;
  while (y > 0) {
    if (y % 2) ret = (__int128)ret * x2p % mod;
    y /= 2;
    x2p = (__int128)x2p * x2p % mod;
  }
  return ret;
}
constexpr int nmods = 2;
constexpr lint mod[] = {1008176417, 1008176437};
constexpr lint base[] = {549817, 549817};
lint inv_base[nmods];

int main() {
  int n;
  scanf("%d", &n);
  string seq(n, ' ');
  for (int i = 0; i < n; ++i)
    scanf(" %c", &seq[i]);

  vector<int> pos_before(n);

  vector<vector<lint>> base_pow(nmods, vector<lint>(n + 1));
  vector<vector<lint>> inv_base_pow(nmods, vector<lint>(n + 1));
  vector<vector<lint>> hash_diff(nmods, vector<lint>(n, 0));
  vector<vector<lint>> suffix(nmods, vector<lint>(n + 1));
  vector<lint> full_seq_hash(nmods);
  for (int k = 0; k < nmods; ++k) {
    base_pow[k][0] = 1;
    for (int i = 1; i <= n; ++i)
      base_pow[k][i] = (__int128)base[k] * base_pow[k][i - 1] % mod[k];

    inv_base[k] = modpow(base[k], mod[k] - 2, mod[k]);
    assert((__int128)base[k] * inv_base[k] % mod[k] == 1);

    inv_base_pow[k][0] = 1;
    for (int i = 1; i <= n; ++i)
      inv_base_pow[k][i] = (__int128)inv_base[k] * inv_base_pow[k][i - 1] % mod[k];

    int pos = 0;
    for (int i = 0; i < n; ++i) {
      pos_before[i] = pos;
      if (seq[i] == '>') ++pos;
      else if (seq[i] == '<') --pos;
      else {
        lint base_pow_pos;
        if (pos >= 0) base_pow_pos = base_pow[k][pos];
        else base_pow_pos = inv_base_pow[k][-pos];
        if (seq[i] == '+') hash_diff[k][i] = base_pow_pos;
        else if (seq[i] == '-') {
          hash_diff[k][i] = mod[k] - base_pow_pos;
          assert(0 <= hash_diff[k][i]);
          assert(hash_diff[k][i] < mod[k]);
        } else assert(0);
      }
    }
    full_seq_hash[k] = 0;
    for (int i = 0; i < n; ++i) {
      full_seq_hash[k] += hash_diff[k][i];
      if (full_seq_hash[k] >= mod[k]) full_seq_hash[k] -= mod[k];
    }

    suffix[k][n] = 0;
    for (int i = n - 1; i >= 0; --i) {
      suffix[k][i] = hash_diff[k][i] + suffix[k][i + 1];
      if (suffix[k][i] >= mod[k]) suffix[k][i] -= mod[k];
    }
  }

  lint result = 0;
  map<vector<lint>, int> count;
  count[vector<lint>(nmods, 0LL)] += 1;
  for (int i = n - 1; i >= 0; --i) {
    vector<lint> shifted_full(nmods);
    for (int k = 0; k < nmods; ++k) {
      if (pos_before[i] >= 0) {
        shifted_full[k] = (__int128)full_seq_hash[k] * base_pow[k][pos_before[i]] % mod[k];
      } else {
        shifted_full[k] = (__int128)full_seq_hash[k] * inv_base_pow[k][-pos_before[i]] % mod[k];
      }
    }

    vector<lint> target(nmods);
    for (int k = 0; k < nmods; ++k) {
      target[k] = suffix[k][i] - shifted_full[k];
      if (target[k] < 0) target[k] += mod[k];
    }

    auto it = count.find(target);
    if (it != count.end())
      result += it->second;

    vector<lint> suffix_vec(nmods);
    for (int k = 0; k < nmods; ++k)
      suffix_vec[k] = suffix[k][i];

    count[suffix_vec] += 1;
  }
  printf("%lld\n", result);

  return 0;
}


Measured memory_bytes: 44380