#include <bits/stdc++.h>
using namespace std;
int N;
string s;
int s0[100005], s1[100005], s2[100005];
int sf[100005], fg[100005];
int stf[100005][21], stg[100005][21];
int nx[100005], ny[100005];
int qmin_f(int l, int r) {
  int k;
  if (l == r)
    k = 0;
  else
    k = log2(r - l);
  return min(stf[l][k], stf[r - (1 << k) + 1][k]);
}
int qmin_g(int l, int r) {
  int k;
  if (l == r)
    k = 0;
  else
    k = log2(r - l);
  return min(stg[l][k], stg[r - (1 << k) + 1][k]);
}
struct Node {
  int l, r, sz;
  Node *ls, *rs;
} pool[40 * 100005];
Node* rt[2][100005];
int top = 0;
Node* copyNode(Node* rt) {
  Node* p = pool + (++top);
  pool[top] = *rt;
  return p;
}
Node* newNode(int l, int r) {
  Node* p = pool + (++top);
  p->l = l;
  p->r = r;
  return p;
}
int getSZ(Node* p) { return (p) ? p->sz : 0; }
Node* insert(Node* rt, int l, int r, int x) {
  Node* p;
  if (rt)
    p = copyNode(rt);
  else
    p = newNode(l, r);
  ++p->sz;
  if (p->l == x && p->r == x) return p;
  int mid = (l + r) / 2;
  if (x <= mid)
    p->ls = insert(p->ls, l, mid, x);
  else
    p->rs = insert(p->rs, mid + 1, r, x);
  return p;
}
int query(Node* p, int l) {
  if (!p) return 0;
  if (p->l == l) return getSZ(p);
  int mid = (p->l + p->r) / 2;
  if (l >= mid + 1)
    return query(p->rs, l);
  else
    return query(p->ls, l) + getSZ(p->rs);
}
long long work() {
  for (int i = 1; i <= N; i++) {
    s0[i] = s0[i - 1];
    s1[i] = s1[i - 1];
    s2[i] = s2[i - 1];
    if (s[i] == '(')
      ++s0[i];
    else if (s[i] == ')')
      ++s1[i];
    else
      ++s2[i];
    sf[i] = stf[i][0] = s0[i] + s2[i] - s1[i];
  }
  for (int i = N; i >= 1; i--) {
    fg[i] = stg[i][0] =
        (s1[N] - s1[i - 1]) + (s2[N] - s2[i - 1]) - (s0[N] - s0[i - 1]);
  }
  for (int j = 1; j <= 20; j++) {
    for (int i = 1; i <= N; i++) {
      if (i + (1 << (j - 1)) > N) break;
      stf[i][j] = min(stf[i][j - 1], stf[i + (1 << (j - 1))][j - 1]);
      stg[i][j] = min(stg[i][j - 1], stg[i + (1 << (j - 1))][j - 1]);
    }
  }
  int l, r, mid;
  int t, id;
  for (int i = 1; i <= N; i++) {
    id = ((i) / 2 + (i) % 2);
    l = i, r = N, mid;
    t = sf[i - 1];
    if (qmin_f(i, l) < t) {
      if (rt[i % 2][id - 1]) rt[i % 2][id] = copyNode(rt[i % 2][id - 1]);
      continue;
    }
    while (l < r) {
      mid = (l + r) / 2;
      if (qmin_f(i, mid) >= t)
        l = mid + 1;
      else
        r = mid;
    }
    if (qmin_f(i, r) < t) r--;
    nx[i] = r;
    rt[i % 2][id] = insert(rt[i % 2][id - 1], 1, N, r);
  }
  long long ans = 0;
  for (int j = 1; j <= N; j++) {
    l = 1, r = j, mid;
    t = fg[j + 1];
    if (qmin_g(r, j) < t) continue;
    while (l < r) {
      mid = (l + r) / 2;
      if (qmin_g(mid, r) >= t)
        r = mid;
      else
        l = mid + 1;
    }
    if ((j - r) % 2 == 0) r++;
    ans += query(rt[(j - 1) % 2][((j - 1) / 2 + (j - 1) % 2)], j) -
           query(rt[(j - 1) % 2][((r) / 2 + (r) % 2) - 1], j);
  }
  return ans;
}
int main() {
  cin >> s;
  N = s.length();
  s = "#" + s;
  cout << work() << endl;
  return 0;
}
