package main
import (
"bufio"
"fmt"
"os"
)
const MOD = 1000000007
func modInverse(n int64) int64 {
return power(n, MOD-2)
}
func power(base, exp int64) int64 {
var res int64 = 1
base %= MOD
for exp > 0 {
if exp%2 == 1 {
res = (res * base) % MOD
}
base = (base * base) % MOD
exp /= 2
}
return res
}
var sumA []int64
var sumD []int64
var lazy []int64
func build(node, l, r int) {
lazy[node] = 1
if l == r {
sumD[node] = 1
sumA[node] = 0
return
}
mid := (l + r) / 2
build(2*node, l, mid)
build(2*node+1, mid+1, r)
sumD[node] = (sumD[2*node] + sumD[2*node+1]) % MOD
sumA[node] = (sumA[2*node] + sumA[2*node+1]) % MOD
}
func push(node int) {
if lazy[node] != 1 {
lz := lazy[node]
left := 2 * node
right := 2*node + 1
lazy[left] = (lazy[left] * lz) % MOD
sumA[left] = (sumA[left] * lz) % MOD
sumD[left] = (sumD[left] * lz) % MOD
lazy[right] = (lazy[right] * lz) % MOD
sumA[right] = (sumA[right] * lz) % MOD
sumD[right] = (sumD[right] * lz) % MOD
lazy[node] = 1
}
}
func updateMul(node, l, r, ql, qr int, val int64) {
if ql <= l && r <= qr {
lazy[node] = (lazy[node] * val) % MOD
sumA[node] = (sumA[node] * val) % MOD
sumD[node] = (sumD[node] * val) % MOD
return
}
push(node)
mid := (l + r) / 2
if ql <= mid {
updateMul(2*node, l, mid, ql, qr, val)
}
if qr > mid {
updateMul(2*node+1, mid+1, r, ql, qr, val)
}
sumA[node] = (sumA[2*node] + sumA[2*node+1]) % MOD
sumD[node] = (sumD[2*node] + sumD[2*node+1]) % MOD
}
func updateAddA(node, l, r, idx int, val int64) {
if l == r {
sumA[node] = (sumA[node] + val) % MOD
return
}
push(node)
mid := (l + r) / 2
if idx <= mid {
updateAddA(2*node, l, mid, idx, val)
} else {
updateAddA(2*node+1, mid+1, r, idx, val)
}
sumA[node] = (sumA[2*node] + sumA[2*node+1]) % MOD
}
func queryA(node, l, r, ql, qr int) int64 {
if ql <= l && r <= qr {
return sumA[node]
}
push(node)
mid := (l + r) / 2
var res int64 = 0
if ql <= mid {
res = (res + queryA(2*node, l, mid, ql, qr)) % MOD
}
if qr > mid {
res = (res + queryA(2*node+1, mid+1, r, ql, qr)) % MOD
}
return res
}
func queryD(node, l, r, idx int) int64 {
if l == r {
return sumD[node]
}
push(node)
mid := (l + r) / 2
if idx <= mid {
return queryD(2*node, l, mid, idx)
}
return queryD(2*node+1, mid+1, r, idx)
}
type Query struct {
typ int
p int
v int
newIdx int
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
buf := make([]byte, 1024*1024)
scanner.Buffer(buf, 10*1024*1024)
nextInt := func() int {
scanner.Scan()
res := 0
for _, v := range scanner.Bytes() {
res = res*10 + int(v-'0')
}
return res
}
v1 := nextInt()
q := nextInt()
queries := make([]Query, q)
N := 1
adj := make([][]int, q+2)
parent := make([]int, q+2)
for i := 0; i < q; i++ {
typ := nextInt()
if typ == 1 {
p := nextInt()
v := nextInt()
N++
queries[i] = Query{typ: 1, p: p, v: v, newIdx: N}
adj[p] = append(adj[p], N)
parent[N] = p
} else {
u := nextInt()
queries[i] = Query{typ: 2, p: u}
}
}
in := make([]int, N+1)
out := make([]int, N+1)
timer := 0
var dfs func(int)
dfs = func(u int) {
timer++
in[u] = timer
for _, v := range adj[u] {
dfs(v)
}
out[u] = timer
}
dfs(1)
sumA = make([]int64, 4*(N+1))
sumD = make([]int64, 4*(N+1))
lazy = make([]int64, 4*(N+1))
build(1, 1, N)
deg := make([]int64, N+1)
for i := 1; i <= N; i++ {
deg[i] = 1
}
dx := queryD(1, 1, N, in[1])
updateAddA(1, 1, N, in[1], (int64(v1)*dx)%MOD)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
for _, qry := range queries {
if qry.typ == 1 {
p := qry.p
v := qry.v
newIdx := qry.newIdx
dx := queryD(1, 1, N, in[newIdx])
val := (int64(v) * dx) % MOD
updateAddA(1, 1, N, in[newIdx], val)
oldDeg := deg[p]
newDeg := oldDeg + 1
deg[p] = newDeg
mul := (newDeg * modInverse(oldDeg)) % MOD
updateMul(1, 1, N, in[p], out[p], mul)
} else {
u := qry.p
ans := queryA(1, 1, N, in[u], out[u])
if u != 1 {
p := parent[u]
dp := queryD(1, 1, N, in[p])
ans = (ans * modInverse(dp)) % MOD
}
fmt.Fprintln(writer, ans)
}
}
}