#include <bits/stdc++.h>
using namespace std;
using int64 = long long int;
const int kModulo = 998244353;
int idiv(int value) {
  int u = value;
  int v = kModulo;
  int p1 = 1, q1 = 0;
  int p2 = 0, q2 = 1;
  while (v != 0) {
    int q = u / v;
    int p3 = p1 - q * p2;
    int q3 = q1 - q * q2;
    int r = u - q * v;
    u = v;
    v = r;
    p1 = p2;
    p2 = p3;
    q1 = q2;
    q2 = q3;
  }
  if (p1 < 0) {
    p1 += kModulo;
  }
  if (p1 >= kModulo) {
    p1 -= kModulo;
  }
  return p1;
}
vector<complex<double>> BW(int k) {
  vector<complex<double>> p(1 << k, 1);
  for (int u = 1; u < k; ++u) {
    complex<double> current =
        polar<double>(1.0, 3.14159265358979323846264338327950288 / (1 << u));
    for (int v = (1 << (u - 1)); v < (1 << u); ++v) {
      p[2 * v] = p[v];
      p[2 * v + 1] = p[v] * current;
    }
  }
  return p;
}
void MakeIt(int k, vector<complex<double>>& w, bool dir,
            vector<complex<double>>* x) {
  int n = 1 << k;
  vector<complex<double>>& t = *x;
  if (t.size() < static_cast<size_t>(n)) {
    t.insert(t.end(), n - t.size(), 0.0);
  }
  int q = 0;
  for (int i = 1; i < n; ++i) {
    for (int j = 0;; ++j) {
      q ^= (1 << (k - j - 1));
      if ((i & (1 << j)) != 0) {
        break;
      }
    }
    if (q < i) {
      swap(t[i], t[q]);
    }
  }
  for (int l = 0; l < k; ++l) {
    int o = 1 << l;
    for (int i = 0; i < n; i += 2 * o) {
      for (int u = i, v = i + o, q = o; u < i + o; ++u, ++v, ++q) {
        auto v1 = (t[v].real() + t[v].imag()) * (w[q].real() + w[q].imag());
        auto v2 = t[v].real() * w[q].real();
        auto v3 = t[v].imag() * w[q].imag();
        complex<double> tmp(v2 - v3, v1 - v2 - v3);
        t[v] = t[u] - tmp;
        t[u] += tmp;
      }
    }
  }
  if (dir) {
    double n_inv = 1.0 / n;
    t[0] *= n_inv;
    t[n / 2] *= n_inv;
    for (int i = 1; i < n / 2; ++i) {
      swap(t[i], t[n - i]);
      t[i] *= n_inv;
      t[n - i] *= n_inv;
    }
  }
}
class Tree {
 public:
  explicit Tree(int n) : edges_(n) {}
  void AddEdge(int u, int v) {
    edges_[u].push_back(v);
    edges_[v].push_back(u);
  }
  int Calc(int64 x) {
    size_.assign(edges_.size(), 0);
    dfs(0, -1);
    Compute(0);
    vector<int> p = Combine();
    int64 current = 1;
    int answer = 0;
    const int xMod = x % kModulo;
    for (size_t i = 1; i < p.size(); ++i) {
      answer = (answer + p[i] * current) % kModulo;
      current = (current * (xMod + i)) % kModulo;
      current = (current * idiv(i)) % kModulo;
    }
    return answer;
  }

