#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int jyb = 1e9 + 7;
struct edge {
  int v, next;
} e[maxn];
int h[maxn], num;
void build_edge(int u, int v) {
  num++;
  e[num].v = v;
  e[num].next = h[u];
  h[u] = num;
}
struct Query {
  int c, x, y;
} Q[maxn];
struct node {
  int l, r, x, lazy;
} t[maxn << 1];
int tot;
int n, q;
int w[maxn], fa[maxn], p[maxn];
int indexx, in[maxn], out[maxn];
int qpow(int x, int y) {
  int res;
  for (res = 1; y; y >>= 1) {
    if (y & 1) res = 1ll * res * x % jyb;
    x = 1ll * x * x % jyb;
  }
  return res;
}
void dfs(int x) {
  in[x] = ++indexx;
  p[x] = 1;
  for (int i = h[x]; i; i = e[i].next) dfs(e[i].v), fa[e[i].v] = x;
  out[x] = indexx;
}
void build(int p, int l, int r) {
  int mid = (l + r) >> 1;
  if (l == r) {
    t[p].x = w[l];
    t[p].lazy = 1;
    return;
  }
  t[p].l = ++tot;
  t[p].r = ++tot;
  build(t[p].l, l, mid);
  build(t[p].r, mid + 1, r);
  t[p].x = (t[t[p].r].x + t[t[p].l].x) % jyb;
  t[p].lazy = 1;
}
void push_down(int p, int lazy) {
  t[p].lazy = 1ll * lazy * t[p].lazy % jyb;
  t[p].x = 1ll * t[p].x * lazy % jyb;
}
int query(int p, int l, int r, int L, int R) {
  int mid = (l + r) >> 1;
  if (L == l && R == r) return t[p].x;
  if (t[p].lazy != 1) {
    push_down(t[p].l, t[p].lazy);
    push_down(t[p].r, t[p].lazy);
    t[p].lazy = 1;
  }
  if (R <= mid)
    return query(t[p].l, l, mid, L, R);
  else if (L > mid)
    return query(t[p].r, mid + 1, r, L, R);
  else
    return (query(t[p].l, l, mid, L, mid) +
            query(t[p].r, mid + 1, r, mid + 1, R)) %
           jyb;
}
void add(int p, int l, int r, int pos, int c) {
  int mid = (l + r) >> 1;
  if (l == r) {
    t[p].x = c;
    return;
  }
  if (t[p].lazy != 1) {
    push_down(t[p].l, t[p].lazy);
    push_down(t[p].r, t[p].lazy);
    t[p].lazy = 1;
  }
  if (pos <= mid)
    add(t[p].l, l, mid, pos, c);
  else
    add(t[p].r, mid + 1, r, pos, c);
  t[p].x = (t[t[p].l].x + t[t[p].r].x) % jyb;
}
void change(int p, int l, int r, int L, int R, int c) {
  int mid = (l + r) >> 1;
  if (l == L && R == r) {
    t[p].x = 1ll * t[p].x * c % jyb;
    t[p].lazy = 1ll * t[p].lazy * c % jyb;
    return;
  }
  if (t[p].lazy != 1) {
    push_down(t[p].l, t[p].lazy);
    push_down(t[p].r, t[p].lazy);
    t[p].lazy = 1;
  }
  if (R <= mid)
    change(t[p].l, l, mid, L, R, c);
  else if (L > mid)
    change(t[p].r, mid + 1, r, L, R, c);
  else {
    change(t[p].l, l, mid, L, mid, c);
    change(t[p].r, mid + 1, r, mid + 1, R, c);
  }
  t[p].x = (t[t[p].l].x + t[t[p].r].x) % jyb;
}
int main() {
  scanf("%d%d", &w[1], &q);
  int now = 1;
  for (int i = 1; i <= q; i++) {
    scanf("%d", &Q[i].c);
    scanf("%d", &Q[i].x);
    if (Q[i].c == 1) {
      now++;
      scanf("%d", &Q[i].y);
      build_edge(Q[i].x, now);
    }
  }
  n = now;
  dfs(1);
  build(0, 1, n);
  now = 1;
  for (int i = 1; i <= q; i++) {
    int x = Q[i].x;
    int inv;
    if (Q[i].c == 2) {
      int ans = query(0, 1, n, in[x], out[x]);
      if (x == 1)
        inv = 1;
      else {
        int faa = fa[x];
        inv = query(0, 1, n, in[faa], in[faa]);
        inv = 1ll * qpow(w[faa], jyb - 2) * inv % jyb;
        inv = qpow(inv, jyb - 2);
      }
      printf("%d\n", 1ll * ans * inv % jyb);
    } else {
      now++;
      int y = Q[i].y;
      w[now] = y;
      int ans = query(0, 1, n, in[x], in[x]);
      inv = qpow(w[x], jyb - 2);
      inv = 1ll * ans * inv % jyb;
      ans = 1ll * inv * w[now] % jyb;
      add(0, 1, n, in[now], ans);
      int P = p[x]++;
      int c = 1ll * qpow(P, jyb - 2) * p[x] % jyb;
      change(0, 1, n, in[x], out[x], c);
    }
  }
  return 0;
}
