#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool upmin(T &x, T y) {
  return y < x ? x = y, 1 : 0;
}
template <typename T>
inline bool upmax(T &x, T y) {
  return x < y ? x = y, 1 : 0;
}
const long double eps = 1e-9;
const long double pi = acos(-1);
const int oo = 1 << 30;
const long long loo = 1ll << 62;
const int mods = 998244353;
const int G = 3;
const int Gi = (mods + 1) / G;
const int MAXN = 400005;
const int INF = 0x3f3f3f3f;
namespace FastIO {
constexpr int SIZE = (1 << 21) + 1;
int num = 0, f;
char ibuf[SIZE], obuf[SIZE], que[65], *iS, *iT, *oS = obuf,
                                                *oT = obuf + SIZE - 1, c;
inline void flush() {
  fwrite(obuf, 1, oS - obuf, stdout);
  oS = obuf;
}
inline void putc(char c) {
  *oS++ = c;
  if (oS == oT) flush();
}
inline void getc(char &c) {
  for (c = (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)),
                       (iS == iT ? EOF : *iS++))
                     : *iS++);
       c == ' ' || c == '\n';
       c = (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    ;
}
inline void reads(char *st) {
  int n;
  getc(st[n = 1]);
  for (c = (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)),
                       (iS == iT ? EOF : *iS++))
                     : *iS++);
       c != ' ' && c != '\n' && c != EOF;
       c = (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    st[++n] = c;
}
template <class I>
inline void read(I &x) {
  for (f = 1, c = (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)),
                              (iS == iT ? EOF : *iS++))
                            : *iS++);
       c < '0' || c > '9';
       c = (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    if (c == '-') f = -1;
  for (x = 0; c >= '0' && c <= '9';
       c = (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    x = (x << 3) + (x << 1) + (c & 15);
  x *= f;
}
template <class I>
inline void print(I x) {
  if (x < 0) putc('-'), x = -x;
  if (!x) putc('0');
  while (x) que[++num] = x % 10 + 48, x /= 10;
  while (num) putc(que[num--]);
}
struct Flusher_ {
  ~Flusher_() { flush(); }
} io_Flusher_;
}  // namespace FastIO
using FastIO ::print;
using FastIO ::putc;
using FastIO ::read;
vector<int> e[MAXN], E[MAXN], f[MAXN], V, F, GF;
int g[MAXN], sz[MAXN], fac[MAXN], inv[MAXN], A[MAXN], B[MAXN], C[MAXN],
    rev[MAXN], H[MAXN], top[MAXN], mx[MAXN], Limit, l;
int upd(int x, int y) { return x + y >= mods ? x + y - mods : x + y; }
int quick_pow(int x, int y) {
  int ret = 1;
  for (; y; y >>= 1) {
    if (y & 1) ret = 1ll * ret * x % mods;
    x = 1ll * x * x % mods;
  }
  return ret;
}
void Init(int n) {
  fac[0] = 1;
  for (int i = 1; i <= n; ++i) fac[i] = 1ll * fac[i - 1] * i % mods;
  inv[n] = quick_pow(fac[n], mods - 2);
  for (int i = n - 1; i >= 0; --i) inv[i] = 1ll * inv[i + 1] * (i + 1) % mods;
}
void getrev(int n) {
  l = 0, Limit = 1;
  while (Limit <= n) Limit <<= 1, ++l;
  for (int i = 0; i < Limit; ++i)
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1));
}
void NTT(int *A, int opt, int n = 0) {
  for (int i = 0; i < Limit; ++i)
    if (rev[i] < i) swap(A[rev[i]], A[i]);
  for (int mid = 1; mid < Limit; mid <<= 1) {
    int Wn = quick_pow((opt == 1 ? G : Gi), (mods - 1) / (mid << 1));
    for (int R = mid << 1, j = 0; j < Limit; j += R)
      for (int k = j, w = 1; k < j + mid; ++k, w = 1ll * w * Wn % mods) {
        int x = A[k], y = 1ll * A[k + mid] * w % mods;
        A[k] = upd(x, y), A[k + mid] = upd(x, mods - y);
      }
  }
  if (opt == -1) {
    int invLimit = quick_pow(Limit, mods - 2);
    for (int i = 0; i < n; ++i) A[i] = 1ll * A[i] * invLimit % mods;
    for (int i = n; i < Limit; ++i) A[i] = 0;
  }
}
void solve(int l, int r, vector<int> &Ans) {
  if (l == r) {
    Ans = f[V[l]];
    return;
  }
  vector<int> L, R;
  int mid = (l + r) >> 1;
  solve(l, mid, L);
  solve(mid + 1, r, R);
  int sum = L.size() + R.size() - 2;
  getrev(sum);
  for (int i = 0; i < (int)L.size(); ++i) A[i] = L[i];
  for (int i = (int)L.size(); i < Limit; ++i) A[i] = 0;
  for (int i = 0; i < (int)R.size(); ++i) B[i] = R[i];
  for (int i = (int)R.size(); i < Limit; ++i) B[i] = 0;
  NTT(A, 1), NTT(B, 1);
  for (int i = 0; i < Limit; ++i) C[i] = 1ll * A[i] * B[i] % mods;
  NTT(C, -1, sum + 1);
  Ans.resize(sum + 1);
  for (int i = 0; i <= sum; ++i) Ans[i] = C[i];
}
void Solve(int l, int r, vector<int> &Ans, vector<int> &All) {
  if (l == r) {
    Ans = All = f[V[l]];
    return;
  }
  vector<int> L, R, _L, _R;
  int mid = (l + r) >> 1;
  Solve(l, mid, L, _L);
  Solve(mid + 1, r, R, _R);
  int sum = L.size() + R.size() - 2;
  getrev(sum);
  for (int i = 0; i < (int)_R.size(); ++i) A[i] = _R[i];
  for (int i = (int)_R.size(); i < Limit; ++i) A[i] = 0;
  for (int i = 0; i < (int)L.size(); ++i) B[i] = L[i];
  for (int i = (int)L.size(); i < Limit; ++i) B[i] = 0;
  NTT(A, 1), NTT(B, 1);
  for (int i = 0; i < Limit; ++i) C[i] = 1ll * A[i] * B[i] % mods;
  NTT(C, -1, sum + 1);
  Ans.resize(sum + 1);
  for (int i = 0; i <= sum; ++i) Ans[i] = C[i];
  for (int i = 0; i < (int)R.size(); ++i) Ans[i] = upd(Ans[i], R[i]);
  for (int i = 0; i < (int)_L.size(); ++i) B[i] = _L[i];
  for (int i = (int)_L.size(); i < Limit; ++i) B[i] = 0;
  NTT(B, 1);
  for (int i = 0; i < Limit; ++i) C[i] = 1ll * A[i] * B[i] % mods;
  NTT(C, -1, sum + 1);
  All.resize(sum + 1);
  for (int i = 0; i <= sum; ++i) All[i] = C[i];
}
void dfs1(int x, int father) {
  sz[x] = 1;
  for (auto v : E[x]) {
    if (v == father) continue;
    e[x].push_back(v);
    dfs1(v, x);
    sz[x] += sz[v];
    if (sz[v] > sz[mx[x]]) mx[x] = v;
  }
}
void dfs2(int x, int Top) {
  top[x] = Top;
  if (mx[x]) dfs2(mx[x], Top), H[x] = H[mx[x]] + 1;
  for (auto v : e[x]) {
    if (v == mx[x]) continue;
    dfs2(v, v);
  }
}
void tree_dp(int x) {
  for (auto v : e[x]) tree_dp(v);
  if (!e[x].size()) {
    f[x].clear(), f[x].push_back(1), f[x].push_back(1);
    return;
  }
  V.clear();
  for (auto v : e[x])
    if (v != mx[x]) V.push_back(v);
  if (V.size()) {
    solve(0, (int)V.size() - 1, f[x]);
    f[x].resize(f[x].size() + 1);
    for (int i = (int)f[x].size() - 1; i >= 1; --i) f[x][i] = f[x][i - 1];
    f[x][0] = 0;
  } else
    f[x].clear(), f[x].push_back(0), f[x].push_back(1);
  if (top[x] == x) {
    V.clear();
    for (int i = 1, nw = x; i <= H[x] + 1; ++i) V.push_back(nw), nw = mx[nw];
    reverse(V.begin(), V.end());
    f[V[0]][0] = 0;
    Solve(0, (int)V.size() - 1, F, GF);
    f[x].resize(F.size());
    for (int i = 0; i < (int)F.size(); ++i) f[x][i] = F[i];
    f[x][0] = 1;
  }
}
signed main() {
  int n;
  long long X;
  read(n), read(X), Init(n);
  for (int i = 1, u, v; i < n; ++i)
    read(u), read(v), E[u].push_back(v), E[v].push_back(u);
  dfs1(1, 0);
  dfs2(1, 1);
  tree_dp(1);
  int ans = 0;
  for (int i = 1, mul = 1; i < (int)f[1].size(); ++i) {
    ans = upd(ans, 1ll * mul * f[1][i] % mods);
    mul = 1ll * mul * quick_pow(i, mods - 2) % mods * ((X + i) % mods) % mods;
  }
  print(ans);
  return 0;
}
