#include <bits/stdc++.h>
using namespace std;
const int p = 998244353;
int s, l, G[2][25], rev[100005 << 1];
void Add(int &x, int y) { x = (x + y) % p; }
void Del(int &x, int y) { x = (x - y) % p; }
void Mul(int &x, int y) { x = (long long)x * y % p; }
int add(int x, int y) { return (x + y) % p; }
int del(int x, int y) { return (x - y) % p; }
int mul(int x, int y) { return (long long)x * y % p; }
int ksm(int x, int y) {
  int ans = 1;
  while (y) {
    if (y & 1) Mul(ans, x);
    Mul(x, x);
    y >>= 1;
  }
  return ans;
}
void Pre() {
  G[0][23] = ksm(3, (p - 1) / (1 << 23));
  G[1][23] = ksm(G[0][23], p - 2);
  for (int i = 22; i; --i) {
    G[0][i] = mul(G[0][i + 1], G[0][i + 1]);
    G[1][i] = mul(G[1][i + 1], G[1][i + 1]);
  }
}
void solve(int n) {
  s = 1, l = 0;
  while (s < n) s <<= 1, ++l;
  for (int i = 0; i < s; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << l - 1);
}
struct Poly {
  int n;
  vector<int> a;
  int &operator[](int x) { return a[x]; }
  void read(int zn) {
    n = zn, a.clear();
    for (int i = 0; i < n; ++i) a.push_back(0), scanf("%d", &a[i]);
  }
  void print() {
    puts("--------------------");
    printf("Len: %d\n", n);
    for (int i = 0; i < n; ++i) printf("%d ", a[i]);
    putchar('\n');
    puts("--------------------");
  }
  void clean() { n = 0, a.clear(); }
  void reuse(int zn) {
    n = zn, a.clear();
    for (int i = 0; i < n; ++i) a.push_back(0);
  }
  void extend(int S = s) {
    int t = S - a.size();
    for (int i = 1; i <= t; ++i) a.push_back(0);
  }
  void rollback(int S) {
    int t = a.size() - S;
    for (int i = 0; i < t; ++i) a.pop_back();
  }
  void NTT(int t) {
    for (int i = 0; i < s; ++i)
      if (i < rev[i]) swap(a[i], a[rev[i]]);
    for (int mid = 1, o = 1; mid < s; mid <<= 1, ++o)
      for (int j = 0; j < s; j += mid << 1) {
        int g = 1;
        for (int k = 0; k < mid; ++k, Mul(g, G[t][o])) {
          int x = a[j + k], y = mul(g, a[j + k + mid]);
          a[j + k] = add(x, y);
          a[j + k + mid] = del(x, y);
        }
      }
  }
  void minv(int S = s) {
    int t = ksm(S, p - 2);
    for (int i = 0; i < s; ++i) Mul(a[i], t);
  }
};
Poly operator+(Poly f, Poly g) {
  int n = max(f.n, g.n);
  f.n = n;
  f.extend(n), g.extend(n);
  for (int i = 0; i < n; ++i) Add(f[i], g[i]);
  return f;
}
void operator+=(Poly &f, Poly &g) {
  int n = max(f.n, g.n);
  f.n = n;
  f.extend(n), g.extend(n);
  for (int i = 0; i < n; ++i) Add(f[i], g[i]);
  g.rollback(g.n);
}
Poly operator*(Poly f, Poly g) {
  int n = f.n, m = g.n;
  solve(n + m);
  f.extend(), g.extend();
  f.NTT(0), g.NTT(0);
  for (int i = 0; i < s; ++i) Mul(f[i], g[i]);
  f.NTT(1), f.minv();
  f.n = n + m - 1, f.rollback(f.n);
  return f;
}
void operator*=(Poly &f, Poly &g) {
  int n = f.n, m = g.n;
  solve(n + m);
  f.extend(), g.extend();
  f.NTT(0), g.NTT(0);
  for (int i = 0; i < s; ++i) Mul(f[i], g[i]);
  f.NTT(1), f.minv();
  f.n = n + m - 1, f.rollback(f.n), g.rollback(m);
}
void polyswap(Poly &f, Poly &g) { f.a.swap(g.a), swap(f.n, g.n); }
int n, x, y, ans;
long long X;
struct edge {
  int nxt, v;
  edge() {}
  edge(int Nxt, int V) : nxt(Nxt), v(V) {}
} e[100005 << 1];
int tot, fr[100005], sz[100005], son[100005], fa[100005];
vector<int> H[100005];
void link(int x, int y) {
  ++tot;
  e[tot] = edge(fr[x], y), fr[x] = tot;
}
void dfs(int u) {
  sz[u] = 1;
  int mx = -1;
  for (int i = fr[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    if (v == fa[u]) continue;
    fa[v] = u;
    dfs(v);
    sz[u] += sz[v];
    if (sz[v] > mx) mx = sz[v], son[u] = v;
  }
}
void dfs2(int u, int tp) {
  H[tp].push_back(u);
  if (!son[u]) return;
  dfs2(son[u], tp);
  for (int i = fr[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    if (v == fa[u] || v == son[u]) continue;
    dfs2(v, v);
  }
}
Poly Z, Z2, F[100005], S[100005 << 2], T[100005 << 2];
void modify(int p, int l, int r, int x, Poly &a) {
  if (l == r) {
    polyswap(S[p], a);
    a.clean();
    T[p] = S[p];
    ++S[p][0];
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    modify((p << 1), l, mid, x, a);
  else
    modify((p << 1 | 1), mid + 1, r, x, a);
}
void calc(int p, int l, int r) {
  if (l == r) return;
  int mid = (l + r) >> 1;
  calc((p << 1), l, mid);
  calc((p << 1 | 1), mid + 1, r);
  --S[(p << 1)][0];
  S[p] = S[(p << 1)] * T[(p << 1 | 1)] + S[(p << 1 | 1)];
  T[p] = T[(p << 1)] * T[(p << 1 | 1)];
  S[(p << 1)].clean(), T[(p << 1)].clean();
  S[(p << 1 | 1)].clean(), T[(p << 1 | 1)].clean();
}
void Solve(int u) {
  if (!son[u]) {
    F[u].reuse(2);
    F[u][0] = F[u][1] = 1;
    return;
  }
  int cnt = 0;
  for (vector<int>::iterator it = H[u].begin(); it != H[u].end(); ++it) {
    int v = *it;
    ++cnt;
    for (int i = fr[v]; i; i = e[i].nxt) {
      int v2 = e[i].v;
      if (v2 == fa[v] || v2 == son[v]) continue;
      Solve(v2);
    }
  }
  --cnt;
  Z2 = Z;
  modify(1, 0, cnt, 0, Z2);
  reverse(H[u].begin(), H[u].end());
  int rct = 0;
  for (vector<int>::iterator it = H[u].begin() + 1; it != H[u].end(); ++it) {
    ++rct;
    int v = *it;
    bool flag = false;
    for (int i = fr[v]; i; i = e[i].nxt) {
      int v2 = e[i].v;
      if (v2 == fa[v] || v2 == son[v]) continue;
      flag = true;
      reverse(F[v2].a.begin(), F[v2].a.end());
      F[v2].a.push_back(0), ++F[v2].n;
      reverse(F[v2].a.begin(), F[v2].a.end());
      modify(1, 0, cnt, rct, F[v2]);
    }
    if (!flag) Z2 = Z, modify(1, 0, cnt, rct, Z2);
  }
  calc(1, 0, cnt);
  polyswap(F[u], S[1]);
  S[1].clean(), T[1].clean();
}
int main() {
  Pre();
  scanf("%d%lld", &n, &X);
  int zx = X % p;
  for (int i = 1; i < n; ++i) {
    scanf("%d%d", &x, &y);
    link(x, y), link(y, x);
  }
  dfs(1);
  dfs2(1, 1);
  Z.reuse(2), Z[1] = 1;
  Solve(1);
  int z1 = 1, z2 = 1;
  for (int i = 1; i <= n; ++i) {
    Add(ans, mul(mul(z1, z2), F[1][i]));
    Mul(z1, add(zx, i));
    Mul(z2, ksm(i, p - 2));
  }
  ans = (ans % p + p) % p;
  printf("%d\n", ans);
  return 0;
}
