#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MOD = 998244353;
const int PRIMROOT = 3;
int pw(int x, int n) {
  int ret = 1;
  while (true) {
    if (n & 1) ret = (long long)ret * x % MOD;
    if ((n >>= 1) == 0) return ret;
    x = (long long)x * x % MOD;
  }
}
struct NTT {
  void _init(int n, int &nlog, int &g, vector<int> &w) {
    assert((MOD - 1) % n == 0);
    g = pw(PRIMROOT, (MOD - 1) / n);
    nlog = 0;
    while ((1 << nlog) < n) ++nlog;
    if ((1 << nlog) != n) nlog = -1;
    w = vector<int>(n);
    w[0] = 1;
    for (int i = (1); i < (n); ++i) w[i] = (long long)w[i - 1] * g % MOD;
  }
  int fftn, fftnlog;
  int fftg;
  vector<int> fftw;
  void initfft(int n) {
    fftn = n, _init(fftn, fftnlog, fftg, fftw);
    assert(fftnlog != -1);
  }
  void fft(int *a, int n, bool inv) {
    if (n != fftn) initfft(n);
    for (int i = 1, j = n >> 1, k, l = j; i < n; j ^= k, ++i) {
      if (i < j) swap(a[i], a[j]);
      for (k = l; k & j; j ^= k, k >>= 1)
        ;
    }
    int *l, *r, *w;
    if (inv) reverse(fftw.begin() + 1, fftw.end());
    for (int hlen = 1, step = n >> 1; hlen < n; hlen <<= 1, step >>= 1) {
      for (int i = 0; i < n; i += (hlen << 1)) {
        l = a + i, r = l + hlen, w = fftw.data();
        for (int off = (0); off < (hlen); ++off) {
          int v = (long long)(*r) * (*w) % MOD;
          *r = (*l) - v;
          if (*r < 0) *r += MOD;
          *l = (*l) + v;
          if (*l >= MOD) *l -= MOD;
          ++l, ++r, w += step;
        }
      }
    }
    if (inv) reverse(fftw.begin() + 1, fftw.end());
    if (inv) {
      int mlt = pw(n, MOD - 2);
      for (int i = (0); i < (n); ++i) a[i] = (long long)a[i] * mlt % MOD;
    }
  }
  void mult(const int *a, int na, const int *b, int nb, int *c, int nc) {
    int sz = 1;
    while (sz < na + nb - 1) sz *= 2;
    vector<int> A(sz, 0), B(sz, 0);
    for (int i = (0); i < (na); ++i) A[i] = a[i];
    for (int i = (0); i < (nb); ++i) B[i] = b[i];
    fft(A.data(), sz, false);
    fft(B.data(), sz, false);
    for (int i = (0); i < (sz); ++i) A[i] = (long long)A[i] * B[i] % MOD;
    fft(A.data(), sz, true);
    for (int i = (0); i < (nc); ++i) c[i] = i < sz ? A[i] : 0;
  }
};
NTT ntt;
void inc(int &a, int b) {
  if ((a += b) >= MOD) a -= MOD;
}
vector<int> add(const vector<int> &a, const vector<int> &b) {
  vector<int> c(max(((int)(a).size()), ((int)(b).size())), 0);
  for (int i = (0); i < (((int)(c).size())); ++i) {
    if (i < ((int)(a).size())) inc(c[i], a[i]);
    if (i < ((int)(b).size())) inc(c[i], b[i]);
  }
  return c;
}
vector<int> mult(const vector<int> &a, const vector<int> &b) {
  vector<int> c(((int)(a).size()) + ((int)(b).size()) - 1, 0);
  ntt.mult(a.data(), ((int)(a).size()), b.data(), ((int)(b).size()), c.data(),
           ((int)(c).size()));
  return c;
}
const int MAXN = 100000;
int n;
long long want;
vector<int> adj[MAXN];
int par[MAXN];
int sz[MAXN];
int dep[MAXN];
int heavy[MAXN];
vector<int> ways[MAXN];
vector<int> waysnonheavy[MAXN];
void dfsinit(int at) {
  dep[at] = par[at] == -1 ? 0 : dep[par[at]] + 1, sz[at] = 1, heavy[at] = -1;
  for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
    int to = adj[at][i];
    if (to == par[at]) continue;
    par[to] = at;
    dfsinit(to);
    sz[at] += sz[to];
    if (heavy[at] == -1 || sz[to] > sz[heavy[at]]) heavy[at] = to;
  }
}
int path[MAXN], npath;
pair<vector<int>, vector<int>> rec(int l, int r) {
  if (l == r) {
    int at = path[l];
    return make_pair(waysnonheavy[at], waysnonheavy[at]);
  } else {
    int lsum = 0, cl = l - 1, rsum = 0, cr = r + 1;
    while (cr - cl > 1)
      if (lsum <= rsum)
        lsum += ((int)(waysnonheavy[path[++cl]]).size());
      else
        rsum += ((int)(waysnonheavy[path[--cr]]).size());
    auto res1 = rec(l, cl);
    auto res2 = rec(cr, r);
    return make_pair(add(res1.first, mult(res1.second, res2.first)),
                     mult(res1.second, res2.second));
  }
}
int lst[MAXN], nlst;
vector<int> tmp[2 * MAXN];
int ntmp;
priority_queue<pair<int, int>> pq;
void calcways(int at);
void calcwaysnonheavy(int at) {
  for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
    int to = adj[at][i];
    if (to == par[at] || to == heavy[at]) continue;
    calcways(to);
  }
  nlst = 0;
  for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
    int to = adj[at][i];
    if (to == par[at] || to == heavy[at]) continue;
    lst[nlst++] = to;
  }
  ntmp = nlst;
  pq = priority_queue<pair<int, int>>();
  for (int i = (0); i < (nlst); ++i)
    tmp[i] = ways[lst[i]], pq.push(make_pair(-((int)(tmp[i]).size()), i));
  while (((int)(pq).size()) >= 2) {
    int a = pq.top().second;
    pq.pop();
    int b = pq.top().second;
    pq.pop();
    int c = ntmp++;
    tmp[ntmp] = mult(tmp[a], tmp[b]),
    pq.push(make_pair(-((int)(tmp[c]).size()), c));
  }
  waysnonheavy[at] =
      ((int)(pq).size()) == 1 ? tmp[pq.top().second] : vector<int>(1, 1);
  waysnonheavy[at].insert(waysnonheavy[at].begin(), 0);
  for (int i = (0); i < (ntmp); ++i) tmp[i].clear();
}
void calcways(int at) {
  for (int x = at; x != -1; x = heavy[x]) calcwaysnonheavy(x);
  npath = 0;
  for (int x = at; x != -1; x = heavy[x]) path[npath++] = x;
  ways[at] = rec(0, npath - 1).first;
  inc(ways[at][0], 1);
}
int inv[MAXN + 1];
void run() {
  scanf("%d%lld", &n, &want);
  for (int i = (0); i < (n - 1); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  par[0] = -1;
  dfsinit(0);
  calcways(0);
  int ret = 0, mlt = 1;
  inv[1] = 1;
  for (int i = (2); i < (((int)(ways[0]).size())); ++i)
    inv[i] = (long long)(MOD - MOD / i) * inv[MOD % i] % MOD;
  for (int i = (1); i < (((int)(ways[0]).size())); ++i) {
    ret = (ret + (long long)ways[0][i] * mlt) % MOD;
    mlt = (long long)mlt * (want % MOD + i) % MOD * inv[i] % MOD;
  }
  printf("%d\n", ret);
}
int main() {
  run();
  return 0;
}
