#include <bits/stdc++.h>
int IntMaxVal = (int)1e20;
int IntMinVal = (int)-1e20;
long long LongMaxVal = (long long)1e20;
long long LongMinVal = (long long)-1e20;
using namespace std;
template <typename T>
struct argument_type;
template <typename T, typename U>
struct argument_type<T(U)> {};
template <typename T1, typename T2>
istream& operator>>(istream& is, pair<T1, T2>& s) {
  is >> s.first >> s.second;
  return is;
}
const int mod = 1000 * 1000 * 1000 + 7;
template <typename T>
class sumTree {
  int gp2(int n) {
    int x = 2;
    while (x < n) x *= 2;
    return x;
  }
  vector<T> data;
  int n;

 public:
  void init(int n) {
    this->n = n = gp2(n);
    data.resize(2 * n);
  }
  T getRes(int i) {
    T res = 0;
    i += n;
    do {
      res += data[i];
      i /= 2;
    } while (i);
    res %= mod;
    return res;
  }
  void add(int l, int r, int i, int fl, int fr, T x) {
    if (l == fl && r + 1 == fr) {
      data[i] += x;
      data[i] %= mod;
      if (data[i] < 0) data[i] += mod;
    } else {
      int m = (fl + fr) / 2;
      if (l < m) add(l, min(r, m - 1), 2 * i, fl, m, x);
      if (r >= m) add(max(l, m), r, 2 * i + 1, m, fr, x);
    }
  }
  void add(int l, int r, T x) { add(l, r, 1, 0, n, x); }
};
sumTree<long long> constSums;
sumTree<long long> heightSums;
int main() {
  ios_base::sync_with_stdio(false);
  int n;
  cin >> n;
  ;
  constSums.init(n);
  heightSums.init(n);
  vector<int> index(n + 1);
  vector<int> right(n + 1);
  vector<int> depth(n + 1);
  vector<vector<int> > children(n + 1);
  vector<int> parent(n + 1);
  const int root = 1;
  parent[root] = -1;
  for (int i = 2; i < n + 1; ++i) {
    cin >> parent[i];
    children[parent[i]].push_back(i);
  }
  vector<int> q;
  q.push_back(root);
  vector<int> order;
  depth[root] = 0;
  while (q.size()) {
    int x = q.back();
    q.pop_back();
    if (x < 0) {
      x = -x;
      right[x] = (int)order.size() - 1;
    } else {
      index[x] = order.size();
      order.push_back(x);
      q.push_back(-x);
      for (auto c : children[x]) {
        q.push_back(c);
        depth[c] = depth[x] + 1;
      }
    }
  }
  int qx;
  cin >> qx;
  ;
  while (qx-- > 0) {
    int tp;
    cin >> tp;
    ;
    int v;
    cin >> v;
    ;
    if (tp == 1) {
      long long x;
      cin >> x;
      ;
      long long k;
      cin >> k;
      ;
      int d = depth[v];
      long long constAdd = x + d * k;
      constAdd %= mod;
      int l = index[v];
      int r = right[v];
      constSums.add(l, r, constAdd);
      heightSums.add(l, r, k);
    } else {
      int i = index[v];
      long long res = constSums.getRes(i) - depth[v] * heightSums.getRes(i);
      res %= mod;
      if (res < 0) res += mod;
      cout << res << endl;
    }
  }
}
