#include <bits/stdc++.h>
const int N = 3e5 + 10;
const int mod = 1e9 + 7;
int n;
std::vector<int> edge[N];
std::pair<int, int> v[N];
int q;
std::pair<int, int> query[N];
int queue[N];
std::pair<int, int> range[N];
int father[N];
int degree[N];
int fastPower(int x, int y) {
  int ret = 1;
  for (; y; y >>= 1) {
    if (y & 1) {
      ret = (long long)ret * x % mod;
    }
    x = (long long)x * x % mod;
  }
  return ret;
}
int inv(int x) { return fastPower(x, mod - 2); }
int lowbit(int x) { return x & (-x); }
struct FenwickTree {
  int e[N];
  void build(int size) {
    for (int i = 1; i <= size; i++) {
      e[i] = 1;
    }
  }
  void change(int x, int value) {
    for (int i = x; i <= n; i += lowbit(i)) {
      e[i] = (long long)e[i] * value % mod;
    }
  }
  int getValue(int x) {
    int ret = 1;
    for (int i = x; i >= 1; i -= lowbit(i)) {
      ret = (long long)ret * e[i] % mod;
    }
    return ret;
  }
};
FenwickTree ft;
struct SegmentTree {
  struct Node {
    int sum;
    int tag;
  };
  Node tree[N << 2];
  void update(int root, int left, int right) {
    tree[root].sum = (long long)tree[root].sum * tree[root].tag % mod;
    if (left != right) {
      tree[root << 1].tag =
          (long long)tree[root << 1].tag * tree[root].tag % mod;
      tree[root << 1 | 1].tag =
          (long long)tree[root << 1 | 1].tag * tree[root].tag % mod;
    }
    tree[root].tag = 1;
  }
  void change(int root, int left, int right, int pos, int value) {
    update(root, left, right);
    if (left == pos && right == pos) {
      tree[root].sum = value;
      return;
    }
    int mid = (left + right) >> 1;
    if (pos <= mid) {
      change(root << 1, left, mid, pos, value);
    } else {
      change(root << 1 | 1, mid + 1, right, pos, value);
    }
    update(root << 1, left, mid);
    update(root << 1 | 1, mid + 1, right);
    tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum;
  }
  void change2(int root, int left, int right, int ql, int qr, int value) {
    update(root, left, right);
    if (left == ql && right == qr) {
      tree[root].tag = value;
      update(root, left, right);
      return;
    }
    int mid = (left + right) >> 1;
    if (qr <= mid) {
      change2(root << 1, left, mid, ql, qr, value);
    } else if (ql > mid) {
      change2(root << 1 | 1, mid + 1, right, ql, qr, value);
    } else {
      change2(root << 1, left, mid, ql, mid, value);
      change2(root << 1 | 1, mid + 1, right, mid + 1, qr, value);
    }
    update(root << 1, left, mid);
    update(root << 1 | 1, mid + 1, right);
    tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum;
  }
  int getSum(int root, int left, int right, int ql, int qr) {
    update(root, left, right);
    if (left == ql && right == qr) {
      return tree[root].sum;
    }
    int mid = (left + right) >> 1;
    if (qr <= mid) {
      return getSum(root << 1, left, mid, ql, qr);
    } else if (ql > mid) {
      return getSum(root << 1 | 1, mid + 1, right, ql, qr);
    } else {
      return (getSum(root << 1, left, mid, ql, mid) +
              getSum(root << 1 | 1, mid + 1, right, mid + 1, qr)) %
             mod;
    }
  }
};
SegmentTree st;
void init() {
  std::cin >> v[1].second >> q;
  n = 1;
  for (int i = 1; i <= q; i++) {
    scanf("%d%d", &query[i].first, &query[i].second);
    if (query[i].first == 1) {
      father[++n] = query[i].second;
      scanf("%d", &v[n].second);
      edge[father[n]].push_back(n);
    }
  }
}
void dfs(int u) {
  static int tot = 0;
  queue[++tot] = u;
  range[u].first = tot;
  for (int i = 0; i < (int)edge[u].size(); i++) {
    dfs(edge[u][i]);
  }
  range[u].second = tot;
}
void work() {
  dfs(1);
  std::fill(degree + 1, degree + n + 1, 1);
  ft.build(n);
  int tmp = 1;
  v[1].first = v[1].second;
  st.change(1, 1, n, range[1].first, v[1].first);
  for (int i = 1; i <= q; i++) {
    if (query[i].first == 1) {
      int fa = query[i].second;
      tmp++;
      v[tmp].first = v[tmp].second;
      degree[fa]++;
      int cc = (long long)degree[fa] * inv(degree[fa] - 1) % mod;
      ft.change(range[fa].first, cc);
      ft.change(range[fa].second + 1, inv(cc));
      st.change2(1, 1, n, range[fa].first, range[fa].second, cc);
      st.change(1, 1, n, range[tmp].first,
                (long long)v[tmp].first * ft.getValue(range[tmp].first) % mod);
    } else {
      int u = query[i].second;
      int answer = st.getSum(1, 1, n, range[u].first, range[u].second);
      if (u != 1) {
        answer =
            (long long)answer * inv(ft.getValue(range[father[u]].first)) % mod;
      }
      printf("%d\n", answer);
    }
  }
}
int main() {
  init();
  work();
  return 0;
}
