#include <bits/stdc++.h>
using namespace std;
const long long MODER = 1000000007;
long long getmod(long long a) {
  if (a < 0 || a >= MODER) a %= MODER;
  if (a < 0) a += MODER;
  return a;
}
long long summod(long long a, long long b) {
  return getmod(getmod(a) + getmod(b));
}
long long mulmod(long long a, long long b) {
  return getmod(getmod(a) * getmod(b));
}
long long powmod(long long a, long long p) {
  long long ret = 1;
  while (p) {
    if (p & 1) ret = mulmod(ret, a);
    a = mulmod(a, a);
    p >>= 1;
  }
  return ret;
}
long long invmod(long long a) { return powmod(a, MODER - 2); }
const int MAXBIN = 1005;
long long fac[MAXBIN], facinv[MAXBIN];
void prepbin() {
  fac[0] = facinv[0] = 1;
  for (int i = 1; i <= MAXBIN - 1; i++) {
    fac[i] = mulmod(fac[i - 1], i);
    facinv[i] = mulmod(facinv[i - 1], invmod(i));
  }
}
long long bin(long long n, long long r) {
  return mulmod(mulmod(fac[n], facinv[n - r]), facinv[r]);
}
const int MAXN = 400005;
long long segTree_val[MAXN * 4], segTree_siz[MAXN * 4],
    segLazy_mul_siz[MAXN * 4];
