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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

vector<int> g[100010];
int sz[100010];
bool dame[100010];
vector<int> cent;
int a[100010];
ll res;

void compute_subtree_size(int v,int pre){
  sz[v]=1;
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    compute_subtree_size(nv,v);
    sz[v]+=sz[nv];
  }
}

void search_centroid(int v,int pre,int tot){
  bool is_cent=true;
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    search_centroid(nv,v,tot);
    if(sz[nv]>tot/2)is_cent=false;
  }
  if(tot-sz[v]>tot/2)is_cent=false;
  if(is_cent)cent.push_back(v);
}

void dfs(ll v,ll pre,vector<ll>& down,ll sum,ll summn){
  sum+=a[v]; minch(summn,sum);
  if(sum-summn<=0){
    assert(-sum>=0);
    down[-sum]++;
  }
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    dfs(nv,v,down,sum,summn);
  }
}

void dfs2(ll v,ll pre,const vector<ll>& down,ll sum,ll summx,ll i){
  sum+=a[v]; maxch(summx,sum);
  if(sum-summx>=0){
    ll up=sum;
    assert(up>=0);
    res+=down[up];
    if(up==0&&i==0){
      res++;
    }
  }
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    dfs2(nv,v,down,sum,summx,i);
  }
}

void dfs3(ll v,ll pre,ll sum,ll summn){
  sum+=a[v]; minch(summn,sum);
  if(sum-summn<=0){
    if(sum==0)res++;
  }
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    dfs3(nv,v,sum,summn);
  }
}

void solve_subprob(ll v){ // main
  compute_subtree_size(v,-1);
  cent.clear();
  search_centroid(v,-1,sz[v]);
  int c=cent[0];
  dame[c]=true;

  // devide
  for(int nv : g[c]){
    if(dame[nv])continue;
    solve_subprob(nv);
  }

  //dbg(c);
  dame[c]=false;
  compute_subtree_size(c,-1);
  ll szc=sz[c];
  // conquer
  rep(i,2){
    reverse(all(g[c]));
    vector<ll> down(szc+1,0);
    for(int nv : g[c]){
      if(dame[nv])continue;
      dfs2(nv,c,down,a[c],max(a[c],0),i);
      dfs(nv,c,down,0,0);
    }
  }
  dfs3(c,-1,0,0);
}


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

  int N;
  string s;
  cin>>N;
  cin>>s;
  rep(i,N){
    if(s[i]=='(')a[i]=1;
    else a[i]=-1;
  }
  rep(i,N-1){
    int b,c;
    cin>>b>>c;
    b--; c--;
    g[b].push_back(c);
    g[c].push_back(b);
  }
  solve_subprob(0);
  cout<<res<<endl;

  return 0;
}


### Prompt

Please formulate a cpp solution to the following problem:

Example

Input

2
()
1 2


Output

1

### Response

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

vector<int> g[100010];
int sz[100010];
bool dame[100010];
vector<int> cent;
int a[100010];
ll res;

void compute_subtree_size(int v,int pre){
  sz[v]=1;
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    compute_subtree_size(nv,v);
    sz[v]+=sz[nv];
  }
}

void search_centroid(int v,int pre,int tot){
  bool is_cent=true;
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    search_centroid(nv,v,tot);
    if(sz[nv]>tot/2)is_cent=false;
  }
  if(tot-sz[v]>tot/2)is_cent=false;
  if(is_cent)cent.push_back(v);
}

void dfs(ll v,ll pre,vector<ll>& down,ll sum,ll summn){
  sum+=a[v]; minch(summn,sum);
  if(sum-summn<=0){
    assert(-sum>=0);
    down[-sum]++;
  }
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    dfs(nv,v,down,sum,summn);
  }
}

void dfs2(ll v,ll pre,const vector<ll>& down,ll sum,ll summx,ll i){
  sum+=a[v]; maxch(summx,sum);
  if(sum-summx>=0){
    ll up=sum;
    assert(up>=0);
    res+=down[up];
    if(up==0&&i==0){
      res++;
    }
  }
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    dfs2(nv,v,down,sum,summx,i);
  }
}

void dfs3(ll v,ll pre,ll sum,ll summn){
  sum+=a[v]; minch(summn,sum);
  if(sum-summn<=0){
    if(sum==0)res++;
  }
  for(int nv : g[v]){
    if(nv==pre||dame[nv])continue;
    dfs3(nv,v,sum,summn);
  }
}

void solve_subprob(ll v){ // main
  compute_subtree_size(v,-1);
  cent.clear();
  search_centroid(v,-1,sz[v]);
  int c=cent[0];
  dame[c]=true;

  // devide
  for(int nv : g[c]){
    if(dame[nv])continue;
    solve_subprob(nv);
  }

  //dbg(c);
  dame[c]=false;
  compute_subtree_size(c,-1);
  ll szc=sz[c];
  // conquer
  rep(i,2){
    reverse(all(g[c]));
    vector<ll> down(szc+1,0);
    for(int nv : g[c]){
      if(dame[nv])continue;
      dfs2(nv,c,down,a[c],max(a[c],0),i);
      dfs(nv,c,down,0,0);
    }
  }
  dfs3(c,-1,0,0);
}


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

  int N;
  string s;
  cin>>N;
  cin>>s;
  rep(i,N){
    if(s[i]=='(')a[i]=1;
    else a[i]=-1;
  }
  rep(i,N-1){
    int b,c;
    cin>>b>>c;
    b--; c--;
    g[b].push_back(c);
    g[c].push_back(b);
  }
  solve_subprob(0);
  cout<<res<<endl;

  return 0;
}


```