#include <bits/stdc++.h>   using namespace std;   const int mod = 1000000007;   int get_inv(int x) {     return (x == 1) ? 1 : (mod - (long long)(mod / x) * get_inv(mod % x) % mod);   }   const int MaxN = 200010, MaxT = 1 << 19;   struct tree_node {     int k, sum;     int lazy;     tree_node() { k = lazy = 1; }   } T[MaxT];   int v[MaxN], deg[MaxN];   class Graph {    public:     int en[MaxN], next[MaxN], point[MaxN], tot;     void add_edge(int x, int y) {       next[++tot] = en[x];       en[x] = tot;       point[tot] = y;     }   } G;   int in[MaxN], out[MaxN];   int n, q;   int dfn;   void dfs(int now) {     in[now] = ++dfn;     for (int i = G.en[now]; i; i = G.next[i]) dfs(G.point[i]);     out[now] = dfn;   }   inline int mul(int &x, int v) { return (x = (long long)x * v % mod); }   inline int inc(int x, int v) {     x += v;     return x >= mod ? x - mod : x;   }   void add_lazy(int now, int lazy) {     mul(T[now].lazy, lazy);     mul(T[now].k, lazy);     mul(T[now].sum, lazy);   }   void push_down(int now) {     if (T[now].lazy != 1) {       add_lazy(now << 1, T[now].lazy);       add_lazy(now << 1 | 1, T[now].lazy);       T[now].lazy = 1;     }   }   void update(int now) { T[now].sum = inc(T[now << 1].sum, T[now << 1 | 1].sum); }   void modify_v(int l, int r, int x, int v, int now) {     if (l == r) {       T[now].sum = 1ll * T[now].k * v % mod;       return;     }     int mid = (l + r) >> 1;     push_down(now);     if (x <= mid)       modify_v(l, mid, x, v, now << 1);     else       modify_v(mid + 1, r, x, v, now << 1 | 1);     update(now);   }   void modify_k(int l, int r, int x, int y, int k, int now) {     if ((r < x) || (y < l)) return;     if ((x <= l) && (r <= y)) return add_lazy(now, k);     int mid = (l + r) >> 1;     push_down(now);     modify_k(l, mid, x, y, k, now << 1);     modify_k(mid + 1, r, x, y, k, now << 1 | 1);     update(now);   }   int query_k(int l, int r, int x, int now) {     if (l == r) return T[now].k;     int mid = (l + r) >> 1;     push_down(now);     if (x <= mid)       return query_k(l, mid, x, now << 1);     else       return query_k(mid + 1, r, x, now << 1 | 1);   }   int query_sum(int l, int r, int x, int y, int now) {     if ((r < x) || (y < l)) return 0;     if ((x <= l) && (r <= y)) return T[now].sum;     int mid = (l + r) >> 1;     push_down(now);     return inc(query_sum(l, mid, x, y, now << 1),                query_sum(mid + 1, r, x, y, now << 1 | 1));   }   void debug() {     for (int i = 1; i <= 17; ++i)       printf( %d: %d %d %d n , i, T[i].sum, T[i].k, T[i].lazy);   }   int main() {     static int type[MaxN], f[MaxN], u[MaxN];     scanf( %d%d , v + 1, &q);     n = 1;     for (int i = 1; i <= q; ++i) {       scanf( %d , type + i);       if (type[i] == 1) {         u[i] = ++n;         scanf( %d%d , &f[n], &v[n]);         G.add_edge(f[n], n);       } else         scanf( %d , u + i);     }     dfs(1);     modify_v(1, n, in[1], v[1], 1);     deg[1] = 1;     for (int i = 1; i <= q; ++i)       if (type[i] == 2) {         int ans = query_sum(1, n, in[u[i]], out[u[i]], 1), k;         if (u[i] == 1)           k = 1;         else           k = query_k(1, n, in[f[u[i]]], 1);         ans = (long long)ans * get_inv(k) % mod;         printf( %d n , ans);       } else {         int k = (long long)(deg[f[u[i]]] + 1) * get_inv(deg[f[u[i]]]) % mod;         ++deg[f[u[i]]];         modify_k(1, n, in[f[u[i]]], out[f[u[i]]], k, 1);         deg[u[i]] = 1;         modify_v(1, n, in[u[i]], v[u[i]], 1);       }     return 0;   }