#include <iostream>
#include <vector>
#include <set>
#include <cstdlib>

using namespace std;

const int INF = 1500000000;

int n, m;
vector<vector<pair<int, int> > > graph;
vector<int> dist;

struct cmp {
	bool operator()(int v1, int v2) {
		if(dist[v1] == dist[v2])
			return v1 < v2;
		return dist[v1] < dist[v2];
	}
};

multiset<int, cmp> heap;
vector<vector<int> > travels;

void verybad(int status) {
	cout << status << endl;
	exit(0);
}

int nextTime(int current, int planet) {
	int index;
	if(planet >= travels.size())
		verybad(42);
	for(index = 0; index < travels[planet].size() && travels[planet][index] < current; ++index);
	if(index == travels[planet].size() || travels[planet][index] != current)
		return current;
	for(;(index + 1) < travels[planet].size() && travels[planet][index + 1] == travels[planet][index] + 1; ++index);
	return travels[planet][index] + 1;
}

void trace(multiset<int, cmp>& tr) {
	cout << "Trace" << endl;
	multiset<int, cmp>::iterator it = tr.begin();
	while(it != tr.end()) {
		cout << *it << " ";
		++it;
	}
	cout << endl << "Endtrace" << endl;
}

void update(int planet, int newVal) {
	//cout << "upd " << planet << endl;
	//trace(heap);
	if(heap.find(planet) == heap.end())
		verybad(43);
	heap.erase(heap.find(planet));
	//trace(heap);
	if(planet >= dist.size())
		verybad(44);
	dist[planet] = newVal;
	heap.insert(planet);
	//trace(heap);
}

int nextPlanet() {
	int value = *heap.begin();
	heap.erase(heap.begin());
	return value;
}

void dijkstra() {
	dist.push_back(0);
	for(int i = 1; i < n; ++i)
		dist.push_back(INF);
	for(int i = 0; i < n; ++i)
		heap.insert(i);
	//trace(heap);
	while(!heap.empty()) {
		int next = nextPlanet();
		//cout << next << " is next" << endl;
		int nowDist = dist[next];

		for(int uind = 0; uind < graph[next].size(); ++uind) {
			int u = graph[next][uind].first;
			int newDist = nextTime(nowDist, next) + graph[next][uind].second;
			//cout << next << "->" << u << ":" << newDist << endl;
			if(dist[u] == INF || dist[u] > newDist) {
				//cout << "updating " << u << " from " << dist[u] << " to " << newDist << endl;
				update(u, newDist);
			}
		}
		if(next == n - 1)
			break;
	}
}

int main() {
	cin >> n >> m;
	graph.resize(n, vector<pair<int, int> >());
	travels.resize(n, vector<int>());
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		a--; b--;
		graph[b].push_back(make_pair(a, t));
		graph[a].push_back(make_pair(b, t));
	}
	for(int i = 0; i < n; ++i) {
		int count;
		cin >> count;
		for(int j = 0; j < count; ++j) {
			int x;
			cin >> x;
			travels[i].push_back(x);
		}
	}
	dijkstra();
	if(dist[n - 1] == INF)
		cout << -1 << endl;
	else
		cout << dist[n - 1] << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <climits>
#include <set>
#include <algorithm>

using namespace std;

const int INF = INT_MAX;
vector<vector<pair<int, int> > > g;
vector<int> dist;
vector<vector<int> > waits;

struct comp{
	bool operator()(int v1, int v2) {
		return dist[v1] < dist[v2];
	}
};

int weight(int u, int v) {
	for(int i = 0; i < g[u].size(); ++i) {
		if(v == g[u][i].first)
			return g[u][i].second;
	}
	return INF;
}

int find() {
	//cout << "fuck" << endl;
	dist.push_back(0);
	for(int v = 1; v < g.size(); ++v)
		dist.push_back(INF);
	multiset<int, comp> dij;
	for(int v = 0; v < g.size(); ++v)
		dij.insert(v);
	while(!dij.empty()) {
		int best = *dij.begin();
		dij.erase(dij.begin());
		for(int index = 0; index < g[best].size(); ++index) {
			int u = g[best][index].first;
			int ti;
			for(ti = 0; ti < waits[best].size() && waits[best][ti] < dist[best]; ++ti);
			for(; ti + 1< waits[best].size() && waits[best][ti] + 1 == waits[best][ti + 1]; ++ti);
			int newdist;
			if(ti < waits[best].size())
				newdist = min(dist[u], dist[best] + weight(best, u) + waits[best][ti] +1 - dist[best]);
			else
				newdist = min(dist[u], dist[best] + weight(best, u)/* + waits[best][index] - dist[best]*/);
			if(newdist != dist[u]) {
				dij.erase(dij.find(u));
				dist[u] = newdist;
				dij.insert(u);
			}
		}
	}
	return dist[dist.size() - 1];
}

int main()
{
	int n, m;
	cin >> n >> m;
	g.resize(n, vector<pair<int, int> >());
	waits.resize(n);
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		--a;
		--b;
		g[a].push_back(make_pair(b, t));
		g[b].push_back(make_pair(a, t));
	}
	for(int i = 0; i < n; ++i) {
		int num;
		cin >> num;
		for(int j = 0; j < num; ++j) {
			waits[i].push_back(num);
		}
	}
	int result = find();
	if(result == INF)
		cout << -1 << endl;
	else
		cout << result << endl;
}


#include <iostream>
#include <vector>
#include <set>
#include <cstdlib>

using namespace std;

const int INF = 1500000000;

int n, m;
vector<vector<pair<int, int> > > graph;
vector<int> dist;

struct cmp {
	bool operator()(int v1, int v2) {
		if(dist[v1] == dist[v2])
			return v1 < v2;
		return dist[v1] < dist[v2];
	}
};

set<int, cmp> heap;
typedef set<int, cmp>::iterator iter;
vector<vector<int> > travels;

void verybad(int status) {
	cout << status << endl;
	exit(0);
}

int nextTime(int current, int planet) {
	int index;
	if(planet >= travels.size())
		verybad(42);
	for(index = 0; index < travels[planet].size() && travels[planet][index] < current; ++index);
	if(index == travels[planet].size() || travels[planet][index] != current)
		return current;
	for(;(index + 1) < travels[planet].size() && travels[planet][index + 1] == travels[planet][index] + 1; ++index);
	return travels[planet][index] + 1;
}

void trace(set<int, cmp>& tr) {
	cout << "Trace" << endl;
	set<int, cmp>::iterator it = tr.begin();
	while(it != tr.end()) {
		cout << *it << " ";
		++it;
	}
	cout << endl << "Endtrace" << endl;
}

void update(int planet, int newVal) {
	//cout << "upd " << planet << endl;
	//trace(heap);
	pair<iter, iter> range = heap.equal_range(planet);
	if(heap.find(planet) == heap.end())
		verybad(43);
	heap.erase(heap.find(planet));
	//trace(heap);
	if(planet >= dist.size())
		verybad(44);
	dist[planet] = newVal;
	heap.insert(planet);
	//trace(heap);
}

int nextPlanet() {
	int value = *heap.begin();
	heap.erase(heap.begin());
	return value;
}

void dijkstra() {
	dist.push_back(0);
	for(int i = 1; i < n; ++i)
		dist.push_back(INF);
	for(int i = 0; i < n; ++i)
		heap.insert(i);
	//trace(heap);
	while(!heap.empty()) {
		int next = nextPlanet();
		//cout << next << " is next" << endl;
		int nowDist = dist[next];

		for(int uind = 0; uind < graph[next].size(); ++uind) {
			int u = graph[next][uind].first;
			int newDist = nextTime(nowDist, next) + graph[next][uind].second;
			//cout << next << "->" << u << ":" << newDist << endl;
			if(dist[u] == INF || dist[u] > newDist) {
				//cout << "updating " << u << " from " << dist[u] << " to " << newDist << endl;
				update(u, newDist);
			}
		}
		if(next == n - 1)
			break;
	}
}

int main() {
	cin >> n >> m;
	graph.resize(n, vector<pair<int, int> >());
	travels.resize(n, vector<int>());
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		a--; b--;
		graph[b].push_back(make_pair(a, t));
		graph[a].push_back(make_pair(b, t));
	}
	for(int i = 0; i < n; ++i) {
		int count;
		cin >> count;
		for(int j = 0; j < count; ++j) {
			int x;
			cin >> x;
			travels[i].push_back(x);
		}
	}
	dijkstra();
	if(dist[n - 1] == INF)
		cout << -1 << endl;
	else
		cout << dist[n - 1] << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <climits>
#include <set>
#include <algorithm>
#include <cassert>

using namespace std;

const int INF = INT_MAX;
vector<vector<pair<int, int> > > g;
vector<int> dist;
vector<vector<int> > waits;

struct comp{
	bool operator()(int v1, int v2) {
		return dist[v1] < dist[v2];
	}
};

int weight(int u, int v) {
	for(int i = 0; i < g[u].size(); ++i) {
		if(v == g[u][i].first)
			return g[u][i].second;
	}
	return INF;
}

int find() {
	//cout << "fuck" << endl;
	dist.push_back(0);
	for(int v = 1; v < g.size(); ++v)
		dist.push_back(INF);
	multiset<int, comp> dij;
	for(int v = 0; v < g.size(); ++v)
		dij.insert(v);
	while(!dij.empty()) {
		int best = *dij.begin();
		dij.erase(dij.begin());
		for(int index = 0; index < g[best].size(); ++index) {
			int u = g[best][index].first;
			int newdist; int w;

			if(waits[best].empty())
				w = 0;
			else
			{

			//waits[v][i]
			//dist[best]
			int i = 0;
			while ((waits[best].size() > i) && (waits[best][i] < dist[best]))  {
				i++;
			}
			if(waits[best].size() == i || ((waits[best].size() > i) && (waits[best][i] != dist[best]))) {
				w = 0;
			}
			else {
				while ((waits[best].size() > i + 1) && (waits[best][i + 1] == waits[best][i] + 1)) {
					i++;
				}
					w = waits[best][i] + 1 - dist[best];

			}
		}
			//cout << w << endl;

			newdist = min(dist[u], dist[best] + weight(best, u) + w);
			if(newdist != dist[u]) {
				dij.erase(dij.find(u));
				dist[u] = newdist;
				dij.insert(u);
			}
		}
	}
	return dist[dist.size() - 1];
}

int main()
{
	int n, m;
	cin >> n >> m;
	g.resize(n, vector<pair<int, int> >());
	waits.resize(n);
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		--a;
		--b;
		g[a].push_back(make_pair(b, t));
		g[b].push_back(make_pair(a, t));
	}
	for(int i = 0; i < n; ++i) {
		int num;
		cin >> num;
		for(int j = 0; j < num; ++j) {
			waits[i].push_back(num);
		}
	}
	int result = find();
	if(result == INF)
		cout << -1 << endl;
	else
		cout << result << endl;
}


#include <iostream>
#include <vector>
#include <climits>
#include <set>
#include <algorithm>

using namespace std;

const int INF = INT_MAX;
vector<vector<pair<int, int> > > g;
vector<int> dist;
vector<vector<int> > waits;

struct comp{
	bool operator()(int v1, int v2) {
		return dist[v1] < dist[v2];
	}
};

int weight(int u, int v) {
	for(int i = 0; i < g[u].size(); ++i) {
		if(v == g[u][i].first)
			return g[u][i].second;
	}
	return INF;
}

int find() {
	//cout << "fuck" << endl;
	dist.push_back(0);
	for(int v = 1; v < g.size(); ++v)
		dist.push_back(INF);
	multiset<int, comp> dij;
	for(int v = 0; v < g.size(); ++v)
		dij.insert(v);
	while(!dij.empty()) {
		int best = *dij.begin();
		dij.erase(dij.begin());
		for(int index = 0; index < g[best].size(); ++index) {
			int u = g[best][index].first;
			int ti;
			for(ti = 0; ti < waits[best].size() && waits[best][ti] < dist[best]; ++ti);
			int newdist;
			if(ti < waits[best].size() && waits[best][index] >= dist[best])
				newdist = min(dist[u], dist[best] + weight(best, u) + waits[best][index] - dist[best] + 1);
			else
				newdist = min(dist[u], dist[best] + weight(best, u)/* + waits[best][index] - dist[best]*/);
			if(newdist != dist[u]) {
				dij.erase(dij.find(u));
				dist[u] = newdist;
				dij.insert(u);
			}
		}
	}
	return dist[dist.size() - 1];
}

int main()
{
	int n, m;
	cin >> n >> m;
	g.resize(n, vector<pair<int, int> >());
	waits.resize(n);
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		--a;
		--b;
		g[a].push_back(make_pair(b, t));
		g[b].push_back(make_pair(a, t));
	}
	for(int i = 0; i < n; ++i) {
		int num;
		cin >> num;
		for(int j = 0; j < num; ++j) {
			waits[i].push_back(num);
		}
	}
	int result = find();
	if(result == INF)
		cout << -1 << endl;
	else
		cout << result << endl;
}


#include <iostream>
#include <vector>
#include <set>
#include <cstdlib>

using namespace std;

const int INF = 1500000000;

int n, m;
vector<vector<pair<int, int> > > graph;
vector<int> dist;

struct cmp {
	bool operator()(int v1, int v2) {
		return dist[v1] < dist[v2];
	}
};

multiset<int, cmp> heap;
vector<vector<int> > travels;

void verybad(int status) {
	cout << status << endl;
	exit(0);
}

int nextTime(int current, int planet) {
	int index;
	if(planet >= travels.size())
		verybad(42);
	for(index = 0; index < travels[planet].size() && travels[planet][index] < current; ++index);
	if(index == travels[planet].size() || travels[planet][index] != current)
		return current;
	for(;(index + 1) < travels[planet].size() && travels[planet][index + 1] == travels[planet][index] + 1; ++index);
	return travels[planet][index] + 1;
}

void update(int planet, int newVal) {
	//cout << "upd " << planet << endl;
	if(heap.find(planet) == heap.end())
		return;
	heap.erase(heap.find(planet));
	if(planet >= dist.size())
		verybad(44);
	dist[planet] = newVal;
	heap.insert(planet);
}

int nextPlanet() {
	int value = *heap.begin();
	heap.erase(heap.begin());
	return value;
}

void dijkstra() {
	dist.push_back(0);
	for(int i = 1; i < n; ++i)
		dist.push_back(INF);
	for(int i = 0; i < n; ++i)
		heap.insert(i);
	while(!heap.empty()) {
		int next = nextPlanet();
		//cout << next << "!" << endl;
		int nowDist = dist[next];
		for(int uind = 0; uind < graph[next].size(); ++uind) {
			int u = graph[next][uind].first;
			int newDist = nextTime(nowDist, next) + graph[next][uind].second;
			//cout << next << "->" << u << ":" << newDist << endl;
			if(dist[u] == INF || dist[u] > newDist) {
				update(u, newDist);
			}
		}
	}
}