 private:
  void dfs(int node, int parent) {
    size_[node] = 1;
    for (size_t i = 0; i < edges_[node].size(); ++i) {
      int child = edges_[node][i];
      if (child != parent) {
        dfs(child, node);
        size_[node] += size_[child];
      } else {
        swap(edges_[node][i--], edges_[node].back());
        edges_[node].resize(edges_[node].size() - 1);
      }
    }
  }
  void Compute(int node) {
    if (edges_[node].empty()) {
      state_.push_back({0, 1});
      return;
    }
    if (edges_[node].size() == 1) {
      Compute(edges_[node][0]);
      state_.push_back({0, 1});
    } else {
      int left = edges_[node][0];
      int right = edges_[node][1];
      if (size_[left] < size_[right]) {
        swap(left, right);
      }
      Compute(right);
      vector<int> right_result = Combine();
      Compute(left);
      state_.push_back(move(right_result));
      ao(&state_.back());
      mull(&state_.back());
    }
  }
  vector<int> Combine() {
    vector<int> result = Combine(0, state_.size()).second;
    state_.clear();
    return result;
  }
  pair<vector<int>, vector<int>> Combine(size_t start, size_t limit) {
    if (start + 1 == limit) {
      return {state_[start], state_[start]};
    }
    size_t middle = (start + limit) / 2;
    auto left = Combine(start, middle);
    auto right = Combine(middle, limit);
    return {proiz(left.first, right.first),
            PolyAdd(proiz(left.second, right.first), right.second)};
  }
  static void mull(vector<int>* p) {
    vector<int>& t = *p;
    t.push_back(0);
    for (size_t i = t.size() - 1; i >= 1; --i) {
      t[i] = t[i - 1];
    }
    t[0] = 0;
  }
  static void ao(vector<int>* p) {
    int& p0 = p->at(0);
    ++p0;
    if (p0 == kModulo) {
      p0 = 0;
    }
  }
  static vector<int> PolyAdd(const vector<int>& a, const vector<int>& b) {
    vector<int> c(max(a.size(), b.size()));
    for (size_t i = 0; i < c.size(); ++i) {
      c[i] = (i < a.size() ? a[i] : 0);
      if (i < b.size()) {
        c[i] += b[i];
        if (c[i] >= kModulo) {
          c[i] -= kModulo;
        }
      }
    }
    return c;
  }
  static vector<int> proiz(const vector<int>& f, const vector<int>& g) {
    size_t k = 0;
    while ((static_cast<size_t>(1) << k) < f.size() + g.size() - 1) {
      ++k;
    }
    int n = 1 << k;
    auto w = BW(k);
    int z = static_cast<int>(floor(sqrt(kModulo)));
    vector<complex<double>> ab(n);
    vector<complex<double>> cd(n);
    for (size_t i = 0; i < ab.size(); ++i) {
      ab[i] = (i < f.size() ? complex<double>(f[i] / z, f[i] % z) : 0.0);
      cd[i] = (i < g.size() ? complex<double>(g[i] / z, g[i] % z) : 0.0);
    }
    MakeIt(k, w, false, &ab);
    MakeIt(k, w, false, &cd);
    vector<complex<double>>& ac_bd = ab;
    vector<complex<double>>& ad_bc = cd;
    {
      complex<double> ac_bd0 = complex<double>(ab[0].real() * cd[0].real(),
                                               ab[0].imag() * cd[0].imag());
      complex<double> ad_bc0 = complex<double>(ab[0].real() * cd[0].imag(),
                                               ab[0].imag() * cd[0].real());
      ac_bd[0] = ac_bd0;
      ad_bc[0] = ad_bc0;
    }
    for (int i = 1; i <= n / 2; ++i) {
      auto a = (ab[i] + conj(ab[n - i])) / 2.0;
      auto ib = (ab[i] - conj(ab[n - i])) / 2.0;
      auto c = (cd[i] + conj(cd[n - i])) / 2.0;
      auto d = (cd[i] - conj(cd[n - i])) * complex<double>(0.0, -1.0 / 2.0);
      auto ac = a * c;
      auto ad = a * d;
      auto ibc = ib * c;
      auto ibd = ib * d;
      ac_bd[i] = ac + ibd;
      ad_bc[i] = ad + ibc;
      ac_bd[n - i] = conj(ac - ibd);
      ad_bc[n - i] = conj(ad - ibc);
    }
    MakeIt(k, w, true, &ac_bd);
    MakeIt(k, w, true, &ad_bc);
    vector<int> result(f.size() + g.size() - 1);
    int64 z2 = static_cast<int64>(z) * z;
    for (size_t i = 0; i < result.size(); ++i) {
      int64 v0 = static_cast<int64>(round(ac_bd[i].imag())) % kModulo;
      int64 v1 = static_cast<int64>(round(ad_bc[i].real() + ad_bc[i].imag())) %
                 kModulo;
      int64 v2 = static_cast<int64>(round(ac_bd[i].real())) % kModulo;
      result[i] = (v0 + v1 * z + v2 * z2) % kModulo;
    }
    return result;
  }
  vector<vector<int>> edges_;
  vector<int> size_;
  vector<vector<int>> state_;
};
void solve() {
  int n;
  scanf("%d", &n);
  int64 x;
  scanf("%I64d", &x);
  Tree t(n);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    scanf("%d %d", &u, &v);
    t.AddEdge(u - 1, v - 1);
  }
  cout << t.Calc(x) << "\n";
}
int main() {
  solve();
  return 0;
}

