Nauuo is a girl who loves drawing circles.

One day she has drawn a circle and wanted to draw a tree on it.

The tree is a connected undirected graph consisting of n nodes and n-1 edges. The nodes are numbered from 1 to n.

Nauuo wants to draw a tree on the circle, the nodes of the tree should be in n distinct points on the circle, and the edges should be straight without crossing each other.

"Without crossing each other" means that every two edges have no common point or the only common point is an endpoint of both edges.

Nauuo wants to draw the tree using a permutation of n elements. A permutation of n elements is a sequence of integers p_1,p_2,…,p_n in which every integer from 1 to n appears exactly once.

After a permutation is chosen Nauuo draws the i-th node in the p_i-th point on the circle, then draws the edges connecting the nodes.

The tree is given, Nauuo wants to know how many permutations are there so that the tree drawn satisfies the rule (the edges are straight without crossing each other). She only wants to know the answer modulo 998244353, can you help her?

It is obvious that whether a permutation is valid or not does not depend on which n points on the circle are chosen.

Input

The first line contains a single integer n (2≤ n≤ 2⋅ 10^5) — the number of nodes in the tree.

Each of the next n-1 lines contains two integers u and v (1≤ u,v≤ n), denoting there is an edge between u and v.

It is guaranteed that the given edges form a tree.

Output

The output contains a single integer — the number of permutations suitable to draw the given tree on a circle satisfying the rule, modulo 998244353.

Examples

Input


4
1 2
1 3
2 4


Output


16

Input


4
1 2
1 3
1 4


Output


24

Note

Example 1

All valid permutations and their spanning trees are as follows.

<image>

Here is an example of invalid permutation: the edges (1,3) and (2,4) are crossed.

<image>

Example 2

Every permutation leads to a valid tree, so the answer is 4! = 24.
#include <bits/stdc++.h>
using namespace std;
template <typename T>
using V = vector<T>;
template <typename T>
using VV = vector<V<T>>;
template <typename T>
using Mi = map<long long, T>;
template <typename T>
using MMi = map<long long, Mi<T>>;
const double PI = 3.141592653589793238463;
pair<long long, long long> zero = {-1, -1};
void cinArr(vector<long long> &arr) {
  for (int i = 0; i < arr.size(); i++) {
    cin >> arr[i];
  }
}
void cinArr(V<int> &arr) {
  for (int i = 0; i < arr.size(); i++) {
    cin >> arr[i];
  }
}
void cinMatr(vector<vector<long long>> &matr) {
  long long n = matr.size();
  long long m = matr[0].size();
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> matr[i][j];
    }
  }
}
int xx[4] = {1, -1, 0, 0};
int yy[4] = {0, 0, 1, -1};
vector<long long> prim;
vector<long long> prims;
void er() {
  long long n = 1e6;
  prim = vector<long long>(n + 1);
  for (int i = 0; i <= n; i++) {
    prim[i] = i;
  }
  for (long long i = 2; i <= n; i++) {
    if (prim[i] == i) {
      prims.push_back(i);
      for (long long j = i * i; j <= n; j += i) {
        if (prim[j] == j) {
          prim[j] = i;
        }
      }
    }
  }
}
class LCA {
 private:
  long long N;
  long long n;
  vector<vector<long long>> up;
  vector<vector<long long>> g;
  vector<long long> lvl;
  void dfs(long long v, long long h) {
    lvl[v] = h;
    for (long long u : g[v]) {
      dfs(u, h + 1);
    }
  }

