#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;
}
