#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:667772160")
template <class T1>
void deb(T1 e1) {
  cout << e1 << endl;
}
template <class T1, class T2>
void deb(T1 e1, T2 e2) {
  cout << e1 << " " << e2 << endl;
}
template <class T1, class T2, class T3>
void deb(T1 e1, T2 e2, T3 e3) {
  cout << e1 << " " << e2 << " " << e3 << endl;
}
template <class T1, class T2, class T3, class T4>
void deb(T1 e1, T2 e2, T3 e3, T4 e4) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << endl;
}
template <class T1, class T2, class T3, class T4, class T5>
void deb(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << " " << e5 << endl;
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
void deb(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5, T6 e6) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << " " << e5 << " " << e6
       << endl;
}
struct data {
  int mn_level;
  long long k, valu;
};
int level[300000 + 7], id = 1;
vector<int> graph[300000 + 7];
data tree[4 * 300000 + 7];
pair<int, int> v_range[300000 + 7];
long long ads(long long a, long long b) {
  if (a < 0) a += 1000000007;
  if (b < 0) b += 1000000007;
  a = a % 1000000007;
  b = b % 1000000007;
  return (a + b) % 1000000007;
}
long long mns(long long a, long long b) {
  a = (a + 1000000007) % 1000000007;
  b = (b + 1000000007) % 1000000007;
  a = (a - b + 1000000007) % 1000000007;
  return a;
}
long long mls(long long a, long long b) {
  if (a < 0) a += 1000000007;
  if (b < 0) b += 1000000007;
  a = a % 1000000007;
  b = b % 1000000007;
  return (a * b) % 1000000007;
}
void dfs(int cur = 1, int par = -1, int dp = 1) {
  v_range[cur].first = id;
  int v;
  for (int i = 0; i < graph[cur].size(); i++) {
    v = graph[cur][i];
    if (v == par) continue;
    dfs(v, cur, dp + 1);
  }
  level[id] = dp;
  v_range[cur].second = id++;
}
void build(int nd, int l, int r) {
  if (l == r) {
    tree[nd].mn_level = level[l];
    return;
  }
  int mid = (l + r) / 2, lft = 2 * nd, rgt = lft + 1;
  build(lft, l, mid);
  build(rgt, mid + 1, r);
  tree[nd].mn_level = min(tree[lft].mn_level, tree[rgt].mn_level);
}
void update(int nd, int l, int r, int i, int j, int v, long long valu,
            long long k) {
  if (r < i or l > j) return;
  if (l >= i and r <= j) {
    long long tp = mns(valu, mls(tree[nd].mn_level - level[v], k));
    tree[nd].valu = ads(tree[nd].valu, tp);
    tree[nd].k = ads(tree[nd].k, k);
    return;
  }
  int mid = (l + r) / 2, lft = 2 * nd, rgt = lft + 1;
  update(lft, l, mid, i, j, v, valu, k);
  update(rgt, mid + 1, r, i, j, v, valu, k);
}
long long query(int nd, int l, int r, int id) {
  if (r < id or l > id) return 0;
  if (l == r) return tree[nd].valu;
  int mid = (l + r) / 2, lft = 2 * nd, rgt = lft + 1;
  long long ans =
      mns(tree[nd].valu, mls(level[id] - tree[nd].mn_level, tree[nd].k));
  long long tp = query(lft, l, mid, id);
  ans = ads(tp, ans);
  tp = query(rgt, mid + 1, r, id);
  ans = ads(ans, tp);
  return ans;
}
int main() {
  int n, u;
  scanf("%d", &n);
  for (int i = 2; i <= n; i++) {
    scanf("%d", &u);
    graph[u].push_back(i);
    graph[i].push_back(u);
  }
  dfs();
  build(1, 1, n);
  int q, t, x, k;
  scanf("%d", &q);
  while (q--) {
    scanf("%d %d", &t, &u);
    if (t == 1) {
      scanf("%d %d", &x, &k);
      update(1, 1, n, v_range[u].first, v_range[u].second, v_range[u].second, x,
             k);
    } else {
      long long ans = query(1, 1, n, v_range[u].second);
      deb(ans);
    }
  }
  return 0;
}
