#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
typedef long long ll;
const int N = 710;
const ll mod = 1e9 + 7;
bool g[N][N];
//g[i][j]代表i，j是否匹配
ll dp[N][N][3][3];
//dp[i][j][k][l]代表区间[i,j]，i染颜色k，j染颜色l的方案数
//0: 不染色；1：红色；2：蓝色
int n;
ll ans;
char s[N];
stack<int> stk;
int match[N];
void work(ll &x, ll y) {
	x = (x + y) % mod;
}
int main() {
	scanf("%s", s + 1);
	n = strlen(s + 1);
	for (int i = 1; i <= n; i++) {
		if (s[i] == '(') stk.push(i);
		else g[stk.top()][i] = 1, match[stk.top()] = i, stk.pop();
		dp[i][i][0][0] = 1;
		dp[i][i][1][1] = 1;
		dp[i][i][2][2] = 1;
	}
	for (int len = 2; len <= n; len++) {
		for (int i = 1; i + len - 1 <= n; i++) {
			int j = i + len - 1;
			if (g[i][j]) {
				if (len > 2) {
					for (int l = 0; l < 3; l++) {
						for (int k = 0; k < 3; k++) {
							if (k != 1) work(dp[i][j][0][1], dp[i + 1][j - 1][l][k]);
							if (k != 2) work(dp[i][j][0][2], dp[i + 1][j - 1][l][k]);
							if (l != 1) work(dp[i][j][1][0], dp[i + 1][j - 1][l][k]);
							if (l != 2) work(dp[i][j][2][0], dp[i + 1][j - 1][l][k]);
						}
					}
				} else {
					dp[i][j][1][0] = 1;
					dp[i][j][2][0] = 1;
					dp[i][j][0][1] = 1;
					dp[i][j][0][2] = 1;
				}
			} else if (match[i]) {
				for (int l = 0; l < 3; l++) {
					for (int k = 0; k < 3; k++) {
						for (int p = 0; p < 3; p++) {
							for (int q = 0; q < 3; q++) {
								if (p == q && p != 0) continue;
								work(dp[i][j][l][k], dp[i][match[i]][l][p] * dp[match[i] + 1][j][q][k] % mod);
							}
						}
					}
				}
			}
		}
	}
	for (int l = 0; l < 3; l++) {
		for (int k = 0; k < 3; k++) {
			work(ans, dp[1][n][l][k]);
		}
	}
	printf("%lld", ans);
	return 0;
}


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

const int N = 777;
const int MOD = 1e9+7;

int nxt[N];
int dp[N][N][3][3], chk[N][N][3][3];

bool same(int C, int D) {
	if(C == 1 && D == 1 || C == 2 && D == 2) return 1;
	return 0;
}

int calc(int L, int R, int X, int Y) {
	if(chk[L][R][X][Y]) return dp[L][R][X][Y];
	chk[L][R][X][Y] = 1;
	if(R == L+1) {
		if((X>0) ^ (Y>0)) return dp[L][R][X][Y] = 1;
		else return dp[L][R][X][Y] = 0;
	}
	int M = nxt[L];
	if(M < R) {
		long long ret = 0;
		for(int C = 0; C < 3; C++) {
			for(int D = 0; D < 3; D++) {
				if(same(C, D)) continue;
				ret += 1ll * calc(L, M, X, C) * calc(M+1, R, D, Y);
				ret %= MOD;
			}
		}
		return dp[L][R][X][Y] = ret;
	}else{
		if(!((X>0) ^ (Y>0))) return dp[L][R][X][Y] = 0;
		long long ret = 0;
		for(int C = 0; C < 3; C++) {
			if(same(X, C)) continue;
			for(int D = 0; D < 3; D++) {
				if(same(D, Y)) continue;
				ret += calc(L+1, R-1, C, D);
				ret %= MOD;
			}
		}
		return dp[L][R][X][Y] = ret;
	}
}

int main() {
//	freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	string s; cin>>s;
	int n = s.size();
	for(int i = 0; i < n; i++) {
		if(s[i] == ')') continue;
		int cur = 0;
		for(int j = i; j < n; j++) {
			if(s[j] == '(') cur++;
			else cur--;
			if(!cur) {
				nxt[i] = j;
				break;
			}
		}
	}
	long long cnt = 0;
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < 3; j++) {
			cnt += calc(0, n-1, i, j);
			cnt %= MOD;
		}
	}
	cout << cnt <<endl;
	return 0;
}


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

const int mod = 1e9 + 7;

#define N 707

int dp[N][N][3][3], prv[N];
char s[N];

void add(int &x, int y) {
    x += y;
    if(x >= mod) x -= mod;
}

int main() {
    scanf("%s", s+1);
    int n = strlen(s+1);
    vector <int> v;
    for(int i = 1; i <= n; i ++) {
        if(s[i] == '(') v.push_back(i);
        else {
            prv[i] = v.back();
            v.pop_back();
        }
    }
    for(int i = n; i; i --) for(int j = i; j <= n; j ++) if(s[i] == '(' && s[j] == ')') {
        int k = prv[j];
        if(k == i) {
            if(k == j-1) {
                dp[i][j][1][0] = 1;
                dp[i][j][2][0] = 1;
                dp[i][j][0][1] = 1;
                dp[i][j][0][2] = 1;
            }
            else {
                for(int a = 0; a <= 2; a ++) for(int b = 0; b <= 2; b ++) {
                    if(a && b) continue;
                    if(a == b) continue;
                    for(int c = 0; c <= 2; c ++) for(int d = 0; d <= 2; d ++) {
                        if(a && a == c) continue;
                        if(b && b == d) continue;
                        add(dp[i][j][a][b], dp[i+1][j-1][c][d]);
                    }
                }
            }
        }
        else {
            for(int a = 0; a <= 2; a ++) for(int b = 0; b <= 2; b ++) {
                for(int c = 0; c <= 2; c ++) for(int d = 0; d <= 2; d ++) {
                    if(b && b == c) continue;
                    dp[i][j][a][d] = (dp[i][j][a][d] + 1ll * dp[i][k-1][a][b] * dp[k][j][c][d]) % mod;
                }
            }
        }
    }
    int ans = 0;
    for(int i = 0; i <= 2; i ++) for(int j = 0; j <= 2; j ++) add(ans, dp[1][n][i][j]);
    cout << ans << endl;
}


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

#define N 1010

char s[N];

int match[N];

const int mod = 1e9 + 7;

typedef long long ll;

void add(int &a, ll b) {
	a = (a + b) % mod;
}

vector<vector<int> > calc(int l, int r) {
	vector<vector<int> > ans;
	ans.resize(3);
	for (int i = 0; i < 3; i ++) ans[i].resize(3);
	if (l > r) {
		ans[0][0] = 1;
		return ans;
	}
	if (r == match[l]) {
		auto now = calc(l + 1, r - 1);
		for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) {
			for (int k = 1; k <= 2; k ++) {
				if (k != i) add(ans[k][0], now[i][j]);
				if (k != j) add(ans[0][k], now[i][j]);
			}
		}
		return ans;
	}
	else {
		auto le = calc(l, match[l]), ri = calc(match[l] + 1, r);
		for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) {
			for (int k = 1; k <= 2; k ++) {
				add(ans[k][j], 1ll * le[k][0] * ri[i][j]);
				if (k != i) add(ans[0][j], 1ll * le[0][k] * ri[i][j]);
			}
		}
		return ans;
	}
}

int main() {
    scanf("%s", s);
    int n = strlen(s);
    for (int i = 0; i < n; i ++) if (s[i] == '(') {
		int sum = 0;
		for (int j = i; j < n; j ++) {
			if (s[j] == '(') sum ++;
			else sum --;
			if (sum == 0) {
				match[i] = j;
				break;
			}
		}
    }
	auto ans = calc(0, n - 1);
	int sum = 0;
	for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) add(sum, ans[i][j]);
	cout<<sum;
}


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

const int N = 705;

char s[N];

int n;

stack <int> stk;

int tot, p[N], l[N], r[N];

bool cmp(int x, int y) {
    return l[x] < l[y];
}

const int mod = 1e9 + 7;

vector <int> v[N];

void add(int &x, int y) {
	x += y;
	if (x >= mod) x -= mod;
}

struct node {
    int dp[3][3];
    node () {memset(dp, 0, sizeof dp);}
    int get_sum() {
		int res = 0;
		for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) {
            add(res, dp[i][j]);
		}
		return res;
    }
    void print() {
        for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) printf("dp[%d][%d] - %d\n", i, j, dp[i][j]);
    }
} I;

int mul(int x, int y) {return 1ll * x * y % mod;}

node solve(vector <node> &V) {
	node res;
    assert(!V.empty());
    int dp[2][3][3] = {0};
    int u = 0, v = 1;
    memset(dp, 0, sizeof dp);
    for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) dp[u][i][j] = V[0].dp[i][j];
    for (int t = 1; t < V.size(); t ++) {
        memset(dp[v], 0, sizeof dp[v]);
        for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) {
            for (int ii = 0; ii < 3; ii ++) for (int jj = 0; jj < 3; jj ++) {
                if (j && ii && j == ii) continue;
				add(dp[v][i][jj], mul(dp[u][i][j], V[t].dp[ii][jj]));
            }
        }
		swap(u, v);
    }
    for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) res.dp[i][j] = dp[u][i][j];
    return res;
}

node dfs(int k) {
    vector <node> V;
    node res;
    for (auto x : v[k]) {
        node u = dfs(x);
        V.push_back(u);
    }
    if (V.empty()) return I;
    node u = solve(V);
    for (int i = 0; i < 3; i ++) {
        for (int j = 0; j < 3; j ++) {
            if (i && j) continue;
            if (!i && !j) continue;
            for (int ii = 0; ii < 3; ii ++) {
                for (int jj = 0; jj < 3; jj ++) {
                    if (i && ii && i == ii) continue;
                    if (j && jj && j == jj) continue;
                    add(res.dp[i][j], u.dp[ii][jj]);
                }
            }
        }
    }
    return res;
}

int id[N];

