#include <bits/stdc++.h>
using namespace std;
inline int getInt() {
  int ret = 0;
  char ch = ' ';
  bool flag = 0;
  while (!(ch >= '0' && ch <= '9')) {
    if (ch == '-') flag ^= 1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    ret = ret * 10 + ch - '0';
    ch = getchar();
  }
  return flag ? -ret : ret;
}
const int N = 200010, MOD = 1000000007;
struct Node {
  static int tot;
  int child[2], num, sum, tag;
} tr[N * 2];
int Node::tot = 0;
struct Operation {
  int opt, p, val;
  Operation() {}
  Operation(int _opt, int _p, int _val) { opt = _opt, p = _p, val = _val; }
} data[N];
int n, m, arr[N];
int first[N], edge[N], nex[N], tot;
int size[N], father[N], path[N], lSide[N], rSide[N], cnt[N];
inline void insert(int u, int v) {
  tot++;
  edge[tot] = v, nex[tot] = first[u];
  first[u] = tot;
}
inline void input() {
  arr[1] = getInt();
  m = getInt();
  n = 1;
  for (int i = 1; i <= m; i++) {
    int opt = getInt(), p = getInt(), val = 0;
    if (opt == 1) val = getInt();
    data[i] = Operation(opt, p, val);
    if (opt == 1) {
      arr[++n] = val;
      insert(p, n);
    }
  }
}
inline int mul(int x, int y) { return (x * 1LL * y) % MOD; }
inline void buildPath() {
  static int que[N], head, tail;
  que[head = tail = 1] = 1;
  while (head <= tail) {
    int u = que[head++];
    for (int tab = first[u]; tab; tab = nex[tab])
      father[que[++tail] = edge[tab]] = u;
  }
  for (int i = n; i >= 1; i--) {
    size[que[i]]++;
    if (father[que[i]]) size[father[que[i]]] += size[que[i]];
  }
  lSide[1] = 1, rSide[1] = n, path[1] = 1;
  for (int i = 1; i <= n; i++)
    for (int u = que[i], tab = first[u], v, now = 1; tab; tab = nex[tab]) {
      v = edge[tab];
      path[lSide[v] = lSide[u] + now] = v;
      rSide[v] = lSide[v] + size[v] - 1;
      now += size[v];
    }
}
inline int buildTree(int left, int right) {
  int x = ++Node::tot, mid = (left + right) >> 1;
  if (left < right) {
    (tr[x].child[0]) = buildTree(left, mid);
    (tr[x].child[1]) = buildTree(mid + 1, right);
  }
  return x;
}
inline void pushDown(int x) {
  if ((tr[x].tag) == 1) return;
  for (int t = 0, u; t < 2; t++)
    if ((u = (tr[x].child[t]))) {
      (tr[u].num) = mul((tr[u].num), (tr[x].tag));
      (tr[u].sum) = mul((tr[u].sum), (tr[x].tag));
      (tr[u].tag) = mul((tr[u].tag), (tr[x].tag));
    }
  (tr[x].tag) = 1;
}
inline void updata(int x) {
  (tr[x].sum) = ((tr[(tr[x].child[0])].sum) + (tr[(tr[x].child[1])].sum)) % MOD;
}
inline int getNum(int x, int l, int r, int u) {
  if (l >= r) return (tr[x].num);
  pushDown(x);
  int mid = (l + r) >> 1;
  if (u <= mid) return getNum((tr[x].child[0]), l, mid, u);
  return getNum((tr[x].child[1]), mid + 1, r, u);
}
inline void setNum(int x, int l, int r, int u, int v) {
  if (l >= r) {
    (tr[x].num) = v;
    (tr[x].sum) = ((tr[x].num) * 1LL * arr[path[l]]) % MOD;
  } else {
    pushDown(x);
    int mid = (l + r) >> 1;
    if (u <= mid)
      setNum((tr[x].child[0]), l, mid, u, v);
    else
      setNum((tr[x].child[1]), mid + 1, r, u, v);
    updata(x);
  }
}
inline void multiply(int x, int l, int r, int left, int right, int v) {
  if (right < l || left > r) return;
  if (l >= left && r <= right) {
    (tr[x].num) = mul((tr[x].num), v);
    (tr[x].sum) = mul((tr[x].sum), v);
    (tr[x].tag) = mul((tr[x].tag), v);
  } else {
    pushDown(x);
    int mid = (l + r) >> 1;
    multiply((tr[x].child[0]), l, mid, left, right, v);
    multiply((tr[x].child[1]), mid + 1, r, left, right, v);
    updata(x);
  }
}
inline long long extGcd(int x, int y, long long &a, long long &b) {
  if (!y) return a = 1, b = 0, x;
  long long ta, tb, g = extGcd(y, x % y, ta, tb), t = x / y;
  return a = tb, b = ta - t * tb, g;
}
inline int inverse(int x, int M) {
  long long t1, t2;
  extGcd(x, M, t1, t2);
  return (t1 + M) % M;
}
inline void add(int x) {
  int y = father[x];
  int now = getNum(1, 1, n, lSide[y]);
  setNum(1, 1, n, lSide[x], now);
  int delta = mul(inverse(cnt[y], MOD), cnt[y] + 1);
  multiply(1, 1, n, lSide[y], rSide[y], delta);
  cnt[y]++, cnt[x]++;
}
inline int getSum(int x, int l, int r, int left, int right) {
  if (l >= left && r <= right) return (tr[x].sum);
  pushDown(x);
  int mid = (l + r) >> 1;
  if (right <= mid) return getSum((tr[x].child[0]), l, mid, left, right);
  if (left > mid) return getSum((tr[x].child[1]), mid + 1, r, left, right);
  return (getSum((tr[x].child[0]), l, mid, left, mid) +
          getSum((tr[x].child[1]), mid + 1, r, mid + 1, right)) %
         MOD;
}
inline int query(int x) {
  int past = father[x] ? getNum(1, 1, n, lSide[father[x]]) : 1;
  return mul(getSum(1, 1, n, lSide[x], rSide[x]), inverse(past, MOD));
}
inline void solve() {
  buildPath();
  buildTree(1, n);
  setNum(1, 1, n, 1, 1), cnt[1] = 1;
  int now = 1;
  for (int i = 1; i <= m; i++) {
    int opt = data[i].opt, p = data[i].p;
    if (opt == 1)
      add(++now);
    else
      printf("%d\n", query(p));
  }
}
int main() {
  input();
  solve();
  return 0;
}
