#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <time.h>
#include <iostream>
#include <functional>
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <string>
#include <bitset>
#include <unordered_map>
#include <set>
using namespace std;
typedef long long lint;
typedef long double llf;
typedef pair<int, int> pi;
const int mod = 1e9 + 7;
vector<int> gph[100005];
int par[17][100005], dep[100005];
int dfn[100005], size[100005];
int n, piv;
struct mat{
int a[2][2];
mat operator*(const mat &a)const{
mat c;
for(int i=0; i<2; i++){
for(int j=0; j<2; j++){
c.a[i][j] = 0;
for(int k=0; k<2; k++){
c.a[i][j] += 1ll * this->a[i][k] * a.a[k][j] % mod;
c.a[i][j] %= mod;
}
}
}
return c;
}
mat operator+(const mat &a)const{
mat c;
for(int i=0; i<2; i++){
for(int j=0; j<2; j++){
c.a[i][j] = this->a[i][j] + a.a[i][j];
c.a[i][j] %= mod;
}
}
return c;
}
}fib, base, inv, gap[100005];
struct bit{
int tree[100005];
void add(int x, int v){
while(x <= n+1){
tree[x] += v;
tree[x] %= mod;
x += x & -x;
}
}
int query(int x){
int ret = 0;
while(x){
ret += tree[x];
ret %= mod;
x -= x & -x;
}
return ret;
}
}bit;
struct bit2{
mat tree[100005];
void add(int x, mat y){
while(x <= n+1){
tree[x] = tree[x] + y;
x += x & -x;
}
}
mat query(int x){
mat ret;
memset(ret.a, 0, sizeof(ret.a));
while(x){
ret = ret + tree[x];
x -= x & -x;
}
return ret;
}
}bit2;
mat ipow(mat x, lint y){
mat ret = base, piv = x;
while(y){
if(y&1) ret = ret * piv;
piv = piv * piv;
y >>= 1;
}
return ret;
}
int lca(int s, int e){
if(dep[s] < dep[e]) swap(s, e);
int dx = dep[s] - dep[e];
for(int i=16; i>=0; i--){
if((dx >> i) & 1) s = par[i][s];
}
for(int i=16; i>=0; i--){
if(par[i][s] != par[i][e]){
s = par[i][s];
e = par[i][e];
}
}
if(s != e) return par[0][s];
return s;
}
int getfib(lint x){
return ipow(fib, x).a[1][0];
}
lint get(int x){
if(x == 0) return 0;
return ((gap[x] * bit2.query(dfn[x])).a[1][0] + bit.query(dfn[x])) % mod;
}
int query(int s, int e){
int l = lca(s, e);
lint ret = get(s) + get(e) - get(l) - get(par[0][l]) + 2 * mod;
return ret % mod;
}
void init(int x){
dfn[x] = ++piv;
size[x] = 1;
for(auto &i : gph[x]){
gap[i] = gap[x] * fib;
init(i);
size[x]+=size[i];
}
}
void addmat(int x, lint val){
mat toadd;
if(val < 0){
toadd = ipow(inv, -val);
}
if(val == 0){
toadd = base;
}
if(val > 0){
toadd = ipow(fib, val);
}
bit2.add(dfn[x], toadd);
for(int i=0; i<2; i++){
for(int j=0; j<2; j++){
toadd.a[i][j] = mod - toadd.a[i][j];
}
}
bit2.add(dfn[x] + size[x], toadd);
}
int main(){
int m;
cin >> n >> m;
for(int i=2; i<=n; i++){
scanf("%d",&par[0][i]);
dep[i] = dep[par[0][i]] + 1;
gph[par[0][i]].push_back(i);
}
for(int i=1; i<17; i++){
for(int j=1; j<=n; j++){
par[i][j] = par[i-1][par[i-1][j]];
}
}
base.a[0][0] = base.a[1][1] = 1;
fib.a[0][0] = fib.a[0][1] = fib.a[1][0] = 1;
inv.a[0][1] = inv.a[1][0] = 1;
inv.a[1][1] = -1;
gap[1] = base;
init(1);
char t[5];
while(m--){
scanf("%s",t);
if(*t == 'Q'){
int s, e;
scanf("%d %d",&s,&e);
printf("%d\n",query(s, e));
}
else{
int x; lint y;
scanf("%d %lld",&x,&y);
lint p1 = getfib(y+1);
bit.add(dfn[x], mod - p1);
bit.add(dfn[x] + size[x], p1);
addmat(x, y + 2 - dep[x]);
}
}
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxsaW1pdHMuaD4KI2luY2x1ZGUgPG1hdGguaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHN0YWNrPgojaW5jbHVkZSA8cXVldWU+CiNpbmNsdWRlIDxkZXF1ZT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGJpdHNldD4KI2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDxzZXQ+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnR5cGVkZWYgbG9uZyBsb25nIGxpbnQ7CnR5cGVkZWYgbG9uZyBkb3VibGUgbGxmOwp0eXBlZGVmIHBhaXI8aW50LCBpbnQ+IHBpOwpjb25zdCBpbnQgbW9kID0gMWU5ICsgNzsKCnZlY3RvcjxpbnQ+IGdwaFsxMDAwMDVdOwppbnQgcGFyWzE3XVsxMDAwMDVdLCBkZXBbMTAwMDA1XTsKaW50IGRmblsxMDAwMDVdLCBzaXplWzEwMDAwNV07CmludCBuLCBwaXY7CgpzdHJ1Y3QgbWF0ewoJaW50IGFbMl1bMl07CgltYXQgb3BlcmF0b3IqKGNvbnN0IG1hdCAmYSljb25zdHsKCQltYXQgYzsKCQlmb3IoaW50IGk9MDsgaTwyOyBpKyspewoJCQlmb3IoaW50IGo9MDsgajwyOyBqKyspewoJCQkJYy5hW2ldW2pdID0gMDsKCQkJCWZvcihpbnQgaz0wOyBrPDI7IGsrKyl7CgkJCQkJYy5hW2ldW2pdICs9IDFsbCAqIHRoaXMtPmFbaV1ba10gKiBhLmFba11bal0gJSBtb2Q7CgkJCQkJYy5hW2ldW2pdICU9IG1vZDsKCQkJCX0KCQkJfQoJCX0KCQlyZXR1cm4gYzsKCX0KCW1hdCBvcGVyYXRvcisoY29uc3QgbWF0ICZhKWNvbnN0ewoJCW1hdCBjOwoJCWZvcihpbnQgaT0wOyBpPDI7IGkrKyl7CgkJCWZvcihpbnQgaj0wOyBqPDI7IGorKyl7CgkJCQljLmFbaV1bal0gPSB0aGlzLT5hW2ldW2pdICsgYS5hW2ldW2pdOwoJCQkJYy5hW2ldW2pdICU9IG1vZDsKCQkJfQoJCX0KCQlyZXR1cm4gYzsKCX0KfWZpYiwgYmFzZSwgaW52LCBnYXBbMTAwMDA1XTsKCnN0cnVjdCBiaXR7CglpbnQgdHJlZVsxMDAwMDVdOwoJdm9pZCBhZGQoaW50IHgsIGludCB2KXsKCQl3aGlsZSh4IDw9IG4rMSl7CgkJCXRyZWVbeF0gKz0gdjsKCQkJdHJlZVt4XSAlPSBtb2Q7CgkJCXggKz0geCAmIC14OwoJCX0KCX0KCWludCBxdWVyeShpbnQgeCl7CgkJaW50IHJldCA9IDA7CgkJd2hpbGUoeCl7CgkJCXJldCArPSB0cmVlW3hdOwoJCQlyZXQgJT0gbW9kOwoJCQl4IC09IHggJiAteDsKCQl9CgkJcmV0dXJuIHJldDsKCX0KfWJpdDsKCnN0cnVjdCBiaXQyewoJbWF0IHRyZWVbMTAwMDA1XTsKCXZvaWQgYWRkKGludCB4LCBtYXQgeSl7CgkJd2hpbGUoeCA8PSBuKzEpewoJCQl0cmVlW3hdID0gdHJlZVt4XSArIHk7CgkJCXggKz0geCAmIC14OwoJCX0KCX0KCW1hdCBxdWVyeShpbnQgeCl7CgkJbWF0IHJldDsKCQltZW1zZXQocmV0LmEsIDAsIHNpemVvZihyZXQuYSkpOwoJCXdoaWxlKHgpewoJCQlyZXQgPSByZXQgKyB0cmVlW3hdOwoJCQl4IC09IHggJiAteDsKCQl9CgkJcmV0dXJuIHJldDsKCX0KfWJpdDI7CgptYXQgaXBvdyhtYXQgeCwgbGludCB5KXsKCW1hdCByZXQgPSBiYXNlLCBwaXYgPSB4OwoJd2hpbGUoeSl7CgkJaWYoeSYxKSByZXQgPSByZXQgKiBwaXY7CgkJcGl2ID0gcGl2ICogcGl2OwoJCXkgPj49IDE7Cgl9CglyZXR1cm4gcmV0Owp9CgppbnQgbGNhKGludCBzLCBpbnQgZSl7CglpZihkZXBbc10gPCBkZXBbZV0pIHN3YXAocywgZSk7CglpbnQgZHggPSBkZXBbc10gLSBkZXBbZV07Cglmb3IoaW50IGk9MTY7IGk+PTA7IGktLSl7CgkJaWYoKGR4ID4+IGkpICYgMSkgcyA9IHBhcltpXVtzXTsKCX0KCWZvcihpbnQgaT0xNjsgaT49MDsgaS0tKXsKCQlpZihwYXJbaV1bc10gIT0gcGFyW2ldW2VdKXsKCQkJcyA9IHBhcltpXVtzXTsKCQkJZSA9IHBhcltpXVtlXTsKCQl9Cgl9CglpZihzICE9IGUpIHJldHVybiBwYXJbMF1bc107CglyZXR1cm4gczsKfQoKaW50IGdldGZpYihsaW50IHgpewoJcmV0dXJuIGlwb3coZmliLCB4KS5hWzFdWzBdOwp9CgpsaW50IGdldChpbnQgeCl7CglpZih4ID09IDApIHJldHVybiAwOwoJcmV0dXJuICgoZ2FwW3hdICogYml0Mi5xdWVyeShkZm5beF0pKS5hWzFdWzBdICsgYml0LnF1ZXJ5KGRmblt4XSkpICUgbW9kOwp9CgppbnQgcXVlcnkoaW50IHMsIGludCBlKXsKCWludCBsID0gbGNhKHMsIGUpOwoJbGludCByZXQgPSBnZXQocykgKyBnZXQoZSkgLSBnZXQobCkgLSBnZXQocGFyWzBdW2xdKSArIDIgKiBtb2Q7CglyZXR1cm4gcmV0ICUgbW9kOwp9Cgp2b2lkIGluaXQoaW50IHgpewoJZGZuW3hdID0gKytwaXY7CglzaXplW3hdID0gMTsKCWZvcihhdXRvICZpIDogZ3BoW3hdKXsKCQlnYXBbaV0gPSBnYXBbeF0gKiBmaWI7CgkJaW5pdChpKTsKCQlzaXplW3hdKz1zaXplW2ldOwoJfQp9Cgp2b2lkIGFkZG1hdChpbnQgeCwgbGludCB2YWwpewoJbWF0IHRvYWRkOwoJaWYodmFsIDwgMCl7CgkJdG9hZGQgPSBpcG93KGludiwgLXZhbCk7Cgl9CglpZih2YWwgPT0gMCl7CgkJdG9hZGQgPSBiYXNlOwoJfQoJaWYodmFsID4gMCl7CgkJdG9hZGQgPSBpcG93KGZpYiwgdmFsKTsKCX0KCWJpdDIuYWRkKGRmblt4XSwgdG9hZGQpOwoJZm9yKGludCBpPTA7IGk8MjsgaSsrKXsKCQlmb3IoaW50IGo9MDsgajwyOyBqKyspewoJCQl0b2FkZC5hW2ldW2pdID0gbW9kIC0gdG9hZGQuYVtpXVtqXTsKCQl9Cgl9CgliaXQyLmFkZChkZm5beF0gKyBzaXplW3hdLCB0b2FkZCk7Cn0KCmludCBtYWluKCl7CglpbnQgbTsKCWNpbiA+PiBuID4+IG07Cglmb3IoaW50IGk9MjsgaTw9bjsgaSsrKXsKCQlzY2FuZigiJWQiLCZwYXJbMF1baV0pOwoJCWRlcFtpXSA9IGRlcFtwYXJbMF1baV1dICsgMTsKCQlncGhbcGFyWzBdW2ldXS5wdXNoX2JhY2soaSk7Cgl9Cglmb3IoaW50IGk9MTsgaTwxNzsgaSsrKXsKCQlmb3IoaW50IGo9MTsgajw9bjsgaisrKXsKCQkJcGFyW2ldW2pdID0gcGFyW2ktMV1bcGFyW2ktMV1bal1dOwoJCX0KCX0KCWJhc2UuYVswXVswXSA9IGJhc2UuYVsxXVsxXSA9IDE7CglmaWIuYVswXVswXSA9IGZpYi5hWzBdWzFdID0gZmliLmFbMV1bMF0gPSAxOwoJaW52LmFbMF1bMV0gPSBpbnYuYVsxXVswXSA9IDE7CglpbnYuYVsxXVsxXSA9IC0xOwoJZ2FwWzFdID0gYmFzZTsKCWluaXQoMSk7CgljaGFyIHRbNV07Cgl3aGlsZShtLS0pewoJCXNjYW5mKCIlcyIsdCk7CgkJaWYoKnQgPT0gJ1EnKXsKCQkJaW50IHMsIGU7CgkJCXNjYW5mKCIlZCAlZCIsJnMsJmUpOwoJCQlwcmludGYoIiVkXG4iLHF1ZXJ5KHMsIGUpKTsKCQl9CgkJZWxzZXsKCQkJaW50IHg7IGxpbnQgeTsKCQkJc2NhbmYoIiVkICVsbGQiLCZ4LCZ5KTsKCQkJbGludCBwMSA9IGdldGZpYih5KzEpOwoJCQliaXQuYWRkKGRmblt4XSwgbW9kIC0gcDEpOwoJCQliaXQuYWRkKGRmblt4XSArIHNpemVbeF0sIHAxKTsKCQkJYWRkbWF0KHgsIHkgKyAyIC0gZGVwW3hdKTsKCQl9Cgl9Cn0=