### Prompt

Develop a solution in Cpp to the problem described below:

The Main Martian Tree grows on Mars. It is a binary tree (a rooted tree, with no more than two sons at each vertex) with n vertices, where the root vertex has the number 1. Its fruits are the Main Martian Fruits. It's summer now, so this tree does not have any fruit yet.

Autumn is coming soon, and leaves and branches will begin to fall off the tree. It is clear, that if a vertex falls off the tree, then its entire subtree will fall off too. In addition, the root will remain on the tree. Formally: the tree will have some connected subset of vertices containing the root.

After that, the fruits will grow on the tree (only at those vertices which remain). Exactly x fruits will grow in the root. The number of fruits in each remaining vertex will be not less than the sum of the numbers of fruits in the remaining sons of this vertex. It is allowed, that some vertices will not have any fruits.

Natasha wondered how many tree configurations can be after the described changes. Since this number can be very large, output it modulo 998244353.

Two configurations of the resulting tree are considered different if one of these two conditions is true:

  * they have different subsets of remaining vertices;
  * they have the same subset of remaining vertices, but there is a vertex in this subset where they have a different amount of fruits.

Input

The first line contains two integers: n and x (1 ≤ n ≤ 10^5, 0 ≤ x ≤ 10^{18}) — the size of the tree and the number of fruits in the root.

The i-th of the following (n-1) lines contains two integers a_i and b_i (1 ≤ a_i, b_i ≤ n) — vertices connected by the i-th edge of the tree.

It is guaranteed that the input data describes a correct binary tree with the root at the vertex 1.

Output

Print one number — the number of configurations of the resulting tree modulo 998244353.

Examples

Input

3 2
1 2
1 3


Output

13


Input

2 5
1 2


Output

7


Input

4 10
1 2
1 3
3 4


Output

441

Note

Consider the first example. <image>

There are 2 fruits at the vertex 1. The following 13 options are possible:

  * there is no vertex 2, there is no vertex 3; <image>
  * there is no vertex 2, there are no fruits at the vertex 3; <image>
  * there is no vertex 2, there is 1 fruit at the vertex 3; <image>
  * there is no vertex 2, there are 2 fruits at the vertex 3; <image>
  * there are no fruits at the vertex 2, there is no vertex 3; <image>
  * there are no fruits at the vertex 2, there are no fruits at the vertex 3; <image>
  * there are no fruits at the vertex 2, there is 1 fruit at the vertex 3; <image>
  * there are no fruits at the vertex 2, there are 2 fruits at the vertex 3; <image>
  * there is 1 fruit at the vertex 2, there is no vertex 3; <image>
  * there is 1 fruit at the vertex 2, there are no fruits at the vertex 3; <image>
  * there is 1 fruit at the vertex 2, there is 1 fruit at the vertex 3; <image>
  * there are 2 fruits at the vertex 2, there is no vertex 3; <image>
  * there are 2 fruits at the vertex 2, there are no fruits at the vertex 3. <image>



