Problem: Hanh is a famous biologist. He loves growing trees and doing experiments on his own garden.

One day, he got a tree consisting of n vertices. Vertices are numbered from 1 to n. A tree with n vertices is an undirected connected graph with n-1 edges. Initially, Hanh sets the value of every vertex to 0.

Now, Hanh performs q operations, each is either of the following types: 

  * Type 1: Hanh selects a vertex v and an integer d. Then he chooses some vertex r uniformly at random, lists all vertices u such that the path from r to u passes through v. Hanh then increases the value of all such vertices u by d. 
  * Type 2: Hanh selects a vertex v and calculates the expected value of v. 



Since Hanh is good at biology but not math, he needs your help on these operations.

Input

The first line contains two integers n and q (1 ≤ n, q ≤ 150 000) — the number of vertices on Hanh's tree and the number of operations he performs.

Each of the next n - 1 lines contains two integers u and v (1 ≤ u, v ≤ n), denoting that there is an edge connecting two vertices u and v. It is guaranteed that these n - 1 edges form a tree.

Each of the last q lines describes an operation in either formats: 

  * 1 v d (1 ≤ v ≤ n, 0 ≤ d ≤ 10^7), representing a first-type operation. 
  * 2 v (1 ≤ v ≤ n), representing a second-type operation. 



It is guaranteed that there is at least one query of the second type.

Output

For each operation of the second type, write the expected value on a single line. 

Let M = 998244353, it can be shown that the expected value can be expressed as an irreducible fraction p/q, where p and q are integers and q not ≡ 0 \pmod{M}. Output the integer equal to p ⋅ q^{-1} mod M. In other words, output such an integer x that 0 ≤ x < M and x ⋅ q ≡ p \pmod{M}.

Example

Input


5 12
1 2
1 3
2 4
2 5
1 1 1
2 1
2 2
2 3
2 4
2 5
1 2 2
2 1
2 2
2 3
2 4
2 5


Output


1
199648871
399297742
199648871
199648871
598946614
199648873
2
2
2

Note

The image below shows the tree in the example:

<image>

For the first query, where v = 1 and d = 1: 

  * If r = 1, the values of all vertices get increased. 
  * If r = 2, the values of vertices 1 and 3 get increased. 
  * If r = 3, the values of vertices 1, 2, 4 and 5 get increased. 
  * If r = 4, the values of vertices 1 and 3 get increased. 
  * If r = 5, the values of vertices 1 and 3 get increased. 



Hence, the expected values of all vertices after this query are (1, 0.4, 0.8, 0.4, 0.4).

For the second query, where v = 2 and d = 2: 

  * If r = 1, the values of vertices 2, 4 and 5 get increased. 
  * If r = 2, the values of all vertices get increased. 
  * If r = 3, the values of vertices 2, 4 and 5 get increased. 
  * If r = 4, the values of vertices 1, 2, 3 and 5 get increased. 
  * If r = 5, the values of vertices 1, 2, 3 and 4 get increased. 