int main() {
    I.dp[0][1] = I.dp[0][2] = I.dp[1][0] = I.dp[2][0] = 1;
    scanf("%s", s);
    n = strlen(s);
    for (int i = 0; i < n; i ++) {
		if (s[i] == '(') stk.push(i);
        else {
            int t = stk.top(); stk.pop();
			++ tot;
            l[tot] = t, r[tot] = i;
            id[tot] = tot;
        }
    }
    sort(id+1, id+tot+1, cmp);
    int q = 0;
    for (int i = 1; i <= tot; i ++) {
        int k = id[i];
        while (q && !(l[q] < l[k] && r[k] < r[q])) q = p[q];
        p[k] = q;
        q = k;
    }
    for (int i = 1; i <= tot; i ++) v[p[i]].push_back(i);
    vector <node> V;
    for (auto x : v[0]) {
        node u = dfs(x);
		V.push_back(u);
    }
    node u = solve(V);
    int ans = u.get_sum();
    printf("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#define ll long long
using std::pair;
typedef pair<int, int> pad;

const int M =1000000007;
//const int M =998244535;

inline int read(){
	int x =0; char c =getchar();
	while(c < '0' || c > '9') c =getchar();
	while(c >= '0' && c <= '9') x = (x<<3) + (x<<1) + (48^c), c =getchar();
	return x;
}

int dp[1200][1200][3][3];
int match[1200];

int dfs(int l, int r, int col, int cor){
//	if(match[l] == 0) while(1);
	if(dp[l][r][col][cor] != -1) return dp[l][r][col][cor];
	if(r == l+1) return dp[l][r][col][cor] =((col+cor > 0) && (col == 0 || cor == 0));
	else if(match[l] == r){
		if(!((col+cor > 0) && (col == 0 || cor == 0))) return dp[l][r][col][cor] =0;
		int ret =0;
		for(int i =0; i < 3; ++i){
			if(i == col && i+col > 0 /*也可以都不染色*/) continue;
			for(int j =0; j < 3; ++j){
				if(j == cor && j+cor > 0) continue;
				ret =(ret+dfs(l+1, r-1, i, j))%M;
			}
		}
		return dp[l][r][col][cor] =ret;
	}
	else{
		int ret =0;
		for(int r1 =0; r1 < 3; ++r1){
			for(int l2 =0; l2 < 3; ++l2){
				if(r1 == l2 && r1+l2 > 0) continue;
				ret =(ret+(1ll*dfs(l, match[l], col, r1)*dfs(match[l]+1, r, l2, cor))%M)%M;
			}
		}
		return dp[l][r][col][cor] =ret;
	}
}

int stk[1200], tot;

int main(){
	tot =0;
	memset(dp, -1, sizeof(dp));
	int n =0;
	char c =getchar();
	for(int i =0; c == '(' || c == ')'; ++i){
		++n;
		if(c == '(') stk[tot++] =i;
		else --tot, match[stk[tot]] =i;//, match[i] =stk[tot];
		c =getchar();
	}
	int ans =0;
	for(int i =0; i < 3; ++i) for(int j =0; j < 3; ++j) ans =(ans+dfs(0, n-1, i, j))%M;
	printf("%d", ans);
}


#include <cstdio>
#include <iostream>
#include <cstring>
#define ll long long
using std::pair;
typedef pair<int, int> pad;

const int M =1000000007;
//const int M =998244535;

inline int read(){
	int x =0; char c =getchar();
	while(c < '0' || c > '9') c =getchar();
	while(c >= '0' && c <= '9') x = (x<<3) + (x<<1) + (48^c), c =getchar();
	return x;
}

int dp[1200][1200][3][3];
int match[1200];

int dfs(int l, int r, int col, int cor){
//	if(match[l] == 0) while(1);
	if(dp[l][r][col][cor] != -1) return dp[l][r][col][cor];
	if(r == l+1) return dp[l][r][col][cor] =((col+cor > 0) && (col == 0 || cor == 0));
	else if(match[l] == r){
		if(!((col+cor > 0) && (col == 0 || cor == 0))) return dp[l][r][col][cor] =0;
		int ret =0;
		for(int i =0; i < 3; ++i){
			if(i == col && i+col > 0 /*Ҳ���Զ���Ⱦɫ*/) continue;
			for(int j =0; j < 3; ++j){
				if(j == cor && j+cor > 0) continue;
				ret =(ret+dfs(l+1, r-1, i, j))%M;
			}
		}
		return dp[l][r][col][cor] =ret;
	}
	else{
		int ret =0;
		for(int r1 =0; r1 < 3; ++r1){
			for(int l2 =0; l2 < 3; ++l2){
				if(r1 == l2 && r1+l2 > 0) continue;
				ret =(ret+(1ll*dfs(l, match[l], col, r1)*dfs(match[l]+1, r, l2, cor))%M)%M;
			}
		}
		return dp[l][r][col][cor] =ret;
	}
}

int stk[1200], tot;

int main(){
	/*tst*/
	tot =0;
	memset(dp, -1, sizeof(dp));
	int n =0;
	char c =getchar();
	for(int i =0; c == '(' || c == ')'; ++i){
		++n;
		if(c == '(') stk[tot++] =i;
		else --tot, match[stk[tot]] =i;//, match[i] =stk[tot];
		c =getchar();
	}
	int ans =0;
	for(int i =0; i < 3; ++i) for(int j =0; j < 3; ++j) ans =(ans+dfs(0, n-1, i, j))%M;
	printf("%d", ans);
}


#include <cstdio>
#include <algorithm>
using std::sort;

const int MAXN =2*1e5+50;

int c[2][MAXN], f[MAXN];
bool rev[MAXN];

inline void pushdown(int x){
	if(rev[x]){
		rev[c[0][x]] ^=1, rev[c[1][x]] ^=1;
		c[0][x] ^=c[1][x] ^=c[0][x] ^=c[1][x];
		rev[x] =0;
	}
}

inline bool isroot(int x){ return (!(c[0][f[x]] == x || c[1][f[x]] == x) || f[x] == 0/*����δ֪����*/); }

inline bool get(int x){ return c[1][f[x]] == x; }

inline void rotate(int x){
	bool r =get(x), rf =get(f[x]);
	int y =f[x], z =f[y], a =c[!r][x];
	f[x] =z; if(!isroot(y)) c[rf][z] =x;
	f[y] =x, c[!r][x] =y;
	f[a] =y, c[r][y] =a;
}

inline void pushall(int x){
	if(!isroot(x)) pushall(f[x]);
	pushdown(x);
}

inline void splay(int x){
	pushall(x);
	for(; !isroot(x); rotate(x))
		if(!isroot(f[x])) rotate((get(f[x]) == get(x)) ? f[x] : x);
}

inline void access(int x){
	for(int pre =0; x; pre =x, x =f[x]){
		splay(x);/*�����x��һ���ǳ�ʼ��*/
		c[1][x] =pre;
	}
}

inline void setroot(int x){
	access(x), splay(x);
	rev[x] =1;
}

inline bool connected(int x, int y){
	if(x == y) return 1;
	access(x), splay(x);
	access(y), splay(y)/*���ܸ�splay��x��x�����Ǹ�*/;
	return f[x] != 0;
}

/**/
inline int findroot(int x){
	access(x), splay(x);
	while(c[0][x]) x =c[0][x], pushdown(x);
	splay(x);/*����Ῠ*/
	return x;
}
inline bool connected2(int x, int y){
	if(findroot(x) == findroot(y)) return 1;
	else return 0;
}
/**/

inline void cut(int x, int y){
	/*���ܲ���Ҫ�ظı� x���ĸ�*/
	setroot(x), access(y), splay(x)/*accessǰ x,y������ͬһsplay*/;
	//if(c[1][x] != y) return 0;
	c[1][x] =f[y] =0;
}

inline void link(int x, int y){
	//if(connected(x, y)) return 0;
	setroot(x); f[x] =y;
}

int N =1, min[3*MAXN], cnt[3*MAXN], det[3*MAXN];
bool lazy[3*MAXN];

inline void pushupSeg(int v){
	if(min[v<<1] == min[(v<<1)|1]){
		min[v] =min[v<<1];
		cnt[v] =cnt[v<<1]+cnt[(v<<1)|1];
	}
	else if(min[v<<1] < min[(v<<1)|1]) min[v] =min[v<<1], cnt[v] =cnt[v<<1];
	else min[v] =min[(v<<1)|1], cnt[v] =cnt[(v<<1)|1];
}

inline void pushdownSeg(int v){
	if(lazy[v]){
		min[v<<1] +=det[v], min[(v<<1)|1] +=det[v];
		det[v<<1] +=det[v], det[(v<<1)|1] +=det[v];
		lazy[v<<1] =lazy[(v<<1)|1] =1;
		lazy[v] =0;
		det[v] =0;/**/
	}
}

inline void updata(int l, int r, int d, int v =1, int nl =1, int nr =N){
	if(l > r) return;
	if(l == nl && r == nr){
		min[v] +=d;
		det[v] +=d;
		lazy[v] =1;
		return;
	}
	pushdownSeg(v);
	int mid =(nl+nr)>>1;
	if(r <= mid) updata(l, r, d, v<<1, nl, mid);
	else if(l > mid) updata(l, r, d, (v<<1)|1, mid+1, nr);
	else updata(l, mid, d, v<<1, nl, mid), updata(mid+1, r, d, (v<<1)|1, mid+1, nr);
	pushupSeg(v);
}

inline int query(int l, int r, int v =1, int nl =1, int nr =N){
	if(l == nl && r == nr){
		//printf("[%d]\n", min[v]);
		if(min[v] != 1/*!*/) return 0;
		else return cnt[v];
	}
	pushdownSeg(v);
	int mid =(nl+nr)>>1;
	if(r <= mid) return query(l, r, v<<1, nl, mid);
	else if(l > mid) return query(l, r, (v<<1)|1, mid+1, nr);
	else return query(l, mid, v<<1, nl, mid) + query(mid+1, r, (v<<1)|1, mid+1, nr);
}

int posx[MAXN], posy[MAXN], dx[4] ={0, 1, 0, -1}, dy[4] ={1, 0, -1, 0};
int map[2000][2000], n, m;

inline int read(){
	int x =0; char cc =getchar();
	while(cc < '0' || cc > '9') cc =getchar();
	while(cc >= '0' && cc <= '9') x =(x<<3)+(x<<1)+(48^cc), cc =getchar();
	return x;
}

inline int outmap(int x, int y){
	if(x < 0 || x >= n) return -1;
	if(y < 0 || y >= m) return -1;
	return map[x][y];
}

inline int test(){
	N =8;
	for(int k =1, count =N, d =1; k <= N; d +=k, k <<=1, count >>=1)
		for(int i =0; i < k; ++i)
			cnt[d+i] =count;
	printf("%d\n", query(1, 8));
	updata(1, 4, 1);
	printf("%d\n", query(1, 8));
	updata(1, 3, -1);
	printf("%d\n", query(1, 8));
	updata(1, 2, -8);
	printf("%d\n", query(1, 1));
	return 0;
}

int main(){
	//return test();
	n =read(), m =read();
	while(N < n*m) N <<=1;
	for(int i =0; i < n; ++i) for(int j =0; j < m; ++j){
		map[i][j] =read();
		posx[map[i][j]] =i, posy[map[i][j]] =j;
	}
	/*preseg(SegmentTree)*/
	for(int k =1, count =N, d =1; k <= N; d +=k, k <<=1, count >>=1)
		for(int i =0; i < k; ++i)
			cnt[d+i] =count;
	long long ans =0;
	for(int l =1, r =0/*��ĿǰΪֹ���Ե�*/; l <= n*m; ++l){
		for(int r2 =r+1/*����Խ��*/; r2 <= n*m; ++r2){
			int lnk[4], tot =0, count =0;
			bool brek =0;
			for(int d =0; d < 4; ++d){
				int to =outmap(posx[r2]+dx[d], posy[r2]+dy[d]);
				if(to == -1 || to > r2 || to < l) continue;
				if(!connected(r2, to)) link(r2, to)/*��ģ����*/, lnk[tot++] =to, ++count;
				else{
					brek =1;
					break;/*��һ��Ҫ*/
				}
			}
			if(brek){
				for(int i =0; i < tot; ++i) cut(r2, lnk[i]);
				break;
			}
			updata(r2, n*m, 1-count);
			r =r2;
		}
		ans +=query(l, r);
		int lnk[4], tot =0;
		for(int d =0; d < 4; ++d){
			int to =outmap(posx[l]+dx[d], posy[l]+dy[d]);
			if(to == -1) continue;
			if(connected(l, to)) cut(l, to), lnk[tot++] =to;
		}
		sort(lnk, lnk+tot);
		if(tot > 0) updata(l, lnk[0]-1, -1);/*l����Խ��*/
		else updata(l, m*n, -1);/*!*/
		for(int i =1; i < tot; ++i){
			if(!connected(lnk[i-1], lnk[i])) updata(lnk[i], n*m, 1);
		}
	}
	printf("%lld", ans);
}


#include<cstdio>
#include<string>
#include<cstring>
#include<utility>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<vector>
#include<iostream>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
#define minn(x,y) x=min(x,y)
#define maxx(x,y) x=max(x,y)
using namespace std;
ll mod=1e9+7;
int a[1000],ss[1000];
ll dp[710][710][3][3];
ll dfs(int l,int r,int x,int y)
{
	bool bx,by;
	//printf("%d %d %d %d\n",l,r,x,y);
	if(r-l==2)
	{
		bx=x;
		by=y;
		if(bx^by)
		{
			return 1;
		}
		return 0;
	}
	if(~dp[l][r][x][y])
	{
		return dp[l][r][x][y];
	}
	ll ans=0;
	if(a[l]+1==r)
	{
		bx=x;
		by=y;
		if(bx^by)
		{
			for(int i=0;i<3;i++)
			{
				for(int j=0;j<3;j++)
				{
					if((x!=0&&i==x)||(y!=0&&j==y))
					{
						continue;
					}
					else
					{
						ans=ans+dfs(l+1,r-1,i,j);
						ans=ans%mod;
					}
				}
			}
			return dp[l][r][x][y]=ans;
		}
		return dp[l][r][x][y]=0;
	}
	int pos=a[l]+1;
	for(int i=0;i<3;i++)//dfs(x,i)*dfs(j,y)
	{
		for(int j=0;j<3;j++)
		{
			if(i!=j||(i==0&&j==0))
			{
				ans=(ans+dfs(l,pos,x,i)*dfs(pos,r,j,y)%mod)%mod;
			}
		}
	}
	return dp[l][r][x][y]=ans;
}
int main()
{
	int i,j,k,n,m,x,y,h;
	ll ans;
	string s;
	cin>>s;
	h=0;
	n=s.size();
	memset(dp,-1,sizeof(dp));
	for(i=0;i<n;i++)
	{
		if(s[i]=='(')
		{
			ss[h]=i;
			h++;
		}
		else
		{
			a[ss[h-1]]=i;
			h--;
		}
	}/*
	for(i=0;i<n;i++)
	{
		printf("%d ",a[i]);
	}*/
	ans=0;
	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)
		{
			ans=(ans+dfs(0,n,i,j))%mod;
		}
	}
	printf("%lld",ans);
}


