#include <bits/stdc++.h>
using namespace std;
const int MX = 500005;
const int MC = 2;
int get(char c) {
  if (c == '(') return 0;
  return 1;
}
struct Node {
  int l, r, pardp;
  Node *par, *sLink;
  Node *chd[MC];
  bool isLeaf;
  int st;
  Node() {
    l = r = pardp = 0;
    par = sLink = NULL;
    st = 0;
    isLeaf = true;
    memset(chd, 0, sizeof chd);
  }
  int len() { return r - l; }
  int depth() { return pardp + len(); }
  bool inEdge(int pos) { return pos >= pardp && pos < depth(); }
  void setEdge(Node *child, int l, int r, char *S) {
    child->par = this;
    child->pardp = depth();
    chd[get(S[l])] = child;
    child->l = l, child->r = r;
    isLeaf = false;
  }
  void print(char *S) {
    for (int i = l; i < r; i++) putchar(S[i]);
    puts("");
  }
};
struct Data {
  int l, r, x;
  Data(int l = 0, int r = 0, int x = 0) : l(l), r(r), x(x) {}
  bool operator<(const Data &b) const { return l < b.l; }
};
vector<Data> que;
struct STree {
  Node *root, *needSLink, *cur;
  int jj, m, size;
  bool needWalk;
  vector<Node> nodes;
  char *S;
  STree(char *str) {
    m = strlen(str);
    S = str;
    nodes.reserve(m * 2 + 10);
    jj = 1, size = 0;
    root = newNode();
    cur = newNode();
    root->setEdge(cur, 0, m, S);
    needSLink = NULL;
    needWalk = true;
    for (int i = 0; i < m - 1; i++) extend(i);
  }
  Node *newNode() {
    nodes.push_back(Node());
    return &nodes[size++];
  }
  Node *walk_down(Node *c, int j, int i) {
    if (i - j + 1 > 0)
      for (int h = j + c->depth(); !c->inEdge(i - j); h += c->len())
        c = c->chd[get(S[h])];
    return c;
  }
  void addSLink(Node *c) {
    if (needSLink) needSLink->sLink = c;
    needSLink = NULL;
  }
  void extend(int i) {
    char c = S[i + 1];
    Node *leaf, *split;
    int k, pos;
    for (; jj <= i + 1; jj++) {
      if (needWalk) {
        if (!cur->sLink && cur->par) cur = cur->par;
        cur = (cur->sLink) ? cur->sLink : root;
        cur = walk_down(cur, jj, i);
      }
      needWalk = true;
      k = i + 1 - jj;
      if (cur->depth() == k) {
        addSLink(cur);
        if (cur->chd[get(c)]) {
          cur = cur->chd[get(c)];
          needWalk = false;
          break;
        } else {
          leaf = newNode();
          cur->setEdge(leaf, i + 1, m, S);
        }
      } else {
        pos = cur->l + k - cur->pardp;
        if (S[pos] == c) {
          addSLink(cur);
          needWalk = false;
          break;
        } else {
          leaf = newNode();
          split = newNode();
          cur->par->setEdge(split, cur->l, pos, S);
          split->setEdge(cur, pos, cur->r, S);
          split->setEdge(leaf, i + 1, m, S);
          addSLink(split);
          if (split->depth() == 1)
            split->sLink = root;
          else
            needSLink = split;
          cur = split;
        }
      }
    }
  }
  void calc(Node *c) {
    int bf = 0;
    int l = c->l - c->pardp, r = c->r;
    if (r) que.push_back(Data(l, r, 1));
    for (int i = 0; i < MC; i++)
      if (c->chd[i]) {
        if (r) que.push_back(Data(l, r, -1));
        calc(c->chd[i]);
        bf++;
      }
  }
};
char A[MX];
int val[MX * 4], cnt[MX * 4], dn[MX * 4];
int p[MX];
void add(pair<int, int> &p, pair<int, int> q) {
  p.first = min(p.first, q.first);
  p.second += q.second;
}
void up(int u) {
  int l = u * 2, r = u * 2 + 1;
  val[u] = min(val[l], val[r]);
  cnt[u] = 0;
  if (val[u] == val[l]) cnt[u] += cnt[l];
  if (val[u] == val[r]) cnt[u] += cnt[r];
}
void renew(int u, int x) {
  val[u] += x;
  dn[u] += x;
}
void down(int u) {
  val[u] += dn[u];
  renew(u * 2, dn[u]);
  renew(u * 2 + 1, dn[u]);
  dn[u] = 0;
}
void build(int u, int l, int r) {
  if (l == r) {
    val[u] = p[l];
    cnt[u] = 1;
    dn[u] = 0;
    return;
  }
  int md = (l + r) / 2;
  build(u * 2, l, md);
  build(u * 2 + 1, md + 1, r);
  up(u);
}
void add(int u, int l, int r, int st, int en, int x) {
  if (st <= l && r <= en) {
    renew(u, x);
    return;
  }
  int md = (l + r) / 2;
  down(u);
  if (st <= md) add(u * 2, l, md, st, en, x);
  if (md < en) add(u * 2 + 1, md + 1, r, st, en, x);
  up(u);
}
int bf = false;
pair<int, int> get(int u, int l, int r, int st, int en) {
  pair<int, int> ret(0, 0);
  if (st <= l && r <= en) {
    if (val[u] == 0) return pair<int, int>(val[u], cnt[u]);
    if (val[u] > 0) return pair<int, int>(val[u], 0);
    if (l == r) return pair<int, int>(val[u], 0);
    down(u);
    int md = (l + r) / 2;
    ret = get(u * 2, l, md, st, en);
    if (ret.first >= 0) {
      add(ret, get(u * 2 + 1, md + 1, r, st, en));
    }
    up(u);
    return ret;
  }
  int md = (l + r) / 2;
  down(u);
  if (st <= md) ret = get(u * 2, l, md, st, en);
  if (md < en)
    if (ret.first >= 0) add(ret, get(u * 2 + 1, md + 1, r, st, en));
  up(u);
  return ret;
}
int main() {
  int n;
  scanf("%d%s", &n, A);
  STree tr(A);
  int dp = 0;
  for (int i = 0; i < n; i++) {
    if (A[i] == '(')
      dp++;
    else
      dp--;
    p[i + 1] = dp;
  }
  build(1, 1, n);
  tr.calc(tr.root);
  sort(que.begin(), que.end());
  int lft = 0;
  long long ans = 0;
  for (int i = 0; i < que.size();) {
    while (lft < que[i].l) {
      if (A[lft] == '(')
        add(1, 1, n, 1, n, -1);
      else
        add(1, 1, n, 1, n, 1);
      lft++;
    }
    while (i < que.size() && que[i].l == lft) {
      pair<int, int> ret = get(1, 1, n, lft + 1, que[i].r);
      ans += ret.second * que[i].x;
      i++;
    }
  }
  printf("%lld\n", ans);
  return 0;
}