int main() {
	cin >> n >> m;
	graph.resize(n, vector<pair<int, int> >());
	travels.resize(n, vector<int>());
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		a--; b--;
		graph[b].push_back(make_pair(a, t));
		graph[a].push_back(make_pair(b, t));
	}
	for(int i = 0; i < n; ++i) {
		int count;
		cin >> count;
		for(int j = 0; j < count; ++j) {
			int x;
			cin >> x;
			travels[i].push_back(x);
		}
	}
	dijkstra();
	if(dist[n - 1] == INF)
		cout << -1 << endl;
	else
		cout << dist[n - 1] << endl;
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
const int NR=2010;
int n;
int a[NR][NR];
struct arr
{
	int from,to,val;
}edge[NR*NR];
int f[NR],gsz;
bool cmp(arr x,arr y)
{
	return x.val<y.val;
}
int find(int x)
{
	if(f[x]==x) return x;
	return f[x]=find(f[x]);
}
int main()
{
	scanf("%d",&n);
	for(int i=0;i<=n;i++)
	{
		f[i]=i;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j<=n;j++)
		{
			scanf("%d",&a[i][j]);
			edge[++gsz].from=i-1;
			edge[gsz].to=j;
			edge[gsz].val=a[i][j];
		}
	}
	sort(edge+1,edge+1+gsz,cmp);
	long long ans=0;
	int cnt=0;
	for(int i=1;i<=gsz;i++)
	{
		if(cnt==n) break;
		int x=find(edge[i].from);
		int y=find(edge[i].to);
		if(x!=y)
		{
			f[x]=y;
			ans+=edge[i].val;
			cnt++;
		}
	}
	printf("%lld",ans);
	return 0;
}


#include <iostream>
#include <cstring>
#include <stack>
using namespace std;
const int mod = 1000000007;
const int R = 1;
const int B = 2;

int n;
char Bra[710];
int match[710];
int dp[710][710][5][5];
stack<int> st;

void getMatch() {
    for (int i = 0; i < n; i++) {
        if (Bra[i] == '(') st.push(i);
        else {
            int s = st.top();
            match[s] = i;
            st.pop();
        }
    }
}

int dfs(int i, int j, int l, int r) {
    int res = 0;
    if (i >= j) return 1;
    if (dp[i][j][l][r] != -1) return dp[i][j][l][r];
    if (match[i] == j) {
        if (l != R ) res += dfs(i+1, j-1, R, 0) % mod;
        if (r != R ) res += dfs(i+1, j-1, 0, R) % mod;
        if (l != B ) res += dfs(i+1, j-1, B, 0) % mod;
        if (r != B ) res += dfs(i+1, j-1, 0, B) % mod;
    }
    else {
        int m = match[i];
        if (l != R) res += (dfs(i+1, m-1, R, 0) * dfs(m+1, j, 0, r)) % mod;
        if (l != B) res += (dfs(i+1, m-1, B, 0) * dfs(m+1, j, 0, r)) % mod;
        res += (dfs(i+1, m-1, 0, R) * dfs(m+1, j, R, r)) % mod;
        res += (dfs(i+1, m-1, 0, B) * dfs(m+1, j, B, r)) % mod;
    }
    dp[i][j][l][r] = res % mod;
    return res;
}

void solve() {
    getMatch();
    memset(dp, -1, sizeof(dp));
    int res = dfs(0, n-1, 3, 3);
    cout << res % mod << endl;
}

int main() {
    cin >> Bra;
    n = strlen(Bra);
    solve();
    return 0;
}


#include<bits/stdc++.h>
#define int long long
#define rev(a) (a==1?2:1)
#define int long long
#define rep2(i) for(int i=0;i<=2;i++)

using namespace std;
const int N=709,mod=1000000007;

int n,match[N],f[N][N][3][3];
int dfs(int l,int r,int cl,int cr){//(l,r)一定是合法括号序列
	if(f[l][r][cl][cr] != -1) return f[l][r][cl][cr];
	if(l == r - 1){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;
		return f[l][r][cl][cr] = 1;
	}
	f[l][r][cl][cr] = 0;
	if(match[l] == r){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;

		if(cl == 0){
			f[l][r][cl][cr] =
			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,rev(cr)) +
			dfs(l + 1,r - 1,1,rev(cr)) +
			dfs(l + 1,r - 1,2,rev(cr));

			f[l][r][cl][cr] %= mod;
			return f[l][r][cl][cr];
		}

		if(cr == 0){
			f[l][r][cl][cr] =
			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,rev(cl),0) +
			dfs(l + 1,r - 1,rev(cl),1) +
			dfs(l + 1,r - 1,rev(cl),2);

			f[l][r][cl][cr] %= mod;
			return f[l][r][cl][cr];
		}
	}
	for(int ck = 0 ; ck <= 2 ; ck ++){
//		if((!cl && !ck) || (cl && ck)) continue;
		for(int kk = 0 ; kk <= 2 ; kk ++){
			if(kk == ck && kk != 0 && ck != 0) continue;
//			if((!cr && !kk) || (cr && kk)) continue;
			f[l][r][cl][cr] += dfs(l,match[l],cl,ck) * dfs(match[l] + 1,r,kk,cr) % mod;
			f[l][r][cl][cr] %= mod;
		}
	}
	return f[l][r][cl][cr];
}
//char s[N];
signed main() {
	memset(f,-1,sizeof(f));
//	scanf("%s",s+1); int n=strlen(s+1);
	stack<int>st;
	string s; cin>>s; int ln = s.length();
	for(int i = 0 ; i < ln ; i ++){
		int k = i + 1;
		if(s[i] == '(') st.push(k);
		else{
			match[st.top()] = k; st.pop();
		}
	}
	int ans=0;
	rep2(i) rep2(j) (ans+=dfs(1,n,i,j))%=mod;
	printf("%lld",ans);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#define int long long
using namespace std;
const int maxn=700+10;
const int mod=1e9+7;
stack<int> q;
int dp[maxn][maxn][3][3],match[maxn],ans=0;
char s[maxn];
void Pre(){
    q.push(1);int cnt=2;
    while(!q.empty()){
        if(s[cnt]=='(')q.push(cnt);
        else {
            match[cnt]=q.top();
            match[q.top()]=cnt;
            q.pop();
        }cnt++;
    }
}
void Dfs(int l,int r){
    if(l+1==r){
        dp[l][r][0][1]=dp[l][r][1][0]=dp[l][r][0][2]=dp[l][r][2][0]=1;
        return;
    }
    if(match[l]==r){
        Dfs(l+1,r-1);
        for(int i=0;i<=2;i++){
            for(int j=0;j<=2;j++){
                if(j!=1)dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;
                if(i!=1)dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
                if(j!=2)dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;
                if(i!=2)dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
            }
        }
    }else {
        Dfs(l,match[l]);Dfs(match[l]+1,r);
        for(int i=0;i<=2;i++){
            for(int j=0;j<=2;j++){
                for(int k=0;k<=2;k++){
                    for(int m=0;m<=2;m++){
                        if(!(j&&j==k))
                        dp[l][r][i][m]=(dp[l][r][i][m]+dp[l][match[l]][i][j]*dp[match[l]+1][r][k][m]%mod)%mod;
                    }
                }
            }
        }
    }
}
signed main(){
    scanf("%s",s+1);
    int len=strlen(s+1);
    Pre();
    Dfs(1,len);
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            ans=(ans+dp[1][len][i][j])%mod;
        }
    }printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define int long long
#define rev(a) (cr==1?2:1)
#define int long long
#define rep2(i) for(int i=0;i<=2;i++)

using namespace std;
const int N=709,mod=1000000007;

int n,match[N],f[N][N][3][3];
int dfs(int l,int r,int cl,int cr) {
	if(f[l][r][cl][cr] != -1) return f[l][r][cl][cr];
	if(l == r - 1){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;
		return f[l][r][cl][cr] = 1;
	}

	f[l][r][cl][cr] = 0;
	if(match[l] == r){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;

		if(cl == 0){
			f[l][r][cl][cr] =
			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,rev(cr)) +
			dfs(l + 1,r - 1,1,rev(cr)) +
			dfs(l + 1,r - 1,2,rev(cr));

			f[l][r][cl][cr] %= mod;
			return f[l][r][cl][cr];
		}

		if(cr == 0){
			f[l][r][cl][cr] =
			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,rev(cl),0) +
			dfs(l + 1,r - 1,rev(cl),1) +
			dfs(l + 1,r - 1,rev(cl),2);

			f[l][r][cl][cr] %= mod;
			return f[l][r][cl][cr];
		}
	}
	else {
		rep2(i) rep2(j) f[l][r][i][j]=0;
		rep2(i) rep2(j) rep2(k) rep2(p)
			if(j&&k&&(j==k)) continue;
			else (f[l][r][i][p]+=dfs(l,match[l],i,j)*dfs(match[l]+1,r,k,p))%=mod;
		return f[l][r][cl][cr];
	}

//	for(int ck = 0 ; ck <= 2 ; ck ++){
//		if((!cl && !ck) || (cl && ck)) continue;
//		for(int kk = 0 ; kk <= 2 ; kk ++){
//			if(kk == ck && kk != 0 &&ck != 0) continue;
//			if((!cr && !kk) || (cr && kk)) continue;
//			f[l][r][cl][cr] = dfs(l,match[l],cl,ck) * dfs(match[l] + 1,r,kk,cr) % mod;
//		}
//	}
//	return f[l][r][cl][cr];
}