#include<cstdio>
#include<string>
#include<cstring>
#include<utility>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<vector>
#include<iostream>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
#define minn(x,y) x=min(x,y)
#define maxx(x,y) x=max(x,y)
using namespace std;
ll mod=1e9+7;
int s[1000],a[1000];
int dp[710][710][3][3];
int dfs(int l,int r,int x,int y)
{
	bool bx,by;
	//printf("%d %d %d %d\n",l,r,x,y);
	if(r-l==2)
	{
		bx=x;
		by=y;
		if(bx^by)
		{
			return 1;
		}
		return 0;
	}
	if(~dp[l][r][x][y])
	{
		return dp[l][r][x][y];
	}
	ll ans=0;
	if(a[l]+1==r)
	{
		bx=x;
		by=y;
		if(bx^by)
		{
			for(int i=0;i<3;i++)
			{
				for(int j=0;j<3;j++)
				{
					if((x!=0&&i==x)||(y!=0&&j==y))
					{
						continue;
					}
					else
					{
						ans=ans+1ll*dfs(l+1,r-1,i,j);
						ans=ans%mod;
					}
				}
			}
			return dp[l][r][x][y]=ans;
		}
		return dp[l][r][x][y]=0;
	}
	int pos=a[l]+1;
	for(int i=0;i<3;i++)//dfs(x,i)*dfs(j,y)
	{
		for(int j=0;j<3;j++)
		{
			if(i!=j||(i==0&&j==0))
			{
				ans=(ans+1ll*dfs(l,pos,x,i)*dfs(pos,r,j,y)%mod)%mod;
			}
		}
	}
	return dp[l][r][x][y]=ans;
}
int main()
{
	int i,j,k,n,m,x,y,h;
	ll ans;
	string s;
	cin>>s;
	h=0;
	n=s.size();
	memset(dp,-1,sizeof(dp));
	for(i=0;i<n;i++)
	{
		if(s[i]=='(')
		{
			s[h]=i;
			h++;
		}
		else
		{
			a[s[h-1]]=i;
			h--;
		}
	}/*
	for(i=0;i<n;i++)
	{
		printf("%d ",a[i]);
	}*/
	ans=0;
	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)
		{
			ans=(1ll*ans+dfs(0,n,i,j))%mod;
		}
	}
	printf("%lld",ans);
}


#include<cstdio>
#include<string>
#include<cstring>
#include<utility>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<vector>
#include<iostream>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
#define minn(x,y) x=min(x,y)
#define maxx(x,y) x=max(x,y)
using namespace std;
ll mod=1e9+7;
int s[1000],a[1000];
ll dp[710][710][3][3];
ll dfs(int l,int r,int x,int y)
{
	bool bx,by;
	//printf("%d %d %d %d\n",l,r,x,y);
	if(r-l==2)
	{
		bx=x;
		by=y;
		if(bx^by)
		{
			return 1;
		}
		return 0;
	}
	if(~dp[l][r][x][y])
	{
		return dp[l][r][x][y];
	}
	ll ans=0;
	if(a[l]+1==r)
	{
		bx=x;
		by=y;
		if(bx^by)
		{
			for(int i=0;i<3;i++)
			{
				for(int j=0;j<3;j++)
				{
					if((x!=0&&i==x)||(y!=0&&j==y))
					{
						continue;
					}
					else
					{
						ans+=dfs(l+1,r-1,i,j);
						ans=ans%mod;
					}
				}
			}
			return dp[l][r][x][y]=ans;
		}
		return dp[l][r][x][y]=0;
	}
	int pos=a[l]+1;
	for(int i=0;i<3;i++)//dfs(x,i)*dfs(j,y)
	{
		for(int j=0;j<3;j++)
		{
			if(i!=j||(i==0&&j==0))
			{
				ans+=(dfs(l,pos,x,i)*dfs(pos,r,j,y))%mod;
				ans%=mod;
			}
		}
	}
	return dp[l][r][x][y]=ans;
}
int main()
{
	int i,j,k,n,m,x,y,h;
	ll ans;
	string s;
	cin>>s;
	h=0;
	n=s.size();
	memset(dp,-1,sizeof(dp));
	for(i=0;i<n;i++)
	{
		if(s[i]=='(')
		{
			s[h]=i;
			h++;
		}
		else
		{
			a[s[h-1]]=i;
			h--;
		}
	}/*
	for(i=0;i<n;i++)
	{
		printf("%d ",a[i]);
	}*/
	ans=0;
	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)
		{
			ans+=dfs(0,n,i,j);
			ans=ans%mod;
		}
	}
	printf("%lld",ans);
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>

using namespace std;

const int MAXN=770;
const long long mod=1e9+7;
char s[MAXN];
int match[MAXN],stk[MAXN];
long long dp[MAXN][MAXN][3][3];

long long dfs(int l,int r,int lc,int rc)
{
	if(l==r-1)
		return (lc&&!rc)||(rc&&!lc);
	if(dp[l][r][lc][rc]!=-1)
		return dp[l][r][lc][rc];
	if(dp[l][r][(3-lc)%3][(3-rc)%3]!=-1)
		return dp[l][r][(3-lc)%3][(3-rc)%3];
	long long ret=0,i,j;
	if(match[l]==r)
	{
		if((lc&&!rc)||(!lc&&rc))
		{
			for(i=0;i<3;i++)
				for(j=0;j<3;j++)
				{
					if(((lc&&lc!=i)||!lc)&&((rc&&rc!=j)||!rc))
						ret=ret+dfs(l+1,r-1,i,j);
				}
			return dp[l][r][i][j]=ret%mod;
		}
		else
		{
			return dp[l][r][lc][rc]=0;
		}
	}
	else
	{
		ret=dfs(l,match[l],lc,0)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,0)*dfs(match[l]+1,r,1,rc)
			+dfs(l,match[l],lc,0)*dfs(match[l]+1,r,2,rc)
			+dfs(l,match[l],lc,1)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,1)*dfs(match[l]+1,r,2,rc)
			+dfs(l,match[l],lc,2)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,2)*dfs(match[l]+1,r,1,rc);
		return dp[l][r][lc][rc]=ret%mod;
	}
}

int main()
{
	int n,i,j,cnt;
	long long ans;
	while(~scanf("%s",&s))
	{
		n=strlen(s);
		cnt=0;
		for(i=0;i<n;i++)
		{
			if(s[i]=='(')
				stk[cnt++]=i;
			else
				match[stk[--cnt]]=i;
		}
		memset(dp,-1,sizeof(dp));
		ans=0;
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
				ans=(ans+dfs(0,n-1,i,j))%mod;
		printf("%lld\n",ans);
	}
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>

using namespace std;

const int MAXN=770;
const long long mod=1e9+7;
char s[MAXN];
int match[MAXN],stk[MAXN];
long long dp[MAXN][MAXN][3][3];

long long dfs(int l,int r,int lc,int rc)
{
	if(l==r-1)
		return (lc&&!rc)||(rc&&!lc);
	if(dp[l][r][lc][rc]!=-1)
		return dp[l][r][lc][rc];
	long long ret=0,i,j;
	if(match[l]==r)
	{
		if((lc&&!rc)||(!lc&&rc))
		{
			for(i=0;i<3;i++)
				for(j=0;j<3;j++)
				{
					if(((lc&&lc!=i)||!lc)&&((rc&&rc!=j)||!rc))
						ret=ret+dfs(l+1,r-1,i,j);
				}
			return dp[l][r][i][j]=ret%mod;
		}
		/*
		if(lc&&!rc)
		{
			ret=dfs(l+1,r-1,0,0)+dfs(l+1,r-1,0,1)+dfs(l+1,r-1,0,2)
				+dfs(l+1,r-1,3-lc,0)+dfs(l+1,r-1,3-lc,1)+dfs(l+1,r-1,3-lc,2);
			return dp[l][r][i][j]=ret%mod;
		}
		else if(!lc&&rc)
		{
			ret=dfs(l+1,r-1,0,0)+dfs(l+1,r-1,1,0)+dfs(l+1,r-1,2,0)
				+dfs(l+1,r-1,0,3-rc)+dfs(l+1,r-1,1,3-rc)+dfs(l+1,r-1,2,3-rc);
			return dp[l][r][i][j]=ret%mod;
		}*/
		else
		{
			return dp[l][r][lc][rc]=0;
		}
	}
	else
	{
		ret=dfs(l,match[l],lc,0)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,0)*dfs(match[l]+1,r,1,rc)
			+dfs(l,match[l],lc,0)*dfs(match[l]+1,r,2,rc)
			+dfs(l,match[l],lc,1)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,1)*dfs(match[l]+1,r,2,rc)
			+dfs(l,match[l],lc,2)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,2)*dfs(match[l]+1,r,1,rc);
		return dp[l][r][lc][rc]=ret%mod;
	}
}

int main()
{
	int n,i,j,cnt;
	long long ans;
	while(~scanf("%s",&s))
	{
		n=strlen(s);
		cnt=0;
		for(i=0;i<n;i++)
		{
			if(s[i]=='(')
				stk[cnt++]=i;
			else
				match[stk[--cnt]]=i;
		}
		memset(dp,-1,sizeof(dp));
		ans=0;
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
				ans=(ans+dfs(0,n-1,i,j))%mod;
		printf("%lld\n",ans);
	}
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>

using namespace std;

const int MAXN=770;
const long long mod=1e9+7;
char s[MAXN];
int match[MAXN],stk[MAXN];
int dp[MAXN][MAXN][3][3];

int dfs(int l,int r,int lc,int rc)
{
	if(l==r-1)
		return (lc&&!rc)||(rc&&!lc);
	if(dp[l][r][lc][rc]!=-1)
		return dp[l][r][lc][rc];
	int ret=0,i,j;
	if(match[l]==r)
	{
		if((lc&&!rc)||(!lc&&rc))
		{
			for(i=0;i<3;i++)
				for(j=0;j<3;j++)
				{
					if(((lc&&lc!=i)||!lc)&&((rc&&rc!=j)||!rc))
						ret=(ret+dfs(l+1,r-1,i,j))%mod;
				}
			return dp[l][r][i][j]=ret;
		}
		else
			return dp[l][r][lc][rc]=0;
	}
	else
	{
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
			{
				if(i&&j&&i==j)
					continue;
				ret=(ret+1l*dfs(l,match[l],lc,i)*dfs(match[l]+1,r,j,rc))%mod;
			}
		return dp[l][r][lc][rc]=ret;
	}
}

int main()
{
	int n,i,j,cnt,ans;
	while(~scanf("%s",&s))
	{
		n=strlen(s);
		cnt=0;
		for(i=0;i<n;i++)
		{
			if(s[i]=='(')
				stk[cnt++]=i;
			else
				match[stk[--cnt]]=i;
		}
		memset(dp,-1,sizeof(dp));
		ans=0;
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
				ans=(ans+dfs(0,n-1,i,j))%mod;
		printf("%d\n",ans);
	}
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>

using namespace std;

const int MAXN=770;
const long long mod=1e9+7;
char s[MAXN];
int match[MAXN],stk[MAXN];
long long dp[MAXN][MAXN][3][3];

long long dfs(int l,int r,int lc,int rc)
{
	if(l==r-1)
		return (lc&&!rc)||(rc&&!lc);
	if(dp[l][r][lc][rc]!=-1)
		return dp[l][r][lc][rc];
	long long ret=0,i,j;
	if(match[l]==r)
	{
		if((lc&&!rc)||(!lc&&rc))
		{
			ret=dfs(l+1,r-1,0,0)+dfs(l+1,r-1,0,1)+dfs(l+1,r-1,0,2)
				+dfs(l+1,r-1,3-lc,0)+dfs(l+1,r-1,3-lc,1)+dfs(l+1,r-1,3-lc,2);
			return dp[l][r][i][j]=ret%mod;
		}
		else if(!lc&&rc)
		{
			ret=dfs(l+1,r-1,0,0)+dfs(l+1,r-1,1,0)+dfs(l+1,r-1,2,0)
				+dfs(l+1,r-1,0,3-rc)+dfs(l+1,r-1,1,3-rc)+dfs(l+1,r-1,2,3-rc);
			return dp[l][r][i][j]=ret%mod;
		}
		else
			return dp[l][r][lc][rc]=0;
	}
	else
	{
		ret=dfs(l,match[l],lc,0)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,0)*dfs(match[l]+1,r,1,rc)
			+dfs(l,match[l],lc,0)*dfs(match[l]+1,r,2,rc)
			+dfs(l,match[l],lc,1)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,1)*dfs(match[l]+1,r,2,rc)
			+dfs(l,match[l],lc,2)*dfs(match[l]+1,r,0,rc)
			+dfs(l,match[l],lc,2)*dfs(match[l]+1,r,1,rc);
		return dp[l][r][lc][rc]=ret%mod;
	}
}

