#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;   }