#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;
}