Hence, the expected values of all vertices after this query are (2.2, 2.4, 2, 2, 2).

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
struct mod_int {
  int val;
  mod_int(long long v = 0) {
    if (v < 0) v = v % MOD + MOD;
    if (v >= MOD) v %= MOD;
    val = v;
  }
  static int mod_inv(int a, int m = MOD) {
    int g = m, r = a, x = 0, y = 1;
    while (r != 0) {
      int q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }
    return x < 0 ? x + m : x;
  }
  explicit operator int() const { return val; }
  mod_int &operator+=(const mod_int &other) {
    val += other.val;
    if (val >= MOD) val -= MOD;
    return *this;
  }
  mod_int &operator-=(const mod_int &other) {
    val -= other.val;
    if (val < 0) val += MOD;
    return *this;
  }
  static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
    return x % m;
    unsigned x_high = x >> 32, x_low = (unsigned)x;
    unsigned quot, rem;
    asm("divl %4\n" : "=a"(quot), "=d"(rem) : "d"(x_high), "a"(x_low), "r"(m));
    return rem;
  }
  mod_int &operator*=(const mod_int &other) {
    val = fast_mod((uint64_t)val * other.val);
    return *this;
  }
  mod_int &operator/=(const mod_int &other) { return *this *= other.inv(); }
  friend mod_int operator+(const mod_int &a, const mod_int &b) {
    return mod_int(a) += b;
  }
  friend mod_int operator-(const mod_int &a, const mod_int &b) {
    return mod_int(a) -= b;
  }
  friend mod_int operator*(const mod_int &a, const mod_int &b) {
    return mod_int(a) *= b;
  }
  friend mod_int operator/(const mod_int &a, const mod_int &b) {
    return mod_int(a) /= b;
  }
  mod_int &operator++() {
    val = val == MOD - 1 ? 0 : val + 1;
    return *this;
  }
  mod_int &operator--() {
    val = val == 0 ? MOD - 1 : val - 1;
    return *this;
  }
  mod_int operator++(int) {
    mod_int before = *this;
    ++*this;
    return before;
  }
  mod_int operator--(int) {
    mod_int before = *this;
    --*this;
    return before;
  }
  mod_int operator-() const { return val == 0 ? 0 : MOD - val; }
  bool operator==(const mod_int &other) const { return val == other.val; }
  bool operator!=(const mod_int &other) const { return val != other.val; }
  mod_int inv() const { return mod_inv(val); }
  mod_int pow(long long p) const {
    assert(p >= 0);
    mod_int a = *this, result = 1;
    while (p > 0) {
      if (p & 1) result *= a;
      a *= a;
      p >>= 1;
    }
    return result;
  }
  friend ostream &operator<<(ostream &stream, const mod_int &m) {
    return stream << m.val;
  }
};
template <typename T, bool maximum_mode = false>
struct RMQ {
  int n = 0, levels = 0;
  vector<T> values;
  vector<vector<int>> range_low;
  RMQ(const vector<T> &_values = {}) {
    if (!_values.empty()) build(_values);
  }
  static int largest_bit(int x) { return 31 - __builtin_clz(x); }
  int better_index(int a, int b) const {
    return (values[a] < values[b]) ^ maximum_mode ? a : b;
  }
  void build(const vector<T> &_values) {
    values = _values;
    n = values.size();
    levels = largest_bit(n) + 1;
    range_low.resize(levels);
    for (int k = 0; k < levels; k++) range_low[k].resize(n - (1 << k) + 1);
    for (int i = 0; i < n; i++) range_low[0][i] = i;
    for (int k = 1; k < levels; k++)
      for (int i = 0; i <= n - (1 << k); i++)
        range_low[k][i] = better_index(range_low[k - 1][i],
                                       range_low[k - 1][i + (1 << (k - 1))]);
  }
  int query_index(int a, int b) const {
    assert(0 <= a && a < b && b <= n);
    int level = largest_bit(b - a);
    return better_index(range_low[level][a],
                        range_low[level][b - (1 << level)]);
  }
  T query_value(int a, int b) const { return values[query_index(a, b)]; }
};
struct LCA {
  int n = 0;
  vector<vector<int>> adj;
  vector<int> parent, depth, subtree_size;
  vector<int> euler, first_occurrence;
  vector<int> tour_start, tour_end, tour_list;
  RMQ<int> rmq;
  LCA(int _n = 0) { init(_n); }
  LCA(const vector<vector<int>> &_adj) { init(_adj); }
  void init(int _n) {
    n = _n;
    adj.assign(n, {});
    parent.resize(n);
    depth.resize(n);
    subtree_size.resize(n);
    first_occurrence.resize(n);
    tour_start.resize(n);
    tour_end.resize(n);
    tour_list.resize(n);
  }
  void init(const vector<vector<int>> &_adj) {
    init(_adj.size());
    adj = _adj;
  }
  void add_edge(int a, int b) {
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  int tour;
  void dfs(int node, int par) {
    parent[node] = par;
    depth[node] = par < 0 ? 0 : depth[par] + 1;
    subtree_size[node] = 1;
    first_occurrence[node] = euler.size();
    euler.push_back(node);
    tour_list[tour] = node;
    tour_start[node] = tour++;
    if (par >= 0)
      adj[node].erase(find(adj[node].begin(), adj[node].end(), par));
    for (int child : adj[node]) {
      dfs(child, node);
      subtree_size[node] += subtree_size[child];
      euler.push_back(node);
    }
    tour_end[node] = tour;
  }
  void build() {
    tour = 0;
    parent.assign(n, -1);
    for (int i = 0; i < n; i++)
      if (parent[i] < 0) {
        dfs(i, -1);
        euler.push_back(-1);
      }
    assert((int)euler.size() == 2 * n);
    vector<int> euler_depths;
    for (int node : euler)
      euler_depths.push_back(node < 0 ? node : depth[node]);
    rmq.build(euler_depths);
  }
  int get_lca(int a, int b) const {
    a = first_occurrence[a];
    b = first_occurrence[b];
    if (a > b) swap(a, b);
    return euler[rmq.query_index(a, b + 1)];
  }
  bool is_ancestor(int a, int b) const {
    return tour_start[a] <= tour_start[b] && tour_start[b] < tour_end[a];
  }
  bool on_path(int x, int a, int b) const {
    int anc = get_lca(a, b);
    return is_ancestor(anc, x) && (is_ancestor(x, a) || is_ancestor(x, b));
  }
  int get_dist(int a, int b) const {
    return depth[a] + depth[b] - 2 * depth[get_lca(a, b)];
  }
  int child_ancestor(int a, int b) const {
    assert(a != b);
    assert(is_ancestor(a, b));
    assert(!adj[a].empty());
    int low = 0, high = (int)adj[a].size() - 1;
    while (low < high) {
      int mid = (low + high) / 2;
      if (tour_start[b] < tour_end[adj[a][mid]])
        high = mid;
      else
        low = mid + 1;
    }
    int child = adj[a][low];
    assert(is_ancestor(child, b));
    return child;
  }
};
struct query {
  int type, v;
  mod_int d;
};
int N, GROUP, Q;
LCA lca;
vector<mod_int> values, updates, query_d;
vector<query> queries;
void apply_updates() {
  for (int node : lca.tour_list) {
    values[node] += updates[node];
    for (int child : lca.adj[node]) updates[child] += updates[node];
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> N >> Q;
  GROUP = 0.75 * sqrt(N) + 1;
  cerr << "Group size: " << GROUP << endl;
  lca.init(N);
  for (int i = 0; i < N - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    lca.add_edge(u, v);
  }
  lca.build();
  values.assign(N, 0);
  mod_int inv_N = mod_int(1) / N;
  for (int q_start = 0; q_start < Q; q_start += GROUP) {
    int q_end = min(q_start + GROUP, Q);
    int q_count = q_end - q_start;
    queries.resize(q_count);
    for (query &qry : queries) {
      cin >> qry.type >> qry.v;
      qry.v--;
      if (qry.type == 1) {
        int d;
        cin >> d;
        qry.d = d;
      }
    }
    for (int q = 0; q < q_count; q++)
      if (queries[q].type == 2) {
        int v = queries[q].v;
        mod_int answer = values[v];
        for (int p = 0; p < q; p++)
          if (queries[p].type == 1) {
            int pv = queries[p].v;
            mod_int pd = queries[p].d;
            if (pv == v) {
              answer += pd;
            } else if (lca.is_ancestor(pv, v)) {
              int ca = lca.child_ancestor(pv, v);
              mod_int probability = (N - lca.subtree_size[ca]) * inv_N;
              answer += probability * pd;
            } else {
              mod_int probability = lca.subtree_size[pv] * inv_N;
              answer += probability * pd;
            }
          }
        cout << answer << '\n';
      }
    updates.assign(N, 0);
    query_d.assign(N, 0);
    for (int q = 0; q < q_count; q++)
      if (queries[q].type == 1) query_d[queries[q].v] += queries[q].d;
    for (int node = 0; node < N; node++)
      if (query_d[node] != 0) {
        mod_int base_probability = lca.subtree_size[node] * inv_N;
        updates[0] += base_probability * query_d[node];
        updates[node] += (1 - base_probability) * query_d[node];
        for (int child : lca.adj[node])
          updates[child] -= lca.subtree_size[child] * inv_N * query_d[node];
      }
    apply_updates();
  }
}