Consider the second example. There are 5 fruits at the vertex 1. The following 7 options are possible:

  * there is no vertex 2;
  * there are no fruits at the vertex 2;
  * there is 1 fruit at the vertex 2;
  * there are 2 fruits at the vertex 2;
  * there are 3 fruits at the vertex 2;
  * there are 4 fruits at the vertex 2;
  * there are 5 fruits at the vertex 2.

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
using int64 = long long int;
const int kModulo = 998244353;
int idiv(int value) {
  int u = value;
  int v = kModulo;
  int p1 = 1, q1 = 0;
  int p2 = 0, q2 = 1;
  while (v != 0) {
    int q = u / v;
    int p3 = p1 - q * p2;
    int q3 = q1 - q * q2;
    int r = u - q * v;
    u = v;
    v = r;
    p1 = p2;
    p2 = p3;
    q1 = q2;
    q2 = q3;
  }
  if (p1 < 0) {
    p1 += kModulo;
  }
  if (p1 >= kModulo) {
    p1 -= kModulo;
  }
  return p1;
}
vector<complex<double>> BW(int k) {
  vector<complex<double>> p(1 << k, 1);
  for (int u = 1; u < k; ++u) {
    complex<double> current =
        polar<double>(1.0, 3.14159265358979323846264338327950288 / (1 << u));
    for (int v = (1 << (u - 1)); v < (1 << u); ++v) {
      p[2 * v] = p[v];
      p[2 * v + 1] = p[v] * current;
    }
  }
  return p;
}
void MakeIt(int k, vector<complex<double>>& w, bool dir,
            vector<complex<double>>* x) {
  int n = 1 << k;
  vector<complex<double>>& t = *x;
  if (t.size() < static_cast<size_t>(n)) {
    t.insert(t.end(), n - t.size(), 0.0);
  }
  int q = 0;
  for (int i = 1; i < n; ++i) {
    for (int j = 0;; ++j) {
      q ^= (1 << (k - j - 1));
      if ((i & (1 << j)) != 0) {
        break;
      }
    }
    if (q < i) {
      swap(t[i], t[q]);
    }
  }
  for (int l = 0; l < k; ++l) {
    int o = 1 << l;
    for (int i = 0; i < n; i += 2 * o) {
      for (int u = i, v = i + o, q = o; u < i + o; ++u, ++v, ++q) {
        auto v1 = (t[v].real() + t[v].imag()) * (w[q].real() + w[q].imag());
        auto v2 = t[v].real() * w[q].real();
        auto v3 = t[v].imag() * w[q].imag();
        complex<double> tmp(v2 - v3, v1 - v2 - v3);
        t[v] = t[u] - tmp;
        t[u] += tmp;
      }
    }
  }
  if (dir) {
    double n_inv = 1.0 / n;
    t[0] *= n_inv;
    t[n / 2] *= n_inv;
    for (int i = 1; i < n / 2; ++i) {
      swap(t[i], t[n - i]);
      t[i] *= n_inv;
      t[n - i] *= n_inv;
    }
  }
}
class Tree {
 public:
  explicit Tree(int n) : edges_(n) {}
  void AddEdge(int u, int v) {
    edges_[u].push_back(v);
    edges_[v].push_back(u);
  }
  int Calc(int64 x) {
    size_.assign(edges_.size(), 0);
    dfs(0, -1);
    Compute(0);
    vector<int> p = Combine();
    int64 current = 1;
    int answer = 0;
    const int xMod = x % kModulo;
    for (size_t i = 1; i < p.size(); ++i) {
      answer = (answer + p[i] * current) % kModulo;
      current = (current * (xMod + i)) % kModulo;
      current = (current * idiv(i)) % kModulo;
    }
    return answer;
  }