 public:
  LCA(vector<long long> &parent) {
    n = parent.size();
    N = log2(n) + 1;
    g = vector<vector<long long>>(n);
    lvl = vector<long long>(n);
    long long core = -1;
    for (int i = 0; i < n; i++) {
      if (parent[i] != -1) {
        g[parent[i]].push_back(i);
      } else {
        core = i;
      }
    }
    dfs(core, 0);
    up = vector<vector<long long>>(N, vector<long long>(n));
    up[0] = parent;
    for (int i = 1; i < N; i++) {
      for (int j = 0; j < n; j++) {
        long long parent = up[i - 1][j];
        if (parent == -1) {
          up[i][j] = -1;
        } else {
          up[i][j] = up[i - 1][parent];
        }
      }
    }
  }
  long long getParent(long long v, long long needUp) {
    for (int i = N - 1; i >= 0; i--) {
      if (up[i][v] != -1 && lvl[v] - lvl[up[i][v]] <= needUp) {
        needUp -= lvl[v] - lvl[up[i][v]];
        v = up[i][v];
      }
    }
    if (needUp != 0) {
      return -1;
    } else {
      return v;
    }
  }
  long long getLCA(long long a, long long b) {
    if (lvl[a] > lvl[b]) {
      long long del = abs(lvl[a] - lvl[b]);
      a = getParent(a, del);
    }
    if (lvl[a] < lvl[b]) {
      long long del = abs(lvl[a] - lvl[b]);
      b = getParent(b, del);
    }
    if (a == b) {
      return a;
    }
    for (int i = N - 1; i >= 0; i--) {
      if (up[i][a] != up[i][b]) {
        a = up[i][a];
        b = up[i][b];
      }
    }
    return up[0][a];
  }
  long long getLvl(long long v) { return lvl[v]; }
};
class Node {
 private:
  long long a;
  long long del;
  LCA &lca;
  long long l;
  long long r;
  Node *lChildren;
  Node *rChildren;
  pair<long long, long long> merge(pair<long long, long long> x,
                                   pair<long long, long long> y, long long len1,
                                   long long len2) {
    if (len1 > 2 && len2 > 2) {
      long long a = x.first;
      long long b = x.second;
      long long c = y.first;
      long long d = y.second;
      long long ac = lca.getLCA(a, c);
      long long acb = lca.getLCA(ac, b);
      long long acd = lca.getLCA(ac, d);
      if (lca.getLvl(acb) > lca.getLvl(acd)) {
        return {acb, d};
      } else {
        return {acd, b};
      }
    }
    if (len1 == 0) {
      return y;
    }
    if (len2 == 0) {
      return x;
    }
    long long a = x.first;
    long long b = x.second;
    long long c = y.first;
    long long d = y.second;
    if (len1 == 1 && len2 == 1) {
      if (lca.getLvl(b) > lca.getLvl(d)) {
        return {b, d};
      } else {
        return {d, b};
      }
    }
    if (len1 == 1) {
      if (len2 == 2) {
        long long bc = lca.getLCA(b, c);
        long long bd = lca.getLCA(b, d);
        long long cd = lca.getLCA(c, d);
        long long lbc = lca.getLvl(bc);
        long long lbd = lca.getLvl(bd);
        long long lcd = lca.getLvl(cd);
        if (lbc > lbd && lbc > lcd) {
          return {bc, d};
        }
        if (lbd > lcd) {
          return {bd, c};
        }
        return {cd, b};
      }
      long long bc = lca.getLCA(b, c);
      long long cd = lca.getLCA(c, d);
      long long lbc = lca.getLvl(bc);
      long long lcd = lca.getLvl(cd);
      if (lbc > lcd) {
        return {bc, d};
      } else {
        return {cd, b};
      }
    }
    if (len2 == 1) {
      if (len1 == 2) {
        long long ab = lca.getLCA(a, b);
        long long ad = lca.getLCA(a, d);
        long long bd = lca.getLCA(b, d);
        long long lab = lca.getLvl(ab);
        long long lad = lca.getLvl(ad);
        long long lbd = lca.getLvl(bd);
        if (lab > lad && lab > lbd) {
          return {ab, d};
        }
        if (lad > lbd) {
          return {ad, b};
        }
        return {bd, a};
      }
      long long ab = lca.getLCA(b, a);
      long long ad = lca.getLCA(a, d);
      long long lab = lca.getLvl(ab);
      long long lad = lca.getLvl(ad);
      if (lab > lad) {
        return {ab, d};
      } else {
        return {ad, b};
      }
    }
    if (len1 == 2 && len2 > 2) {
      long long abc = lca.getLCA(a, lca.getLCA(b, c));
      long long acd = lca.getLCA(a, lca.getLCA(c, d));
      long long bcd = lca.getLCA(b, lca.getLCA(c, d));
      long long labc = lca.getLvl(abc);
      long long lacd = lca.getLvl(acd);
      long long lbcd = lca.getLvl(bcd);
      long long ans = max({labc, lacd, lbcd});
      if (labc == ans) {
        return {abc, d};
      }
      if (lacd == ans) {
        return {acd, b};
      }
      if (lbcd == ans) {
        return {bcd, a};
      }
    }
    if (len2 == 2 && len1 > 2) {
      long long abc = lca.getLCA(a, lca.getLCA(b, c));
      long long abd = lca.getLCA(a, lca.getLCA(b, d));
      long long acd = lca.getLCA(a, lca.getLCA(c, d));
      long long labc = lca.getLvl(abc);
      long long labd = lca.getLvl(abd);
      long long lacd = lca.getLvl(acd);
      long long ans = max({labc, labd, lacd});
      if (labc == ans) {
        return {abc, d};
      }
      if (labd == ans) {
        return {abd, c};
      }
      if (lacd == ans) {
        return {acd, b};
      }
    }
    long long abc = lca.getLCA(a, lca.getLCA(b, c));
    long long abd = lca.getLCA(a, lca.getLCA(b, d));
    long long acd = lca.getLCA(a, lca.getLCA(c, d));
    long long bcd = lca.getLCA(b, lca.getLCA(c, d));
    long long labc = lca.getLvl(abc);
    long long labd = lca.getLvl(abd);
    long long lacd = lca.getLvl(acd);
    long long lbcd = lca.getLvl(bcd);
    long long ans = max({labc, labd, lacd, lbcd});
    if (labc == ans) {
      return {abc, d};
    }
    if (labd == ans) {
      return {abd, c};
    }
    if (lacd == ans) {
      return {acd, b};
    }
    if (lbcd == ans) {
      return {bcd, a};
    }
    return zero;
  }
  Node(long long l, long long r, vector<long long> &arr, LCA &lca) : lca(lca) {
    this->l = l;
    this->r = r;
    if (l == r) {
      a = -1;
      del = arr[l];
    } else {
      long long mid = (l + r) / 2;
      lChildren = new Node(l, mid, arr, lca);
      rChildren = new Node(mid + 1, r, arr, lca);
      long long len1 = mid - l + 1;
      long long len2 = r - mid;
      pair<long long, long long> p =
          merge(lChildren->getValue(), rChildren->getValue(), len1, len2);
      a = p.first;
      del = p.second;
    }
  }

