#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
struct EdgeNode {
  int to, next;
} edge[maxn];
int cnt, head[maxn], fa[maxn], deg[maxn];
void add_edge(int u, int v) {
  edge[cnt].to = v, edge[cnt].next = head[u];
  head[u] = cnt++;
}
struct Query {
  int id, u, v;
} qur[maxn];
int bef[maxn], aft[maxn], dclk;
void dfs(int u) {
  bef[u] = ++dclk;
  for (int k = head[u]; k != -1; k = edge[k].next) dfs(edge[k].to);
  aft[u] = dclk;
}
const long long mod = 1e9 + 7;
long long rev[maxn];
long long pow_mod(long long x, long long n) {
  long long ans = 1;
  while (n) {
    if (n & 1) ans = ans * x % mod;
    x = x * x % mod;
    n >>= 1;
  }
  return ans;
}
long long sum[maxn << 2], cof[maxn << 2], lazy[maxn << 2];
void build(int l, int r, int o) {
  sum[o] = 0;
  cof[o] = lazy[o] = 1;
  if (l == r) return;
  int mid = (l + r) / 2;
  build(l, mid, (o << 1));
  build(mid + 1, r, (o << 1 | 1));
}
void pushup(int o) { sum[o] = (sum[(o << 1)] + sum[(o << 1 | 1)]) % mod; }
void fun(int o, long long cl) {
  sum[o] = sum[o] * cl % mod;
  cof[o] = cof[o] * cl % mod;
  lazy[o] = lazy[o] * cl % mod;
}
void pushdown(int o) {
  if (lazy[o] != 1) {
    fun((o << 1), lazy[o]);
    fun((o << 1 | 1), lazy[o]);
    lazy[o] = 1;
  }
}
void addLeaf(int l, int r, int o, int L, long long v) {
  if (l == r) {
    sum[o] = v * cof[o] % mod;
    return;
  }
  pushdown(o);
  int mid = (l + r) / 2;
  if (L <= mid)
    addLeaf(l, mid, (o << 1), L, v);
  else
    addLeaf(mid + 1, r, (o << 1 | 1), L, v);
  pushup(o);
}
void update(int l, int r, int o, int L, int R, long long cl) {
  if (L <= l && r <= R) {
    fun(o, cl);
    return;
  }
  pushdown(o);
  int mid = (l + r) / 2;
  if (L <= mid) update(l, mid, (o << 1), L, R, cl);
  if (R > mid) update(mid + 1, r, (o << 1 | 1), L, R, cl);
  pushup(o);
}
long long querySum(int l, int r, int o, int L, int R) {
  if (L <= l && r <= R) return sum[o];
  pushdown(o);
  int mid = (l + r) / 2;
  long long ans = 0;
  if (L <= mid) ans += querySum(l, mid, (o << 1), L, R);
  if (R > mid) ans += querySum(mid + 1, r, (o << 1 | 1), L, R);
  pushup(o);
  return ans % mod;
}
long long queryCof(int l, int r, int o, int L) {
  if (l == r) return cof[o];
  pushdown(o);
  int mid = (l + r) / 2, ans;
  if (L <= mid)
    ans = queryCof(l, mid, (o << 1), L);
  else
    ans = queryCof(mid + 1, r, (o << 1 | 1), L);
  pushup(o);
  return ans;
}
long long getRev(long long val) {
  if (rev[val] == -1) rev[val] = pow_mod(val, mod - 2);
  return rev[val];
}
void add(int p, long long v) {
  int f = fa[p];
  addLeaf(1, aft[1], 1, bef[p], v);
  long long tmp = ++deg[f];
  tmp = (tmp + 1) * getRev(tmp) % mod;
  update(bef[1], aft[1], 1, bef[f], aft[f], tmp);
}
int main() {
  int v, q;
  scanf("%d%d", &v, &q);
  int cur = 1;
  cnt = 0;
  memset(head, -1, sizeof(head));
  memset(deg, 0, sizeof(deg));
  memset(rev, -1, sizeof(rev));
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qur[i].id, &qur[i].u);
    if (qur[i].id == 1) {
      scanf("%d", &qur[i].v);
      ++cur;
      fa[cur] = qur[i].u;
      add_edge(qur[i].u, cur);
      qur[i].u = cur;
    }
  }
  dclk = 0;
  dfs(1);
  build(bef[1], aft[1], 1);
  addLeaf(bef[1], aft[1], 1, bef[1], v);
  for (int i = 0; i < q; i++) {
    if (qur[i].id == 1)
      add(qur[i].u, qur[i].v);
    else {
      int u = qur[i].u;
      long long sum = querySum(bef[1], aft[1], 1, bef[u], aft[u]);
      long long cc = queryCof(bef[1], aft[1], 1, bef[u]);
      long long tmp = (deg[u] + 1) * pow_mod(cc, mod - 2) % mod;
      printf("%I64d\n", sum * tmp % mod);
    }
  }
  return 0;
}
