#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline string tostr(const T &x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
inline long long parse(const string &s) {
  stringstream ss(s);
  long long x;
  ss >> x;
  return x;
}
const double EPS = 1e-10;
const int INF = 1000 * 1000 * 1000;
const long long LINF = INF * 1ll * INF;
const double DINF = 1e200;
const double PI = 3.1415926535897932384626433832795l;
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
bool isprime(long long a) {
  if (a <= 1) return false;
  for (long long i = 2; i * i <= a; ++i) {
    if (a % i == 0) return false;
  }
  return true;
}
long long sqrtup(long long a) {
  if (!a) return 0;
  long long x = max(0ll, (long long)sqrt((double)a));
  while (x * x >= a) --x;
  while ((x + 1) * (x + 1) < a) ++x;
  return x + 1;
}
long long sqrtdown(long long a) {
  long long x = max(0ll, (long long)sqrt((double)a));
  while (x * x > a) --x;
  while ((x + 1) * (x + 1) <= a) ++x;
  return x;
}
template <class T>
ostream &operator<<(ostream &s, const vector<T> &v);
template <class A, class B>
ostream &operator<<(ostream &s, const pair<A, B> &p);
template <class K, class V>
ostream &operator<<(ostream &s, const map<K, V> &m);
template <class T, size_t N>
ostream &operator<<(ostream &s, const array<T, N> &a);
template <class T>
ostream &operator<<(ostream &s, const vector<T> &v) {
  s << '[';
  for (int i = 0; i < (((int)(v).size())); ++i) {
    if (i) s << ',';
    s << v[i];
  }
  s << ']';
  return s;
}
template <class A, class B>
ostream &operator<<(ostream &s, const pair<A, B> &p) {
  s << "(" << p.first << "," << p.second << ")";
  return s;
}
template <class K, class V>
ostream &operator<<(ostream &s, const map<K, V> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it.first << ": " << it.second;
  }
  s << "}";
  return s;
}
template <class T, size_t N>
ostream &operator<<(ostream &s, const array<T, N> &a) {
  s << '[';
  for (int i = 0; i < (((int)(a).size())); ++i) {
    if (i) s << ',';
    s << a[i];
  }
  s << ']';
  return s;
}
template <size_t n, class... T>
struct put1 {
  static ostream &put(ostream &s, const tuple<T...> &t) {
    s << get<sizeof...(T) - n>(t);
    if (n > 1) s << ',';
    return put1<n - 1, T...>::put(s, t);
  }
};
template <class... T>
struct put1<0, T...> {
  static ostream &put(ostream &s, const tuple<T...> &t) { return s; }
};
template <class... T>
ostream &operator<<(ostream &s, const tuple<T...> &t) {
  s << "(";
  put1<sizeof...(T), T...>::put(s, t);
  s << ")";
  return s;
}
ostream &put2(ostream &s, const tuple<> &t) { return s; }
template <class U>
ostream &put2(ostream &s, const tuple<U> &t) {
  return s << get<0>(t);
}
template <class U, class V, class... T>
ostream &put2(ostream &s, const tuple<U, V, T...> &t) {
  return s << t;
}
const long long mod = INF + 7;
struct segtree {
  vector<long long> C, S;
  segtree(int n) : C(n * 4, 1), S(n * 4) {}
  void mulc(int l, int r, long long v, int a, int b, int k) {
    if (!k) do {
      } while (false);
    if (l >= b || r <= a) return;
    if (l <= a && r >= b) {
      (C[k] *= v) %= mod;
      (S[k] *= v) %= mod;
      return;
    }
    int c = (a + b) / 2;
    mulc(l, r, v, a, c, k * 2 + 1);
    mulc(l, r, v, c, b, k * 2 + 2);
    S[k] = (S[k * 2 + 1] + S[k * 2 + 2]) * C[k] % mod;
  }
  long long gets(int l, int r, int a, int b, int k) {
    if (!k) do {
      } while (false);
    if (l >= b || r <= a) return 0;
    if (l <= a && r >= b) return S[k];
    int c = (a + b) / 2;
    return (gets(l, r, a, c, k * 2 + 1) + gets(l, r, c, b, k * 2 + 2)) * C[k] %
           mod;
  }
  long long getc(int p, int a, int b, int k) {
    if (b == a + 1) return C[k];
    int c = (a + b) / 2;
    return (p < c ? getc(p, a, c, k * 2 + 1) : getc(p, c, b, k * 2 + 2)) *
           C[k] % mod;
  }
  void setv(int p, long long v, int a, int b, int k) {
    if (!k) do {
      } while (false);
    if (b == a + 1) {
      S[k] = v * C[k] % mod;
      return;
    }
    int c = (a + b) / 2;
    if (p < c)
      setv(p, v, a, c, k * 2 + 1);
    else
      setv(p, v, c, b, k * 2 + 2);
    S[k] = (S[k * 2 + 1] + S[k * 2 + 2]) * C[k] % mod;
  }
};
struct vert {
  vector<int> g;
  int a = -1, b = -1;
  long long v = LINF;
  int p = -1, c = 1;
};
vector<vert> G(1);
int cnt = 0;
void dfs(int v) {
  G[v].a = cnt;
  ++cnt;
  for (int p : G[v].g) {
    dfs(p);
  }
  G[v].b = cnt;
}
int main(int argc, char **argv) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int tc;
  cin >> G[0].v >> tc;
  vector<int> Q(tc);
  for (int q = 0; q < (tc); ++q) {
    int t;
    cin >> t;
    if (t == 1) {
      int p;
      long long x;
      cin >> p >> x;
      --p;
      int v = ((int)(G).size());
      assert(p < v);
      Q[q] = ~v;
      G.push_back(vert());
      G[v].p = p;
      G[p].g.push_back(v);
      G[v].v = x;
    } else {
      cin >> Q[q];
      --Q[q];
    }
  }
  dfs(0);
  segtree T(((int)(G).size()));
  T.setv(G[0].a, G[0].v, 0, ((int)(G).size()), 0);
  for (int v : Q) {
    do {
    } while (false);
    if (v < 0) {
      v = ~v;
      int p = G[v].p;
      T.setv(G[v].a, G[v].v, 0, ((int)(G).size()), 0);
      int &c = G[p].c;
      long long x = powmod(c, mod - 2, mod) * (c + 1) % mod;
      ++c;
      T.mulc(G[p].a, G[p].b, x, 0, ((int)(G).size()), 0);
    } else {
      long long s = T.gets(G[v].a, G[v].b, 0, ((int)(G).size()), 0);
      long long c = T.getc(G[v].a, 0, ((int)(G).size()), 0);
      long long cc = c * powmod(G[v].c, mod - 2, mod) % mod;
      do {
      } while (false);
      cout << s * powmod(cc, mod - 2, mod) % mod << '\n';
    }
  }
  return 0;
}
