#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll long long
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
#define pii pair<int,int>
#define fi first
#define se second
#define mk(x,y) make_pair(x,y)
const int mod=998244353;
const int maxn=2e5;
const int ub=1e6;
const ll INF=1e18;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){
if(y==0) return x;
return gcd(y,x%y);
}
vector<int> g[maxn];
int n,q;
ll w[maxn];
///树剖
int sz[maxn],dep[maxn],son[maxn],fa[maxn];
void dfs1(int u,int f){
dep[u]=dep[f]+1,sz[u]=1,son[u]=0,fa[u]=f;
for(auto v:g[u]) if(v^f){
dfs1(v,u);
sz[u]+=sz[v];
if(sz[son[u]]<sz[v]) son[u]=v;
}
}
int top[maxn],dfn[maxn],tot=0;
void dfs2(int u,int f){
top[u]=f,dfn[u]=++tot;
if(son[u]) dfs2(son[u],f);
for(auto v:g[u]) if(v^son[u]&&v^fa[u])
dfs2(v,v);
}
///树状数组修改结构
ll bit[maxn];
void upd(int x,ll d){
for(;x<tot+100;(bit[x]+=d)%=mod,x+=x&-x);
}
void update(int x,int y,ll v){
upd(x,v),upd(y+1,-v+mod);
}
ll sum(int x){
ll ret=0;
for(;x>0;(ret+=bit[x])%=mod,x-=x&-x);
return ret;
}
int main(){
ios::sync_with_stdio(false);
mst(bit,0),mst(w,0);
cin>>n>>q;
rep(i,1,n){
int x,y;
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(1,0),dfs2(1,1);
ll inv=powmod(n,mod-2);
rep(i,0,q){
int op,x,y;
cin>>op;
if(op==1){
cin>>x>>y;
ll tmp=1LL*sz[x]*y%mod;
w[x]=(w[x]+y)%mod;
upd(1,tmp),update(dfn[x],dfn[x]+sz[x]-1,mod-tmp);
if(son[x]){
x=son[x];
update(dfn[x],dfn[x]+sz[x]-1,1LL*(n-sz[x])*y%mod);
}
}else{
cin>>x;
ll ret=(sum(dfn[x])+w[x]*n%mod)%mod;
for(x=top[x];x;x=top[fa[x]]){
ret=(ret+1LL*(n-sz[x])*w[fa[x]]%mod);
}
cout<<ret*inv%mod<<"\n";
}
}
return 0;
}