from collections import defaultdict class UnionFind: def __init__(self,N,label=None,f=None,weighted=False,rollback=False): self.N=N self.parents=[None]*self.N self.size=[1]*self.N self.roots={i for i in range(self.N)} self.label=label if self.label!=None: self.label=[x for x in label] self.f=f self.weighted=weighted if self.weighted: self.weight=[0]*self.N self.rollback=rollback if self.rollback: self.operate_list=[] self.operate_set=[] def Find(self,x): stack=[] while self.parents[x]!=None: stack.append(x) x=self.parents[x] if not self.rollback: if self.weighted: w=0 for y in stack[::-1]: self.parents[y]=x w+=self.weight[y] self.weight[y]=w else: for y in stack[::-1]: self.parents[y]=x return x def Union(self,x,y,w=None): root_x=self.Find(x) root_y=self.Find(y) if self.rollback: self.operate_list.append([]) self.operate_set.append([]) if root_x==root_y: if self.weighted: if self.weight[y]-self.weight[x]==w: return True else: return False else: if self.size[root_x]v: u,v=v,u graph[v].append(u) cnt=[0]*N UF=UnionFind(N,label=[x for x in range(N)],f=max) edges=[] for x in range(N): for y in graph[x]: edges.append((UF.Label(x),UF.Label(y))) UF.Union(x,y) cnt[UF.Label(x)]+=1 G=Graph(N,edges=edges) parents,tour=G.SIV_DFS(UF.Label(N-1),parents=True,preorder=True) for x in tour: for y in G.graph[x]: if y==parents[x]: continue cnt[y]+=cnt[x] ans=1 mod=10**9+7 for x in range(N): ans*=R[x]+cnt[x] ans%=mod print(ans)