#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &_p) {
  return os << "(" << _p.first << "," << _p.second << ")";
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &_V) {
  bool f = true;
  os << "[";
  for (auto v : _V) {
    os << (f ? "" : ",") << v;
    f = false;
  }
  return os << "]";
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> &_S) {
  bool f = true;
  os << "(";
  for (auto s : _S) {
    os << (f ? "" : ",") << s;
    f = false;
  }
  return os << ")";
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &_M) {
  return os << set<pair<T, U>>(_M.begin(), _M.end());
}
template <class TH>
void _dbg(const char *sdbg, TH h) {
  cerr << sdbg << '=' << h << endl;
}
template <class TH, class... TA>
void _dbg(const char *sdbg, TH h, TA... a) {
  while (*sdbg != ',') cerr << *sdbg++;
  cerr << '=' << h << ',';
  _dbg(sdbg + 1, a...);
}
const signed long long INF = 1000000100;
const long double EPS = 1e-9;
void read_data() {}
void solve() {}
const long long MAXN = 200010;
long long In[MAXN], Out[MAXN];
long long TS;
vector<long long> V[MAXN];
void dfs(long long a) {
  In[a] = ++TS;
  for (long long v : V[a]) dfs(v);
  Out[a] = ++TS;
}
vector<tuple<long long, long long, long long>> Q;
long long val[MAXN];
const long long Mod = 1000000007;
long long odw(long long a) {
  long long b = Mod - 2;
  long long res = 1;
  a %= Mod;
  while (b) {
    if (b % 2) res = (res * a) % Mod;
    a = (a * a) % Mod;
    b /= 2;
  }
  return res;
}
struct tree {
  struct node {
    signed long long result;
    signed long long lazy_s;
    signed long long lazy_m;
    node() : result(0), lazy_s(0), lazy_m(1) {}
  };
  const signed long long ZERO = 0;
  inline void update_s(long long v, signed long long delta) {
    T[v].lazy_s += delta;
    T[v].lazy_s %= Mod;
  }
  inline void update_m(long long v, signed long long delta) {
    T[v].lazy_m = T[v].lazy_m * delta % Mod;
    T[v].lazy_s = T[v].lazy_s * delta % Mod;
  }
  inline void push(long long v) {
    if (v >= M) {
    } else {
      T[2 * v].lazy_m *= T[v].lazy_m;
      T[2 * v].lazy_s = T[2 * v].lazy_s * T[v].lazy_m % Mod;
      T[2 * v].lazy_s += T[v].lazy_s;
      T[2 * v + 1].lazy_m *= T[v].lazy_m;
      T[2 * v + 1].lazy_s = T[2 * v + 1].lazy_s * T[v].lazy_m % Mod;
      T[2 * v + 1].lazy_s += T[v].lazy_s;
      T[2 * v + 1].lazy_m %= Mod;
      T[2 * v].lazy_m %= Mod;
      T[2 * v].lazy_s %= Mod;
      T[2 * v + 1].lazy_s %= Mod;
      T[v].lazy_s = 0;
      T[v].lazy_m = 1;
    }
  }
  inline signed long long eval(long long v) {
    if (v >= M) {
      return T[v].lazy_s;
    } else {
      return (T[2 * v].lazy_s +
              (2 * v < M) * T[2 * v].result * T[v * 2].lazy_m % Mod +
              T[2 * v + 1].lazy_s +
              (2 * v + 1 < M) * T[2 * v + 1].result * T[v * 2 + 1].lazy_m %
                  Mod) %
             Mod;
    }
  }
  inline signed long long merge(const signed long long &x,
                                const signed long long &y) {
    return x + y;
  }
  long long M;
  node *T;
  tree(long long n) : M(1 << (32 - __builtin_clz(n))), T(new node[2 * M]) {}
  inline signed long long get_sum(long long a, long long b, long long l,
                                  long long r, long long v) {
    if (a > r or b < l) return ZERO;
    push(v);
    if (a == l and r == b) {
      return T[v].result = eval(v);
    }
    long long mid = (l + r) / 2;
    signed long long x = get_sum(a, min(b, mid), l, mid, 2 * v) % Mod;
    signed long long y =
        get_sum(max(a, mid + 1), b, mid + 1, r, 2 * v + 1) % Mod;
    T[v].result = eval(v);
    return merge(x, y);
  }
  inline signed long long get_mul(long long a, long long b, long long l,
                                  long long r, long long v) {
    if (a > r or b < l) return 1;
    push(v);
    if (a == l and r == b) {
      T[v].result = eval(v);
      return T[v].lazy_m;
    }
    long long mid = (l + r) / 2;
    signed long long x = get_mul(a, min(b, mid), l, mid, 2 * v) % Mod;
    signed long long y =
        get_mul(max(a, mid + 1), b, mid + 1, r, 2 * v + 1) % Mod;
    T[v].result = eval(v);
    assert(x == 1 or y == 1);
    return x * y % Mod;
  }
  inline void insert_m(long long a, long long b, long long l, long long r,
                       long long v, long long delta) {
    if (a > r or b < l) return;
    push(v);
    if (a == l and r == b) {
      update_m(v, delta);
      push(v);
      T[v].result = eval(v);
      return;
    }
    long long mid = (l + r) / 2;
    insert_m(a, min(b, mid), l, mid, 2 * v, delta);
    insert_m(max(a, mid + 1), b, mid + 1, r, 2 * v + 1, delta);
    T[v].result = eval(v);
  }
  inline void insert_s(long long a, long long b, long long l, long long r,
                       long long v, long long delta) {
    if (a > r or b < l) return;
    push(v);
    if (a == l and r == b) {
      update_s(v, delta);
      push(v);
      T[v].result = eval(v);
      return;
    }
    long long mid = (l + r) / 2;
    insert_s(a, min(b, mid), l, mid, 2 * v, delta);
    insert_s(max(a, mid + 1), b, mid + 1, r, 2 * v + 1, delta);
    T[v].result = eval(v);
  }
  void Mul(long long a, long long b, signed long long c) {
    insert_m(a, b, 0, M - 1, 1, c);
  }
  void Add(long long a, signed long long c) { insert_s(a, a, 0, M - 1, 1, c); }
  signed long long get_sum(long long a, long long b) {
    return get_sum(a, b, 0, M - 1, 1) % Mod;
  }
  signed long long get_mul(long long a) {
    return get_mul(a, a, 0, M - 1, 1) % Mod;
  }
};
struct brute {
  vector<signed long long> SUM;
  vector<signed long long> MUL;
  brute(long long N) : SUM(N, 0), MUL(N, 1) {}
  void Mul(long long a, long long b, signed long long c) {
    for (long long(i) = (a); (i) <= (b); (i)++) SUM[i] = SUM[i] * c % Mod;
    for (long long(i) = (a); (i) <= (b); (i)++) MUL[i] = MUL[i] * c % Mod;
  }
  void Add(long long a, signed long long c) {
    for (long long(i) = (a); (i) <= (a); (i)++) SUM[i] = (SUM[i] + c) % Mod;
  }
  signed long long get_sum(long long a, long long b) {
    signed long long ret = 0;
    for (long long(i) = (a); (i) <= (b); (i)++) ret = (ret + SUM[i]) % Mod;
    return ret;
  }
  signed long long get_mul(long long a) {
    signed long long ret = MUL[a];
    return ret;
  }
};
void test() {
  srand(time(NULL));
  const long long N = 1000;
  const long long MAX_DELTA = 1000000;
  tree T(N);
  brute A(N);
  long long cnt = 0;
  while (true) {
    cnt++;
    if (cnt % 100000 == 0) {
      printf("%lld queries successfully done\n", cnt);
    }
    long long a = rand() % N;
    long long b = rand() % N;
    long long c = rand() % MAX_DELTA;
    if (a > b) swap(a, b);
    T.Add(a, c);
    A.Add(a, c);
    a = rand() % N;
    b = rand() % N;
    if (a > b) swap(a, b);
    signed long long x = T.get_sum(a, b);
    signed long long y = A.get_sum(a, b);
    if (x != y) {
      printf("Failed after %lld queries!!\n", cnt);
      ;
      ;
      exit(1);
    }
    a = rand() % N;
    b = rand() % N;
    c = rand() % MAX_DELTA;
    if (a > b) swap(a, b);
    T.Mul(a, b, c);
    A.Mul(a, b, c);
    a = rand() % N;
    b = rand() % N;
    if (a > b) swap(a, b);
    x = T.get_mul(a);
    y = A.get_mul(a);
    if (x != y) {
      printf("Failed after %lld queries!\n", cnt);
      exit(1);
    }
  }
}
signed long long S[MAXN];
int main() {
  long long q;
  scanf("%lld%lld", &val[1], &q);
  long long nxt = 1;
  for (long long(i) = (1); (i) <= (q); (i)++) {
    long long t, a, b;
    scanf("%lld", &t);
    if (t == 1) {
      nxt++;
      scanf("%lld%lld", &a, &b);
      V[a].push_back(nxt);
      val[nxt] = b;
      b = nxt;
    } else {
      scanf("%lld", &a);
      b = -1;
    }
    Q.push_back(tie(t, a, b));
  }
  dfs(1);
  S[1] = 1;
  tree TRE(TS + 13);
  TRE.Add(In[1], val[1]);
  for (auto ev : Q) {
    long long t, a, b;
    tie(t, a, b) = ev;
    if (t == 1) {
      S[b] = 1;
      S[a]++;
      TRE.Mul(In[a], Out[a], S[a] * odw(S[a] - 1) % Mod);
      ;
      ;
      TRE.Add(In[b], val[b] * TRE.get_mul(In[b]));
    } else {
      printf("%lld\n", S[a] * TRE.get_sum(In[a], Out[a]) % Mod *
                           odw(TRE.get_mul(In[a])) % Mod);
    }
  }
}