long long siz[MAXN];
int n;
void segTree_clear(int x) {
  segTree_val[x] = segTree_siz[x] = 0;
  segLazy_mul_siz[x] = -1;
}
void segTree_maintain(int x) {
  segTree_val[x] =
      summod(segTree_val[((x) << 1)], segTree_val[(((x) << 1) + 1)]);
  segTree_siz[x] =
      mulmod(segTree_siz[((x) << 1)], segTree_siz[(((x) << 1) + 1)]);
}
void segTree_build(int cl = -1, int cr = -1, int x = -1) {
  if (x == -1) {
    segTree_build(1, n, 1);
    return;
  }
  segTree_clear(x);
  if (cl == cr) {
    segTree_siz[x] = 1;
    return;
  } else if (cl < cr) {
    int mid = (cl + cr) >> 1;
    segTree_build(cl, mid, ((x) << 1));
    segTree_build(mid + 1, cr, (((x) << 1) + 1));
    segTree_maintain(x);
  }
}
void segTree_pushdown(int x) {
  if (segLazy_mul_siz[x] != -1) {
    segTree_siz[((x) << 1)] =
        mulmod(segTree_siz[((x) << 1)], segLazy_mul_siz[x]);
    segTree_val[((x) << 1)] =
        mulmod(segTree_val[((x) << 1)], segLazy_mul_siz[x]);
    segTree_siz[(((x) << 1) + 1)] =
        mulmod(segTree_siz[(((x) << 1) + 1)], segLazy_mul_siz[x]);
    segTree_val[(((x) << 1) + 1)] =
        mulmod(segTree_val[(((x) << 1) + 1)], segLazy_mul_siz[x]);
    if (segLazy_mul_siz[((x) << 1)] == -1) segLazy_mul_siz[((x) << 1)] = 1;
    segLazy_mul_siz[((x) << 1)] =
        mulmod(segLazy_mul_siz[((x) << 1)], segLazy_mul_siz[x]);
    if (segLazy_mul_siz[(((x) << 1) + 1)] == -1)
      segLazy_mul_siz[(((x) << 1) + 1)] = 1;
    segLazy_mul_siz[(((x) << 1) + 1)] =
        mulmod(segLazy_mul_siz[(((x) << 1) + 1)], segLazy_mul_siz[x]);
    segLazy_mul_siz[x] = -1;
  }
}
void segTree_mul(int l, int r, long long val, int cl = -1, int cr = -1,
                 int x = -1) {
  if (x == -1) {
    segTree_mul(l, r, val, 1, n, 1);
    return;
  }
  segTree_pushdown(x);
  if (cr < l || cl > r) return;
  if (cl >= l && cr <= r) {
    segTree_siz[x] = mulmod(segTree_siz[x], val);
    segTree_val[x] = mulmod(segTree_val[x], val);
    if (segLazy_mul_siz[x] == -1) segLazy_mul_siz[x] = 1;
    segLazy_mul_siz[x] = mulmod(segLazy_mul_siz[x], val);
  } else {
    int mid = (cl + cr) >> 1;
    segTree_mul(l, r, val, cl, mid, ((x) << 1));
    segTree_mul(l, r, val, mid + 1, cr, (((x) << 1) + 1));
    segTree_maintain(x);
  }
}
void segTree_update_val(int pos, long long val, int cl = -1, int cr = -1,
                        int x = -1) {
  if (x == -1) {
    segTree_update_val(pos, val, 1, n, 1);
    return;
  }
  segTree_pushdown(x);
  if (cr < pos || cl > pos) return;
  if (cl >= pos && cr <= pos) {
    segTree_val[x] = val * segTree_siz[x];
    return;
  } else {
    int mid = (cl + cr) >> 1;
    segTree_update_val(pos, val, cl, mid, ((x) << 1));
    segTree_update_val(pos, val, mid + 1, cr, (((x) << 1) + 1));
    segTree_maintain(x);
  }
}
long long qres;
long long segTree_query_siz(int pos, int cl = -1, int cr = -1, int x = -1) {
  if (x == -1) {
    qres = 0;
    segTree_query_siz(pos, 1, n, 1);
    return qres;
  }
  segTree_pushdown(x);
  if (cr < pos || cl > pos) return 0;
  if (cl >= pos && cr <= pos) {
    qres += segTree_siz[x];
  } else {
    int mid = (cl + cr) >> 1;
    segTree_query_siz(pos, cl, mid, ((x) << 1));
    segTree_query_siz(pos, mid + 1, cr, (((x) << 1) + 1));
    segTree_maintain(x);
  }
  return 0;
}
long long segTree_query_val(int l, int r, int cl = -1, int cr = -1,
                            int x = -1) {
  if (x == -1) {
    qres = 0;
    segTree_query_val(l, r, 1, n, 1);
    return qres;
  }
  segTree_pushdown(x);
  if (cr < l || cl > r) return 0;
  if (cl >= l && cr <= r) {
    qres += segTree_val[x];
  } else {
    int mid = (cl + cr) >> 1;
    segTree_query_val(l, r, cl, mid, ((x) << 1));
    segTree_query_val(l, r, mid + 1, cr, (((x) << 1) + 1));
    segTree_maintain(x);
  }
  return 0;
}
int head[MAXN], nxt[MAXN], ed[MAXN], q;
void gph_clr() {
  for (int i = 1; i <= n; i++) head[i] = 0;
  q = 2;
}
void gph_ade(int s, int t) {
  ed[q] = t;
  nxt[q] = head[s];
  head[s] = q++;
}
struct Query {
  int typ, arg1, arg2, pid;
} qry[MAXN];
long long V[MAXN], Q;
void buildtree() {
  gph_clr();
  for (int i = 1; i <= Q; i++) {
    if (qry[i].typ == 1) {
      gph_ade(qry[i].arg1, qry[i].pid);
    }
  }
}
int dfs_clock, dfn_in[MAXN], dfn_out[MAXN], par[MAXN];
void dfs(int u, int p) {
  ++dfs_clock;
  par[u] = p;
  dfn_in[u] = dfs_clock;
  for (int i = head[u]; i; i = nxt[i]) {
    int v = ed[i];
    if (v != p) {
      dfs(v, u);
    }
  }
  dfn_out[u] = dfs_clock;
}
void getdfn() {
  dfs_clock = 0;
  dfs(1, -1);
}
void solve() {
  buildtree();
  getdfn();
  segTree_build();
  siz[1] = 1;
  segTree_update_val(dfn_in[1], V[1]);
  for (int i = 1; i <= Q; i++) {
    if (qry[i].typ == 1) {
      siz[qry[i].pid] = 1;
      segTree_update_val(dfn_in[qry[i].pid], qry[i].arg2);
      segTree_mul(dfn_in[qry[i].arg1], dfn_out[qry[i].arg1],
                  invmod(siz[qry[i].arg1]));
      siz[qry[i].arg1]++;
      segTree_mul(dfn_in[qry[i].arg1], dfn_out[qry[i].arg1], siz[qry[i].arg1]);
    } else {
      long long res =
          segTree_query_val(dfn_in[qry[i].arg1], dfn_out[qry[i].arg1]);
      if (par[qry[i].arg1] != -1) {
        res = mulmod(res, invmod(segTree_query_siz(dfn_in[par[qry[i].arg1]])));
      }
      cout << res << endl;
    }
  }
}
int main(int argc, const char* argv[]) {
  while (cin >> V[1] >> Q) {
    n = 1;
    for (int i = 1; i <= Q; i++) {
      cin >> qry[i].typ >> qry[i].arg1;
      if (qry[i].typ == 1) {
        qry[i].pid = ++n;
        cin >> qry[i].arg2;
        V[qry[i].pid] = qry[i].arg2;
      }
    }
    solve();
  }
  return 0;
}
