#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
const int MOD = 1e9 + 7;
const int INF = 1e9 + 7;
const int MAXN = 2e6 + 5;
const double eps = 1e-9;
int st[MAXN], en[MAXN], t = 0;
long long lvl[MAXN];
long long tree1[MAXN], tree2[MAXN];
long long lazy1[MAXN], lazy2[MAXN];
vector<int> adj[MAXN];
void dfs(int u, int p, int d) {
  lvl[u] = d;
  st[u] = t++;
  for (int v : adj[u])
    if (v != p) dfs(v, u, d + 1);
  en[u] = t;
}
void prop(int l, int r, int k, bool fl = true) {
  if (l != r) {
    if (fl) {
      lazy1[k * 2] = (lazy1[k * 2] + lazy1[k]) % MOD;
      lazy1[k * 2 + 1] = (lazy1[k * 2 + 1] + lazy1[k]) % MOD;
    } else {
      lazy2[k * 2] = (lazy2[k * 2] + lazy2[k]) % MOD;
      lazy2[k * 2 + 1] = (lazy2[k * 2 + 1] + lazy2[k]) % MOD;
    }
  }
  if (fl)
    lazy1[k] = 0;
  else
    lazy2[k] = 0;
}
long long qry(int l, int r, int k, int a, bool fl = true) {
  if (r < a || a < l) return 0;
  if (fl && lazy1[k] != 0) {
    tree1[k] = (tree1[k] + lazy1[k]) % MOD;
    prop(l, r, k);
  }
  if (!fl && lazy2[k] != 0) {
    tree2[k] = (tree2[k] + lazy2[k]) % MOD;
    prop(l, r, k, false);
  }
  if (a <= l && r <= a) return (fl) ? tree1[k] : tree2[k];
  int m = (l + r) / 2;
  return max(qry(l, m, k * 2, a, fl), qry(m + 1, r, k * 2 + 1, a, fl)) % MOD;
}
void upd(int l, int r, int k, int a, int b, long long val, bool fl = true) {
  if (r < a || b < l) return;
  if (fl && lazy1[k] != 0) {
    tree1[k] = (tree1[k] + lazy1[k]) % MOD;
    prop(l, r, k);
  }
  if (!fl && lazy2[k] != 0) {
    tree2[k] = (tree2[k] + lazy2[k]) % MOD;
    prop(l, r, k, false);
  }
  if (a <= l && r <= b) {
    if (fl) {
      tree1[k] = (tree1[k] + val) % MOD;
      if (l != r) {
        lazy1[k] = (lazy1[k] + val) % MOD;
        prop(l, r, k);
      }
    } else {
      tree2[k] = (tree2[k] + val) % MOD;
      if (l != r) {
        lazy2[k] = (lazy2[k] + val) % MOD;
        prop(l, r, k, false);
      }
    }
    return;
  }
  int m = (l + r) / 2;
  upd(l, m, k * 2, a, b, val, fl);
  upd(m + 1, r, k * 2 + 1, a, b, val, fl);
  if (fl)
    tree1[k] = max(tree1[k * 2], tree1[k * 2 + 1]);
  else
    tree2[k] = max(tree2[k * 2], tree2[k * 2 + 1]);
}
int main() {
  int n;
  scanf("%d", &(n));
  for (int i = 1; i < n; i++) {
    int p;
    scanf("%d", &(p));
    p--;
    adj[i].push_back(p);
    adj[p].push_back(i);
  }
  dfs(0, -1, 1);
  int q;
  scanf("%d", &(q));
  for (int i = 0; i < q; i++) {
    int t, v;
    long long k, x;
    scanf("%d %d", &t, &v);
    v--;
    if (t == 1) {
      scanf("%I64d %I64d", &x, &k);
      long long val = (lvl[v] * k) % MOD;
      val = (val + x) % MOD;
      upd(0, n - 1, 1, st[v], en[v] - 1, val % MOD);
      upd(0, n - 1, 1, st[v], en[v] - 1, k % MOD, false);
    } else {
      long long val = qry(0, n - 1, 1, st[v]) % MOD;
      long long val2 = qry(0, n - 1, 1, st[v], false) % MOD;
      val2 = (val2 * lvl[v]) % MOD;
      val = (val - val2 + MOD) % MOD;
      printf("%I64d\n", (val));
    }
  }
  return 0;
}
