#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5, mod = 1e9 + 7;
struct node {
  int x, y;
};
node seg[4 * N];
node lazy[4 * N];
int n;
int in[N], out[N];
long long depth[N];
vector<int> adj[N];
node Merge(node a, node b) { return node({a.x + a.x % mod, b.y + b.y % mod}); }
void add(int &A, int B) {
  B %= mod;
  A += B;
  A %= mod;
}
void push(int id, int l, int r) {
  add(seg[id].x, (r - l + 1) * lazy[id].x % mod);
  add(seg[id].y, (r - l + 1) * lazy[id].y % mod);
  if (l != r) {
    add(lazy[id * 2].x, lazy[id].x);
    add(lazy[id * 2 + 1].x, lazy[id].x);
    add(lazy[id * 2].y, lazy[id].y);
    add(lazy[id * 2 + 1].y, lazy[id].y);
  }
  lazy[id].x = 0;
  lazy[id].y = 0;
}
void update(int su, int eu, long long val, int f, int id = 1, int l = 0,
            int r = n - 1) {
  push(id, l, r);
  if (l >= su && r <= eu) {
    if (f == 1)
      lazy[id].y += val;
    else
      lazy[id].x += val;
    push(id, l, r);
    return;
  }
  if (r < su || l > eu) return;
  int mid = (l + r) / 2;
  update(su, eu, val, f, id * 2, l, mid);
  update(su, eu, val, f, id * 2 + 1, mid + 1, r);
  seg[id] = Merge(seg[id * 2], seg[id * 2 + 1]);
}
node query(int idx, int id = 1, int l = 0, int r = n - 1) {
  push(id, l, r);
  if (l == r) return node({seg[id].x, seg[id].y});
  int mid = (l + r) / 2;
  if (idx <= mid)
    return query(idx, id * 2, l, mid);
  else
    return query(idx, id * 2 + 1, mid + 1, r);
}
int t = 0;
void dfs(int u, int d) {
  in[u] = t++;
  depth[u] = d;
  for (auto v : adj[u]) dfs(v, d + 1);
  out[u] = t - 1;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = 1; i < n; i++) {
    int p;
    cin >> p;
    p--;
    adj[p].push_back(i);
  }
  dfs(0, 0);
  int q;
  cin >> q;
  while (q--) {
    int c, v;
    cin >> c >> v;
    v--;
    if (c == 2) {
      node ans = query(in[v]);
      printf("%d\n", (ans.x - depth[v] * ans.y % mod + mod) % mod);
    } else {
      int x, k;
      cin >> x >> k;
      update(in[v], out[v], (x + depth[v] * k % mod) % mod, 0);
      update(in[v], out[v], k, 1);
    }
  }
  return 0;
}
