#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long x = 0;
  char ch = getchar();
  bool f = 0;
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = 1;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  return f ? -x : x;
}
void write(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
void writeln(long long x) {
  write(x);
  puts("");
}
void writep(long long x) {
  write(x);
  putchar(' ');
}
const int N = 6e5 + 5, mo = 1000000007;
int n, dep[N], c[N], st[N], ed[N], cnt, head[N], opt, dfn[N], size[N], tot;
struct info {
  int to, nxt;
} e[N << 1];
void link(int x, int y) {
  e[++opt] = (info){y, head[x]};
  head[x] = opt;
  e[++opt] = (info){x, head[y]};
  head[y] = opt;
}
void dfs(int u, int fa) {
  dep[u] = dep[fa] + 1;
  st[u] = ++cnt;
  size[u] = 1;
  dfn[u] = ++tot;
  for (int i = head[u]; i; i = e[i].nxt) {
    int k = e[i].to;
    if (k == fa) continue;
    dfs(k, u);
    size[u] += size[k];
  }
  ed[u] = ++cnt;
}
int upd(int x, int y) {
  x += y;
  if (x < 0) x += mo;
  if (x >= mo) x -= mo;
  return x;
}
void add(int x, int y) {
  for (int i = x; i <= 2 * n; i += (i & -i)) c[i] = upd(c[i], y);
}
int find(int x) {
  int res = 0;
  for (int i = x; i; i -= (i & -i)) res = upd(res, c[i]);
  return res;
}
int sum[N << 2], lazy[N << 2], len[N << 2];
void buildtree(int k, int l, int r) {
  len[k] = r - l + 1;
  if (l == r) return;
  int mid = l + r >> 1;
  buildtree(k << 1, l, mid);
  buildtree(k << 1 | 1, mid + 1, r);
}
void modify(int k, int x) {
  lazy[k] = upd(lazy[k], x);
  sum[k] = upd(sum[k], (long long)len[k] * x % mo);
}
void pushdown(int k) {
  if (!lazy[k]) return;
  modify(k << 1, lazy[k]);
  modify(k << 1 | 1, lazy[k]);
  lazy[k] = 0;
}
void change(int k, int l, int r, int L, int R, int x) {
  if (l >= L && r <= R) {
    modify(k, x);
    return;
  }
  pushdown(k);
  int mid = l + r >> 1;
  if (L <= mid) change(k << 1, l, mid, L, R, x);
  if (R > mid) change(k << 1 | 1, mid + 1, r, L, R, x);
  sum[k] = upd(sum[k << 1], sum[k << 1 | 1]);
}
int query(int k, int l, int r, int pos) {
  if (l == r) return sum[k];
  pushdown(k);
  int mid = l + r >> 1;
  if (pos <= mid) return query(k << 1, l, mid, pos);
  return query(k << 1 | 1, mid + 1, r, pos);
}
int main() {
  n = read();
  for (int i = (int)(2); i <= (int)(n); i++) link(i, read());
  dfs(1, 0);
  buildtree(1, 1, n);
  int m = read();
  for (int i = (int)(1); i <= (int)(m); i++) {
    int op = read(), x = read();
    if (op == 1) {
      int y = read(), z = read();
      int t = upd(y, (long long)dep[x] * z % mo);
      add(st[x], t);
      add(ed[x], mo - t);
      change(1, 1, n, dfn[x], dfn[x] + size[x] - 1, z);
    } else {
      int t = query(1, 1, n, dfn[x]);
      int ans = find(st[x]) - (long long)dep[x] * t % mo;
      writeln((ans + mo) % mo);
    }
  }
}
