#include <bits/stdc++.h>
const long long N = 5e5 + 9, mod = 998244353;
typedef long long aN[N];
long long cnt = 0, tot = 0;
long long readll() {
  long long x = 0, w = 1;
  int c = getchar();
  for (; c < '0' || c > '9'; c - '-' || (w = -w), c = getchar())
    ;
  for (; c >= '0' && c <= '9'; x = x * 10 + (c ^ 48), c = getchar())
    ;
  return x * w;
}
int readchar(int l = '0', int r = 'z') {
  int c = getchar();
  for (; c < l || c > r; c = getchar())
    ;
  return c;
}
aN next, to, head, dfn, size, son, top, tag, fa;
long long pow(long long a, long long b, long long p) {
  long long res = 1;
  while (b) {
    if (b & 1) res = res * a % p;
    a = a * a % p, b >>= 1;
  }
  return res;
}
void add(long long u, long long v) {
  next[++cnt] = head[u], to[head[u] = cnt] = v;
}
void dfs(long long u, long long fa) {
  dfn[u] = ++tot, size[u] = 1, son[u] = 0;
  for (register long long i = head[u], v; v = to[i], i; i = next[i])
    if (v ^ fa)
      dfs(v, u), size[u] += size[v], (size[v] > size[son[u]]) && (son[u] = v);
}
void dfs(long long u, long long fa, long long t) {
  ::fa[u] = fa, top[u] = t ? top[fa] : u;
  if (son[u]) dfs(son[u], u, 1);
  for (register long long i = head[u], v; v = to[i], i; i = next[i])
    if (v ^ fa && v ^ son[u]) dfs(v, u, 0);
}
struct bit {
  aN f;
  long long tag, n;
  void set(long long n_) {
    memset(f, tag = 0, sizeof(long long) * ((n = n_) + 1));
  }
  void update(long long u, long long c) {
    for (; u <= n; f[u] += c, u += u & -u)
      ;
  }
  void update(long long l, long long r, long long c) {
    update(l, c), update(r + 1, -c);
  }
  long long query(long long u) {
    long long res = 0;
    while (u) res += f[u], u &= ~-u;
    return tag + res;
  }
} t;
void update_tree(long long u, long long c, long long n) {
  tag[u] = (tag[u] + c) % mod;
  if (son[u])
    t.update(dfn[son[u]], dfn[son[u]] + size[son[u]] - 1,
             (n - size[son[u]]) * c % mod);
  if (u != 1)
    t.tag = (t.tag + size[u] * c) % mod,
    t.update(dfn[u], dfn[u] + size[u] - 1, (mod - size[u]) * c % mod);
}
long long query_tree(long long u, long long n) {
  long long res = (tag[u] * n + t.query(dfn[u])) % mod;
  u = top[u];
  while (u) res = (res + tag[fa[u]] * (n - size[u])) % mod, u = top[fa[u]];
  return res;
}
int main() {
  long long n = readll(), m = readll(), u, v, ni = pow(n, mod - 2, mod);
  for (register long long i = 2; i <= n; i++)
    u = readll(), v = readll(), add(u, v), add(v, u);
  dfs(1, 0), dfs(1, 0, 0);
  t.set(n);
  for (register long long i = 1; i <= m; i++)
    if (readll() == 1)
      u = readll(), update_tree(u, readll(), n);
    else
      printf("%lld\n", query_tree(readll(), n) * ni % mod);
  return 0;
}
