#include <bits/stdc++.h>
const int p = 1000000007;
struct treenode {
  int left, right, size, mul, num;
};
treenode tree[1000000];
int edge[500000], next[500000], fa[300000], first[300000];
int d[300000], l[300000], r[300000], v[300000], x[300000], y[300000], z[300000];
int i, m, n, t, w, root, dfs_clock, sum_edge, sum_node;
inline void addedge(int x, int y) {
  sum_edge++, edge[sum_edge] = y, next[sum_edge] = first[x],
              first[x] = sum_edge;
  return;
}
inline void dfs(int x, int y) {
  dfs_clock++, l[x] = dfs_clock;
  for (int i = first[x]; i != 0; i = next[i])
    if (edge[i] != y) dfs(edge[i], x);
  r[x] = dfs_clock;
  return;
}
inline int power(int x, int y) {
  int s = 1;
  for (int i = 30; i >= 0; i--) {
    s = 1LL * s * s % p;
    if (y & (1 << i)) s = 1LL * s * x % p;
  }
  return s;
}
inline void pushdown(int node) {
  if ((node) && (tree[node].mul != 1)) {
    tree[node].num = 1LL * tree[node].num * tree[node].mul % p;
    if (tree[node].left)
      tree[tree[node].left].mul =
          1LL * tree[tree[node].left].mul * tree[node].mul % p;
    if (tree[node].right)
      tree[tree[node].right].mul =
          1LL * tree[tree[node].right].mul * tree[node].mul % p;
    tree[node].mul = 1;
  }
  return;
}
inline void pushup(int node) {
  pushdown(tree[node].left);
  pushdown(tree[node].right);
  tree[node].size = tree[tree[node].left].size + tree[tree[node].right].size;
  tree[node].num = (tree[tree[node].left].num + tree[tree[node].right].num) % p;
  return;
}
inline void inserttree(int l, int r, int x, int y, int& node) {
  if (!node) sum_node++, node = sum_node, tree[node].mul = 1;
  pushdown(node);
  if (l == r)
    tree[node].size = 1, tree[node].num = y;
  else {
    int mid = (l + r) >> 1;
    if (x <= mid)
      inserttree(l, mid, x, y, tree[node].left);
    else
      inserttree(mid + 1, r, x, y, tree[node].right);
    pushup(node);
  }
  return;
}
inline void multree(int l, int r, int x, int y, int z, int node) {
  if (!node) return;
  pushdown(node);
  if ((l == x) && (r == y))
    tree[node].mul = 1LL * tree[node].mul * z % p;
  else {
    int mid = (l + r) >> 1;
    if (y <= mid)
      multree(l, mid, x, y, z, tree[node].left);
    else if (x > mid)
      multree(mid + 1, r, x, y, z, tree[node].right);
    else {
      multree(l, mid, x, mid, z, tree[node].left);
      multree(mid + 1, r, mid + 1, y, z, tree[node].right);
    }
    pushup(node);
  }
  return;
}
inline int asktree(int l, int r, int x, int y, int node) {
  if (!x) return 1;
  if (!node) return 0;
  pushdown(node);
  if ((l == x) && (r == y)) return tree[node].num;
  int mid = (l + r) >> 1;
  if (y <= mid) return asktree(l, mid, x, y, tree[node].left);
  if (x > mid) return asktree(mid + 1, r, x, y, tree[node].right);
  return (asktree(l, mid, x, mid, tree[node].left) +
          asktree(mid + 1, r, mid + 1, y, tree[node].right)) %
         p;
}
int main() {
  scanf("%d%d", &v[1], &m);
  n = 1;
  for (i = 1; i <= m; i++) {
    scanf("%d", &z[i]);
    if (z[i] == 1) {
      scanf("%d%d", &x[i], &y[i]);
      n++, v[n] = y[i], addedge(x[i], n), addedge(n, x[i]);
    } else
      scanf("%d", &x[i]);
  }
  dfs(1, 0);
  inserttree(1, n, l[1], v[1], root);
  t = 1, d[1] = 1;
  for (i = 1; i <= m; i++) {
    if (z[i] == 1) {
      d[x[i]]++, t++, fa[t] = x[i], d[t]++;
      multree(1, n, l[x[i]], r[x[i]],
              1LL * d[x[i]] * power(d[x[i]] - 1, p - 2) % p, root);
      inserttree(1, n, l[t],
                 1LL * y[i] * power(v[x[i]], p - 2) % p *
                     asktree(1, n, l[x[i]], l[x[i]], root) % p,
                 root);
    } else {
      if (x[i] != 1)
        w = 1LL * power(asktree(1, n, l[fa[x[i]]], l[fa[x[i]]], root), p - 2) %
            p * v[fa[x[i]]] % p;
      else
        w = 1;
      printf("%d\n", 1LL * asktree(1, n, l[x[i]], r[x[i]], root) * w % p);
    }
  }
  return 0;
}