 private:
  void dfs(int node, int parent) {
    size_[node] = 1;
    for (size_t i = 0; i < edges_[node].size(); ++i) {
      int child = edges_[node][i];
      if (child != parent) {
        dfs(child, node);
        size_[node] += size_[child];
      } else {
        swap(edges_[node][i--], edges_[node].back());
        edges_[node].resize(edges_[node].size() - 1);
      }
    }
  }
  void Compute(int node) {
    if (edges_[node].empty()) {
      state_.push_back({0, 1});
      return;
    }
    if (edges_[node].size() == 1) {
      Compute(edges_[node][0]);
      state_.push_back({0, 1});
    } else {
      int left = edges_[node][0];
      int right = edges_[node][1];
      if (size_[left] < size_[right]) {
        swap(left, right);
      }
      Compute(right);
      vector<int> right_result = Combine();
      Compute(left);
      state_.push_back(move(right_result));
      ao(&state_.back());
      mull(&state_.back());
    }
  }
  vector<int> Combine() {
    vector<int> result = Combine(0, state_.size()).second;
    state_.clear();
    return result;
  }
  pair<vector<int>, vector<int>> Combine(size_t start, size_t limit) {
    if (start + 1 == limit) {
      return {state_[start], state_[start]};
    }
    size_t middle = (start + limit) / 2;
    auto left = Combine(start, middle);
    auto right = Combine(middle, limit);
    return {proiz(left.first, right.first),
            PolyAdd(proiz(left.second, right.first), right.second)};
  }
  static void mull(vector<int>* p) {
    vector<int>& t = *p;
    t.push_back(0);
    for (size_t i = t.size() - 1; i >= 1; --i) {
      t[i] = t[i - 1];
    }
    t[0] = 0;
  }
  static void ao(vector<int>* p) {
    int& p0 = p->at(0);
    ++p0;
    if (p0 == kModulo) {
      p0 = 0;
    }
  }
  static vector<int> PolyAdd(const vector<int>& a, const vector<int>& b) {
    vector<int> c(max(a.size(), b.size()));
    for (size_t i = 0; i < c.size(); ++i) {
      c[i] = (i < a.size() ? a[i] : 0);
      if (i < b.size()) {
        c[i] += b[i];
        if (c[i] >= kModulo) {
          c[i] -= kModulo;
        }
      }
    }
    return c;
  }
  static vector<int> proiz(const vector<int>& f, const vector<int>& g) {
    size_t k = 0;
    while ((static_cast<size_t>(1) << k) < f.size() + g.size() - 1) {
      ++k;
    }
    int n = 1 << k;
    auto w = BW(k);
    int z = static_cast<int>(floor(sqrt(kModulo)));
    vector<complex<double>> ab(n);
    vector<complex<double>> cd(n);
    for (size_t i = 0; i < ab.size(); ++i) {
      ab[i] = (i < f.size() ? complex<double>(f[i] / z, f[i] % z) : 0.0);
      cd[i] = (i < g.size() ? complex<double>(g[i] / z, g[i] % z) : 0.0);
    }
    MakeIt(k, w, false, &ab);
    MakeIt(k, w, false, &cd);
    vector<complex<double>>& ac_bd = ab;
    vector<complex<double>>& ad_bc = cd;
    {
      complex<double> ac_bd0 = complex<double>(ab[0].real() * cd[0].real(),
                                               ab[0].imag() * cd[0].imag());
      complex<double> ad_bc0 = complex<double>(ab[0].real() * cd[0].imag(),
                                               ab[0].imag() * cd[0].real());
      ac_bd[0] = ac_bd0;
      ad_bc[0] = ad_bc0;
    }
    for (int i = 1; i <= n / 2; ++i) {
      auto a = (ab[i] + conj(ab[n - i])) / 2.0;
      auto ib = (ab[i] - conj(ab[n - i])) / 2.0;
      auto c = (cd[i] + conj(cd[n - i])) / 2.0;
      auto d = (cd[i] - conj(cd[n - i])) * complex<double>(0.0, -1.0 / 2.0);
      auto ac = a * c;
      auto ad = a * d;
      auto ibc = ib * c;
      auto ibd = ib * d;
      ac_bd[i] = ac + ibd;
      ad_bc[i] = ad + ibc;
      ac_bd[n - i] = conj(ac - ibd);
      ad_bc[n - i] = conj(ad - ibc);
    }
    MakeIt(k, w, true, &ac_bd);
    MakeIt(k, w, true, &ad_bc);
    vector<int> result(f.size() + g.size() - 1);
    int64 z2 = static_cast<int64>(z) * z;
    for (size_t i = 0; i < result.size(); ++i) {
      int64 v0 = static_cast<int64>(round(ac_bd[i].imag())) % kModulo;
      int64 v1 = static_cast<int64>(round(ad_bc[i].real() + ad_bc[i].imag())) %
                 kModulo;
      int64 v2 = static_cast<int64>(round(ac_bd[i].real())) % kModulo;
      result[i] = (v0 + v1 * z + v2 * z2) % kModulo;
    }
    return result;
  }
  vector<vector<int>> edges_;
  vector<int> size_;
  vector<vector<int>> state_;
};
void solve() {
  int n;
  scanf("%d", &n);
  int64 x;
  scanf("%I64d", &x);
  Tree t(n);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    scanf("%d %d", &u, &v);
    t.AddEdge(u - 1, v - 1);
  }
  cout << t.Calc(x) << "\n";
}
int main() {
  solve();
  return 0;
}

```