 public:
  Node(vector<long long> &arr, LCA &lca) : Node(0, arr.size() - 1, arr, lca) {}
  pair<long long, long long> getValue() {
    pair<long long, long long> p = {a, del};
    return p;
  }
  pair<long long, long long> getValue(long long left, long long right) {
    if (l == left && r == right) {
      return getValue();
    }
    long long mid = (l + r) / 2;
    pair<long long, long long> p1, p2;
    long long len1 = 0;
    long long len2 = 0;
    p1 = p2 = zero;
    if (left <= mid) {
      p1 = lChildren->getValue(left, min(right, mid));
      len1 = min(right, mid) - left + 1;
    }
    if (right > mid) {
      p2 = rChildren->getValue(max(mid + 1, left), right);
      len2 = right - max(mid + 1, left) + 1;
    }
    pair<long long, long long> p = merge(p1, p2, len1, len2);
    return p;
  }
  void update(long long l, long long r, long long value) {
    if (l == this->l && r == this->r) {
      return;
    }
    long long mid = (this->l + this->r) / 2;
    if (l <= mid) {
      lChildren->update(l, min(mid, r), value);
    }
    if (r > mid) {
      rChildren->update(max(mid + 1, l), r, value);
    }
  }
};
long long gcd(long long a, long long b) {
  if (a < b) {
    swap(a, b);
  }
  if (b == 0) {
    return a;
  }
  return gcd(b, a % b);
}
long long gcd(long long a, long long b, long long &x, long long &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  long long x1, y1;
  long long d = gcd(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}
long long nok(long long a, long long b) {
  long long nnod = gcd(a, b);
  long long ans = a / nnod * b;
  return ans;
}
long long divup(long long a, long long b) {
  if (a % b == 0) {
    return a / b;
  } else {
    return a / b + 1;
  }
}
class SNM {
 private:
  vector<long long> parent;
  vector<long long> size;

 public:
  SNM(long long n) {
    parent = vector<long long>(n);
    size = vector<long long>(n, 1);
    for (int i = 0; i < n; i++) {
      parent[i] = i;
    }
  }
  void make_set(int v) { parent[v] = v; }
  int find_set(int v) {
    if (v == parent[v]) return v;
    long long ans = find_set(parent[v]);
    parent[v] = ans;
    return ans;
  }
  void union_sets(int a, int b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
      parent[b] = a;
      size[a] += size[b];
    }
  }
  long long getSize(int v) {
    v = find_set(v);
    return size[v];
  }
};
long long bs(long long x, vector<long long> &arr) {
  long long l = 0;
  long long r = arr.size();
  while (l < r) {
    long long mid = (l + r) / 2;
    if (arr[mid] >= x) {
      r = mid;
    } else {
      l = mid + 1;
    }
  }
  return l;
}
void dfs(long long v, vector<vector<long long>> &g, vector<bool> &viz,
         vector<long long> &count, vector<long long> &lvl, long long len) {
  viz[v] = true;
  count[v] = 1;
  lvl[v] = len;
  for (long long u : g[v]) {
    if (!viz[u]) {
      dfs(u, g, viz, count, lvl, len + 1);
      count[v] += count[u];
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long n;
  cin >> n;
  if (n == 2) {
    cout << 2;
    return 0;
  }
  vector<vector<long long>> g(n);
  vector<pair<long long, long long>> reb;
  for (int i = 0; i < n - 1; i++) {
    long long v, u;
    cin >> v >> u;
    v--;
    u--;
    g[v].push_back(u);
    g[u].push_back(v);
    reb.push_back({v, u});
  }
  long long E = 998244353;
  long long ans = 1;
  for (int i = 2; i <= n; i++) {
    ans *= i;
    ans %= E;
  }
  vector<long long> count(n, 0);
  vector<long long> lvl(n, 0);
  vector<bool> viz(n, false);
  dfs(0, g, viz, count, lvl, 0);
  for (pair<long long, long long> p : reb) {
    long long v = p.first;
    long long u = p.second;
    if (lvl[v] < lvl[u]) {
      swap(v, u);
    }
    long long a = count[v] - 1;
    long long b = n - a - 2;
    long long minys = (a) * (b);
    ans -= minys * 2 * n;
    ans %= E;
  }
  cout << ans;
  return 0;
}