int main()
{
	int n,i,j,cnt;
	long long ans;
	while(~scanf("%s",&s))
	{
		n=strlen(s);
		cnt=0;
		for(i=0;i<n;i++)
		{
			if(s[i]=='(')
				stk[cnt++]=i;
			else
				match[stk[--cnt]]=i;
		}
		memset(dp,-1,sizeof(dp));
		ans=0;
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
				ans=(ans+dfs(0,n-1,i,j))%mod;
		printf("%lld\n",ans);
	}
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>

using namespace std;

const int MAXN=770;
const long long mod=1e9+7;
char s[MAXN];
int match[MAXN],stk[MAXN];
int dp[MAXN][MAXN][3][3];

int dfs(int l,int r,int lc,int rc)
{
	if(l==r-1)
		return (lc&&!rc)||(rc&&!lc);
	if(dp[l][r][lc][rc]!=-1)
		return dp[l][r][lc][rc];
	int ret=0,i,j;
	if(match[l]==r)
	{
		if((lc&&!rc)||(!lc&&rc))
		{
			for(i=0;i<3;i++)
				for(j=0;j<3;j++)
				{
					if(((lc&&lc!=i)||!lc)&&((rc&&rc!=j)||!rc))
						ret=(ret+dfs(l+1,r-1,i,j))%mod;
				}
			return dp[l][r][i][j]=ret;
		}
		else
			return dp[l][r][lc][rc]=0;
	}
	else
	{
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
			{
				if(i&&j&&i==j)
					continue;
				ret=(ret+1ll*dfs(l,match[l],lc,i)*dfs(match[l]+1,r,j,rc))%mod;
			}
		return dp[l][r][lc][rc]=ret;
	}
}

int main()
{
	int n,i,j,cnt,ans;
	while(~scanf("%s",&s))
	{
		n=strlen(s);
		cnt=0;
		for(i=0;i<n;i++)
		{
			if(s[i]=='(')
				stk[cnt++]=i;
			else
				match[stk[--cnt]]=i;
		}
		memset(dp,-1,sizeof(dp));
		ans=0;
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
				ans=(ans+dfs(0,n-1,i,j))%mod;
		printf("%d\n",ans);
	}
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>

using namespace std;

const int MAXN=770;
const long long mod=1e9+7;
char s[MAXN];
int match[MAXN],stk[MAXN];
long long dp[MAXN][MAXN][3][3];

long long dfs(int l,int r,int lc,int rc)
{
	if(l==r-1)
		return (lc&&!rc)||(rc&&!lc);
	if(dp[l][r][lc][rc]!=-1)
		return dp[l][r][lc][rc];
	long long ret=0,i,j;
	if(match[l]==r)
	{
		if((lc&&!rc)||(!lc&&rc))
		{
			for(i=0;i<3;i++)
				for(j=0;j<3;j++)
				{
					if(((lc&&lc!=i)||!lc)&&((rc&&rc!=j)||!rc))
						ret=(ret+dfs(l+1,r-1,i,j))%mod;
				}
			return dp[l][r][lc][rc]=ret;
		}
		else
			return dp[l][r][lc][rc]=0;
	}
	else
	{
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
			{
				if(i&&j&&i==j)
					continue;
				ret=(ret+dfs(l,match[l],lc,i)*dfs(match[l]+1,r,j,rc))%mod;
			}
		return dp[l][r][lc][rc]=ret;
	}
}

int main()
{
	int n,i,j,cnt;
	long long ans;
	while(~scanf("%s",&s)&&s[0]!='e')
	{
		n=strlen(s);
		cnt=0;
		for(i=0;i<n;i++)
		{
			if(s[i]=='(')
				stk[cnt++]=i;
			else
				match[stk[--cnt]]=i;
		}
		memset(dp,-1,sizeof(dp));
		ans=0;
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
				ans=(ans+dfs(0,n-1,i,j))%mod;
		printf("%lld\n",ans);
	}
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>

using namespace std;

const int MAXN=770;
const long long mod=1e9+7;
char s[MAXN];
int match[MAXN],stk[MAXN];
long long dp[MAXN][MAXN][3][3];

long long dfs(int l,int r,int lc,int rc)
{
	if(l==r-1)
		return (lc&&!rc)||(rc&&!lc);
	if(dp[l][r][lc][rc]!=-1)
		return dp[l][r][lc][rc];
	long long ret=0,i,j;
	if(match[l]==r)
	{
		if((lc&&!rc)||(!lc&&rc))
		{
			for(i=0;i<3;i++)
				for(j=0;j<3;j++)
				{
					if(((lc&&lc!=i)||!lc)&&((rc&&rc!=j)||!rc))
						ret=(ret+dfs(l+1,r-1,i,j))%mod;
				}
			return dp[l][r][i][j]=ret;
		}
		else
			return dp[l][r][lc][rc]=0;
	}
	else
	{
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
			{
				if(i&&j&&i==j)
					continue;
				ret=(ret+dfs(l,match[l],lc,i)*dfs(match[l]+1,r,j,rc))%mod;
			}
		return dp[l][r][lc][rc]=ret;
	}
}

int main()
{
	int n,i,j,cnt;
	long long ans;
	while(~scanf("%s",&s)&&s[0]!='e')
	{
		n=strlen(s);
		cnt=0;
		for(i=0;i<n;i++)
		{
			if(s[i]=='(')
				stk[cnt++]=i;
			else
				match[stk[--cnt]]=i;
		}
		memset(dp,-1,sizeof(dp));
		ans=0;
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
				ans=(ans+dfs(0,n-1,i,j))%mod;
		printf("%lld\n",ans);
	}
}


#include <string.h>
#include <stdio.h>
#include <stack>

std::stack<unsigned> st;
unsigned match[1005], n;
long long dp[1005][1005][3];

const unsigned mod = 1000000007;

char bracket[1005];

int main() {
	scanf("%s", bracket);
	n = strlen(bracket);

	for (unsigned i = 0; i < n; ++i) {
		if (bracket[i] == '(')
			st.push(i);
		else {
			match[i] = st.top();
			match[st.top()] = i;
			st.pop();
		}
	}

	for (unsigned len = 1; len < n; len += 2)
		for (unsigned l = 0, r = len; r < n; ++l, ++r) {
			if (bracket[l] == ')' || bracket[r] == '(') continue;
			if (len == 1) {
				dp[l][r][0] = 4;
				dp[l][r][1] = dp[l][r][2] = 1;
			} else if (match[l] == r) {
				dp[l][r][1] = (dp[l + 1][r - 1][0] - dp[l + 1][r - 1][1] + mod) % mod;
				dp[l][r][2] = (dp[l + 1][r - 1][0] - dp[l + 1][r - 1][2] + mod) % mod;
				dp[l][r][0] = ((dp[l][r][1] << 1) + (dp[l][r][2] << 1)) % mod;
			} else {
				dp[l][r][1] = dp[l][match[l]][1] * dp[match[l] + 1][r][0] % mod;
				if(match[r]) dp[l][r][2] = dp[l][match[r] - 1][0] * dp[match[r]][r][2] % mod;
				dp[l][r][0] = ((dp[l][match[l]][0] * dp[match[l] + 1][r][0] - (dp[l][match[l]][2] * dp[match[l] + 1][r][1] << 1)) % mod + mod) % mod;
			}
		}

	printf("%lld", dp[0][n - 1][0]);
	return 0;
}


#include <string.h>
#include <stdio.h>
#include <stack>

std::stack<unsigned> st;
unsigned match[1005], n;
long long dp[1005][1005][3];

const unsigned mod = 1000000007;

char bracket[1005];

int main() {
	scanf("%s", bracket);
	n = strlen(bracket);

	for (unsigned i = 0; i < n; ++i) {
		if (bracket[i] == '(')
			st.push(i);
		else {
			match[i] = st.top();
			match[st.top()] = i;
			st.pop();
		}
	}

	for (unsigned len = 1; len < n; ++len)
		for (unsigned l = 0, r = len; r < n; ++l, ++r) {
			if (len == 1) {
				dp[l][r][0] = 4;
				dp[l][r][1] = dp[l][r][2] = 1;
			} else if (match[l] == r) {
				dp[l][r][1] = (dp[l + 1][r - 1][0] - dp[l + 1][r - 1][1] + mod) % mod;
				dp[l][r][2] = (dp[l + 1][r - 1][0] - dp[l + 1][r - 1][2] + mod) % mod;
				dp[l][r][0] = ((dp[l][r][1] << 1) + (dp[l][r][2] << 1)) % mod;
			} else {
				dp[l][r][1] = dp[l][match[l]][1] * dp[match[l] + 1][r][0] % mod;
				dp[l][r][2] = dp[l][match[l]][0] * dp[match[l] + 1][r][2] % mod;
				dp[l][r][0] = ((dp[l][match[l]][0] * dp[match[l] + 1][r][0] - (dp[l][match[l]][2] * dp[match[l] + 1][r][1] << 1)) % mod + mod) % mod;
			}
		}

	printf("%lld", dp[0][n - 1][0]);
	return 0;
}


#include <string.h>
#include <stdio.h>
#include <stack>

std::stack<unsigned> st;
unsigned match[4005], n;
long long dp[4005][4005][3];

const unsigned mod = 1000000007;

char bracket[4005];

int main() {
	scanf("%s", bracket);
	n = strlen(bracket);

	for (unsigned i = 0; i < n; ++i) {
		if (bracket[i] == '(')
			st.push(i);
		else {
			match[i] = st.top();
			match[st.top()] = i;
			st.pop();
		}
	}

	for (unsigned len = 1; len < n; len += 2)
		for (unsigned l = 0, r = len; r < n; ++l, ++r) {
			if (bracket[l] == ')' || bracket[r] == '(') continue;
			if (len == 1) {
				dp[l][r][0] = 4;
				dp[l][r][1] = dp[l][r][2] = 1;
			} else if (match[l] == r) {
				dp[l][r][1] = (dp[l + 1][r - 1][0] - dp[l + 1][r - 1][1] + mod) % mod;
				dp[l][r][2] = (dp[l + 1][r - 1][0] - dp[l + 1][r - 1][2] + mod) % mod;
				dp[l][r][0] = ((dp[l][r][1] << 1) + (dp[l][r][2] << 1)) % mod;
			} else {
				dp[l][r][1] = dp[l][match[l]][1] * dp[match[l] + 1][r][0] % mod;
				if(match[r]) dp[l][r][2] = dp[l][match[r] - 1][0] * dp[match[r]][r][2] % mod;
				dp[l][r][0] = ((dp[l][match[l]][0] * dp[match[l] + 1][r][0] - (dp[l][match[l]][2] * dp[match[l] + 1][r][1] << 1)) % mod + mod) % mod;
			}
		}

	printf("%lld", dp[0][n - 1][0]);
	return 0;
}


#include <cstdio>
#include<iostream>
#include<string>
#include<stack>
using namespace std;
int character = 0;

stack<char> s;

int main()
{

	string s;
	cin >> s;
	int n=0;

	for (int i = 0; i < s.length(); i++) {
		for (int j = i; j <s.length(); j++) {
			int error = 0;
			if ((j - i) % 2 == 0)continue;

			int start = i;
			int end = j;
			int left = 0;
			int leftquestion = 0;

			int right = 0;
			int rightquestion = 0;

			while (start < end && start - end != 1) {
				error = 2;
				if (s[start] == '(')left++;
				if (s[end]== ')')right++;
				if (s[start] == '?')leftquestion++;

				if (s[start] == ')')left--;
				if (s[end] == '(')right--;
				if (s[end] == '?')rightquestion++;

				if (left < 0 && leftquestion>0) {
					left++;
					leftquestion--;
				}
				else if (left < 0) {
					error = 1;
					break;
				}

				if (right < 0 && rightquestion>0) {
					right++;
					rightquestion--;
				}
				else if (right < 0) {
					error = 1;
					break;
				}

				start++;
				end--;
			}

			if (error == 1)continue;
			if(error==2)
			n++;

		}
	}

	printf("%d", n);

	return 0;
}


#include <cstdio>
#include<iostream>
#include<string>
#include<stack>
#include<math.h>
using namespace std;
int character = 0;

//stack<char> s;

int main()
{
	std::ios::sync_with_stdio(false);
	string s;
	cin >> s;
	int n=0;

	for (int i = 0; i < s.length(); i++) {
		int left = 0;
		int leftquestion = 0;

		for (int j = i; j <s.length(); j++) {
			int error = 0;
			int start = i;
			int end = j;

			if (s[j] == '(')left++;
			if (s[j] == ')')left--;
			if (s[j] == '?') {
				leftquestion++;
				if (left <= 0) {
					//leftlimited++;
					left++;
					leftquestion--;
				}
			}
			if (left < 0 && leftquestion>0) {
				left++;
				leftquestion--;
			}
			else if (left < 0) {
				//error = 3;
				break;
			}

			if ((j - i) % 2 == 0)continue;
			if (leftquestion<left)continue;

			n++;

		}
	}

	printf("%d", n);

	return 0;
}


#include <cstdio>
#include<iostream>
#include<string>
#include<stack>
#include<math.h>
using namespace std;

int main()
{
	//std::ios::sync_with_stdio(false);
	char s[10000];
	scanf_s("%s",s,10000);
	int length = 0;
	for (; s[length] != 0; length++);

	int n=0;

	for (int i = 0; i < length; i++) {
		int left = 0;
		int leftquestion = 0;

		for (int j = i; j <length; j++) {

			if (s[j] == '(')
			{
				left++;
				continue;
			}
			if (s[j] == ')') {
				left--;
				if (leftquestion > 0 && leftquestion>left) {
					left++;
					leftquestion--;
				}
			}
			if (s[j] == '?') {
				leftquestion++;
				if (leftquestion > left) {
					left++;
					leftquestion--;
				}
			}

			if (left <= 0 && leftquestion>0) {
				left++;
				leftquestion--;
			}
			else if (left < 0) {
				break;
			}
			if ((j - i) % 2 == 0)continue;
			if (leftquestion<left)continue;
			n++;
		}
	}
	printf("%d", n);
	return 0;
}


#include <cstdio>
#include<iostream>
#include<string>
#include<stack>
#include<math.h>
using namespace std;
int character = 0;

//stack<char> s;

int main()
{
	std::ios::sync_with_stdio(false);
	string s;
	cin >> s;
	int n=0;

	for (int i = 0; i < s.length(); i++) {
		for (int j = i; j <s.length(); j++) {
			int error = 0;
			if ((j - i) % 2 == 0)continue;

			int start = i;
			int end = j;
			int left = 0;
			int leftquestion = 0;
			//int leftlimited = 0;

			int right = 0;
			int rightquestion = 0;
			//int rightlimited = 0;

			while (start < end && start - end != 1) {
				error = 2;
				if (s[start] == '(')left++;
				if (s[start] == ')')left--;
				if (s[start] == '?') {
					leftquestion++;
					if (left<=0) {
						//leftlimited++;
						left++;
						leftquestion--;
					}
				}

				if (s[end] == '(')right--;
				if (s[end] == ')')right++;
				if (s[end] == '?') {
					rightquestion++;
					if (right <= 0) {
						//leftlimited++;
						right++;
						rightquestion--;
					}
				}
				if (left < 0 && leftquestion>0) {
					left++;
					leftquestion--;
				}
				else if (left < 0) {
					error = 3;
					break;
				}

				if (right < 0 && rightquestion>0) {
					right++;
					rightquestion--;
				}
				else if (right < 0) {
					error = 1;
					break;
				}

				start++;
				end--;
			}

			if (error == 1)continue;
			if (error == 3)break;
			if (leftquestion + rightquestion<abs(left - right))continue;

			if(error==2)
			n++;

		}
	}

	printf("%d", n);

	return 0;
}


#include <cstdio>
#include<iostream>
#include<string>
#include<stack>
#include<math.h>
using namespace std;

int main()
{
	//std::ios::sync_with_stdio(false);
	char s[10000];
	scanf("%s",s);
	int length = 0;
	for (; s[length] != 0; length++);

	int n=0;

	for (int i = 0; i < length; i++) {
		int left = 0;
		int leftquestion = 0;

		for (int j = i; j <length; j++) {

			if (s[j] == '(')
			{
				left++;
				continue;
			}
			if (s[j] == ')')left--;
			if (s[j] == '?') {
				leftquestion++;
				if (left <= 0) {
					left++;
					leftquestion--;
				}
			}
			if (left <= 0 && leftquestion>0) {
				left++;
				leftquestion--;
			}
			else if (left < 0) {
				break;
			}
			if ((j - i) % 2 == 0)continue;
			if (leftquestion<left)continue;

			n++;
		}
	}
	printf("%d", n);
	return 0;
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace The_Monster
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            writer.WriteLine(Solve(args));
            writer.Flush();
        }

        private static int Solve(string[] args)
        {
            string s = reader.ReadLine();

            var list = new List<Point>();
            int count = 0;
            foreach (char c in s)
            {
                foreach (Point point in list)
                {
                    count += point.Add(c);
                }

                if (c != ')')
                    list.Add(new Point(c));
            }

            return count;
        }

        #region Nested type: Point

        private class Point
        {
            private int cnt;
            private int max;
            private int min;

            public Point(char c)
            {
                min = 1;
                max = 1;
                cnt = 1;
            }

            public int Add(char c)
            {
                cnt++;
                if (c == '?')
                {
                    min--;
                    max++;
                }
                else if (c == '(')
                {
                    min++;
                    max++;
                    return 0;
                }
                else // )
                {
                    min--;
                    max--;
                }

                if ((cnt & 1) == 0 && min <= 0 && max >= 0)
                    return 1;
                return 0;
            }
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace The_Monster
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            writer.WriteLine(Solve(args));
            writer.Flush();
        }

        private static int Solve(string[] args)
        {
            string s = reader.ReadLine();

            var list = new List<Point>();
            int count = 0;
            foreach (char c in s)
            {
                foreach (Point point in list)
                {
                    count += point.Add(c);
                }

                if (c != ')')
                    list.Add(new Point(c));
            }

            return count;
        }

        #region Nested type: Point

        private class Point
        {
            private int cnt;
            private bool invalid;
            private int max;
            private int min;

            public Point(char c)
            {
                min = 1;
                max = 1;
                cnt = 1;
            }

            public int Add(char c)
            {
                if (invalid)
                    return 0;
                cnt++;
                if (c == '?')
                {
                    min--;
                    if (min < 0)
                        min = 0;
                    max++;
                }
                else if (c == '(')
                {
                    min++;
                    max++;
                    return 0;
                }
                else // )
                {
                    min--;
                    if (min < 0)
                        min = 0;
                    max--;
                    if (max < 0)
                    {
                        invalid = true;
                        return 0;
                    }
                }

                if ((cnt & 1) == 0 && min <= 0 && max >= 0)
                    return 1;
                return 0;
            }
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace The_Monster
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            writer.WriteLine(Solve(args));
            writer.Flush();
        }

        private static int Solve(string[] args)
        {
            string s = reader.ReadLine();

            var list = new List<Point>();
            int count = 0;
            foreach (char c in s)
            {
                foreach (Point point in list)
                {
                    count += point.Add(c);
                }

                if (c != ')')
                    list.Add(new Point(c));
            }

            return count;
        }

        #region Nested type: Point

        private class Point
        {
            private int cnt;
            private bool invalid;
            private int max;
            private int min;

            public Point(char c)
            {
                min = 1;
                max = 1;
                cnt = 1;
            }

            public int Add(char c)
            {
                if (invalid)
                    return 0;
                cnt++;
                if (c == '?')
                {
                    min--;
                    max++;
                }
                else if (c == '(')
                {
                    min++;
                    max++;
                    return 0;
                }
                else // )
                {
                    min--;
                    max--;
                    if (max < 0)
                    {
                        invalid = true;
                        return 0;
                    }
                }

                if ((cnt & 1) == 0 && min <= 0 && max >= 0)
                    return 1;
                return 0;
            }
        }

        #endregion
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		memo = new int[N][];
		for(int i=0;i<N;i++){
			memo[i] = new int[N+1];
			for(int j=0;j<=N;j++) memo[i][j] = -1;
		}

		dfs(0,N);
		dfs(1,N);
		dfs(0,N-1);
		dfs(1,N-1);

		int cnt = 0;
		for(int i=0;i<N;i++){
			for(int j=i+1;j<=N;j++){
				if(memo[i][j] == 1) cnt++;
			}
		}

		Console.WriteLine(cnt);

	}

	int dfs(int l, int r){
//Console.WriteLine("{0} {1}",l,r);
		if(memo[l][r] != -1) return memo[l][r];
		if(r == l){ return memo[l][r] = 1;}
		if(r - l == 1){
			return memo[l][r] = 0;
		}

		int ret = 0;
		for(int i=l+1;i<r;i++){
			if(dfs(l,i) == 1 && dfs(i,r) == 1) ret = 1;
		}
		if(S[l] == '(' && dfs(l+1,r-1) == 1 && S[r-1] == ')') ret = 1;
		if(S[l] == '?' && dfs(l+1,r-1) == 1 && S[r-1] == ')') ret = 1;
		if(S[l] == '(' && dfs(l+1,r-1) == 1 && S[r-1] == '?') ret = 1;
		if(S[l] == '?' && dfs(l+1,r-1) == 1 && S[r-1] == '?') ret = 1;
		return memo[l][r] = ret;

	}

	int N;
	int[][] memo;

	String S;
	public Sol(){
		S = rs();
		N = S.Length;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){

		int cnt = 0;
		for(int i=0;i<N;i++){
			int v = 0;
			int q = 0;
			for(int j=i;j<N;j++){
				if(S[j] == '(') v++;
				if(S[j] == ')') v--;
				if(S[j] == '?'){
					if(v > 0){
						q++;
					} else {
						v++;
					}
				}
				if(v < 0 && q + v < 0) break;
				if(((j - i)%2 ) == 1){
					if(v == 0){
						cnt++;
					}
					if(v > 0 && q >= v && ((v - q) % 2 ) == 0){
						cnt++;
					}
					if(v < 0 && q >= - v && ((v + q) % 2 ) == 0){
						cnt++;
					}
				}
			}
		}
		Console.WriteLine(cnt);
	}
	int N;

	String S;
	public Sol(){
		S = rs();
		N = S.Length;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){

		int cnt = 0;
		for(int i=0;i<N;i++){
			int l = 0, r = 0;
			for(int j=i;j<N;j++){
				switch(S[j]){
					case '(' : {
						l++;r++;
					} break;

					case ')' : {
						r--;
						if(l == 0){
							l++;
						} else {
							l--;
						}
					} break;

					case '?' : {
						r++;
						if(l == 0){
							l++;
						} else {
							l--;
						}
					} break;
				}
//Console.WriteLine("{0} {1} {2} {3}",i,j,l,r);
				if(r < 0) break;
				if(l > r) break;
				if(l == 0 && r >= 0 && ((j - i) % 2) == 1){
					cnt++;
//Console.WriteLine("a{0} {1} {2} {3}",i,j,l,r);
				}
			}
		}
		Console.WriteLine(cnt);
	}
	int N;

	String S;
	public Sol(){
		S = rs();
		N = S.Length;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		memo = new int[N][];
		for(int i=0;i<N;i++){
			memo[i] = new int[N+1];
			for(int j=0;j<=N;j++) memo[i][j] = -1;
		}

		dfs(0,N);
		dfs(1,N);
		dfs(0,N-1);
		dfs(1,N-1);

		int cnt = 0;
		for(int i=0;i<N;i++){
			for(int j=i+2;j<=N;j++){
				if(memo[i][j] == 1) cnt++;
			}
		}

		Console.WriteLine(cnt);

	}

	int dfs(int l, int r){
//Console.WriteLine("{0} {1}",l,r);
		if(memo[l][r] != -1) return memo[l][r];
		if(r - l <= 1){
			return memo[l][r] = 0;
		}
		if(r - l == 2){
			memo[l][r] = 0;
			if(S[l] == '(' && S[r-1] == ')') memo[l][r] = 1;
			if(S[l] == '(' && S[r-1] == '?') memo[l][r] = 1;
			if(S[l] == '?' && S[r-1] == ')') memo[l][r] = 1;
			if(S[l] == '?' && S[r-1] == '?') memo[l][r] = 1;
			return memo[l][r];
		}

		int ret = 0;
		for(int i=l;i<r;i++){
			if(dfs(l,i) == 1 && dfs(i,r) == 1) ret = 1;
		}
		if(S[l] == '(' && dfs(l+1,r-1) == 1 && S[r-1] == ')') ret = 1;
		if(S[l] == '?' && dfs(l+1,r-1) == 1 && S[r-1] == ')') ret = 1;
		if(S[l] == '(' && dfs(l+1,r-1) == 1 && S[r-1] == '?') ret = 1;
		if(S[l] == '?' && dfs(l+1,r-1) == 1 && S[r-1] == '?') ret = 1;
		return memo[l][r] = ret;

	}

	int N;
	int[][] memo;

	String S;
	public Sol(){
		S = rs();
		N = S.Length;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		memo = new int[N][];
		for(int i=0;i<N;i++){
			memo[i] = new int[N+1];
			for(int j=0;j<=N;j++) memo[i][j] = -1;
		}
		/*
		dfs(0,N);
		dfs(1,N);
		dfs(0,N-1);
		dfs(1,N-1);
		*/
		/*
		int[] sum = new int[N+1];
		for(int i=0;i<N;i++){
			int v = S[i] == '?' ? 1 : 0;
			sum[i+1] = sum[i] + v;
		}

		int cnt = 0;
		for(int i=0;i<N;i++){
			for(int j=i+1;j<=N;j++){
				if(memo[i][j] == 1) {
					int q = sum[j] - sum[i];
					if(q > 0)cnt++;
				}
			}
		}
		*/

		for(int i=0;i<N;i++){
			for(int j=i;j<=N;j++){
				dfs(i,j);
			}
		}
		int cnt = 0;
		for(int i=0;i<N;i++){
			for(int j=i+1;j<=N;j++){
				if(memo[i][j] == 1) {
					cnt++;
				}
			}
		}

		Console.WriteLine(cnt);

	}

	int dfs(int l, int r){
//Console.WriteLine("{0} {1}",l,r);
		if(memo[l][r] != -1) return memo[l][r];
		if(r == l){ return memo[l][r] = 1;}
		if(r - l == 1){
			return memo[l][r] = 0;
		}

		int ret = 0;
		for(int i=l+1;i<r;i++){
			if(dfs(l,i) == 1 && dfs(i,r) == 1) ret = 1;
		}
		if(S[l] == '(' && dfs(l+1,r-1) == 1 && S[r-1] == ')') ret = 1;
		if(S[l] == '?' && dfs(l+1,r-1) == 1 && S[r-1] == ')') ret = 1;
		if(S[l] == '(' && dfs(l+1,r-1) == 1 && S[r-1] == '?') ret = 1;
		if(S[l] == '?' && dfs(l+1,r-1) == 1 && S[r-1] == '?') ret = 1;
		return memo[l][r] = ret;

	}

	int N;
	int[][] memo;

	String S;
	public Sol(){
		S = rs();
		N = S.Length;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){

		int cnt = 0;
		for(int i=0;i<N;i++){
			int l = 0, r = 0;
			for(int j=i;j<N;j++){
				switch(S[j]){
					case '(' : {
						l++;r++;
					} break;

					case ')' : {
						l--;r--;
					} break;

					case '?' : {
						r++;
						if(l == 0){
							l++;
						} else {
							l--;
						}
					} break;
				}
//Console.WriteLine("{0} {1} {2} {3}",i,j,l,r);
				if(r < 0) break;
				if(l == 0 && r >= 0 && ((j - i) % 2) == 1){
					cnt++;
//Console.WriteLine("a{0} {1} {2} {3}",i,j,l,r);
				}
			}
		}
		Console.WriteLine(cnt);
	}
	int N;

	String S;
	public Sol(){
		S = rs();
		N = S.Length;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){

		int cnt = 0;
		for(int i=0;i<N;i++){
			int v = 0;
			int q = 0;
			for(int j=i;j<N;j++){
				if(S[j] == '(') v++;
				if(S[j] == ')') v--;
				if(S[j] == '?'){
					if(j != i){
						q++;
					} else {
						v++;
					}
				}
				if(v < 0 && q + v < 0) break;
				if(((j - i)%2 ) == 1){
					if(v == 0){
						cnt++;
					}
					if(v > 0 && q >= v && ((v - q) % 2 ) == 0){
						cnt++;
					}
					if(v < 0 && q >= - v && ((v + q) % 2 ) == 0){
						cnt++;
					}
				}
			}
		}
		Console.WriteLine(cnt);
	}
	int N;

	String S;
	public Sol(){
		S = rs();
		N = S.Length;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Diagnostics;
using static System.Console;
//using System.Numerics;
//using static System.Math;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;

    void solve()
    {
        var S = ReadLine();
        int N = S.Length;

        long ans = 0;
        for (int i = 0; i < N; i++)
        {
            int kakko = 0;
            int hatena = 0;
            int hanyou = 0;
            for (int j = i; j < N; j++)
            {
                //[i,j]で
                if (S[j] == '(')
                {
                    kakko++;
                    if (hatena % 2 == 1 && kakko > 0)
                    {
                        kakko++;
                        hanyou += hatena - 1;
                        hatena = 0;
                    }
                    else if (hatena % 2 == 0 && kakko > 0)
                    {
                        hanyou += hatena;
                        hatena = 0;
                    }
                }
                else if (S[j] == ')')
                {
                    kakko--;
                    if (kakko < 0)
                    {
                        if (hatena == 0 && hanyou == 0)
                        {
                            break;
                        }
                        if (hatena > 0)
                        {
                            hatena--;
                            kakko++;
                        }
                        else if (hanyou > 0)
                        {
                            kakko += 2;
                            hanyou -= 2;
                        }
                    }

                }
                else
                {
                    hatena++;

                }

                if (kakko == 0 && hatena % 2 == 0)
                {
                    ans++;
                    //WriteLine($"{i} {j}");
                }
                else if (kakko - hatena == 0)
                {
                    ans++;
                    //WriteLine($"{i} {j}");
                }
                else if(S[j] == '?')
                {
                    int k = kakko - 1;
                    int p = hatena - 1;
                    p -= Math.Abs(k);
                    if (p > 0 && p % 2 == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                }
                else if(S[j] != '?')
                {
                    int p = hatena - Math.Abs(kakko);
                    if (p > 0 && p % 2 == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                }
            }
        }
        WriteLine(ans);
    }

}

class Scanner
{
    string[] s; int i;
    char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan { get { return ReadLine().Split(); } }
    public int[] scanint { get { return Array.ConvertAll(scan, int.Parse); } }
    public long[] scanlong { get { return Array.ConvertAll(scan, long.Parse); } }
    public double[] scandouble { get { return Array.ConvertAll(scan, double.Parse); } }
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint { get { return int.Parse(next); } }
    public long nextlong { get { return long.Parse(next); } }
    public double nextdouble { get { return double.Parse(next); } }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Diagnostics;
using static System.Console;
//using System.Numerics;
//using static System.Math;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;

    void solve()
    {
        var S = ReadLine();
        int N = S.Length;

        long ans = 0;
        for (int i = 0; i < N; i++)
        {
            int kakko = 0;
            int hatena = 0;
            int hanyou = 0;
            for (int j = i; j < N; j++)
            {
                //[i,j]で
                if (S[j] == '(')
                {
                    kakko++;
                    if (hatena % 2 == 1 && kakko > 0)
                    {
                        kakko++;
                        hanyou += hatena - 1;
                        hatena = 0;
                    }
                    else if (hatena % 2 == 0 && kakko > 0)
                    {
                        hanyou += hatena;
                        hatena = 0;
                    }
                }
                else if (S[j] == ')')
                {
                    kakko--;
                    if (kakko < 0)
                    {
                        if (hatena == 0 && hanyou == 0)
                        {
                            break;
                        }
                        if (hatena > 0)
                        {
                            hatena--;
                            kakko++;
                        }
                        else if (hanyou > 0)
                        {
                            kakko += 2;
                            hanyou -= 2;
                        }
                    }

                }
                else
                {
                    hatena++;

                }

                if(S[j] == '?')
                {
                    int k = kakko - 1;
                    int p = hatena - 1;
                    p -= Math.Abs(k);
                    if (p >= 0 && p % 2 == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                }
                else if(S[j] != '?')
                {
                    int p = hatena - Math.Abs(kakko);
                    if (p >= 0 && p % 2 == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                }
            }
        }
        WriteLine(ans);
    }

}

class Scanner
{
    string[] s; int i;
    char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan { get { return ReadLine().Split(); } }
    public int[] scanint { get { return Array.ConvertAll(scan, int.Parse); } }
    public long[] scanlong { get { return Array.ConvertAll(scan, long.Parse); } }
    public double[] scandouble { get { return Array.ConvertAll(scan, double.Parse); } }
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint { get { return int.Parse(next); } }
    public long nextlong { get { return long.Parse(next); } }
    public double nextdouble { get { return double.Parse(next); } }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Diagnostics;
using static System.Console;
//using System.Numerics;
//using static System.Math;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;

    void solve()
    {
        var S = ReadLine();
        int N = S.Length;

        long ans = 0;
        for (int i = 0; i < N; i++)
        {
            int kakko = 0;
            int hatena = 0;
            int hanyou = 0;
            for (int j = i; j < N; j++)
            {
                //[i,j]で
                if (S[j] == '(')
                {
                    kakko++;
                    if (hatena % 2 == 1 && kakko > 0)
                    {
                        kakko++;
                        hanyou += hatena - 1;
                        hatena = 0;
                    }
                    else if (hatena % 2 == 0 && kakko > 0)
                    {
                        hanyou += hatena;
                        hatena = 0;
                    }
                }
                else if (S[j] == ')')
                {
                    kakko--;
                }
                else
                {
                    hatena++;
                }

                if (kakko < 0)
                {
                    if (hatena == 0 && hanyou == 0)
                    {
                        break;
                    }
                    if (hatena > 0)
                    {
                        hatena--;
                        kakko++;
                    }
                    else if (hanyou > 0)
                    {
                        kakko += 2;
                        hanyou -= 2;
                    }
                }

                if (kakko == 0 && hatena % 2 == 0)
                {
                    ans++;
                    //WriteLine($"{i} {j}");
                }
                else if (kakko - hatena == 0)
                {
                    ans++;
                    //WriteLine($"{i} {j}");
                }

            }
        }
        WriteLine(ans);

        //var A = new int[N];
        //var B = new int[N];
        //var C = new int[N];
        //for (int i = 0; i < N; i++)
        //{
        //    if (S[i] == '(')
        //    {
        //        A[i]++;
        //    }
        //    else if (S[i] == ')')
        //    {
        //        B[i]++;
        //    }

        //}
    }

}

class Scanner
{
    string[] s; int i;
    char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan { get { return ReadLine().Split(); } }
    public int[] scanint { get { return Array.ConvertAll(scan, int.Parse); } }
    public long[] scanlong { get { return Array.ConvertAll(scan, long.Parse); } }
    public double[] scandouble { get { return Array.ConvertAll(scan, double.Parse); } }
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint { get { return int.Parse(next); } }
    public long nextlong { get { return long.Parse(next); } }
    public double nextdouble { get { return double.Parse(next); } }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Diagnostics;
using static System.Console;
//using System.Numerics;
//using static System.Math;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;

    void solve()
    {
        var S = ReadLine();
        int N = S.Length;
        int ans = 0;
        for (int i = 0; i < N; i++)
        {
            int min = 0;
            int max = 0;
            for (int j = i; j < N; j++)
            {
                if (S[j] == '(')
                {
                    min++;
                    max++;
                }
                else if (S[j] == ')')
                {
                    min--;
                    max--;

                }
                else
                {
                    if (max > 0) min--;
                    max++;
                }

                if (min < 0)
                {
                    min += 1;
                }
                if (min > max)
                {
                    break;
                }

                if (j - i > 0 && (j - i) % 2 == 1 && min == 0)
                {
                    ans++;
                    //WriteLine($"{i + 1} {j + 1}");
                }
            }
        }
        WriteLine(ans);
    }

}

class Scanner
{
    string[] s; int i;
    char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan { get { return ReadLine().Split(); } }
    public int[] scanint { get { return Array.ConvertAll(scan, int.Parse); } }
    public long[] scanlong { get { return Array.ConvertAll(scan, long.Parse); } }
    public double[] scandouble { get { return Array.ConvertAll(scan, double.Parse); } }
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint { get { return int.Parse(next); } }
    public long nextlong { get { return long.Parse(next); } }
    public double nextdouble { get { return double.Parse(next); } }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Diagnostics;
using static System.Console;
//using System.Numerics;
//using static System.Math;

class Program
{
    static void Main()
    {
        SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;

    void solve()
    {
        var S = cin.next;
        int N = S.Length;
        var B = new bool[N, N];
        for (int i = 0; i < N; i++)
        {
            for (int j = i + 1; j < N; j += 2)
            {
                if (S[i] != ')' && S[j] != '(')
                {
                    B[i, j] = true;
                }
            }
        }
        var dp = new bool[N, N];
        for (int i = 1; i < N; i += 2)//文字数
        {
            for (int j = 0; j < N; j++)//開始地点
            {
                if (j + i >= N) continue;
                if (i == 1)
                {
                    dp[j, j + i] = B[j, j + i];
                }
                else
                {
                    dp[j, j + i] = (B[j, j + i] && dp[j + 1, j + i - 1]);
                    for (int k = 1; k < i; k += 2)
                    {
                        if (dp[j, j + i]) break;
                        dp[j, j + i] = (dp[j, j + k] && dp[j + k + 1, j + i]);
                    }
                }
            }

        }

        int ans = 0;
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                if (dp[i, j]) ans++;
            }
        }
        WriteLine(ans);
    }

}

class Scanner
{
    string[] s; int i;
    char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan { get { return ReadLine().Split(); } }
    public int[] scanint { get { return Array.ConvertAll(scan, int.Parse); } }
    public long[] scanlong { get { return Array.ConvertAll(scan, long.Parse); } }
    public double[] scandouble { get { return Array.ConvertAll(scan, double.Parse); } }
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint { get { return int.Parse(next); } }
    public long nextlong { get { return long.Parse(next); } }
    public double nextdouble { get { return double.Parse(next); } }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Diagnostics;
using static System.Console;
//using System.Numerics;
//using static System.Math;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;

    void solve()
    {
        var S = ReadLine();
        int N = S.Length;

        long ans = 0;
        for (int i = 0; i < N; i++)
        {
            int kakko = 0;
            int hatena = 0;
            int hanyou = 0;
            for (int j = i; j < N; j++)
            {
                //[i,j]で
                if (S[j] == '(')
                {
                    kakko++;
                    if (hatena % 2 == 1 && kakko > 0)
                    {
                        kakko++;
                        hanyou += hatena - 1;
                        hatena = 0;
                    }
                    else if (hatena % 2 == 0 && kakko > 0)
                    {
                        hanyou += hatena;
                        hatena = 0;
                    }

                    if (kakko == 0 && hatena % 2 == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                    else if (kakko - hatena == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                }
                else if (S[j] == ')')
                {
                    kakko--;
                    if (kakko < 0)
                    {
                        if (hatena == 0 && hanyou == 0)
                        {
                            break;
                        }
                        if (hatena > 0)
                        {
                            hatena--;
                            kakko++;
                        }
                        else if (hanyou > 0)
                        {
                            kakko += 2;
                            hanyou -= 2;
                        }
                    }

                    if (kakko == 0 && hatena % 2 == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                    else if (kakko - hatena == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                }
                else
                {
                    hatena++;

                    if (kakko == 0 && hatena % 2 == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                    else if (kakko - hatena == 0)
                    {
                        ans++;
                        //WriteLine($"{i} {j}");
                    }
                    else
                    {
                        int k = kakko - 1;
                        int p = hatena - 1;
                        p -= Math.Abs(k);
                        if (p > 0 &&  p % 2 == 0)
                        {
                            ans++;
                            //WriteLine($"{i} {j}");
                        }
                    }
                }

            }
        }
        WriteLine(ans);
    }

}

class Scanner
{
    string[] s; int i;
    char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan { get { return ReadLine().Split(); } }
    public int[] scanint { get { return Array.ConvertAll(scan, int.Parse); } }
    public long[] scanlong { get { return Array.ConvertAll(scan, long.Parse); } }
    public double[] scandouble { get { return Array.ConvertAll(scan, double.Parse); } }
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint { get { return int.Parse(next); } }
    public long nextlong { get { return long.Parse(next); } }
    public double nextdouble { get { return double.Parse(next); } }
}


S = raw_input()
N = len(S)

A = 0
for i in xrange(N):
	D = 0
	Q = 0
	for j in xrange(i, N):
		D += S[j] == '('
		D -= S[j] == ')'
		Q += S[j] == '?'

		if D + Q < 0:
			break

		if Q > D:
			D, Q = Q, D

		if Q == D:
			A += 1
print A


def main():
    S = raw_input()
    N = len(S)

    A = 0
    for i in xrange(N):
	    D = 0
	    Q = 0
	    for j in xrange(i, N):
	    	D += S[j] == '('
	    	D -= S[j] == ')'
	    	Q += S[j] == '?'

	    	if D + Q < 0:
	    		break

	    	if Q > D:
	    		D, Q = Q, D

	    	if Q == D:
	    		A += 1
    print A


def main():
    S = raw_input()
    N = len(S)

    A = 0
    for i in xrange(N):
	    D = 0
	    Q = 0
	    for j in xrange(i, N):
	    	D += S[j] == '('
	    	D -= S[j] == ')'
	    	Q += S[j] == '?'

	    	if D + Q < 0:
	    		break

	    	if Q > D:
	    		D, Q = Q, D

	    	if Q == D:
	    		A += 1
    print A
main()


# -*- coding: utf-8 -*-
"""
Created on Tue Jan 30 14:32:23 2018

@author: Lixiang
"""

S = raw_input()
N = len(S)
A = 0
for i in xrange(N):
    D = 0
    Q = 0
    for j in xrange(i, N):
        D += S[j] == '('
        D -= S[j] == ')'
        Q += S[j] == '?'
        if D + Q < 0:
            break
        if Q > D:
            D, Q = Q, D
        if Q == D:
            A += 1
print A


s = list(raw_input())
n = len(s)
ans = 0
for i in range(n):
    lcnt = 0
    rcnt = 0
    cnt = 0
    for j in range(i,n):
        if s[j]=='(':
            lcnt += 1
        elif s[j]==')':
            if not lcnt and not cnt:
                break
            elif lcnt==0:
                cnt -= 1
                lcnt += 1
            else:
                lcnt -= 1
        else:
            if lcnt:
                lcnt -= 1
                cnt += 1
            else:
                lcnt += 1
        if not lcnt:
            ans += 1
print ans


# -*- coding: utf-8 -*-
def good_prefixes(line):
    result = 0
    begin, end = 0, 0
    for char in line:
        if char == '(':
            begin += 1
            end += 1
        elif char == ')':
            end -= 1
            if begin:
                begin -= 1
            else:
                begin += 1
                if begin > end:
                    return result
        else:
            if begin:
                begin -= 1
            else:
                begin += 1
            end += 1
        if begin == 0:
            result += 1
    return result

def main():
    line = raw_input()
    print(sum(good_prefixes(line[i:]) for i in range(len(line))))

main()


from sys import stdin

s, ans = stdin.readline().strip(), 0
for i in range(len(s)):
    stk, q = 0, 0
    for j in range(i, len(s)):
        if s[j] == '(':
            stk += 1
        elif s[j] == ')':
            stk -= 1
        else:
            q += 1

        if stk < 0:
            if q == abs(stk):
                ans += 1
            else:
                break

        elif stk == 0:
            ans += (not q or q % 2 == 0)
        else:
            ans += (q == stk and s[j]!='(')

        # print(ans, stk, i)

print(ans)


from sys import stdin

s, ans = stdin.readline().strip(), 0
for i in range(len(s)):
    stk, q = 0, 0
    for j in range(i, len(s)):
        if s[j] == '(':
            stk += 1
        elif s[j] == ')':
            stk -= 1
        else:
            q += 1

        if stk < 0:
            break
        if q > stk:
            stk += 1
            q -= 1

        if (j - i) & 1 and q >= stk:
            ans += 1
        # print(stk, ans, i)

print(ans)


from sys import stdin

s, ans = stdin.readline().strip(), 0
for i in range(len(s)):
    stk, q = 0, 0
    for j in range(i, len(s)):
        if s[j] == '(':
            stk += 1
        elif s[j] == ')':
            stk -= 1
        else:
            q += 1

        if q > stk:
            stk += 1
            q -= 1
        if stk < 0:
            break
        if (j - i) & 1 and q >= stk:
            ans += 1
        # print(stk, ans, i)

print(ans)


from sys import stdin

s, ans = stdin.readline().strip(), 0
for i in range(len(s)):
    stk, q = 0, 0
    for j in range(i, len(s)):
        if s[j] == '(':
            stk += 1
        elif s[j] == ')':
            stk -= 1
        else:
            q += 1

        if stk < 0:
            if (q + abs(stk)) % 2 == 0:
                ans += 1
            elif q < abs(stk):
                break

        elif stk == 0:
            ans += (s[j] != '(') and (not q or q % 2 == 0)
        else:
            ans += ((q + stk) % 2 == 0 and s[j] != '(')

        # print(ans, stk, i)

print(ans)


range = xrange
input = raw_input

s = input()
n = len(s)

combs = 0
for i in range(n):
    leftmin = 0
    leftmax = 0
    for j in range(i,n):
        if s[j]=='(':
            leftmin += 1
            leftmax += 1
        elif s[j]==')':
            if leftmin>0:
                leftmin -=1
            else:
                leftmin +=1
            leftmax -=1
        elif s[j]=='?':
            leftmax+=1
            if leftmin>0:
                leftmin-=1
            else:
                leftmin+=1

        if leftmax<0 or leftmin>leftmax:
            break

        if leftmin==0:
            combs+=1
print combs


s = input()
l = len(s)
ans = 0
for i in range(0, l):
    m = n = 0
    for j in range(i, l):
        m += s[j] == '('
        m -= s[j] == ')'
        n += s[j] == '?'
        if m + n < 0:
            break
        if m < n:
            m, n = n, m
        ans += m == n
print (ans)


s = input()
l = len(s)
ans = 0
for i in range(0, l):
    ln = n = 0
    for j in range(i, l):
        if s[j] == '(':
            ln += 1
        elif s[j] == ')':
            ln -= 1
        else:
            n += 1
            ln -= 1
        if ln == 0:
            ans += 1
        elif ln < 0:
            if n > 0:
                ln += 2
                n -= 1
            else:
                break
print (ans)


s = input()
a=0
n=len(s)
for i in range(n):
    l=0
    k=0
    for j in range(i, n):
        l+=s[j]=='('
        l-=s[j]==')'
        k+=s[j]=='?'
        if l+k<0:
            break
        if k>l:
            l,k = k,l
        if l==k:
            a+=1
print(a)


s = input()
res, n = 0, len(s)
for i in range(n-1):

    o, c, q = 0, 0, 0
    ind = i

    while ind < n:

        if s[ind] == "(":
            o += 1
        elif s[ind] == ")":
            c += 1
        else:
            q += 1

        if o+q < c:
            break
        if s[ind] != "(" and (o+q == c or o == c+q or (o+q-c) % 2 == 0 or (c+q-o) % 2 == 0):
            res += 1

        ind += 1
print(res)


s = input()
res, n = 0, len(s)
for i in range(n-1):

    cur, q, ind = 0, 0, i

    while ind < n:

        if s[ind] == "(":
            cur += 1
        elif s[ind] == ")":
            cur -= 1
        else:
            q += 1

        if cur+q < 0:
            break

        if q > cur:
            cur, q = q, cur

        res += (cur == q)
        ind += 1
print(res)


import sys, math, os.path

FILE_INPUT = "c.in"
DEBUG = os.path.isfile(FILE_INPUT)
if DEBUG:
    sys.stdin = open(FILE_INPUT)

def ni():
    return int(input())

def nvi():
    return map(int, input().split(" "))

def nia():
    return list(map(int,input().split()))

def log(x):
    if (DEBUG):
        print(x)

s = input()
ls = len(s)
count = 0

for i in range(0,ls):
    low = 0
    high = 0
    if s[i] != ')':
        # log(i)
        for j in range(i,ls):
            if s[j] == '(':
                low += 1
                high += 1
            elif s[j] == ')':
                low = max(0, low-1)
                high -= 1
            else:
                low = max(0, low-1)
                high += 1
            # log(str(i) + ": "+str(low) + "-"+str(high))
            if (low > high):
                break
            if (low <= 0 <= high) and ((j - i) % 2 == 1):
                # log("count " + str(i) + " - " + str(j))
                count += 1

print(count)


#!/user/bin/env python 3.5
# -*- coding: utf-8 -*-
s=input()
a=0
n=len(s)
for i in range(n):
	l=0
	k=0
	for j in range(i,n):
		l+=s[j]=='('
		l-=s[j]==')'
		k+=s[j]=='?'
		if l+k<0:
			break
		if k>l:
			l,k=k,l
		if l==k:
			a=a+1
print(a)


S = input()
n = len(S)
Ans = 0
for l in range(0, n):
    bs = 0
    det = 0
    for r in range(l, n):
        #print(S[r])
        if (S[r] == '?'):
            if (bs > 0):
                det = det + 1
                bs = bs - 1
            else:
                bs = bs + 1
        elif (S[r] == '('):
           bs = bs + 1
        else:
            if (bs == 0 and det > 0):
                bs = bs + 2
                det = det - 1
            bs = bs - 1
        if (bs < 0):
            break
        if (bs > 0):
            continue
        if (bs % 2 == 0):
            Ans = Ans + 1
            #print(bs, det, S[l:r])
print(Ans)


import sys
li  =   lambda : [int(x) for x in sys.stdin.readline().strip().split()]
rw  =   lambda : sys.stdin.readline().strip().split()
ni  =   lambda : int(sys.stdin.readline().strip())
nsi =   lambda : sys.stdin.readline().strip()

from collections import defaultdict as df
from math import *

s=nsi()
n=len(s)
ans=0

for i in range(n):
    l=0
    r=0
    for j in range(i,n):
        if(s[j]=='('):
            l+=1
            r+=1
        elif(s[j]==')'):
            l-=1
            r-=1
        else:
            l-=1
            r+=1
        if(l<0):
            l+=2
        if(r<0):
            break
        if(l==0):
            ans+=1
print(ans)


s = input()
n = len(s)
res = 0

for i in range(n):
	depth1, depth2 = 0, 0
	for c in s[i:]:
		if c == '(':
			depth1 += 1
			depth2 += 1
		elif c == ')':
			depth1 -= 1
			depth2 -= 1
		else:
			depth1 += 1
			depth2 -= 1
		if depth1 < 0:
			break
		depth2 = max(depth2, 0)
		if depth1&1 == 0 and depth2 == 0:
			res += 1

print(res)


n=int(input())
s=input().strip()
ques=ans=ini=0
for i in range(n):
    ques=ini=0
    for j in range(i,n):
        c=s[j]
        if(c=="?"):ques+=1
        elif(c=='('):ini+=1
        else:ini-=1
        if(ini<0):break
        if(ques>ini):
            ques-=1;ini+=1;
        if((j-i+1)%2==0) and ques>=ini):ans+=1
print(ans)


s=input().strip();n=len(s)
ques=ans=ini=0
for i in range(n):
    ques=ini=0
    for j in range(i,n):
        c=s[j]
        if(c=="?"):ques+=1
        elif(c=='('):ini+=1
        else:ini-=1  #present situation dekh li
        if(ini<0):break   #invalid cheez h bhaaya
        if(ques>ini):       #agr mujhe wo question mark opening se replace krna jo ki krna hi h
            ques-=1;ini+=1;  #ye kr denge hum fir
        if((j-i+1)%2==0 and ques==ini):ans+=1 #aur ques fir ini ke barabar hi hone chahiye kyu ki hum baa
print(ans)                                  #baar baar quest mark ko ini jo ki >o h se replace kr rhe h


n=int(input())
s=input().strip()
ques=ans=ini=0
for i in range(n):
    ques=ini=0
    for j in range(i,n):
        c=s[j]
        if(c=="?"):ques+=1
        elif(c=='('):ini+=1
        else:ini-=1
        if(ini<0):break
        if(ques>ini):
            ques-=1;ini+=1;
        if((j-i+1)%2==0 and ques>=ini):ans+=1
print(ans)


s=input().strip();n=len(s)
ques=ans=ini=0
for i in range(n):
    ques=ini=0
    for j in range(i,n):
        c=s[j]
        if(c=="?"):ques+=1
        elif(c=='('):ini+=1
        else:ini-=1
        if(ini<0):break
        if(ques>ini):
            ques-=1;ini+=1;
        if((j-i+1)%2==0 and ques==ini):ans+=1
print(ans)


s=input().strip()
n=len(s)
ques=ans=ini=0
for i in range(n):
    ques=ini=0
    for j in range(i,n):
        c=s[j]
        if(c=="?"):ques+=1
        elif(c=='('):ini+=1
        else:ini-=1
        if(ini<0):break
        if(ques>ini):
            ques-=1;ini+=1;
        if((j-i+1)%2==0 and ques>=ini):ans+=1
print(ans)


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class IOHelper : IDisposable
    {
        StreamReader reader;
        StreamWriter writer;

        public IOHelper(string inputFile, string outputFile, Encoding encoding)
        {
            StreamReader iReader;
            StreamWriter oWriter;
            if (inputFile == null)
                iReader = new StreamReader(Console.OpenStandardInput(), encoding);
            else
                iReader = new StreamReader(inputFile, encoding);

            if (outputFile == null)
                oWriter = new StreamWriter(Console.OpenStandardOutput(), encoding);
            else
                oWriter = new StreamWriter(outputFile, false, encoding);

            reader = iReader;
            writer = oWriter;

            curLine = new string[] { };
            curTokenIdx = 0;
        }

        string[] curLine;
        int curTokenIdx;

        char[] whiteSpaces = new char[] { ' ', '\t', '\r', '\n' };

        public string ReadNextToken()
        {
            if (curTokenIdx >= curLine.Length)
            {
                //Read next line
                string line = reader.ReadLine();
                if (line != null)
                    curLine = line.Split(whiteSpaces, StringSplitOptions.RemoveEmptyEntries);
                else
                    curLine = new string[] { };
                curTokenIdx = 0;
            }

            if (curTokenIdx >= curLine.Length)
                return null;

            return curLine[curTokenIdx++];
        }

        public int ReadNextInt()
        {
            return int.Parse(ReadNextToken());
        }

        public double ReadNextDouble()
        {
            var nextToken = ReadNextToken();
            var result = 0.0;
            nextToken = nextToken.Replace(".", System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator);
            result = double.Parse(nextToken);
            return result;
        }

        public void Write(string stringToWrite)
        {
            writer.Write(stringToWrite);
        }

        public void WriteLine(string stringToWrite)
        {
            writer.WriteLine(stringToWrite);
        }

        public void WriteLine(double valueToWrite)
        {
            long intPart = (long)valueToWrite;
            double fracPart = valueToWrite - intPart;
            var fracPartStr = fracPart.ToString();
            if (fracPartStr.Length > 1)
                fracPartStr = fracPartStr.Substring(2);
            var strToWrite = string.Format("{0}.{1}", intPart, fracPartStr);
            writer.WriteLine(strToWrite);
        }

        public void Dispose()
        {
            try
            {
                if (reader != null)
                {
                    reader.Dispose();
                }
                if (writer != null)
                {
                    writer.Dispose();
                }
            }
            catch { };
        }

        public void Flush()
        {
            if (writer != null)
            {
                writer.Flush();
            }
        }
    }

    class Program
    {
        protected IOHelper ioHelper;

        int n;
        string str;

        long res = 0;

        public void Solve()
        {
            str = ioHelper.ReadNextToken();
            n = str.Length;

            int i, j, k;

            for(i=0;i<n;i++)
            {
                if (str[i] == ')')
                    continue;

                j = i+1;

                int opened = 1;
                int numqC = 0;
                int numqO = 0;

                while(j<n)
                {
                    if (str[j] == '(')
                        opened++;
                    else if (str[j] == ')')
                        opened--;
                    else if(str[j]=='?')
                    {
                        if (opened > 0)
                        {
                            opened--;
                            numqC++;
                        }
                        else
                        {
                            if (numqC > 0)
                            { numqC--; opened += 2; opened--; numqC++; }
                            else
                            {
                                opened++;
                            }
                        }
                    }

                    if (opened == 0)
                        res++;

                    if(opened < 0)
                    {
                        if (numqC == 0)
                            break;

                        numqC--;
                        opened += 2;
                    }

                    j++;
                }
            }

            ioHelper.WriteLine(res.ToString());
            ioHelper.Flush();

            //Console.ReadKey();
        }

        public Program(string inputFile, string outputFile)
        {
            ioHelper = new IOHelper(inputFile, outputFile, Encoding.Default);
            Solve();
            ioHelper.Dispose();
        }

        static void Main(string[] args)
        {
            Program myProgram = new Program(null, null);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace C_TheMonster
{
    class Program
    {
        static void Main(string[] args)
        {
            var line = Console.ReadLine();

            int result = 0;
            for(int l = 0; l < line.Length; ++l)
            {
                int left = 0;
                int right = 0;
                int question = 0;

                for (int r = l; r < line.Length; ++r)
                {
                    if (line[r] == '(')
                    {
                        left++;
                    }
                    else if (line[r] == '?')
                    {
                        question++;
                    }
                    else
                    {
                        // Had (, now have matching )
                        if (left > 0)
                        {
                            left--;
                        }
                        else if (question > 0)
                        {
                            // Had ?, now have matching )
                            question--;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (left == 0 && right == 0 && question % 2 == 0)
                    {
                        result++;
                    } else if (right == 0 && question >= left && (question - left) % 2 == 0)
                    {
                        result++;
                    }
                }
            }

            Console.WriteLine(result);
        }
    }
}