char s[N];
signed main() {
	memset(f,-1,sizeof(f));
	scanf("%s",s+1); int n=strlen(s+1);
	stack<int>st;
	for(int i=1;i<=n;i++) {
		if(s[i]=='(') st.push(i);
		else match[st.top()]=i,st.pop();
	}
	int ans=0;
	rep2(i) rep2(j) (ans+=dfs(1,n,i,j))%=mod;
	printf("%lld",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rev(k) (k == 1) ? 2 : 1
#define int long long
const int N = 1e3 + 9;
const int p = 1000000007;
int f[N][N][3][3],mat[N];

int dfs(int l,int r,int cl,int cr){//(l,r)一定是合法括号序列
	if(f[l][r][cl][cr] != -1) return f[l][r][cl][cr];
	if(l == r - 1){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;
		return f[l][r][cl][cr] = 1;
	}
	f[l][r][cl][cr] = 0;
	if(mat[l] == r){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;

		if(cl == 0){
			f[l][r][cl][cr] =
			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,rev(cr)) +
			dfs(l + 1,r - 1,1,rev(cr)) +
			dfs(l + 1,r - 1,2,rev(cr));

			f[l][r][cl][cr] %= p;
			return f[l][r][cl][cr];
		}

		if(cr == 0){
			f[l][r][cl][cr] =
			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,rev(cl),0) +
			dfs(l + 1,r - 1,rev(cl),1) +
			dfs(l + 1,r - 1,rev(cl),2);

			f[l][r][cl][cr] %= p;
			return f[l][r][cl][cr];
		}
	}
	for(int ck = 0 ; ck <= 2 ; ck ++){
		if((!cl && !ck) || (cl && ck)) continue;
		for(int kk = 0 ; kk <= 2 ; kk ++){
			if(kk == ck && kk != 0 && ck != 0) continue;
//			if((!cr && !kk) || (cr && kk)) continue;
			f[l][r][cl][cr] += dfs(l,mat[l],cl,ck) * dfs(mat[l] + 1,r,kk,cr) % p;
			f[l][r][cl][cr] %= p;
		}
	}
	return f[l][r][cl][cr];
}
signed main(){
	memset(f,-1,sizeof(f));
	stack<int> st; int ans = 0;
	string s; cin>>s; int ln = s.length();
	for(int i = 0 ; i < ln ; i ++){
		int k = i + 1;
		if(s[i] == '(') st.push(k);
		else{
			mat[st.top()] = k; st.pop();
		}
	}
	for(int i = 0 ; i <= 2 ; i ++){
		for(int j = 0 ; j <= 2 ; j ++){
			ans += dfs(1,ln,i,j) % p; ans %= p;
		}
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std ;
const int Mod = 1000000007 ;
struct Dp {
	long long A[3][3] ;
	inline int Val() {
		long long Ans = 0 ;
		for(register int i = 0 ; i < 3 ; ++i )
			for(register int j = 0 ; j < 3 ; ++j )
				Ans += A[i][j] ;
		return Ans % Mod ;
	}
	Dp() {
		memset( A , 0 , sizeof A ) ;
	}
} ;
inline Dp Merge( Dp A , Dp B ) { // Á½¸öÍ¬¼¶×´Ì¬ºÏ²¢
	Dp Ans ;
	for(register int i = 0 ; i < 3 ; ++i )
		for(register int j = 0 ; j < 3 ; ++j )
			for(register int k = 0 ; k < 3 ; ++k )
				for(register int l = 0 ; l < 3 ; ++l )
					if( l == 0 or l != k )
						( Ans.A[i][j] += A.A[i][k] * B.A[l][j] ) %= Mod ;
	return Ans ;
}
inline Dp Contain( Dp A ) { // Í¬¼¶×´Ì¬ºÏ²¢ºó£¬ÓëÉÏ¼¶ºÏ²¢
	Dp Ans ;
	for(register int i = 0 ; i < 3 ; ++i )
		for(register int j = 0 ; j < 3 ; ++j )
			if( ( i == 0 ) != ( j == 0 ) )
			for(register int k = 0 ; k < 3 ; ++k )
				for(register int l = 0 ; l < 3 ; ++l )
					if( ( i == 0 or i != k ) and ( j == 0 or j != l ) )
						( Ans.A[i][j] += A.A[k][l] ) %= Mod ;
	return Ans ;
}
char S[777] ;
int N ;
int I = 1 ;
Dp Dfs() {
	Dp Ans ;
	if( S[++I] == ')' ) Ans.A[0][0] = 1 ;
	else {
		Ans = Dfs() ;
		while( S[++I] == '(' ) Ans = Merge( Ans , Dfs() ) ;
	}
	return Contain( Ans ) ;
}
int main() {
	scanf( "%s" , S + 1 ) ;
	N = strlen( S + 1 ) ;
	Dp Ans = Dfs() ;
	while( ++I <= N ) Ans = Merge( Ans , Dfs() ) ;
	return not printf( "%d\n" , Ans.Val() ) ;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#define int long long
using namespace std;
const int maxn=700+1;
const int mod=1e9+7;
stack<int> q;
int dp[maxn][maxn][3][3],match[maxn],ans=0;
char s[maxn];
void Pre(){
    q.push(1);int cnt=2;
    while(!q.empty()){
        if(s[cnt]=='(')q.push(cnt);
        else {
            match[cnt]=q.top();
            match[q.top()]=cnt;
            q.pop();
        }cnt++;
    }
}
void Dfs(int l,int r){
    if(l+1==r){
        dp[l][r][0][1]=dp[l][r][1][0]=dp[l][r][0][2]=dp[l][r][2][0]=1;
        return;
    }
    if(match[l]==r){
        Dfs(l+1,r-1);
        for(int i=0;i<=2;i++){
            for(int j=0;j<=2;j++){
                if(j!=1)dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;
                if(i!=1)dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
                if(j!=2)dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;
                if(i!=2)dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
            }
        }
    }else {
        Dfs(l,match[l]);Dfs(match[l]+1,r);
     /*   for(int i=0;i<=2;i++){
            for(int j=0;j<=2;j++){
                for(int k=0;k<=2;k++){
                    for(int m=0;m<=2;m++){
                        if(!(j&&j==k))
                            dp[l][r][i][m]=(dp[l][r][i][m]+dp[l][match[l]][i][j]*dp[match[l]+1][r][k][m]%mod)%mod;
                    }
                }
            }
        }*/
    }
}
signed main(){
    scanf("%s",s+1);
    int len=strlen(s+1);
    Pre();
    Dfs(1,len);
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            ans=(ans+dp[1][len][i][j])%mod;
        }
    }printf("%lld\n",ans);
    return 0;
}


#include<iostream>
#include<cstring>
#include<stack>
const int maxn=710;
const int mod=1e9+7;
using namespace std;
int other[maxn];
stack<int>st;
int n,dp[maxn][maxn][3][3];
long long cheng(long long a,long long b)
{
    long long s=0;
    while (b)
    {
        if (b&1) s=(s+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return s;
}

void dfs(int l,int r)
{
    if(l+1==r)
    {
        dp[l][r][1][0]=dp[l][r][2][0]=dp[l][r][0][1]=dp[l][r][0][2]=1;
        return;
    }
    if(other[l]==r)
    {
        dfs(l+1,r-1);
        for(int i=0;i<=2;i++)for(int j=0;j<=2;j++){
        if(j!=1) dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;
        if(j!=2) dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;
        if(i!=1) dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
        if(i!=2) dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
        }
        return;
    }
    dfs(l,other[l]);
    dfs(other[l]+1,r);
    for(int i=0;i<=2;i++)
    {
        for(int j=0;j<=2;j++)
        {
            for(int k=0;k<=2;k++)
            {
                for(int h=0;h<=2;h++)
                {
                    if(j==1 && k==1) continue;
                    if(j==2 && k==2) continue;
                    dp[l][r][i][h]+=cheng(dp[l][other[l]][i][j],dp[other[l]+1][r][k][h])%mod;
                    dp[l][r][i][h]%=mod;
                }
            }
        }
    }
}
signed main()
{
    string s;
    cin>>s;
    n=s.size();
    for(int i=0;i<n;i++)
    {
        if(s[i]=='(') st.push(i+1);
        else
        {
            other[st.top()]=i+1;
            st.pop();
        }
    }
    dfs(1,n);
    int ans=0;
    for(int i=0;i<=2;i++)
    {
        for(int j=0;j<=2;j++)
        {
            ans+=dp[1][n][i][j];
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rev(k) (k == 1) ? 2 : 1
#define int long long
const int N = 1e3 + 9;
const int p = 1000000007;
int f[N][N][3][3],mat[N];

int dfs(int l,int r,int cl,int cr){//(l,r)一定是合法括号序列
	if(f[l][r][cl][cr] != -1) return f[l][r][cl][cr];
	if(l == r - 1){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;
		return f[l][r][cl][cr] = 1;
	}
	f[l][r][cl][cr] = 0;
	if(mat[l] == r){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;

		if(cl == 0){
			f[l][r][cl][cr] =
			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,rev(cr)) +
			dfs(l + 1,r - 1,1,rev(cr)) +
			dfs(l + 1,r - 1,2,rev(cr));

			f[l][r][cl][cr] %= p;
			return f[l][r][cl][cr];
		}

		if(cr == 0){
			f[l][r][cl][cr] =
			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,rev(cl),0) +
			dfs(l + 1,r - 1,rev(cl),1) +
			dfs(l + 1,r - 1,rev(cl),2);

			f[l][r][cl][cr] %= p;
			return f[l][r][cl][cr];
		}
	}
	for(int ck = 0 ; ck <= 2 ; ck ++){
//		if((!cl && !ck) || (cl && ck)) continue;
		for(int kk = 0 ; kk <= 2 ; kk ++){
			if(kk == ck && kk != 0 && ck != 0) continue;
//			if((!cr && !kk) || (cr && kk)) continue;
			f[l][r][cl][cr] += dfs(l,mat[l],cl,ck) * dfs(mat[l] + 1,r,kk,cr) % p;
			f[l][r][cl][cr] %= p;
		}
	}
	return f[l][r][cl][cr];
}
signed main(){
	memset(f,-1,sizeof(f));
	stack<int> st; int ans = 0;
	string s; cin>>s; int ln = s.length();
	for(int i = 0 ; i < ln ; i ++){
		int k = i + 1;
		if(s[i] == '(') st.push(k);
		else{
			mat[st.top()] = k; st.pop();
		}
	}
	for(int i = 0 ; i <= 2 ; i ++){
		for(int j = 0 ; j <= 2 ; j ++){
			ans += dfs(1,ln,i,j) % p; ans %= p;
		}
	}
	cout<<ans;
	return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<bitset>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
const int N = 720 , mod = 1e9+7;
inline int read()
{
    register int x = 0 , f = 0; register char c = getchar();
    while(c < '0' || c > '9') f |= c == '-' , c = getchar();
    while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
    return f ? -x : x;
}
int n;
char s[N];
int dp[N][N][3][3];
inline int add(int a , int b) { a += b; return a >= mod ? a - mod : a; }
inline int mul(int a , int b) { return (LL)a * b % mod; }
void solve(int l , int r)
{
	if(l + 1 == r)
	{
		for(int i = 1 ; i <= 2 ; ++i) dp[l][r][i][0] = dp[l][r][0][i] = 1;
		return ;
	}
	int res = 0;
	for(int pos = l ; pos <  r ; ++pos)
	{
		res += s[pos] == '(' ? 1 : -1;
		if(res == 0)
		{
			solve(l , pos); solve(pos+1 , r);
			for(int i = 0 ; i <= 2 ; ++i)
				for(int j = 0 ; j <= 2 ; ++j)
					for(int k = 0 ; k <= 2 ; ++k)
						for(int s = 0 ; s <= 2 ; ++s)
							if(!((k == 1 && s == 1) || (k == 2 && s == 2)))
								dp[l][r][i][j] = add(dp[l][r][i][j] , mul(dp[l][pos][i][k] , dp[pos+1][r][s][j]));
			return ;
		}
	}
	solve(l + 1 , r - 1);
	for(int i = 1 ; i <= 2 ; ++i)
	{
		int &res1 = dp[l][r][i][0];
		for(int j = 0 ; j <= 2 ; ++j) if(j != i) res1 = add(res1 , dp[l+1][r-1][j][0]);
		for(int j = 0 ; j <= 2 ; ++j) res1 = add(res1 , dp[l+1][r-1][0][j]);
		int &res2 = dp[l][r][0][i];
		for(int j = 0 ; j <= 2 ; ++j) if(j != i) res2 = add(res2 , dp[l+1][r-1][0][j]);
		for(int j = 0 ; j <= 2 ; ++j) res2 = add(res2 , dp[l+1][r-1][j][0]);
	}
	return ;
}

int main()
{
	scanf("%s" , s+1); n = strlen(s+1);
	solve(1 , n);
	int ans = 0;
	for(int i = 1 ; i <= 2 ; ++i) ans = add(ans , add(dp[1][n][i][0] , dp[1][n][0][i]));
	cout << ans << '\n';
	return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<bitset>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
const int N = 720 , mod = 1e9+7;
inline int read()
{
    register int x = 0 , f = 0; register char c = getchar();
    while(c < '0' || c > '9') f |= c == '-' , c = getchar();
    while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
    return f ? -x : x;
}
int n;
char s[N];
int dp[N][N][3][3];
inline int add(int a , int b) { a += b; return a >= mod ? a - mod : a; }
inline int mul(int a , int b) { return (LL)a * b % mod; }
void solve(int l , int r)
{
	if(l + 1 == r)
	{
		for(int i = 1 ; i <= 2 ; ++i) dp[l][r][i][0] = dp[l][r][0][i] = 1;
		return ;
	}
	int res = 0;
	for(int pos = l ; pos <  r ; ++pos)
	{
		res += s[pos] == '(' ? 1 : -1;
		if(res == 0)
		{
			solve(l , pos); solve(pos+1 , r);
//			for(int i = 1 ; i <= 2 ; ++i)
//			{
//				dp[l][r][i][0] = mul(dp[l][pos][i][0] , add(dp[pos+1][r][i][0] , dp[pos+1][r][3-i][0]));
//				dp[l][r][0][i] = mul(dp[pos+1][r][0][i] , add(dp[l][pos][0][i] , dp[l][pos][0][3-i]));
//			}
			for(int i = 0 ; i <= 2 ; ++i)
				for(int j = 0 ; j <= 2 ; ++j)
					for(int k = 0 ; k <= 2 ; ++k)
						for(int s = 0 ; s <= 2 ; ++s)
							if(!((k == 1 && s == 1) || (k == 2 && s == 2)))
								dp[l][r][i][j] = add(dp[l][r][i][j] , mul(dp[l][pos][i][k] , dp[pos+1][r][s][j]));
			return ;
		}
	}
	solve(l + 1 , r - 1);
//	for(int i = 1 ; i <= 2 ; ++i) // (())
//	{
//		int &res1 = dp[l][r][i][0];
//		for(int j = 0 ; j <= 2 ; ++j) if(j != i) res1 = add(res1 , dp[l+1][r-1][j][0]);
//		for(int j = 0 ; j <= 2 ; ++j) res1 = add(res1 , dp[l+1][r-1][0][j]);
//		int &res2 = dp[l][r][0][i];
//		for(int j = 0 ; j <= 2 ; ++j) if(j != i) res2 = add(res2 , dp[l+1][r-1][0][j]);
//		for(int j = 0 ; j <= 2 ; ++j) res2 = add(res2 , dp[l+1][r-1][j][0]);
//	}
	for(int i = 1 ; i <= 2 ; ++i) // (()())
	{
		int &res1 = dp[l][r][i][0];
		for(int j = 0 ; j <= 2 ; ++j) for(int k = 0 ; k <= 2 ; ++k) if(j != i) res1 = add(res1 , dp[l+1][r-1][j][k]);
		int &res2 = dp[l][r][0][i];
		for(int j = 0 ; j <= 2 ; ++j) for(int k = 0 ; k <= 2 ; ++k) if(k != i) res2 = add(res2 , dp[l+1][r-1][j][k]);
	}
	return ;
}

int main()
{
	scanf("%s" , s+1); n = strlen(s+1);
	solve(1 , n);
	int ans = 0;
	for(int i = 1 ; i <= 2 ; ++i) ans = add(ans , add(dp[1][n][i][0] , dp[1][n][0][i]));
	cout << ans << '\n';
	return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<bitset>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
const int N = 720 , mod = 1e9+7;
inline int read()
{
    register int x = 0 , f = 0; register char c = getchar();
    while(c < '0' || c > '9') f |= c == '-' , c = getchar();
    while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
    return f ? -x : x;
}
int n;
char s[N];
int dp[N][N][3][3];
inline int add(int a , int b) { a += b; return a >= mod ? a - mod : a; }
inline int mul(int a , int b) { return (LL)a * b % mod; }
void solve(int l , int r)
{
	if(l + 1 == r)
	{
		for(int i = 1 ; i <= 2 ; ++i) dp[l][r][i][0] = dp[l][r][0][i] = 1;
		return ;
	}
	int res = 0;
	for(int pos = l ; pos <  r ; ++pos)
	{
		res += s[pos] == '(' ? 1 : -1;
		if(res == 0)
		{
			solve(l , pos); solve(pos+1 , r); // 右侧的pos+1 与 r不一定是匹配的。
//			for(int i = 1 ; i <= 2 ; ++i)
//			{
//				dp[l][r][i][0] = mul(dp[l][pos][i][0] , add(dp[pos+1][r][i][0] , dp[pos+1][r][3-i][0]));
//				dp[l][r][0][i] = mul(dp[pos+1][r][0][i] , add(dp[l][pos][0][i] , dp[l][pos][0][3-i]));
//			}
			for(int i = 0 ; i <= 2 ; ++i)
				for(int j = 0 ; j <= 2 ; ++j)
					for(int k = 0 ; k <= 2 ; ++k)
						for(int s = 0 ; s <= 2 ; ++s)
							if(!((k == 1 && s == 1) || (k == 2 && s == 2)))
								dp[l][r][i][j] = add(dp[l][r][i][j] , mul(dp[l][pos][i][k] , dp[pos+1][r][s][j]));
			return ;
		}
	}
	solve(l + 1 , r - 1);
//	for(int i = 1 ; i <= 2 ; ++i) // (()) 这个只能处理这种
//	{
//		int &res1 = dp[l][r][i][0];
//		for(int j = 0 ; j <= 2 ; ++j) if(j != i) res1 = add(res1 , dp[l+1][r-1][j][0]);
//		for(int j = 0 ; j <= 2 ; ++j) res1 = add(res1 , dp[l+1][r-1][0][j]);
//		int &res2 = dp[l][r][0][i];
//		for(int j = 0 ; j <= 2 ; ++j) if(j != i) res2 = add(res2 , dp[l+1][r-1][0][j]);
//		for(int j = 0 ; j <= 2 ; ++j) res2 = add(res2 , dp[l+1][r-1][j][0]);
//	}
	for(int i = 1 ; i <= 2 ; ++i) // (()()) // 这个都可以
	{
		int &res1 = dp[l][r][i][0];
		for(int j = 0 ; j <= 2 ; ++j) for(int k = 0 ; k <= 2 ; ++k) if(j != i) res1 = add(res1 , dp[l+1][r-1][j][k]);
		int &res2 = dp[l][r][0][i];
		for(int j = 0 ; j <= 2 ; ++j) for(int k = 0 ; k <= 2 ; ++k) if(k != i) res2 = add(res2 , dp[l+1][r-1][j][k]);
	}
	return ;
}

int main()
{
	scanf("%s" , s+1); n = strlen(s+1);
	solve(1 , n);
	int ans = 0;
//	for(int i = 1 ; i <= 2 ; ++i) ans = add(ans , add(dp[1][n][i][0] , dp[1][n][0][i]));
	for(int i = 0 ; i <= 2 ; ++i) for(int j = 0 ; j <= 2 ; ++j) ans = add(ans , dp[1][n][i][j]);
	cout << ans << '\n';
	return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <fstream>
#include <queue>
#include <stack>
using namespace std;

const int maxn=2e5+100;
typedef long long LL;
#define mod 1000000007
LL dp[888][888][3][3];

int main( )
{
	// freopen("input.txt", "r", stdin);
	char str[111];
	scanf("%s",str);
			int n = strlen(str);
			int match[n+1];
			int mask[n+1];
			memset(dp,0,sizeof(dp));
			memset(match,0,sizeof(match));
			memset(mask,0,sizeof(mask));
			int i=0,j=0,s=0;
			while(i<n){
				if(mask[i]){
					i++;
					continue;}
				s=0;
				j=i;
				if (str[i]=='(')
					s++;
				if (str[i]==')')
					s--;
				while(s){
					j++;
				if (str[j]=='(')
					s++;
				if (str[j]==')')
					s--;
				}
				match[i]=j;
				match[j]=i;
				mask[i]=1;
				mask[j]=1;
				i++;
			}
			// for (int i = 0; i < n; ++i)
			// 	printf("%d ",match[i] );

			for(int j=1;j<n;j++)
				for(int i=j-1;i>=0;i--){
					if(match[i]==j){
						if (j-i>1){
							for(int pc=0;pc<3;pc++)
								for (int qc=0;qc<3;qc++){
									if (qc!=1)
										dp[i][j][0][1]=(dp[i][j][0][1]+dp[i+1][j-1][pc][qc])%mod;
									if (qc!=2)
										dp[i][j][0][2]=(dp[i][j][0][2]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=1)
										dp[i][j][1][0]=(dp[i][j][1][0]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=2)
										dp[i][j][2][0]=(dp[i][j][2][0]+dp[i+1][j-1][pc][qc])%mod;
								}
							}
						else{
							dp[i][j][0][1]=1;
							dp[i][j][0][2]=1;
							dp[i][j][1][0]=1;
							dp[i][j][2][0]=1;
						}
					}
					else
						{
						int k=match[i];
							// printf("%d %d %d\n",i,k,j );
							for(int ic=0;ic<3;ic++)
								for(int jc=0;jc<3;jc++)
									for(int pc=0;pc<3;pc++)
										for (int qc=0;qc<3;qc++){
											if ((pc==1 or pc==2) and pc==qc)
												continue;
											else
												dp[i][j][ic][jc]=(dp[i][j][ic][jc]+(dp[i][k][ic][pc]*dp[k+1][j][qc][jc])%mod)%mod;
											}
					}
			}
			// for(int j=1;j<n;j++)
			// 	for(int i=j-1;i>=0;i--)
			// 		for(int k1=0;k1<3;k1++)
			// 			for(int k2=0;k2<3;k2++)
			// 				printf("%d %d _ %d %d _ %d \n", i,j ,k1,k2,dp[i][j][k1][k2]);
			LL ans=0;
			for(int pc=0;pc<3;pc++)
				for (int qc=0;qc<3;qc++)
					ans=(ans+dp[0][n-1][pc][qc])%mod;
		     printf("%I64d\n", ans);

	return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <fstream>
#include <queue>
#include <stack>
using namespace std;

const int maxn=2e5+100;
typedef long long LL;
#define mod 1000000007

int main( )
{
	freopen("input.txt", "r", stdin);
	char str[111];
	scanf("%s",str);
			int n = strlen(str);
			int match[n+1];
			int mask[n+1];
			int dp[n+1][n+1][3][3];
			memset(dp,0,sizeof(dp));
			memset(match,0,sizeof(match));
			memset(mask,0,sizeof(mask));
			int i=0,j=0,s=0;
			while(i<n){
				if(mask[i]){
					i++;
					continue;}
				s=0;
				j=i;
				if (str[i]=='(')
					s++;
				if (str[i]==')')
					s--;
				while(s){
					j++;
				if (str[j]=='(')
					s++;
				if (str[j]==')')
					s--;
				}
				match[i]=j;
				match[j]=i;
				mask[i]=1;
				mask[j]=1;
				i++;
			}
			// for (int i = 0; i < n; ++i)
			// 	printf("%d ",match[i] );

			for(int j=1;j<n;j++)
				for(int i=j-1;i>=0;i--){
					if(match[i]==j){
						if (j-i>1){
							for(int pc=0;pc<3;pc++)
								for (int qc=0;qc<3;qc++){
									if (qc!=1)
										dp[i][j][0][1]=(dp[i][j][0][1]+dp[i+1][j-1][pc][qc])%mod;
									if (qc!=2)
										dp[i][j][0][2]=(dp[i][j][0][2]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=1)
										dp[i][j][1][0]=(dp[i][j][1][0]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=2)
										dp[i][j][2][0]=(dp[i][j][2][0]+dp[i+1][j-1][pc][qc])%mod;
								}
							}
						else{
							dp[i][j][0][1]=1;
							dp[i][j][0][2]=1;
							dp[i][j][1][0]=1;
							dp[i][j][2][0]=1;
						}
					}
					else
						{
						int k=match[i];
							// printf("%d %d %d\n",i,k,j );
							for(int ic=0;ic<3;ic++)
								for(int jc=0;jc<3;jc++)
									for(int pc=0;pc<3;pc++)
										for (int qc=0;qc<3;qc++){
											if ((pc==1 or pc==2) and pc==qc)
												continue;
											else
												dp[i][j][ic][jc]=(dp[i][j][ic][jc]+dp[i][k][ic][pc]*dp[k+1][j][qc][jc]%mod)%mod;
											}
					}
			}
			// for(int j=1;j<n;j++)
			// 	for(int i=j-1;i>=0;i--)
			// 		for(int k1=0;k1<3;k1++)
			// 			for(int k2=0;k2<3;k2++)
			// 				printf("%d %d _ %d %d _ %d \n", i,j ,k1,k2,dp[i][j][k1][k2]);
			int ans=0;
			ans+=dp[0][n-1][0][1]+dp[0][n-1][0][2]+dp[0][n-1][2][0]+dp[0][n-1][2][0]+dp[0][n-1][0][0];
		     printf("%d\n", ans);

	return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <fstream>
#include <queue>
#include <stack>
using namespace std;

const int maxn=2e5+100;
typedef long long LL;
#define mod 1000000007

int main( )
{
	freopen("input.txt", "r", stdin);
	char str[111];
	scanf("%s",str);
			int n = strlen(str);
			int match[n+1];
			int mask[n+1];
			int dp[n+1][n+1][5][5];
			memset(dp,0,sizeof(dp));
			memset(match,0,sizeof(match));
			memset(mask,0,sizeof(mask));
			int i=0,j=0,s=0;
			while(i<n){
				if(mask[i]){
					i++;
					continue;}
				s=0;
				j=i;
				if (str[i]=='(')
					s++;
				if (str[i]==')')
					s--;
				while(s){
					j++;
				if (str[j]=='(')
					s++;
				if (str[j]==')')
					s--;
				}
				match[i]=j;
				match[j]=i;
				mask[i]=1;
				mask[j]=1;
				i++;
			}
			// for (int i = 0; i < n; ++i)
			// 	printf("%d ",match[i] );

			for(int j=1;j<n;j++)
				for(int i=j-1;i>=0;i--){
					if(match[i]==j){
						if (j-i>1){
							for(int pc=0;pc<3;pc++)
								for (int qc=0;qc<3;qc++){
									if (qc!=1)
										dp[i][j][0][1]=(dp[i][j][0][1]+dp[i+1][j-1][pc][qc])%mod;
									if (qc!=2)
										dp[i][j][0][2]=(dp[i][j][0][2]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=1)
										dp[i][j][1][0]=(dp[i][j][1][0]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=2)
										dp[i][j][2][0]=(dp[i][j][2][0]+dp[i+1][j-1][pc][qc])%mod;
								}
							}
						else{
							dp[i][j][0][1]=1;
							dp[i][j][0][2]=1;
							dp[i][j][1][0]=1;
							dp[i][j][2][0]=1;
						}
					}
					else
						{
						int k=match[i];
							// printf("%d %d %d\n",i,k,j );
							for(int ic=0;ic<3;ic++)
								for(int jc=0;jc<3;jc++)
									for(int pc=0;pc<3;pc++)
										for (int qc=0;qc<3;qc++){
											if ((pc==1 or pc==2) and pc==qc)
												continue;
											else
												dp[i][j][ic][jc]=(dp[i][j][ic][jc]+dp[i][k][ic][pc]*dp[k+1][j][qc][jc]%mod)%mod;
											}
					}
			}
			// for(int j=1;j<n;j++)
			// 	for(int i=j-1;i>=0;i--)
			// 		for(int k1=0;k1<3;k1++)
			// 			for(int k2=0;k2<3;k2++)
			// 				printf("%d %d _ %d %d _ %d \n", i,j ,k1,k2,dp[i][j][k1][k2]);
			int ans=0;
			for(int pc=0;pc<3;pc++)
				for (int qc=0;qc<3;qc++)
					ans=(ans+dp[0][n-1][pc][qc])%mod;
		     printf("%d\n", ans);

	return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <fstream>
#include <queue>
#include <stack>
using namespace std;

const int maxn=2e5+100;
typedef long long LL;
#define mod 1000000007

int main( )
{
	// freopen("input.txt", "r", stdin);
	char str[111];
	scanf("%s",str);
			int n = strlen(str);
			int match[n+1];
			int mask[n+1];
			int dp[n+1][n+1][5][5];
			memset(dp,0,sizeof(dp));
			memset(match,0,sizeof(match));
			memset(mask,0,sizeof(mask));
			int i=0,j=0,s=0;
			while(i<n){
				if(mask[i]){
					i++;
					continue;}
				s=0;
				j=i;
				if (str[i]=='(')
					s++;
				if (str[i]==')')
					s--;
				while(s){
					j++;
				if (str[j]=='(')
					s++;
				if (str[j]==')')
					s--;
				}
				match[i]=j;
				match[j]=i;
				mask[i]=1;
				mask[j]=1;
				i++;
			}
			// for (int i = 0; i < n; ++i)
			// 	printf("%d ",match[i] );

			for(int j=1;j<n;j++)
				for(int i=j-1;i>=0;i--){
					if(match[i]==j){
						if (j-i>1){
							for(int pc=0;pc<3;pc++)
								for (int qc=0;qc<3;qc++){
									if (qc!=1)
										dp[i][j][0][1]=(dp[i][j][0][1]+dp[i+1][j-1][pc][qc])%mod;
									if (qc!=2)
										dp[i][j][0][2]=(dp[i][j][0][2]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=1)
										dp[i][j][1][0]=(dp[i][j][1][0]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=2)
										dp[i][j][2][0]=(dp[i][j][2][0]+dp[i+1][j-1][pc][qc])%mod;
								}
							}
						else{
							dp[i][j][0][1]=1;
							dp[i][j][0][2]=1;
							dp[i][j][1][0]=1;
							dp[i][j][2][0]=1;
						}
					}
					else
						{
						int k=match[i];
							// printf("%d %d %d\n",i,k,j );
							for(int ic=0;ic<3;ic++)
								for(int jc=0;jc<3;jc++)
									for(int pc=0;pc<3;pc++)
										for (int qc=0;qc<3;qc++){
											if ((pc==1 or pc==2) and pc==qc)
												continue;
											else
												dp[i][j][ic][jc]=(dp[i][j][ic][jc]+dp[i][k][ic][pc]*dp[k+1][j][qc][jc]%mod)%mod;
											}
					}
			}
			// for(int j=1;j<n;j++)
			// 	for(int i=j-1;i>=0;i--)
			// 		for(int k1=0;k1<3;k1++)
			// 			for(int k2=0;k2<3;k2++)
			// 				printf("%d %d _ %d %d _ %d \n", i,j ,k1,k2,dp[i][j][k1][k2]);
			LL ans=0;
			for(int pc=0;pc<3;pc++)
				for (int qc=0;qc<3;qc++)
					ans=(ans+dp[0][n-1][pc][qc])%mod;
		     printf("%I64d\n", ans);

	return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <fstream>
#include <queue>
#include <stack>
using namespace std;

const int maxn=2e5+100;
typedef long long LL;
#define mod 1000000007
LL dp[888][888][3][3];
char str[888];
int main( )
{
	// freopen("input.txt", "r", stdin);
	scanf("%s",str);
			int n = strlen(str);
			int match[n+1];
			int mask[n+1];
			memset(dp,0,sizeof(dp));
			memset(match,0,sizeof(match));
			memset(mask,0,sizeof(mask));
			int i=0,j=0,s=0;
			while(i<n){
				if(mask[i]){
					i++;
					continue;}
				s=0;
				j=i;
				if (str[i]=='(')
					s++;
				if (str[i]==')')
					s--;
				while(s){
					j++;
				if (str[j]=='(')
					s++;
				if (str[j]==')')
					s--;
				}
				match[i]=j;
				match[j]=i;
				mask[i]=1;
				mask[j]=1;
				i++;
			}
			// for (int i = 0; i < n; ++i)
			// 	printf("%d ",match[i] );

			for(int j=1;j<n;j++)
				for(int i=j-1;i>=0;i--){
					if(match[i]==j){
						if (j-i>1){
							for(int pc=0;pc<3;pc++)
								for (int qc=0;qc<3;qc++){
									if (qc!=1)
										dp[i][j][0][1]=(dp[i][j][0][1]+dp[i+1][j-1][pc][qc])%mod;
									if (qc!=2)
										dp[i][j][0][2]=(dp[i][j][0][2]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=1)
										dp[i][j][1][0]=(dp[i][j][1][0]+dp[i+1][j-1][pc][qc])%mod;
									if (pc!=2)
										dp[i][j][2][0]=(dp[i][j][2][0]+dp[i+1][j-1][pc][qc])%mod;
								}
							}
						else{
							dp[i][j][0][1]=1;
							dp[i][j][0][2]=1;
							dp[i][j][1][0]=1;
							dp[i][j][2][0]=1;
						}
					}
					else
						{
						int k=match[i];
							// printf("%d %d %d\n",i,k,j );
							for(int ic=0;ic<3;ic++)
								for(int jc=0;jc<3;jc++)
									for(int pc=0;pc<3;pc++)
										for (int qc=0;qc<3;qc++){
											if ((pc==1 or pc==2) and pc==qc)
												continue;
											else
												dp[i][j][ic][jc]=(dp[i][j][ic][jc]+(dp[i][k][ic][pc]*dp[k+1][j][qc][jc])%mod)%mod;
											}
					}
			}
			// for(int j=1;j<n;j++)
			// 	for(int i=j-1;i>=0;i--)
			// 		for(int k1=0;k1<3;k1++)
			// 			for(int k2=0;k2<3;k2++)
			// 				printf("%d %d _ %d %d _ %d \n", i,j ,k1,k2,dp[i][j][k1][k2]);
			LL ans=0;
			for(int pc=0;pc<3;pc++)
				for (int qc=0;qc<3;qc++)
					ans=(ans+dp[0][n-1][pc][qc])%mod;
		     printf("%I64d\n", ans);

	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<set>
#include<bitset>
#include<map>

#include<tr1/unordered_map>
using namespace std::tr1;

using namespace std;

template <typename T> void read(T &x) {
	x = 0; int f = 1; char c;
	for (c = getchar(); c < '0' || c > '9'; c = getchar()) if (c == '-') f = -f;
	for (; c >= '0' && c <= '9'; c = getchar()) x = 10 * x + c - '0' ;
	x *= f;
}
template <typename T> void write(T x){
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) { write(x); putchar('\n'); }
template <typename T> void writesn(T x) { write(x); putchar(' '); }

#define int long long
#define inf 1234567890
#define next net
#define midd ((l+r)>>1)
#define lson (o<<1)
#define rson (o<<1|1)
#define R register
#define debug puts("zxt")
#define IT set<node>::iterator

const int P = 1000000007;
int n;
char s[705];
int match[705], hh[705], top;
int dp[705][705][3][3], ans;

inline void dfs(int l, int r)
{
	if(l + 1 == r)
	{
		dp[l][r][1][0] = dp[l][r][2][0] = dp[l][r][0][1] = dp[l][r][0][2] = 1;
		return;
	}
	if(match[l] == r)
	{
		dfs(l + 1, r -1);
		for(R int i = 0; i <= 2; i++)
			for(R int j = 0; j <= 2; j++)
			{
				if(i != 1) dp[l][r][1][0] = (dp[l][r][1][0] + dp[l + 1][r - 1][i][j]) % P;
				if(i != 2) dp[l][r][2][0] = (dp[l][r][2][0] + dp[l + 1][r - 1][i][j]) % P;
				if(j != 1) dp[l][r][0][1] = (dp[l][r][0][1] + dp[l + 1][r - 1][i][j]) % P;
				if(j != 2) dp[l][r][0][2] = (dp[l][r][0][2] + dp[l + 1][r - 1][i][j]) % P;
			}
		return;
	}
	dfs(l, match[l]); dfs(match[l] + 1, r);
	for(R int i = 0; i <= 2; i++)
		for(R int j = 0; j <= 2; j++)
			for(R int m = 0; m <= 2; m++)
				for(R int n = 0; n <= 2; n++)
				{
					if((j == 1 && m == 1) || (j == 2 && m == 2))continue;
					dp[l][r][i][n] = (dp[l][r][i][n] + dp[l][match[l]][i][j] * dp[match[l] + 1][r][m][n]);
				}
	return;
}

signed main()
{
	scanf("%s", s + 1);
	n = strlen(s + 1);
	for(R int i = 1; i <= n; i++)
	{
		if(s[i] == '(') hh[++top] = i;
		else match[hh[top]] = i, match[i] = hh[top], top--;
	}
	dfs(1, n);
	for(R int i = 0; i <= 2; i++)
		for(R int j = 0; j <= 2; j++)
			ans = (ans + dp[1][n][i][j]) % P;
	writeln(ans);
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <stack>
#include <cstring>
using namespace std;
#define MAXN 700
const long long INF = 1e9 + 7;
long long dp[13][MAXN + 5][MAXN + 5];
int s[MAXN + 5];
char c[MAXN + 5];
long long f(int l, int r, int x, int y) {
    long long sum = 0;
    for (int i = 0; i < 3; i++) {
        long long ans = 0;
        for (int j = 0; j < 3; j++) {
            if (i == j && i != 0) {
                continue;
            }
            ans += dp[j * 3 + y][s[l] + 1][r];
            ans %= INF;
        }
        sum += dp[x * 3 + i][l][s[l]] * ans;
        sum %= INF;
    }
    return sum;
}
long long g(int l, int r, int x, int y) {
    long long sum = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if ((i == x && i != 0) || (j == y && j != 0)) {
                continue;
            }
            sum += dp[i * 3 + j][l + 1][r - 1];
            sum %= INF;
        }
    }
    return sum;
}
int main() {
    //	freopen ("coloring.in", "r", stdin);
    //	freopen ("coloring.out", "w", stdout);
    int n;
    scanf("%s", c + 1);
    n = strlen(c + 1);
    stack<int> S;
    for (int i = 1; i <= n; i++) {
        if (c[i] == '(') {
            S.push(i);
        } else {
            s[S.top()] = i;
            s[i] = S.top();
            S.pop();
        }
    }
    for (int i = 1; i <= n; i++) {
        if (s[i] - i == 1) {
            //			dp[1][i][s[i]] = dp[2][i][s[i]] = dp[3][i][s[i]] = dp[4][i][s[i]] = 2;
            //			dp[5][i][s[i]] = dp[6][i][s[i]] = dp[7][i][s[i]] = dp[8][i][s[i]] = 1;
            dp[1][i][s[i]] = dp[2][i][s[i]] = dp[3][i][s[i]] = dp[6][i][s[i]] = 1;
            /*
//			*1:左非蓝, 右非红
//			*2:左非红, 右非蓝
//			*3:左非蓝, 右非蓝
//			*4:左非红, 右非红
//			*5:左黑, 右红
//			*6:左红, 右黑
//			*7:左蓝, 右黑
//			*8:左黑, 右蓝
-------------------------
            *0:左黑, 右黑
            *1:左黑, 右红
            *2:左黑, 右蓝
            *3:左红, 右黑
            *4:左红, 右红
            *5:左红, 右蓝
            *6:左蓝, 右黑
            *7:左蓝, 右红
            *8:左蓝, 右蓝
            */
        }
    }
    for (int i = 4; i <= n; i++) {
        for (int j = 1; j <= n - i + 1; j++) {
            if (c[j] == '(' && c[j + i - 1] == ')' && s[j] != j + i - 1 && s[j] < j + i - 1 &&
                s[j + i - 1] > s[j]) {
                //				dp[1][j][j + i - 1] = (dp[2][j][s[j]] * dp[2][s[j + i -1]][j + i -
                //1] + dp[4][j][s[j]] * dp[3][s[j + i -1]][j + i - 1]) % INF; 				dp[2][j][j + i - 1] =
                //(dp[1][j][s[j]] * dp[1][s[j + i -1]][j + i - 1] + dp[3][j][s[j]] * dp[4][s[j + i -1]][j + i
                //- 1]) % INF; 				dp[3][j][j + i - 1] = (dp[2][j][s[j]] * dp[4][s[j + i -1]][j + i - 1] +
                //dp[4][j][s[j]] * dp[1][s[j + i -1]][j + i - 1]) % INF; 				dp[4][j][j + i - 1] = (dp[1][j][s[j]]
                //* dp[3][s[j + i -1]][j + i - 1] + dp[3][j][s[j]] * dp[2][s[j + i -1]][j + i - 1]) % INF;
                for (int k = 0; k < 9; k++) {
                    dp[k][j][j + i - 1] = f(j, j + i - 1, k / 3, k % 3);
                }
            } else if (s[j] == j + i - 1) {
                //				dp[1][j][j + i - 1] = 2 * dp[2][j + 1][j + i - 2] % INF;
                //				dp[2][j][j + i - 1] = 2 * dp[1][j + 1][j + i - 2] % INF;
                //				dp[3][j][j + i - 1] = 2 * dp[4][j + 1][j + i - 2] % INF;
                //				dp[4][j][j + i - 1] = 2 * dp[3][j + 1][j + i - 2] % INF;
                dp[1][j][j + i - 1] = g(j, j + i - 1, 0, 1);
                dp[2][j][j + i - 1] = g(j, j + i - 1, 0, 2);
                dp[3][j][j + i - 1] = g(j, j + i - 1, 1, 0);
                dp[6][j][j + i - 1] = g(j, j + i - 1, 2, 0);
            }
        }
    }
    long long sum = 0;
    for (int i = 0; i < 9; i++) {
        sum += dp[i][1][n];
        sum %= INF;
    }
    printf("%d", sum);
}


#include<bits/stdc++.h>
using namespace std;
#define rev(k) (k == 1) ? 2 : 1
#define int long long
const int N = 1e3 + 9;
const int p = 1000000007;
int f[N][N][3][3],mat[N],t[N];

int dfs(int l,int r,int cl,int cr){//(l,r)一定是合法括号序列
	if(f[l][r][cl][cr] != -1) return f[l][r][cl][cr];
	if(l == r - 1){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;
		return f[l][r][cl][cr] = 1;
	}
	f[l][r][cl][cr] = 0;
	if(mat[l] == r){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;

		if(cl == 0){
			f[l][r][cl][cr] =
			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,rev(cr)) +
			dfs(l + 1,r - 1,1,rev(cr)) +
			dfs(l + 1,r - 1,2,rev(cr));

			f[l][r][cl][cr] %= p;
			return f[l][r][cl][cr];
		}

		if(cr == 0){
			f[l][r][cl][cr] =
			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,rev(cl),0) +
			dfs(l + 1,r - 1,rev(cl),1) +
			dfs(l + 1,r - 1,rev(cl),2);

			f[l][r][cl][cr] %= p;
			return f[l][r][cl][cr];
		}
	}
	for(int ck = 0 ; ck <= 2 ; ck ++){
		if((!cl && !ck) || (cl && ck)) continue;
		for(int kk = 0 ; kk <= 2 ; kk ++){
			if(kk == ck && kk != 0 &&ck != 0) continue;
			if((!cr && !kk) || (cr && kk)) continue;
			f[l][r][cl][cr] += dfs(l,mat[l],cl,ck) * dfs(mat[l] + 1,r,kk,cr) % p;
			f[l][r][cl][cr] %= p;
		}
	}
	return f[l][r][cl][cr];
}
signed main(){
	memset(f,-1,sizeof(f));
	stack<int> st; int ans = 0;
	string s; cin>>s; int ln = s.length(),cnt = 0;
	for(int i = 0 ; i < ln ; i ++){
		int k = i + 1;
		if(s[i] == '(') st.push(k);
		else{
			mat[st.top()] = k; st.pop();
		}
	}
	for(int i = 0 ; i <= 2 ; i ++){
		for(int j = 0 ; j <= 2 ; j ++){
			ans += dfs(1,ln,i,j) % p; ans %= p;
		}
	}
	cout<<ans;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rev(k) ((k == 1) ? 2 : 1)
#define int long long
const int N = 1e3 + 9;
const int p = 1000000007;
int f[N][N][3][3],mat[N];

int dfs(int l,int r,int cl,int cr){//(l,r)一定是合法括号序列
	if(f[l][r][cl][cr] != -1) return f[l][r][cl][cr];
	if(l == r - 1){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;
		return f[l][r][cl][cr] = 1;
	}
	f[l][r][cl][cr] = 0;
	if(mat[l] == r){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;

		if(cl == 0){
			f[l][r][cl][cr] =
			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,rev(cr)) +
			dfs(l + 1,r - 1,1,rev(cr)) +
			dfs(l + 1,r - 1,2,rev(cr));

			f[l][r][cl][cr] %= p;
			return f[l][r][cl][cr];
		}

		if(cr == 0){
			f[l][r][cl][cr] =
			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,rev(cl),0) +
			dfs(l + 1,r - 1,rev(cl),1) +
			dfs(l + 1,r - 1,rev(cl),2);

			f[l][r][cl][cr] %= p;
			return f[l][r][cl][cr];
		}
	}
	for(int ck = 0 ; ck <= 2 ; ck ++){
//		if((!cl && !ck) || (cl && ck)) continue;
		for(int kk = 0 ; kk <= 2 ; kk ++){
			if(kk == ck && kk != 0 && ck != 0) continue;
//			if((!cr && !kk) || (cr && kk)) continue;
			f[l][r][cl][cr] += dfs(l,mat[l],cl,ck) * dfs(mat[l] + 1,r,kk,cr) % p;
			f[l][r][cl][cr] %= p;
		}
	}
	return f[l][r][cl][cr];
}
signed main(){
	memset(f,-1,sizeof(f));
	stack<int> st; int ans = 0;

	string s; cin>>s; int ln = s.length();
	for(int i = 0 ; i < ln ; i ++){
		int k = i + 1;
		if(s[i] == '(') st.push(k);
		else{
			mat[st.top()] = k; st.pop();
		}
	}

	for(int i = 0 ; i <= 2 ; i ++){
		for(int j = 0 ; j <= 2 ; j ++){
			ans += dfs(1,ln,i,j) % p; ans %= p;
		}
	}
	cout<<ans;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N =  710,mod = 1e9 + 7;
int f[N][N][3][3];
char s[N];
int match[N];
int len;
stack<int >st;

/*
f(l,r,[0,1,2],[0,1,2]) 代表这个区间的左右两边的染色方案数

*/
inline void dfs(int l,int r)
{
	if(l == r - 1)
	{
		f[l][r][0][1] = f[l][r][1][0] = f[l][r][0][2] = f[l][r][2][0] = 1ll;
		return ;
	}
	if(match[l] == r)
	{
		dfs(l + 1,r - 1);
		for(int i = 0;i <= 2;++ i)
		{
			for(int j = 0;j <= 2;++ j)
			{
				for(int p = 0;p <= 2;++ p)
				{
					for(int q = 0;q <= 2;++ q)
					{
						if(i == j) continue;
						if(i && j) continue;
						if((i == p && i != 0)||( j == q && j != 0)) continue;
						f[l][r][i][j] = (f[l][r][i][j] + f[l + 1][r - 1][p][q]) % mod;
					}
				}
			}
		}
	}
	else
	{
		dfs(l,match[l]);
		dfs(match[l] + 1,r);
		int mid = match[l];
		for(int i = 0;i <= 2;++ i)
			for(int j = 0;j <= 2;++ j)
				for(int p = 0;p <= 2;++ p)
					for(int q = 0;q <= 2;++ q)
					{
						if(p == q && p != 0) continue;
						f[l][r][i][j] = (f[l][r][i][j] + f[l][mid][i][p] * f[mid + 1][r][q][j] % mod) % mod;
					}
	}
//	cout << l << " " << r << endl;
}
signed main()
{
	scanf("%s",s + 1);
	len = strlen(s + 1);
	for(int i = 1;i <= len;++ i)
	{
		if(s[i] == '(') st.push(i);
		else match[i] = st.top(),match[st.top()] = i,st.pop();
	}
	int ans = 0;
	dfs(1,len);
	for(int i = 0;i <= 2;++ i)
		for(int j = 0;j <= 2;++ j)
			ans = (ans + f[1][len][i][j]) % mod;
	cout << ans;
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#define int long long
using namespace std;
const int maxn=700+1;
const int mod=1e9+7;
int dp[maxn][maxn][3][3];
stack<int> q;
char s[maxn];
int match[maxn],ans=0;
void Pre(){
    q.push(1);int cnt=2;
    while(!q.empty()){
        if(s[cnt]=='(')q.push(cnt);
        else {
            match[cnt]=q.top();
            match[q.top()]=cnt;
            q.pop();
        }cnt++;
    }
}
void Dfs(int l,int r){
    if(l+1==r){
        dp[l][r][0][1]=dp[l][r][1][0]=dp[l][r][0][2]=dp[l][r][2][0]=1;
        return;
    }
    if(match[l]==r){
        Dfs(l+1,r-1);
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                if(j!=1)dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;
                if(i!=1)dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
                if(j!=2)dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;
                if(i!=2)dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
            }
        }
    }else {
        int mid=match[l];
        Dfs(l,mid);Dfs(mid+1,r);
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                for(int k=0;k<3;k++){
                    for(int m=0;m<3;m++){
                        if(!(k==1&&m==1)&&!(k==2&&m==2))
                            dp[l][r][i][j]=(dp[l][r][i][j]+dp[l][mid][i][k]*dp[mid+1][r][m][j]%mod)%mod;
                    }
                }
            }
        }
    }
}
signed main(){
    scanf("%s",s+1);
    int len=strlen(s+1);
    Pre();
    Dfs(1,len);
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            ans=(ans+dp[1][len][i][j])%mod;
        }
    }printf("%lld\n",ans);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int mod = 1000000007;
char s[705];
int dp[705][705][2] , n;
int pd(int x , int y) {
	int f = 1 , top = 0;
	for (int i = x; i <= y; ++i) {
		if(s[i] == '(') top ++;
		else top --;
		if(top < 0) return 0;
		if(!top && i != y && f == 1) f = i;
	}
	if(top != 0) return 0;
	return f;
}
int main() {
	freopen("coloring.in" , "r" , stdin);
	freopen("coloring.out" , "w" , stdout);
	scanf("%s" , s + 1);
	n = strlen(s + 1);
	for (int len = 2; len <= n; len += 2) {
		for (int i = 1; i <= n; ++i) {
			int j = i + len - 1;
			if(len == 2) {
				if(s[i] == '(' && s[j] == ')') {
					dp[i][j][0] = 4;
					dp[i][j][1] = 1;
				}
				continue;
			}
			int f = pd(i , j);
			if(!f) continue;
			else if(f == 1) {
				dp[i][j][0] = (4ll * (long long)(dp[i + 1][j - 1][0] - dp[i + 1][j - 1][1]) % mod + mod) % mod;
				dp[i][j][1] = ((dp[i + 1][j - 1][0] - dp[i + 1][j - 1][1]) % mod + mod) % mod;
			}
			else {
				dp[i][j][0] = (long long)dp[i][f][0] * (long long)dp[f + 1][j][0] % mod - (long long) dp[i][f][1] * (long long)dp[f + 1][j][1] * 2ll % mod;
				dp[i][j][0] = (dp[i][j][0] % mod + mod) % mod;
				dp[i][j][1] = (long long)dp[i][f][1] * (long long)dp[f + 1][j][0] % mod;
			}
		}
	}
	printf("%d" , dp[1][n][0]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
char t[710];
int len;
const int mod=1e9+7;
int f[710][710][4][4];
int U[710][710][4][4];
int dui[710];
int ksm(int a,int k)
{
	int sum=1;
	while(k)
	{
		if(k&1) sum=1ll*sum*a%mod;
		a=1ll*a*a%mod;
		k>>=1;
	}
	return sum;
}
int dp(int l,int r,int L,int R)//l到r的方案数
{
	if(U[l][r][L][R]) return f[l][r][L][R];
	U[l][r][L][R]=1;
	if(l==r-1)
	{
		if((L&&R)||(!L&&!R)) return f[l][r][L][R]=0;
		return f[l][r][L][R]=1;
	}
	int T=dui[l];
	if(T==r)
	{
		if((L&&R)||(!L&&!R)) return f[l][r][L][R]=0;
		if(L)
		{
			int u=0;
			for(int i=0;i<=2;i++)
			for(int j=0;j<=2;j++)
			if(i!=L) u=(u+dp(l+1,r-1,i,j))%mod;
			return f[l][r][L][R]=u;
		}
		else
		{
			int u=0;
			for(int i=0;i<=2;i++)
			for(int j=0;j<=2;j++)
			if(j!=R) u=(u+dp(l+1,r-1,i,j))%mod;
			return f[l][r][L][R]=u;
		}
	}
	else
	{
		int u=0;
		for(int i=0;i<=2;i++)
		for(int j=0;j<=2;j++)
		if((i==0&&j==0)||i!=j) u=(u+1ll*dp(l,T,L,i)*dp(T+1,r,j,R)%mod)%mod;
		return f[l][r][L][R]=u;
	}
}
int st[710];
int num;
int main()
{
	scanf("%s",&t[1]);
	len=strlen(&t[1]);
	for(int i=len;i>=1;i--)
	{
		if(t[i]==')') st[++num]=i;
		else
		{
			dui[i]=st[num];
			num--;
		}
	}
	int ans=0;
	for(int i=0;i<=2;i++)
	for(int j=0;j<=2;j++)
	ans=(ans+dp(1,len,i,j))%mod;
	cout<<ans;
	return 0;
}
//()()


#include<bits/stdc++.h>
#define int long long
#define rev(a) (cr==1?2:1)
#define int long long
#define rep2(i) for(int i=0;i<=2;i++)

using namespace std;
const int N=709,mod=1000000007;

int n,match[N],f[N][N][3][3];
int dfs(int l,int r,int cl,int cr) {
	if(f[l][r][cl][cr] != -1) return f[l][r][cl][cr];
	if(l == r - 1){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;
		return f[l][r][cl][cr] = 1;
	}

	f[l][r][cl][cr] = 0;
	if(match[l] == r){
		if((!cl && !cr) || (cl && cr)) return f[l][r][cl][cr] = 0;

		if(cl == 0){
			f[l][r][cl][cr] =
			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,rev(cr)) +
			dfs(l + 1,r - 1,1,rev(cr)) +
			dfs(l + 1,r - 1,2,rev(cr));

			f[l][r][cl][cr] %= mod;
			return f[l][r][cl][cr];
		}

		if(cr == 0){
			f[l][r][cl][cr] =
			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,rev(cl),0) +
			dfs(l + 1,r - 1,rev(cl),1) +
			dfs(l + 1,r - 1,rev(cl),2);

			f[l][r][cl][cr] %= mod;
			return f[l][r][cl][cr];
		}
	}
	else {
//		rep2(i) rep2(j) f[l][r][i][j]=0;
		rep2(j) rep2(k)
			if(j&&k&&(j==k)) continue;
			else (f[l][r][cl][cr]+=
			dfs(l,match[l],cl,j)*dfs(match[l]+1,r,k,cr))%=mod;
		return f[l][r][cl][cr];
	}

//	for(int ck = 0 ; ck <= 2 ; ck ++){
//		if((!cl && !ck) || (cl && ck)) continue;
//		for(int kk = 0 ; kk <= 2 ; kk ++){
//			if(kk == ck && kk != 0 &&ck != 0) continue;
//			if((!cr && !kk) || (cr && kk)) continue;
//			f[l][r][cl][cr] = dfs(l,match[l],cl,ck) * dfs(match[l] + 1,r,kk,cr) % mod;
//		}
//	}
//	return f[l][r][cl][cr];
}

char s[N];
signed main() {
	memset(f,-1,sizeof(f));
	scanf("%s",s+1); int n=strlen(s+1);
	stack<int>st;
	for(int i=1;i<=n;i++) {
		if(s[i]=='(') st.push(i);
		else match[st.top()]=i,st.pop();
	}
	int ans=0;
	rep2(i) rep2(j) (ans+=dfs(1,n,i,j))%=mod;
	printf("%lld",ans);
	return 0;
}


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

#define I inline
#define ri register int
#define ll long long
#define ull unsigned long long
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define rep(i,a,b) for(ri i=(a);i<=(b);++i)
#define dow(i,a,b) for(ri i=(a);i>=(b);--i)
#define go(i,u) for(ri i=lnk[u];i;i=nxt[i])
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define vec vector
#define que queue
#define pb push_back
#define lowbit(x) (x&(-x))
#define mem(f,x) memset(f,x,sizeof(f))

I int gi(){
	int x=0,f=0;char ch=getchar();
	while(!isdigit(ch)){f|=ch=='-',ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48,ch=getchar();}
	return f?-x:x;
}

I void pi(int x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)pi(x/10);
	putchar(x%10+48);
}
I void pib(int x){pi(x);putchar(' ');}
I void pin(int x){pi(x);putchar('\n');}

const int N = 2e3+5;
const int mo = 998244535;

stack<int> st;
char s[N];
int dp[N][N][3][3],match[N];
void dfs(int l,int r){
	if(l+1==r){rep(i,1,2)dp[l][r][0][i]=dp[l][r][i][0]=1;}
	else if(match[l]==r){
		dfs(l+1,r-1);
		rep(i,0,2)rep(j,0,2){
			if(j!=1)dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mo;
			if(j!=2)dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mo;
			if(i!=1)dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mo;
			if(i!=2)dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mo;
		}
	}
	else{
		dfs(l,match[l]);dfs(match[l]+1,r);
		rep(i,0,2)rep(j,0,2)rep(p,0,2)rep(q,0,2){
			if((j==1&&p==1) || (j==2&&p==2))continue;
			dp[l][r][i][q]=(dp[l][r][i][q]+dp[l][match[l]][i][j]*dp[match[l]+1][r][p][q])%mo;
		}
	}
}

signed main(){
	for(int t=1;t;--t){
		mem(dp,0);
		scanf("%s",s);
		int n=strlen(s);
		rep(i,0,n-1){
			if(s[i]=='(')st.push(i);
			else match[st.top()]=i,match[i]=st.top(),st.pop();
		}
		dfs(0,n-1);
		int ans=0;
		rep(i,0,2)rep(j,0,2)ans=(ans+dp[0][n-1][i][j])%mo;
		pin(ans);
	}
	return 0;
}


//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;

void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;

const int N=810,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int n;
LL f[N][N][5][5];
int stk[N],top,id[N];
char s[N];

void dfs(int l,int r)
{
    if(l+1==r) f[l][r][0][1]=f[l][r][1][0]=f[l][r][0][2]=f[l][r][2][0]=1;
    else if(id[l]==r)
    {
        dfs(l+1,r-1);
        for(int i=0;i<=2;i++)
        {
            for(int j=0;j<=2;j++)
            {
                if(i!=1) f[l][r][1][0]+=f[l+1][r-1][i][j],f[l][r][1][0]%=mod;
                if(i!=2) f[l][r][2][0]+=f[l+1][r-1][i][j],f[l][r][2][0]%=mod;
                if(j!=1) f[l][r][0][1]+=f[l+1][r-1][i][j],f[l][r][0][1]%=mod;
                if(j!=2) f[l][r][0][2]+=f[l+1][r-1][i][j],f[l][r][0][2]%=mod;
            }
        }
    }
    else
    {
        dfs(l,id[l]),dfs(id[l]+1,r);
        for(int i=0;i<=2;i++)
            for(int j=0;j<=2;j++)
                for(int k=0;k<=2;k++)
                    for(int c=0;c<=2;c++)
                        if((j==1&&k==1)||(j==2&&k==2)) continue;
                        else f[l][r][i][c]+=f[l][id[l]][i][j]*f[id[l]+1][r][k][c]%mod,f[l][r][i][c]%=mod;
    }
}

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);

    scanf("%s",s+1); n=strlen(s+1);
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='(') stk[++top]=i;
        else id[stk[top]]=i,id[i]=stk[top],top--;
    }
    dfs(1,n);
    LL ans=0;
    for(int i=0;i<=2;i++)
        for(int j=0;j<=2;j++)
            ans+=f[1][n][i][j],ans%=mod;
    printf("%lld\n",ans);

	return 0;
}
/*

*/


#include <cstdio>
#include <cstring>
#include <iostream>
#define int long long
using namespace std;

const int N = 710, mod = 1e9 + 7;

char c[N];
int n, tp;
int st[N], mch[N];
int res, f[N][N][3][3];

inline void fuck1(int l, int r)
{
	return (void)(f[l][r][0][1] = f[l][r][0][2] = f[l][r][1][0] = f[l][r][2][0] = 1);
}

inline void fuck2(int l, int r)
{
	int i, j;
	for (i = 0; i <= 2; ++ i)
	{
		for (j = 0; j <= 2; ++ j)
		{
			if (j != 1) (f[l][r][0][1] += f[l + 1][r - 1][i][j]) %= mod;
			if (j != 2) (f[l][r][0][2] += f[l + 1][r - 1][i][j]) %= mod;
			if (i != 1) (f[l][r][1][0] += f[l + 1][r - 1][i][j]) %= mod;
			if (i != 2) (f[l][r][2][0] += f[l + 1][r - 1][i][j]) %= mod;
		}
	}
	return;
}

inline void fuck3(int l, int r)
{
	int i, j, p, q;
	for (i = 0; i <= 2; ++ i) for (j = 0; j <= 2; ++ j)
	for (p = 0; p <= 2; ++ p) for (q = 0; q <= 2; ++ q)
	{
		if ((j == 1 && p == 1) || (j == 2 && p == 2)) continue;//next the '()' differt color
		(f[l][r][i][q] += f[l][mch[l]][i][j] * f[mch[l] + 1][r][p][q]) %= mod;
	}
	return;
}

inline void dfs(int l, int r)
{
	if (l + 1 == r) return (void)(fuck1(l, r));
	if (mch[l] == r) return dfs(l + 1, r - 1), (void)(fuck2(l, r));
	return dfs(l, mch[l]), dfs(mch[l] + 1, r), (void)(fuck3(l, r));
}
signed main()
{
	int i, j, k;
	scanf ("%s", c + 1);
	n = strlen(c + 1);
	for (i = 1; i <= n; ++ i)
	{
		if (c[i] == '(') st[++ tp] = i;
		else mch[st[tp]] = i, mch[i] = st[tp --];
	}
	dfs(1, n);
	for (i = 0; i <= 2; ++ i)
		for (j = 0; j <= 2; ++ j)
			(res += f[1][n][i][j]) %= mod;
	cout << res;
	return 0;
}


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

#define I inline
#define ri register int
#define int long long
#define ll long long
#define ull unsigned long long
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define rep(i,a,b) for(ri i=(a);i<=(b);++i)
#define dow(i,a,b) for(ri i=(a);i>=(b);--i)
#define go(i,u) for(ri i=lnk[u];i;i=nxt[i])
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define vec vector
#define que queue
#define pb push_back
#define lowbit(x) (x&(-x))
#define mem(f,x) memset(f,x,sizeof(f))

I int gi(){
	int x=0,f=0;char ch=getchar();
	while(!isdigit(ch)){f|=ch=='-',ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48,ch=getchar();}
	return f?-x:x;
}

I void pi(int x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)pi(x/10);
	putchar(x%10+48);
}
I void pib(int x){pi(x);putchar(' ');}
I void pin(int x){pi(x);putchar('\n');}

