#include <bits/stdc++.h>
using namespace std;
template <class T = int>
inline T nxt() {
  T first = 0;
  int c = getchar();
  int minus = 0;
  while (c != '-' && !isdigit(c)) {
    c = getchar();
  }
  if (c == '-') {
    minus = 1;
    c = getchar();
  }
  while (isdigit(c)) {
    first = first * 10 + c - '0';
    c = getchar();
  }
  return (minus ? -first : first);
}
template <class T>
inline T sqr(T first) {
  return first * first;
}
inline long long isSqr(long long v) {
  long long t = (long long)sqrt(v);
  for (long long i = t - 1; i <= t + 1; ++i) {
    if (i * i == v) return i;
  }
  return -1;
}
inline long long gcd(long long a, long long b) {
  a = abs(a);
  b = abs(b);
  while (b) {
    a %= b;
    swap(a, b);
  }
  return a;
}
const long long mod = 1000 * 1000 * 1000 + 7;
long long pw(long long a, long long n) {
  long long ret = 1;
  while (n) {
    if (n & 1) ret = ret * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return ret;
}
template <class DataType>
struct Fenwick {
  vector<DataType> t;
  int n;
  void init(int sz) {
    n = sz;
    t.assign(n, 1);
  }
  void add(int p, DataType val) {
    for (; p < n; p |= (p + 1)) {
      t[p] *= val;
      t[p] %= mod;
    }
  }
  DataType sum(int r) {
    DataType ret = 1;
    for (; r >= 0; r &= (r + 1), --r) {
      ret *= t[r];
      ret %= mod;
    }
    return ret % mod;
  }
  DataType sum(int l, int r) {
    if (l > r) return 1;
    DataType res = sum(r) * pw(sum(l - 1), mod - 2) % mod;
    return res;
  }
};
struct Query {
  int id, p, v;
};
const int N = 200000 + 10;
long long val[N];
vector<int> g[N];
Query Q[N];
int sz;
int timer = 0;
int l[N];
int r[N];
int parent[N];
int subTreeSize[N];
int tin[N];
int tout[N];
int path[N];
int pathSize[N];
int pathPos[N];
int pathRoot[N];
int pathCount;
inline void dfs1(int v, int p) {
  tin[v] = timer++;
  parent[v] = p;
  subTreeSize[v] = 1;
  for (int to : g[v]) {
    if (to == p) continue;
    dfs1(to, v);
    subTreeSize[v] += subTreeSize[to];
  }
  tout[v] = timer++;
}
inline int newPath(int u) {
  pathRoot[pathCount] = u;
  return pathCount++;
}
inline void buildPaths(int v, int pth) {
  path[v] = pth;
  pathPos[v] = pathSize[pth]++;
  int maId = -1;
  for (int to : g[v]) {
    if (to == parent[v]) continue;
    if (maId == -1 || subTreeSize[to] > subTreeSize[maId]) {
      maId = to;
    }
  }
  for (int to : g[v]) {
    if (to == parent[v]) continue;
    if (to == maId) {
      buildPaths(to, pth);
    } else {
      buildPaths(to, newPath(to));
    }
  }
}
Fenwick<long long> *fenwick;
inline void makeHld() {
  memset(pathSize, 0, sizeof(pathSize));
  pathCount = 0;
  timer = 0;
  dfs1(0, -1);
  buildPaths(0, newPath(0));
  fenwick = new Fenwick<long long>[pathCount];
  for (int i = 0; i < pathCount; ++i) {
    fenwick[i].init(pathSize[i]);
  }
}
inline bool isUpper(int a, int b) {
  return tin[a] <= tin[b] && tout[b] <= tout[a];
}
inline void modifyPath(int pth, int p, long long mm) {
  fenwick[pth].add(p, mm);
}
inline long long queryPath(int pth, int l, int r) {
  return fenwick[pth].sum(l, r);
}
inline void update(int a, long long mm) { modifyPath(path[a], pathPos[a], mm); }
inline long long query(int a, int b) {
  long long ret = 1;
  for (int root; !isUpper(root = pathRoot[path[a]], b); a = parent[root]) {
    ret *= queryPath(path[a], 0, pathPos[a]);
    ret %= mod;
  }
  for (int root; !isUpper(root = pathRoot[path[b]], a); b = parent[root]) {
    ret *= queryPath(path[b], 0, pathPos[b]);
    ret %= mod;
  }
  ret *= queryPath(path[a], min(pathPos[a], pathPos[b]),
                   max(pathPos[a], pathPos[b]));
  ret %= mod;
  return ret;
}
void dfs(int v, int p = -1) {
  l[v] = timer++;
  r[v] = l[v];
  for (int to : g[v]) {
    if (to == p) continue;
    dfs(to, v);
    r[v] = max(r[v], r[to]);
  }
}
struct MulSegTree {
  vector<long long> t;
  vector<long long> mm;
  int n;
  void init(int sz) {
    n = sz;
    t.resize(4 * n);
    mm.resize(4 * n);
    build(1, 0, n);
  }
  void build(int v, int tl, int tr) {
    t[v] = 0;
    mm[v] = 1;
    if (tl + 1 == tr) {
      return;
    }
    int tm = (tl + tr) >> 1;
    build(v + v, tl, tm);
    build(v + v + 1, tm, tr);
  }
  inline long long get(int l, int r) { return get(1, 0, n, l, r + 1); }
  void push(int v) {
    mm[v + v] = mm[v] * mm[v + v] % mod;
    mm[v + v + 1] = mm[v] * mm[v + v + 1] % mod;
    mm[v] = 1;
  }
  long long get(int v, int tl, int tr, int l, int r) {
    if (l >= r) return 0;
    if (l == tl && r == tr) {
      return t[v] * mm[v] % mod;
    }
    push(v);
    int tm = (tl + tr) >> 1;
    long long res = get(v + v, tl, tm, l, min(tm, r)) +
                    get(v + v + 1, tm, tr, max(l, tm), r);
    if (res >= mod) res -= mod;
    t[v] = t[v + v] * mm[v + v] + t[v + v + 1] * mm[v + v + 1];
    t[v] %= mod;
    return res;
  }
  inline void mul(int l, int r, long long val) { mul(1, 0, n, l, r + 1, val); }
  void mul(int v, int tl, int tr, int l, int r, long long val) {
    if (l >= r) return;
    if (l == tl && r == tr) {
      mm[v] *= val;
      mm[v] %= mod;
      return;
    }
    push(v);
    int tm = (tl + tr) >> 1;
    mul(v + v, tl, tm, l, min(r, tm), val);
    mul(v + v + 1, tm, tr, max(l, tm), r, val);
    t[v] = t[v + v] * mm[v + v] + t[v + v + 1] * mm[v + v + 1];
    t[v] %= mod;
  }
  inline void upd(int p, long long val) { upd(1, 0, n, p, val); }
  void upd(int v, int tl, int tr, int p, long long val) {
    if (tl + 1 == tr) {
      t[v] = val;
      mm[v] = 1;
      return;
    }
    push(v);
    int tm = (tl + tr) >> 1;
    if (p < tm)
      upd(v + v, tl, tm, p, val);
    else
      upd(v + v + 1, tm, tr, p, val);
    t[v] = t[v + v] * mm[v + v] + t[v + v + 1] * mm[v + v + 1];
    t[v] %= mod;
  }
};
MulSegTree tr;
void solve() {
  val[0] = nxt();
  sz = 1;
  int q = nxt();
  for (int i = 0; i < q; ++i) {
    Q[i].id = nxt();
    if (Q[i].id == 1) {
      Q[i].p = nxt() - 1;
      Q[i].v = nxt();
      g[Q[i].p].push_back(sz);
      val[sz] = Q[i].v;
      sz++;
    } else {
      Q[i].p = nxt() - 1;
    }
  }
  dfs(0);
  makeHld();
  tr.init(sz);
  tr.upd(l[0], val[0]);
  int pos = 1;
  for (int i = 0; i < q; ++i) {
    if (Q[i].id == 1) {
      int p = Q[i].p;
      int v = pos;
      long long tm = query(p, p);
      update(p, pw(tm, mod - 2) * (tm + 1) % mod);
      tr.mul(l[p], r[p], pw(tm, mod - 2) * (tm + 1) % mod);
      tr.upd(l[v], val[pos] * query(0, v) % mod);
      pos++;
    } else {
      int v = Q[i].p;
      long long di = 1;
      if (parent[v] != -1) {
        di = query(0, parent[v]);
      }
      long long ans = tr.get(l[v], r[v]) * pw(di, mod - 2) % mod;
      cout << ans << "\n";
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  solve();
  return 0;
}
