import
java.util.ArrayList;
import
java.util.Collections;
public
class
Product {
static
class
Edge
implements
Comparable<Edge> {
int
first, second, weight;
Edge(
int
x,
int
y,
int
w)
{
this
.first = x;
this
.second = y;
this
.weight = w;
}
@Override
public
int
compareTo(Edge edge)
{
return
this
.weight - edge.weight;
}
}
static
int
mod =
1000000007
;
static
int
power(
int
x,
int
y,
int
p)
{
int
res =
1
;
x = x % p;
while
(y >
0
) {
if
((y &
1
) ==
1
)
res = (res * x) % p;
y = y >>
1
;
x = (x * x) % p;
}
return
res;
}
static
int
size[] =
new
int
[
300005
];
static
int
freq[] =
new
int
[
300004
];
static
ArrayList<Edge> edges =
new
ArrayList<Edge>();
static
void
initialize(
int
Arr[],
int
N)
{
for
(
int
i =
0
; i < N; i++) {
Arr[i] = i;
size[i] =
1
;
}
}
static
int
root(
int
Arr[],
int
i)
{
while
(Arr[i] != i) {
i = Arr[i];
}
return
i;
}
static
void
weighted_union(
int
Arr[],
int
size[],
int
A,
int
B)
{
int
root_A = root(Arr, A);
int
root_B = root(Arr, B);
if
(size[root_A] < size[root_B]) {
Arr[root_A] = Arr[root_B];
size[root_B] += size[root_A];
}
else
{
Arr[root_B] = Arr[root_A];
size[root_A] += size[root_B];
}
}
static
void
AddEdge(
int
a,
int
b,
int
w)
{
edges.add(
new
Edge(a, b, w));
}
static
void
MakeTree()
{
AddEdge(
1
,
2
,
1
);
AddEdge(
1
,
3
,
3
);
AddEdge(
3
,
4
,
2
);
}
static
int
MinProduct()
{
int
result =
1
;
Collections.sort(edges);
for
(
int
i = edges.size() -
1
; i >=
0
; i--) {
int
curr_weight = edges.get(i).weight;
int
Node1 = edges.get(i).first;
int
Node2 = edges.get(i).second;
int
Root1 = root(freq, Node1);
int
Set1_size = size[Root1];
int
Root2 = root(freq, Node2);
int
Set2_size = size[Root2];
int
prod = Set1_size * Set2_size;
int
Product = power(curr_weight, prod, mod);
result
= ((result % mod) * (Product % mod)) % mod;
weighted_union(freq, size, Node1, Node2);
}
return
result % mod;
}
public
static
void
main(String[] args)
{
int
n =
4
;
initialize(freq, n);
MakeTree();
System.out.println(MinProduct());
}
}