const int N = 2e3+5;
const int mo = 998244535;

stack<int> st;
char s[N];
int dp[N][N][3][3],match[N];
void dfs(int l,int r){
	if(l+1==r){rep(i,1,2)dp[l][r][0][i]=dp[l][r][i][0]=1;}
	else if(match[l]==r){
		dfs(l+1,r-1);
		rep(i,0,2)rep(j,0,2){
			if(j!=1)dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mo;
			if(j!=2)dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mo;
			if(i!=1)dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mo;
			if(i!=2)dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mo;
		}
	}
	else{
		dfs(l,match[l]);dfs(match[l]+1,r);
		rep(i,0,2)rep(j,0,2)rep(p,0,2)rep(q,0,2){
			if((j==1&&p==1) || (j==2&&p==2))continue;
			dp[l][r][i][q]=(dp[l][r][i][q]+dp[l][match[l]][i][j]*dp[match[l]+1][r][p][q])%mo;
		}
	}
}

signed main(){
	for(int t=1;t;--t){
		mem(dp,0);
		scanf("%s",s);
		int n=strlen(s);
		rep(i,0,n-1){
			if(s[i]=='(')st.push(i);
			else match[st.top()]=i,match[i]=st.top(),st.pop();
		}
		dfs(0,n-1);
		int ans=0;
		rep(i,0,2)rep(j,0,2)ans=(ans+dp[0][n-1][i][j])%mo;
		pin(ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define int long long
#define rev(a) (cr==1?2:1)
#define int long long
#define rep2(i) for(int i=0;i<=2;i++)
using namespace std;
const int N=705,mod=1000000007;
int n,match[N],f[N][N][3][3];
int dfs(int l,int r,int cl,int cr) {
	if(f[l][r][cl][cr]!=-1) return f[l][r][cl][cr];
	else if(r-l==1) return f[l][r][cl][cr]=(cl>0)!=(cr>0);

	f[l][r][cl][cr]=0;
	if(match[l]==r) {
		if(!cl&&!cr||cl&&cr) return f[l][r][cl][cr]=0;
		else if(cl==0)
			return f[l][r][cl][cr]=(dfs(l+1,r-1,1,0)+dfs(l+1,r-1,2,0)
							+dfs(l+1,r-1,0,rev(cr))
							+dfs(l+1,r-1,1,rev(cr))
							+dfs(l+1,r-1,2,rev(cr))
							+dfs(l+1,r-1,0,0))%mod;
		else if(cr==0)
			return f[l][r][cl][cr]=(dfs(l+1,r-1,0,1)+dfs(l+1,r-1,0,2)
							+dfs(l+1,r-1,rev(cl),0)
							+dfs(l+1,r-1,rev(cl),1)
							+dfs(l+1,r-1,rev(cl),2)
							+dfs(l+1,r-1,0,0))%mod;
	} else {
		rep2(i) rep2(j) f[l][r][i][j]=0;
		rep2(i) rep2(j) rep2(k) rep2(p)
			if(j&&k&&(j==k)) continue;
			else (f[l][r][i][p]+=dfs(l,match[l],i,j)*dfs(match[l]+1,r,k,p))%=mod;
		return f[l][r][cl][cr];
	}
}
char s[N];
signed main() {
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	memset(f,-1,sizeof(f));
	scanf("%s",s+1); int n=strlen(s+1);
	stack<int>st;
	for(int i=1;i<=n;i++) {
		if(s[i]=='(') st.push(i);
		else match[st.top()]=i,st.pop();
	}
	int ans=0;
	rep2(i) rep2(j) (ans+=dfs(1,n,i,j))%=mod;
	printf("%lld",ans);
	return 0;
}


n=int(input())
child={}
for i in range(1,n+1):
    child[i]=[]
parents=set()
for i in range(n-1):
    a=int(input())
    parents.add(a)
    child[a].append(i+2)
stat=True
for i in parents:
    cnt=0
    for j in child[i]:
        if(len(child[j])==0):
            cnt+=1
    if(cnt<3):
        stat=False
        break
if(stat==False):
    print("NO")
else:
    print("YES")


n = gets.to_i
x = (n-1).times.map{gets.to_i-1}

ha = Array.new(n, true)
ha[0] = false
x.each{|t| ha[t] = false}

cnt = Array.new(n, 0)
x.each.with_index{|t,i| cnt[t]+=1 if ha[i+1]}

puts (n.times.all?{|i| ha[i]||cnt[i]>2}) ? 'Yes' : 'No'


import sys as sys
import math as math
#n = int( sys.stdin.readline())

integers = map(int,sys.stdin.readline().split())

# root
n = integers[0]

mn = range(n-1)
for i in range(0,n-1):
	m = map(int,sys.stdin.readline().split())
	mn[i] = m[0]

listofzeros = [0] * n

for i in range(0,n-1):
    listofzeros[mn[i]-1]=listofzeros[mn[i]-1]+1

ss = 0
for i in range(0,len(listofzeros)):
    if listofzeros[i]>0:
        s = 0
        for j in range(0,n-1):
            if mn[j]==i+1 and listofzeros[j+1] == 0:
                s=s+1
        if s < 3:
            ss = 1

if ss ==1:
    print 'NO'
else:
    print 'YES'


n = int(raw_input())
dict = {}
counter = 1
for i in range(n-1):
	a = raw_input()
	if(dict.has_key(a)):
		dict[a] += [counter + 1]
	else:
		dict[a] = [counter + 1]
	counter += 1

list = dict.keys()
list = [int(j) for j in list]
for i in list:
	dict[str(i)] = [x for x in dict[str(i)] if x not in list]

flag = 0

for i in dict.keys():
	if len(dict[i]) < 3:
		flag = 1
		break
if flag == 1:
	print "No"
else:
	print "Yes"


n = int(raw_input())
chs = [0 for i in xrange(n)]
leaf = [0 for i in xrange(n)]
ps = [0 for i in xrange(n)]
for i in xrange(1, n):
    p = int(raw_input()) - 1
    ps[i] = p
    chs[p] += 1
    leaf[p] += 1
for i in xrange(1, n):
    if chs[i]:
        leaf[ps[i]] -= 1
# print leaf
print 'Yes' if all([bool(leaf[i] == 0 or leaf[i] >= 3) for i in xrange(n)]) else 'No'


n = int(raw_input())
chs = [0 for i in xrange(n)]
leaf = [0 for i in xrange(n)]
ps = [0 for i in xrange(n)]
for i in xrange(1, n):
    p = int(raw_input()) - 1
    ps[i] = p
    chs[p] += 1
    leaf[p] += 1
for i in xrange(n):
    if chs[i]:
        leaf[ps[i]] -= 1
# print leaf
# print chs
print 'Yes' if all([bool(leaf[i] == 0 or leaf[i] >= 3) for i in xrange(n)]) else 'No'


n = int(raw_input())
chs = [0 for i in xrange(n)]
leaf = [0 for i in xrange(n)]
ps = [0 for i in xrange(n)]
for i in xrange(n-1):
    p = int(raw_input()) - 1
    ps[i] = p
    chs[p] += 1
    leaf[p] += 1
for i in xrange(1, n):
    if chs[i]:
        leaf[ps[i]] -= 1

print 'Yes' if all([bool(leaf[i] == 0 or leaf[i] >= 3) for i in xrange(n)]) else 'No'


n = int(raw_input())
chs = [0 for i in xrange(n)]
leaf = [0 for i in xrange(n)]
ps = [0 for i in xrange(n)]
for i in xrange(1, n):
    p = int(raw_input()) - 1
    ps[i] = p
    chs[p] += 1
    leaf[p] += 1
for i in xrange(1, n):
    if chs[i]:
        leaf[ps[i]] -= 1
# print leaf
# print chs
print 'Yes' if all([bool(chs[i] == 0 or leaf[i] >= 3) for i in xrange(n)]) else 'No'


'''
tt = int(raw_input())
a = map(int, raw_input().split())
for i in xrange(tt):
a = map(int, (' '.join(n for n in raw_input())).split())
'''

n = int(raw_input())
tree = {}
child = {}
for t in xrange(1, n):
    tree[t+1] = int(raw_input())

for c in tree:
    p = tree[c]
    if p in child:
        child[p].append(c)

    else:
        child[p] = [c]

leaf = [0]*(n+1)
for i in xrange(1, n+1):

    if i not in child:
        leaf[i] = 1

count = [0]*(n+1)
for c in tree:
    p = tree[c]
    if leaf[c] == 1:
        count[p] += 1

# print child
# print count, leaf
ans = "Yes"
for i in xrange(1, n+1):

    if i in child:
        if count[i] >= 3:
            ans = "Yes"

        else:
            ans = "No"
            break

print ans


from collections import defaultdict
def main():
    n=input()
    dic=defaultdict(list)
    p=0
    u=[]
    k=[0]*(n)
    for i in xrange(n-1):
        j=input()
        u.append(j)
        dic[j].append(i+2)
    for i in set(u):
        c=0
        if len(dic[i])>=3:
            for j in dic[i]:
                if len(dic[j])==0:
                    c+=1
                #print j,dic[i],c
            if c<3:
                print "No"
                p=1
                break
        else:
            print "No"
            p=1
            break

    if p==0:
        print "Yes"

main()


def dfs(c, f, g):
    if len(g[c]) == 1: return 1
    cnt = 0
    for i in g[c]:
        if i == f: continue
        cnt += dfs(i, c, g)
    if cnt == 1 or cnt == 2:
        print 'No'
        exit(0)
    return 0
t = [[] for _ in xrange(1005)]
n = input()
for i in xrange(2, n+1):
    x = input()
    t[x].append(i)
    t[i].append(x)
dfs(1, -1, t)
print 'Yes'


def dfs(c, f, g):
    if len(g[c]) == 1: return 1
    cnt = 0
    for i in g[c]:
        if i == f: continue
        cnt += dfs(i, c, g)
    if cnt < 3:
        print 'No'
        exit(0)
    return 0
t = [[] for _ in xrange(1005)]
n = input()
for i in xrange(2, n+1):
    x = input()
    t[x].append(i)
    t[i].append(x)
dfs(1, -1, t)
print 'Yes'


def dfs(c, f, t):
    ans, cnt = 0, 0
    if len(t[c]) == 1: return ans, 1
    for i in t[c]:
        if i == f: continue
        x, y = dfs(i, c, t)
        if x: ans = 1
        cnt += y
    if cnt < 3: return 1, cnt
    return ans, 0
n = input()
t = [[] for i in xrange(1005)]
for i in xrange(2, n+1):
    x = input()
    t[i].append(x)
    t[x].append(i)
ans, cnt = dfs(1, -1, t)
print 'No' if ans else 'Yes'


n = int(raw_input())

tree = [list() for _ in xrange(n+1)]

for i in xrange(1, n):
    p = int(raw_input())
    tree[p].append(i+1)

for v in tree[1:]:
    lists_cnt = 0
    if len(v) > 0:
        for child in v:
            if len(tree[child]) == 0:
                lists_cnt += 1

        if lists_cnt < 3:
            print 'No'
            exit(0)

print 'Yes'


n = int(raw_input())
p = [1, 1] + [int(raw_input()) for _ in xrange(n - 1)]
l = [1] * (n + 1)
d = [0] * (n + 1)
ans = 1
for i in xrange(n, 0, -1):
    l[p[i]] = 0
    d[p[i]] += l[i]
    if not l[i] and d[i] < 3:
        ans = 0
print "Yes" if ans else "No"


n = input()

num = { }
arr = [ ]

for _ in range(n-1):
    arr.append( input() )

for i in set(arr):
    num[i]=0

for i in range(1 , len(arr)+1 ):
    if ( arr.count(i+1) == 0):
        num[arr[i-1]] += 1

status = 1

for i in num.keys():
    if num[i] < 3:
        status = 0
        break

print [ "No" , "Yes"][status]


def IsLeaf(edges,i):
    if edges[i] == []:
        return True
    else:
        return False

def Has3LeafChilds(edges,i):
    count = 0
    for j in edges[i]:
        if IsLeaf(edges,j):
            count += 1

    if count >= 3:
        return True
    else:
        return False

def IsSpruce(edges):
    for i in edges:
        if edges[i] != [] and not Has3LeafChilds(edges,i):
            return False

    return True

def Spruce():
    n = int(raw_input())
    edges = {}
    for i in range(1,n+1):
        edges[i] = []
    for i in range(2,n+1):
        index = int(raw_input())
        edges[index].append(i)

    if IsSpruce(edges):
        print 'Yes'
    else:
        print 'No'

Spruce()


import sys
v = int(raw_input())

node_stat = { 1 : True }
node_map = {}
node_c = 2
for x in range(v-1):
    p = int(raw_input())
    if p not in node_map:
        node_map[p] = []
    node_map[p].append(node_c)
    node_stat[p] = True

p_c = 0

for i,j in node_map.iteritems():
    if i in node_stat:
        p_c = p_c + 1
        cnt = 0
        for cs in j:
            if cs not in node_stat:
                cnt = cnt + 1
        if cnt < 3:
            print "No"
            sys.exit()

if p_c == 0:
    print "No"
else:
    print "Yes"


import sys
v = int(raw_input())

node_stat = { 1 : True }
node_map = {}
node_c = 2
for x in range(v-1):
    p = int(raw_input())
    if p not in node_map:
        node_map[p] = []
    node_map[p].append(node_c)
    node_stat[p] = True
    node_c = node_c + 1

p_c = 0

for i,j in node_map.iteritems():
    if i in node_stat:
        p_c = p_c + 1
        cnt = 0
        for cs in j:
            if cs not in node_stat:
                cnt = cnt + 1
        if cnt < 3:
            print "No"
            sys.exit()

if p_c == 0:
    print "No"
else:
    print "Yes"


import sys
v = int(raw_input())

node_stat = { 1 : True }
node_map = {}
node_c = 2
for x in range(v-1):
    p = int(raw_input())
    if p not in node_map:
        node_map[p] = []
    node_map[p].append(node_c)
    node_stat[p] = True

for i,j in node_map.iteritems():
    if i in node_stat:
        cnt = 0
        for cs in j:
            if cs not in node_stat:
                cnt = cnt + 1
        if cnt < 3:
            print "No"
            sys.exit()

print "Yes"


n = input()
children = {}
for i in range(2,n+1):
    num=input()
    if num not in children:
        children[num]=[i]
    else:
        children[num].append(i)
flag=True
for child in children:
    if len(children[child])<3:
        flag=False
        break
    count=0
    for child2 in children[child]:
        if(child2 not in children):
            count += 1
    if(count<3):
        flag=False
        break

if(flag ): print "YES"
else: print "NO"


def do_it(trees):
    import collections
    a = collections.defaultdict(list)
    non_leaf = collections.defaultdict(int)
    for i in xrange(len(trees)):
        a[trees[i]].append(i+2)
        non_leaf[trees[i]] = 1

    for tr in a:
        tem_sum = 0
        for val in a[tr]:
            tem_sum += non_leaf[val]
        number_of_child_leaf = len(a[tr])-tem_sum
        if number_of_child_leaf <3: return "No"
    return "Yes"

n = int(raw_input())
trees = []
for i in range(n-1):
   trees.append(int(raw_input()))
print do_it(trees)


from collections import defaultdict

n = int(input())

leafs = {i for i in range(1,n+1)}
par = dict()

for i in range(2,n+1):
    parent = int(input())

    if parent in leafs:
        leafs.remove(parent)

    par[i] = parent

res = defaultdict(int)
for x in leafs:
    res[par[x]] += 1

sp = 0
for x in res.keys():
    if res[x] >= 3:
        sp += 1

if sp + len(leafs) == n:
    print("Yes")
else:
    print("No")


def solution():
    n = int(raw_input())
    g = [[] for _ in range(n)]
    for i in range(n)[1:]:
        idx = int(raw_input())
        g[idx - 1].append(i)
    for i in range(n):
        if len(g[i]) > 0:
            count = 0
            for idx in g[i]:
                if len(g[idx]) == 0:
                    count += 1
            if count < 3:
                return 'No'
    return 'Yes'

if __name__ == '__main__':
    print solution()


import sys

n = int(raw_input())

parents = [-1]

isleaf = [True]*n

for i in xrange(n-1):
    p = int(raw_input()) - 1
    parents.append(p)
    isleaf[p] = False

children = [0]*n

for i in range(1, n):
    if isleaf[i]:
        children[parents[i]] += 1

for i in xrange(n):
    if isleaf[i] == False and children[i] < 3:
        print "No"
        sys.exit()

print "Yes"


def bfs(s, v, l, r) :
	q = []
	q.append(s)
	while q :
		p = q.pop()
		c = 0
		for i in l[p] :
			if v[i] == 0 :
				if len(l[i]) == 0 :
					c += 1
				else :
					q.append(i)
				v[i] = 1
		#print c
		if c < 3 :
			return 0
	return 1

n = input()
l, v = [], []
l.append([])
v.append(0)
for i in range (1, n+1) :
	l.append([])
	v.append(0)
for i in range (1,n) :
	k = input()
	l[k].append(i+1)
p = 0
r = 0

if bfs(1, v, l, r) == 1 :
	print "Yes"
else :
	print "No"


n=input()
lst=[]
for i in  range(0,n):
  lst.append([])
#print lst
for i in range(1,n):
  s=input()
  lst[s-1].append(i)
c=0
#print lst
for i in range(0,n):
  if len(lst[i])>0:
    c2=0
    for j in range(0,len(lst[i])):
      if len(lst[lst[i][j]])==0:
        c2=c2+1
    if c2<3:
      c=1
if c==1:
  print "No"
else:
  print "Yes"


# -*- coding: utf-8 -*-
import sys

def readline(sep=None): return map(int, raw_input().split(sep))
def writeline(seq): print(" ".join(map(str, seq)))

def main():
    n, = readline()
    parent = [int(token) - 1 for token in sys.stdin.readlines()]

    children = [list() for __ in xrange(n)]

    for c, p in enumerate(parent):
        children[p].append(c + 1)

    for ch in children:
        if ch:
            spikes = sum(not bool(children[x]) for x in ch)
            if spikes < 3:
                print "No"
                break
    else:
        print "Yes"

main()


def has3leaf(v, h):
    ee = map(str, h[v].strip(',').split(','))
    c=len(ee)
    for e in ee:
        if h.get(int(e)):
            c-=1
    if c<3: return 0
    else: return 1

r=int(raw_input().strip())

l=list()
l.append(r)
for n in xrange(r-1):
    l.append(int(raw_input().strip()))

h=dict()
w=1
for i in l[1:]:
    h[i-1] = str(h.get(i-1,'')) + ','+str(w)
    w+=1

r=0
for e in h:
    ln=len(h[e].split(','))
    if ln < 3:
        continue
    r +=has3leaf(e, h)

if r==len(h): print 'Yes'
else: print 'No'


n = int(raw_input())
A=[False for i in range(n)]
A[0]=True
B=[[] for i in range(n)]

for i in range(n-1):
    x = int(raw_input())-1
    B[x].append(i+1)
    A[x]=True
#print A
#print B

def spruce(n,A,B):
    for i in range(n):
        if A[i]==True:
            ct=0
            for x in B[i]:
                if A[x]==False:
                    ct+=1
            if ct<3:
                return False
                break
        else:
            continue
    return True

if spruce(n,A,B):
    print 'Yes'
else:
    print 'No'


n = input()
children = [set() for i in xrange(n)]
parents = set()
parents.add(0)
for i in xrange(n - 1):
    p = input() - 1
    children[p].add(i + 1)
    parents.add(p)
for p in parents:
    if len(children[p] - parents) < 3:
        print("No")
        exit()
print("Yes")


n = input()
P = [-1]+[input()-1 for _ in range(n-1)]
C1 = [0]*n
for i in range(1,n):
  C1[P[i]] += 1
C2 = [0]*n
for i in range(1,n):
  if C1[i]==0:
    C2[P[i]] += 1
ans = "Yes"
for i in range(n):
  if C1[i]>0 and C2[i]<3:
    ans = "No"
print ans


n = int(raw_input())

p = [None] * n
d = [0] * n
for i in xrange(1, n):
    parent = int(raw_input())
    p[i] = parent - 1
    d[i] += 1
    d[parent - 1] += 1

c = [0] * n
for i in xrange(n):
    if d[i] == 1:
        c[p[i]] += 1

elka = 'Yes'
for i in xrange(n):
    if d[i] > 1 and c[i] < 3:
        elka = 'No'

print elka


n = input()
a1 = dict()
for i in xrange(2,n+1):
	n1 = input()
	if n1 in a1:
		a1[n1].append(i)
	else:
		a1[n1] = [i]
#print a1
for i in a1:
	s = 0
	for j in a1[i]:
		if j not in a1:
			s+=1
	if s<3:
		print 'No'
		exit(0)
print 'Yes'


n = int(raw_input())
l = []
for i in range(n-1):
    x = int(raw_input())
    l.append(x)
w = set(range(1,n+1))-set(l)
d = 1
for i in set(l):
    m = 0
    for j in range(len(l)):
        if l[j]==i and (j+2 in w):
            m += 1
    if m<3:
        print "No"
        d = 0
        break
if d:
    print "Yes"


import sys
n = int(raw_input())

arr = [[] for i in xrange(1001)]
for i in xrange(n-1):
  idx = int(raw_input())
  arr[idx-1].append(i+1)

def find(idx, arr):
  if len(arr[idx]) == 0: return 1
  cnt = 0
  for child in arr[idx]:
    cnt += find(child, arr)
  if cnt < 3:
    print "No"
    sys.exit()
  return 0

find(0, arr)
print "Yes"


def mp():
	return map(int, raw_input().split())
n=input()
a=[[] for i in range(n)]
for i in xrange(n-1):
	ai=input()
	#print ai
	a[ai-1].append(i+1)
#print a
b=1
for i in a:
	t=0
	for j in i:
		if len(a[j])==0:t+=1
	if t<3 and len(i)!=0:
		b=0
		#print i
if b==1:
	print "Yes"
else:
	print "No"


def mp():
		return map(int, raw_input().split())
	n=input()
	a=[[] for i in range(n)]
	for i in xrange(n-1):
		ai=input()
		#print ai
		a[ai-1].append(i+1)
	#print a
	b=1
	for i in a:
		t=0
		for j in i:
			if len(a[j])==0:t+=1
		if t<3 and len(i)!=0:
			b=0
			#print i
	if b==1:
		print "Yes"
	else:
		print "No"


# import sys

# sys.stdin = open('test', 'r')

n = int(raw_input())
arr = [[0, True, []] for x in xrange(n)]
for i in xrange(1, n):
    x = int(raw_input()) - 1
    arr[i][0] = x
    arr[x][1] = False
    arr[x][2].append(i)

for node in arr:
    if not node[1]:
        counter = 0
        for child in node[2]:
            if arr[child][1]:
                counter += 1
                if counter >= 3:
                    break
        else:
            print "No"
            exit(0)

print "Yes"


from sys import stdin

n =int( stdin.readline().rstrip().split()[0])
V=[]
for i in range (n-1):
        V+=[int( stdin.readline().rstrip().split()[0])]
tree={}

for i in range(2,n+1):
        if V[i-2] in tree:
                tree[V[i-2]]+=[i]
        else :
                tree[V[i-2]]=[i]

for elk, elv in tree.items():
        sum=0
        for e in elv:
                if e not in tree:
                        sum+=1
        if sum<3:
                print "No"
                exit()
print "Yes"


n=int(input())
child =[0 for i in range(n+1)]
node=[0 for i in range(n+1)]
for i in range(2,n+1):
  u=(int(input()))
  node[i]=u
for i in range(2,n+1):
  child[node[i]]+=1
  if node[node[i]]==-1:continue
  child[node[node[i]]]-=1
  node[node[i]]=-1
f="Yes"
for i in  range(1,n+1):
  if child[i]<3 and child[i]!=0:
    f="No"
    break
if child[1]==0:f="No"
print f


n=int(input())
child =[0 for i in range(n+1)]
node=[0 for i in range(n+1)]
for i in range(2,n+1):
  u=(int(input()))
  node[i]=u
for i in range(2,n+1):
  child[node[i]]+=1
  if node[node[i]]==-1:continue
  child[node[node[i]]]-=1
  node[node[i]]=-1
f="Yes"
for i in  range(1,n+1):
  if child[i]<3 and child[i]!=0:
    f="No"
    break
print f


n=int(input())
dic={}
dic[1]=1
child =[0 for i in range(n+1)]
node=[0 for i in range(n+1)]
for i in range(2,n+1):
  u=(int(input()))
  node[i]=u
  if u not in dic:
    dic[u]=1
for i in range(2,n+1):
  child[node[i]]+=1
  if node[node[i]]==-1:continue
  child[node[node[i]]]-=1
  node[node[i]]=-1
f="Yes"
for i in  range(1,n+1):
  if child[i]<3 and child[i] in dic:
    f="No"
    break
if child[1]<3:f="No"
print f


n=int(input())
dic={}
dic[1]=1
child =[0 for i in range(n+1)]
node=[0 for i in range(n+1)]
for i in range(2,n+1):
  u=(int(input()))
  node[i]=u
  if u not in dic:
    dic[u]=1
for i in range(2,n+1):
  child[node[i]]+=1
  if node[node[i]]==-1:continue
  child[node[node[i]]]-=1
  node[node[i]]=-1
f="Yes"
for i in  range(1,n+1):
  if child[i]<3 and child[i] in dic:
    f="No"
    break
if child[1]==0:f="No"
print f


n=int(input())
dic={}
dic[1]=1
child =[0 for i in range(n+1)]
node=[0 for i in range(n+1)]
for i in range(2,n+1):
  u=(int(input()))
  node[i]=u
  if u not in dic:
    dic[u]=1
for i in range(2,n+1):
  child[node[i]]+=1
  if node[node[i]]==-1:continue
  child[node[node[i]]]-=1
  node[node[i]]=-1
f="Yes"
'''print node
print child
print dic'''
for i in  range(1,n+1):
  if child[i]<3 and i in dic:
    f="No"
    break
#if child[1]<3:f="No"
print f


n=int(input())
dic={}
dic[1]=1
child =[0 for i in range(n+1)]
node=[0 for i in range(n+1)]
for i in range(2,n+1):
  u=(int(input()))
  node[i]=u
  if u not in dic:
    dic[u]=1
for i in range(2,n+1):
  child[node[i]]+=1
  if node[node[i]]==-1:continue
  child[node[node[i]]]-=1
  node[node[i]]=-1
f="Yes"
print node
print child
print dic
for i in  range(1,n+1):
  if child[i]<3 and i in dic:
    f="No"
    break
#if child[1]<3:f="No"
print f


n=input()
d={}
pre_root=1
for i in range(2,n+1):
    r=input()
    if r<>pre_root and r<i:
        d[pre_root]-=1
    d[r]=d.get(r,0)+1
    pre_root=r
if min(d.itervalues())>=3:
    print 'Yes'
else:
    print 'No'


n=input()
d={}
p={}
f=[0]*(n+1)
for i in range(2,n+1):
    r=input()
    p[i]=r
    if r<>1 and f[r]==0:
        d[p[r]]-=1
        f[r]=1
    d[r]=d.get(r,0)+1
if min(d.itervalues())>=3:
    print 'Yes'
else:
    print 'No'


from sys import stdin
lines = stdin.readlines()
n = int(lines[0])
dikte = {}

for i in range(1,n):
    c = int(lines[i])
    if c not in dikte:
        dikte[c] = [i+1]
    else:
        dikte[c].append(i+1)

def isleaf(x,dikte):
    nonleaf = []
    leaf = []
    for i in range(1,x+1):
        if i in dikte:
            nonleaf.append(i)
        else:
            leaf.append(i)
    return (nonleaf,leaf)
x = isleaf(n,dikte)[0]
y = isleaf(n,dikte)[1]
def final(x,y,dikte):

    for i in x:
        summ = 0
        for j in dikte[i]:
            if j in y and j not in x:
                summ += 1
        if summ < 3:
            return "No"
    return "Yes"
print final(x,y,dikte)


from sys import stdin
lines = stdin.readlines()
n = int(lines[0])
dikte = {}

for i in range(1,n):
    c = int(lines[i])
    if c not in dikte:
        dikte[c] = [i+1]
    else:
        dikte[c].append(i+1)

def isleaf(x,dikte):
    nonleaf = []
    leaf = []
    for i in range(1,x+1):
        if i in dikte:
            nonleaf.append(i)
        else:
            leaf.append(i)
    return (nonleaf,leaf)
x = isleaf(n,dikte)[0]
y = isleaf(n,dikte)[1]
def final(x,y,dikte):
    summ = 0
    for i in x:
        for j in dikte[i]:
            if j in y:
                summ += 1
        if summ < 3:
            return "No"
    return "Yes"
print final(x,y,dikte)


n = int(raw_input())
L = [True for i in range(n)]
L[0] = False
I = [None]*n
for i in range(n-1):
    c = int(raw_input())
    L[c-1] = False
    I[i+1] = c-1

leaf = []
parent = []
for i in range(n):
    if L[i] : leaf.append(i)
    else: parent.append(i)

cnt = [0 for i in range(n)]

for i in leaf:
    cnt[I[i]] += 1

ans = True
for i in parent:
    if cnt[i] < 3 : ans = False

if ans : print "Yes"
else: print "No"


import sys

n = int(sys.stdin.readline())
ind = [0] * n
oud = [0] * n

ch = [[] for i in xrange(n)]

for i in xrange(n - 1):
    a = int(sys.stdin.readline())
    ind[i + 1] += 1
    oud[a - 1] += 1
    ch[a - 1].append(i + 1)

for i in xrange(n):
    if oud[i] > 0:
        count = 0
        for x in ch[i]:
            if oud[x] == 0:
                count += 1
                if count == 3:
                    break
        if count < 3:
            print "No"
            exit()

print "Yes"


import sys

n = int(raw_input())

parents = []

for i in range(n-1):
	parents.append(int(raw_input()))

non_leaf = {}

leaf = []

non_leaf[1] = 0

for i in range(0,len(parents)):
	non_leaf[parents[i]] = 0

# print non_leaf

for i in range(len(parents)):
	if i+2 not in non_leaf:
		leaf.append(i+1)

# print leaf

for i in leaf:
	non_leaf[parents[i-1]] += 1

# print non_leaf

flag = 0

for i in non_leaf:
	if non_leaf[i] < 3:
		flag = -1
		break

if flag == 0:
	print 'Yes'
else:
	print 'No'


import sys
ch=[]
pa = []
for i in range(1001):
    pa.append([])
l=int(input())
for i in range(l+2):
    ch.append(0)
for i in range(l-1):
    temp=int(input())
    pa[temp].append(i+2)
    ch[temp]+=1
for i in range(l):
    ct=0
    if(ch[i]==0):
        continue
    for j in range(len(pa[i])):
        if(ch[pa[i][j]]==0):
            ct+=1
    if(ct<3):
        print("No\n")
        sys.exit()
print("Yes\n")
sys.exit()


n = input()

l1 = [0]*(n+1)

l2 = [[] for _ in range((n+1))]

for i in range(n-1):

    index = input()

    l1[index] += 1

    l2[index].append(i+2)

is_spruce = True

for _ in l2:

    if len(_):

        c = 0

        for __ in _:

            c += (l1[__] == 0)

        if c < 3:

            is_spruce = False

            break

if is_spruce:

    print "Yes"

else:

    print "No"


n = input()
adj = [[] for i in range(n+1)]
for i in range(1,n):
    m = input()
    adj[m].append(i+1)
f = 0
for i in range(1,n+1):
    if len(adj[i]):
        q = 0
        for j in range(len(adj[i])):
            if len(adj[adj[i][j]])==0:
                q+=1
        if q<3:
            f=1
            break
if f:
    print 'No'
else:
    print 'Yes'


class G:
    def __init__(self,v):
        self.v = v
        self.graph = [[] for _ in range(v)]
    def connect(self,u,v):
        self.graph[u].append(v) # u is the parent of v

def isSpruceUtil(g,src):
    leaf = 0
    spruce = True
    for i in range(len(g.graph[src])):
        if len(g.graph[g.graph[src][i]])==0:
            leaf += 1
        else:
            spruce = spruce and isSpruceUtil(g,g.graph[src][i])
    if leaf >= 3 and spruce:
        return True
    else:
        False

def isSpruce(g):
    return isSpruceUtil(g,0)

def solve():
    n = int(raw_input())
    g = G(n)
    for i in range(1,n,1):
        parent = int(raw_input())
        g.connect(parent-1,i)
    if isSpruce(g):
        print("Yes")
    else:
        print("No")
if __name__ == "__main__":
    solve()


n = input()
fa = [0]*(n+1)
p = [0]*(n+1)
g = [0]*(n+1)

for i in range(2,n+1):
	fa[i] = input()

for i in range(2,n+1):
	p[fa[i]] += 1

for i in range(1, n+1):
	if p[i] == 0 :
		g[fa[i]] +=1

ans = "Yes"

for i in range(1, n):
	if p[i] != 0:
		if g[i] <3:
			ans ="No"
print ans


n = input()
fa = [0]*(n+1)
p = [0]*(n+1)
g = [0]*(n+1)

for i in range(2,n+1):
	fa[i] = input()

for i in range(2,n+1):
	print fa[i]
	p[fa[i]] += 1

for i in range(1, n+1):
	if p[i] == 0 :
		g[fa[i]] +=1

ans = "Yes"

for i in range(1, n):
	if p[i] != 0:
		if g[i] <3:
			ans ="No"
print ans