#include using namespace std; #define rep(i,a,n) for (int i=(a);i<(n);i++) #define per(i,n,a) for (int i=(n)-1;i>=(a);i--) #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second typedef long long ll; typedef long double ld; typedef vector vi; typedef vector vll; typedef pair pll; const int maxn=300500; const int maxk=19; const int mod=(int)1e9+7; void inc(int &x,int y){ x+=y; if(x>=mod)x-=mod; } int sum(int x,int y){ inc(x,y); return x; } namespace fibcalc{ int fib[maxn]; void pre(){ fib[0]=fib[1]=1; rep(i,2,maxn){ fib[i]=sum(fib[i-1],fib[i-2]); } } int calc(int n,int a,int b){ if(n==0)return a; if(n==1)return b; return (1LL*a*fib[n-2]+1LL*b*fib[n-1])%mod; } int calcnth(int n,int a,int b){ //0-index if(n==0)return a; int ret=sum(calc(n+2,a,b),mod-b); return ret; } } struct fenwick { int n; int sa, sb; int *fa, *fb; fenwick(){} fenwick(int n): n(n), sa(0), sb(0){ fa = new int[n]; fb = new int[n]; for(int i=0;i=0;i=(i&(i+1))-1){ inc(a,mod-fa[i]); inc(b,mod-fb[i]); } return fibcalc::calc(idx,a,b); } }; int mark[maxn],sz[maxn]; int n,q; vector g[maxn]; int anc[maxn]; vector nodes; void calcsz(int v,int p=-1){ nodes.pb(v); sz[v]=1; anc[v]=p; for(int x:g[v]){ if(x==p||mark[x])continue; calcsz(x,v); sz[v]+=sz[x]; } } int find(int n){ for(int x:nodes){ int mxsz=n-sz[x]; for(int y:g[x]){ if(mark[y]||y==anc[x])continue; mxsz=max(mxsz,sz[y]); } if(mxsz<=n/2)return x; } assert(false); } int curtreenum=0; int treenum[maxn][maxk]; int depthon[maxn][maxk]; int rooton[maxn][maxk]; fenwick tree[2*maxn]; int lvl[maxn]; int dfs(int v,int root,int p=-1,int de=0,int num=-1){ treenum[v][lvl[root]]=num; depthon[v][lvl[root]]=de; rooton[v][lvl[root]]=root; int mxsz=de; for(int x:g[v]){ if(x==p||mark[x])continue; if(root==v)curtreenum++; mxsz=max(mxsz,dfs(x,root,v,de+1,curtreenum)); } if(v==root){ tree[v]=fenwick(mxsz+1); }else if(p==root){ tree[curtreenum]=fenwick(mxsz+1); } return mxsz; } void build(int v,int dep) { nodes.clear(); calcsz(v); v=find(sz[v]); lvl[v]=dep; mark[v]=1; dfs(v,v); for(int x:g[v]){ if(mark[x])continue; build(x,dep+1); } } int main(){ //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); fibcalc::pre(); int t; scanf("%d", &t); while(t--) { scanf("%d%d",&n,&q); curtreenum=n; for(int i=0;i=0;--i){ int num=rooton[v][i]; int num2=treenum[v][i]; int de=depthon[v][i]; int na=fibcalc::calc(de,a,b); int nb=fibcalc::calc(de+1,a,b); tree[num].add(d-de,na,nb); tree[num2].add(d-de,na,nb); } }else{ int v; scanf("%d",&v); int res=tree[v].get(0); for(int i=lvl[v]-1;i>=0;--i){ int num=rooton[v][i]; int num2=treenum[v][i]; int de=depthon[v][i]; inc(res,tree[num].get(de)); inc(res,mod-tree[num2].get(de)); } printf("%d\n",res); } } for(int i = 0; i <= n; ++i) { mark[i] = 0; g[i].clear(); } } }