#include <bits/stdc++.h>
const long long INF = 0x3f3f3f3f3f3f3f3fLL;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-6;
void err() { puts(""); }
template <typename T, typename... Args>
void err(const T &arg, const Args &...args) {
  std::cout << arg << ' ';
  err(args...);
}
template <typename T>
void read(T &x) {
  x = 0;
  char ch = getchar();
  long long f = 1;
  while (!isdigit(ch)) {
    if (ch == '-') f *= -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - 48;
    ch = getchar();
  }
  x *= f;
}
template <typename T, typename... Args>
void read(T &first, Args &...args) {
  read(first);
  read(args...);
}
using namespace std;
const int maxn = 710;
struct BigInteger {
  static const int BASE = 100000000;
  static const int WIDTH = 8;
  bool sign;
  size_t length;
  std::vector<int> num;
  BigInteger(long long x = 0) { *this = x; }
  BigInteger(const std::string &x) { *this = x; }
  BigInteger(const BigInteger &x) { *this = x; }
  void cutLeadingZero() {
    while (num.back() == 0 && num.size() != 1) {
      num.pop_back();
    }
  }
  void setLength() {
    cutLeadingZero();
    int tmp = num.back();
    if (tmp == 0) {
      length = 1;
    } else {
      length = (num.size() - 1) * WIDTH;
      while (tmp > 0) {
        ++length;
        tmp /= 10;
      }
    }
  }
  BigInteger &operator=(long long x) {
    num.clear();
    if (x >= 0)
      sign = true;
    else {
      sign = false;
      x = -x;
    }
    do {
      num.emplace_back(x % BASE);
      x /= BASE;
    } while (x > 0);
    setLength();
    return *this;
  }
  BigInteger &operator=(const std::string &str) {
    num.clear();
    sign = (str[0] != '-');
    int x, len = (str.size() - 1 - (!sign)) / WIDTH + 1;
    for (int i = 0; i < len; i++) {
      int End = str.length() - i * WIDTH;
      int start = std::max((int)(!sign), End - WIDTH);
      sscanf(str.substr(start, End - start).c_str(), "%d", &x);
      num.push_back(x);
    }
    setLength();
    return *this;
  }
  BigInteger &operator=(const BigInteger &tmp) {
    num = tmp.num;
    sign = tmp.sign;
    length = tmp.length;
    return *this;
  }
  size_t size() const { return length; }
  BigInteger e(size_t n) const {
    int tmp = n % WIDTH;
    BigInteger ans;
    ans.length = n + 1;
    n /= WIDTH;
    while (ans.num.size() <= n) ans.num.push_back(0);
    ans.num[n] = 1;
    while (tmp--) ans.num[n] *= 10;
    return ans * (*this);
  }
  BigInteger abs() const {
    BigInteger ans(*this);
    ans.sign = true;
    return ans;
  }
  const BigInteger &operator+() const { return *this; }
  BigInteger operator+(const BigInteger &b) const {
    if (!b.sign) {
      return *this - (-b);
    }
    if (!sign) {
      return b - (-*this);
    }
    BigInteger ans;
    ans.num.clear();
    for (int i = 0, g = 0;; i++) {
      if (g == 0 && i >= num.size() && i >= b.num.size()) break;
      int x = g;
      if (i < num.size()) x += num[i];
      if (i < b.num.size()) x += b.num[i];
      ans.num.push_back(x % BASE);
      g = x / BASE;
    }
    ans.setLength();
    return ans;
  }
  BigInteger operator-() const {
    BigInteger ans(*this);
    if (ans != 0) ans.sign = !ans.sign;
    return ans;
  }
  BigInteger operator-(const BigInteger &b) const {
    if (!b.sign) {
      return *this + (-b);
    }
    if (!sign) {
      return -((-*this) + b);
    }
    if (*this < b) {
      return -(b - *this);
    }
    BigInteger ans;
    ans.num.clear();
    for (int i = 0, g = 0;; i++) {
      if (g == 0 && i >= num.size() && i >= b.num.size()) break;
      int x = g;
      g = 0;
      if (i < num.size()) x += num[i];
      if (i < b.num.size()) x -= b.num[i];
      if (x < 0) {
        x += BASE;
        g = -1;
      }
      ans.num.push_back(x);
    }
    ans.setLength();
    return ans;
  }
  BigInteger operator*(const BigInteger &b) const {
    int lena = num.size(), lenb = b.num.size();
    std::vector<long long> ansLL;
    for (int i = 0; i < lena + lenb; i++) ansLL.push_back(0);
    for (int i = 0; i < lena; i++) {
      for (int j = 0; j < lenb; j++) {
        ansLL[i + j] += (long long)num[i] * (long long)b.num[j];
      }
    }
    while (ansLL.back() == 0 && ansLL.size() != 1) ansLL.pop_back();
    int len = ansLL.size();
    long long g = 0, tmp;
    BigInteger ans;
    ans.sign = (ansLL.size() == 1 && ansLL[0] == 0) || (sign == b.sign);
    ans.num.clear();
    for (int i = 0; i < len; i++) {
      tmp = ansLL[i];
      ans.num.emplace_back((tmp + g) % BASE);
      g = (tmp + g) / BASE;
    }
    if (g > 0) ans.num.emplace_back(g);
    ans.setLength();
    return ans;
  }
  BigInteger operator/(const long long &b) const {
    BigInteger c;
    c.num.clear();
    for (int i = 0; i < num.size(); i++) {
      c.num.push_back(0);
    }
    long long g = 0;
    for (int i = num.size() - 1; i >= 0; i--) {
      c.num[i] = int((num[i] + g * BASE) / b);
      g = num[i] + g * BASE - c.num[i] * b;
    }
    for (int i = num.size() - 1; c.num[i] == 0; i--) {
      c.num.pop_back();
    }
    return c;
  }
  BigInteger operator/(const BigInteger &b) const {
    BigInteger aa((*this).abs());
    BigInteger bb(b.abs());
    if (aa < bb) return 0;
    char *str = new char[aa.size() + 1];
    memset(str, 0, sizeof(char) * (aa.size() + 1));
    BigInteger tmp;
    int lena = aa.length, lenb = bb.length;
    for (int i = 0; i <= lena - lenb; i++) {
      tmp = bb.e(lena - lenb - i);
      while (aa >= tmp) {
        ++str[i];
        aa = aa - tmp;
      }
      str[i] += '0';
    }
    BigInteger ans(str);
    delete[] str;
    ans.sign = (ans == 0 || sign == b.sign);
    return ans;
  }
  BigInteger operator%(const long long &b) const {
    long long ans = 0;
    for (int i = num.size() - 1; i >= 0; i--) ans = (ans * BASE + num[i]) % b;
    return ans;
  }
  BigInteger operator%(const BigInteger &b) const {
    return *this - *this / b * b;
  }
  BigInteger &operator++() {
    *this = *this + 1;
    return *this;
  }
  BigInteger &operator--() {
    *this = *this - 1;
    return *this;
  }
  BigInteger &operator+=(const BigInteger &b) {
    *this = *this + b;
    return *this;
  }
  BigInteger &operator-=(const BigInteger &b) {
    *this = *this - b;
    return *this;
  }
  BigInteger &operator*=(const BigInteger &b) {
    *this = *this * b;
    return *this;
  }
  BigInteger &operator/=(const long long &b) {
    *this = *this / b;
    return *this;
  }
  BigInteger &operator/=(const BigInteger &b) {
    *this = *this / b;
    return *this;
  }
  BigInteger &operator%=(const long long &b) {
    *this = *this % b;
    return *this;
  }
  BigInteger &operator%=(const BigInteger &b) {
    *this = *this % b;
    return *this;
  }
  bool operator<(const BigInteger &b) const {
    if (sign && !b.sign) {
      return false;
    } else if (!sign && b.sign) {
      return true;
    } else if (!sign && !b.sign) {
      return -b < -*this;
    }
    if (num.size() != b.num.size()) return num.size() < b.num.size();
    for (int i = num.size() - 1; i >= 0; i--)
      if (num[i] != b.num[i]) return num[i] < b.num[i];
    return false;
  }
  bool operator>(const BigInteger &b) const { return b < *this; }
  bool operator<=(const BigInteger &b) const { return !(b < *this); }
  bool operator>=(const BigInteger &b) const { return !(*this < b); }
  bool operator!=(const BigInteger &b) const { return b < *this || *this < b; }
  bool operator==(const BigInteger &b) const {
    return !(b < *this) && !(*this < b);
  }
  bool operator||(const BigInteger &b) const { return *this != 0 || b != 0; }
  bool operator&&(const BigInteger &b) const { return *this != 0 && b != 0; }
  bool operator!() { return (bool)(*this == 0); }
  friend std::ostream &operator<<(std::ostream &out, const BigInteger &x) {
    if (!x.sign) out << '-';
    out << x.num.back();
    for (int i = x.num.size() - 2; i >= 0; i--) {
      char buf[10];
      sprintf(buf, "%08d", x.num[i]);
      for (int j = 0; j < strlen(buf); j++) out << buf[j];
    }
    return out;
  }
  friend std::istream &operator>>(std::istream &in, BigInteger &x) {
    std::string str;
    in >> str;
    size_t len = str.size();
    int start = 0;
    if (str[0] == '-') start = 1;
    if (str[start] == '\0') return in;
    for (int i = start; i < len; i++) {
      if (str[i] < '0' || str[i] > '9') return in;
    }
    x.sign = !start;
    x = str.c_str();
    return in;
  }
  BigInteger pow(int n) {
    BigInteger ans = 1, base = *this;
    while (n) {
      if (n & 1) ans = ans * base;
      base = base * base;
      n >>= 1;
    }
    return ans;
  }
} dp[maxn][maxn], cur[maxn];
struct EDGE {
  int next, to;
} edge[maxn << 1];
int head[maxn], tot;
inline void addedge(int u, int v) {
  edge[tot] = {head[u], v};
  head[u] = tot++;
}
int sz[maxn];
void dfs(int u, int pre) {
  sz[u] = 1;
  dp[u][1] = 1;
  for (int i = head[u]; ~i; i = edge[i].next) {
    int v = edge[i].to;
    if (v == pre) continue;
    dfs(v, u);
    for (int j = 1; j <= sz[u]; ++j) cur[j] = dp[u][j];
    for (int j = 1; j <= sz[u]; ++j) {
      for (int k = 1; k <= sz[v]; ++k) {
        dp[u][j + k] = max(dp[u][j + k], cur[j] / j * dp[v][k] / k * (j + k));
        dp[u][j] = max(dp[u][j], cur[j] * dp[v][k]);
      }
    }
    sz[u] += sz[v];
  }
}
int main() {
  memset(head, -1, sizeof head);
  int n;
  read(n);
  for (int i = 1; i < n; ++i) {
    int u, v;
    read(u, v);
    addedge(u, v);
    addedge(v, u);
  }
  dfs(1, 0);
  BigInteger ans = 0;
  for (int i = 1; i <= sz[1]; ++i) ans = max(ans, dp[1][i]);
  cout << ans << endl;
}

### Prompt

Please create a solution in CPP to the following problem:

Recently Bob invented a new game with a tree (we should remind you, that a tree is a connected graph without cycles): he deletes any (possibly, zero) amount of edges of the tree, and counts the product of sizes of the connected components left after the deletion. Your task is to find out the maximum number that Bob can get in his new game for a given tree.

Input

The first input line contains integer number n (1 ≤ n ≤ 700) — amount of vertices in the tree. The following n - 1 lines contain the description of the edges. Each line contains the pair of vertices' indexes, joined by an edge, ai, bi (1 ≤ ai, bi ≤ n). It's guaranteed that the graph described in the input is a tree.

Output

Output the only number — the maximum product of sizes of the connected components, that Bob can get after deleting some of the tree's edges.

Examples

Input

5
1 2
2 3
3 4
4 5


Output

6

Input

8
1 2
1 3
2 4
2 5
3 6
3 7
6 8


Output

18

Input

3
1 2
1 3


Output

3

### Response

```cpp
#include <bits/stdc++.h>
const long long INF = 0x3f3f3f3f3f3f3f3fLL;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-6;
void err() { puts(""); }
template <typename T, typename... Args>
void err(const T &arg, const Args &...args) {
  std::cout << arg << ' ';
  err(args...);
}
template <typename T>
void read(T &x) {
  x = 0;
  char ch = getchar();
  long long f = 1;
  while (!isdigit(ch)) {
    if (ch == '-') f *= -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - 48;
    ch = getchar();
  }
  x *= f;
}
template <typename T, typename... Args>
void read(T &first, Args &...args) {
  read(first);
  read(args...);
}
using namespace std;
const int maxn = 710;
struct BigInteger {
  static const int BASE = 100000000;
  static const int WIDTH = 8;
  bool sign;
  size_t length;
  std::vector<int> num;
  BigInteger(long long x = 0) { *this = x; }
  BigInteger(const std::string &x) { *this = x; }
  BigInteger(const BigInteger &x) { *this = x; }
  void cutLeadingZero() {
    while (num.back() == 0 && num.size() != 1) {
      num.pop_back();
    }
  }
  void setLength() {
    cutLeadingZero();
    int tmp = num.back();
    if (tmp == 0) {
      length = 1;
    } else {
      length = (num.size() - 1) * WIDTH;
      while (tmp > 0) {
        ++length;
        tmp /= 10;
      }
    }
  }
  BigInteger &operator=(long long x) {
    num.clear();
    if (x >= 0)
      sign = true;
    else {
      sign = false;
      x = -x;
    }
    do {
      num.emplace_back(x % BASE);
      x /= BASE;
    } while (x > 0);
    setLength();
    return *this;
  }
  BigInteger &operator=(const std::string &str) {
    num.clear();
    sign = (str[0] != '-');
    int x, len = (str.size() - 1 - (!sign)) / WIDTH + 1;
    for (int i = 0; i < len; i++) {
      int End = str.length() - i * WIDTH;
      int start = std::max((int)(!sign), End - WIDTH);
      sscanf(str.substr(start, End - start).c_str(), "%d", &x);
      num.push_back(x);
    }
    setLength();
    return *this;
  }
  BigInteger &operator=(const BigInteger &tmp) {
    num = tmp.num;
    sign = tmp.sign;
    length = tmp.length;
    return *this;
  }
  size_t size() const { return length; }
  BigInteger e(size_t n) const {
    int tmp = n % WIDTH;
    BigInteger ans;
    ans.length = n + 1;
    n /= WIDTH;
    while (ans.num.size() <= n) ans.num.push_back(0);
    ans.num[n] = 1;
    while (tmp--) ans.num[n] *= 10;
    return ans * (*this);
  }
  BigInteger abs() const {
    BigInteger ans(*this);
    ans.sign = true;
    return ans;
  }
  const BigInteger &operator+() const { return *this; }
  BigInteger operator+(const BigInteger &b) const {
    if (!b.sign) {
      return *this - (-b);
    }
    if (!sign) {
      return b - (-*this);
    }
    BigInteger ans;
    ans.num.clear();
    for (int i = 0, g = 0;; i++) {
      if (g == 0 && i >= num.size() && i >= b.num.size()) break;
      int x = g;
      if (i < num.size()) x += num[i];
      if (i < b.num.size()) x += b.num[i];
      ans.num.push_back(x % BASE);
      g = x / BASE;
    }
    ans.setLength();
    return ans;
  }
  BigInteger operator-() const {
    BigInteger ans(*this);
    if (ans != 0) ans.sign = !ans.sign;
    return ans;
  }
  BigInteger operator-(const BigInteger &b) const {
    if (!b.sign) {
      return *this + (-b);
    }
    if (!sign) {
      return -((-*this) + b);
    }
    if (*this < b) {
      return -(b - *this);
    }
    BigInteger ans;
    ans.num.clear();
    for (int i = 0, g = 0;; i++) {
      if (g == 0 && i >= num.size() && i >= b.num.size()) break;
      int x = g;
      g = 0;
      if (i < num.size()) x += num[i];
      if (i < b.num.size()) x -= b.num[i];
      if (x < 0) {
        x += BASE;
        g = -1;
      }
      ans.num.push_back(x);
    }
    ans.setLength();
    return ans;
  }
  BigInteger operator*(const BigInteger &b) const {
    int lena = num.size(), lenb = b.num.size();
    std::vector<long long> ansLL;
    for (int i = 0; i < lena + lenb; i++) ansLL.push_back(0);
    for (int i = 0; i < lena; i++) {
      for (int j = 0; j < lenb; j++) {
        ansLL[i + j] += (long long)num[i] * (long long)b.num[j];
      }
    }
    while (ansLL.back() == 0 && ansLL.size() != 1) ansLL.pop_back();
    int len = ansLL.size();
    long long g = 0, tmp;
    BigInteger ans;
    ans.sign = (ansLL.size() == 1 && ansLL[0] == 0) || (sign == b.sign);
    ans.num.clear();
    for (int i = 0; i < len; i++) {
      tmp = ansLL[i];
      ans.num.emplace_back((tmp + g) % BASE);
      g = (tmp + g) / BASE;
    }
    if (g > 0) ans.num.emplace_back(g);
    ans.setLength();
    return ans;
  }
  BigInteger operator/(const long long &b) const {
    BigInteger c;
    c.num.clear();
    for (int i = 0; i < num.size(); i++) {
      c.num.push_back(0);
    }
    long long g = 0;
    for (int i = num.size() - 1; i >= 0; i--) {
      c.num[i] = int((num[i] + g * BASE) / b);
      g = num[i] + g * BASE - c.num[i] * b;
    }
    for (int i = num.size() - 1; c.num[i] == 0; i--) {
      c.num.pop_back();
    }
    return c;
  }
  BigInteger operator/(const BigInteger &b) const {
    BigInteger aa((*this).abs());
    BigInteger bb(b.abs());
    if (aa < bb) return 0;
    char *str = new char[aa.size() + 1];
    memset(str, 0, sizeof(char) * (aa.size() + 1));
    BigInteger tmp;
    int lena = aa.length, lenb = bb.length;
    for (int i = 0; i <= lena - lenb; i++) {
      tmp = bb.e(lena - lenb - i);
      while (aa >= tmp) {
        ++str[i];
        aa = aa - tmp;
      }
      str[i] += '0';
    }
    BigInteger ans(str);
    delete[] str;
    ans.sign = (ans == 0 || sign == b.sign);
    return ans;
  }
  BigInteger operator%(const long long &b) const {
    long long ans = 0;
    for (int i = num.size() - 1; i >= 0; i--) ans = (ans * BASE + num[i]) % b;
    return ans;
  }
  BigInteger operator%(const BigInteger &b) const {
    return *this - *this / b * b;
  }
  BigInteger &operator++() {
    *this = *this + 1;
    return *this;
  }
  BigInteger &operator--() {
    *this = *this - 1;
    return *this;
  }
  BigInteger &operator+=(const BigInteger &b) {
    *this = *this + b;
    return *this;
  }
  BigInteger &operator-=(const BigInteger &b) {
    *this = *this - b;
    return *this;
  }
  BigInteger &operator*=(const BigInteger &b) {
    *this = *this * b;
    return *this;
  }
  BigInteger &operator/=(const long long &b) {
    *this = *this / b;
    return *this;
  }
  BigInteger &operator/=(const BigInteger &b) {
    *this = *this / b;
    return *this;
  }
  BigInteger &operator%=(const long long &b) {
    *this = *this % b;
    return *this;
  }
  BigInteger &operator%=(const BigInteger &b) {
    *this = *this % b;
    return *this;
  }
  bool operator<(const BigInteger &b) const {
    if (sign && !b.sign) {
      return false;
    } else if (!sign && b.sign) {
      return true;
    } else if (!sign && !b.sign) {
      return -b < -*this;
    }
    if (num.size() != b.num.size()) return num.size() < b.num.size();
    for (int i = num.size() - 1; i >= 0; i--)
      if (num[i] != b.num[i]) return num[i] < b.num[i];
    return false;
  }
  bool operator>(const BigInteger &b) const { return b < *this; }
  bool operator<=(const BigInteger &b) const { return !(b < *this); }
  bool operator>=(const BigInteger &b) const { return !(*this < b); }
  bool operator!=(const BigInteger &b) const { return b < *this || *this < b; }
  bool operator==(const BigInteger &b) const {
    return !(b < *this) && !(*this < b);
  }
  bool operator||(const BigInteger &b) const { return *this != 0 || b != 0; }
  bool operator&&(const BigInteger &b) const { return *this != 0 && b != 0; }
  bool operator!() { return (bool)(*this == 0); }
  friend std::ostream &operator<<(std::ostream &out, const BigInteger &x) {
    if (!x.sign) out << '-';
    out << x.num.back();
    for (int i = x.num.size() - 2; i >= 0; i--) {
      char buf[10];
      sprintf(buf, "%08d", x.num[i]);
      for (int j = 0; j < strlen(buf); j++) out << buf[j];
    }
    return out;
  }
  friend std::istream &operator>>(std::istream &in, BigInteger &x) {
    std::string str;
    in >> str;
    size_t len = str.size();
    int start = 0;
    if (str[0] == '-') start = 1;
    if (str[start] == '\0') return in;
    for (int i = start; i < len; i++) {
      if (str[i] < '0' || str[i] > '9') return in;
    }
    x.sign = !start;
    x = str.c_str();
    return in;
  }
  BigInteger pow(int n) {
    BigInteger ans = 1, base = *this;
    while (n) {
      if (n & 1) ans = ans * base;
      base = base * base;
      n >>= 1;
    }
    return ans;
  }
} dp[maxn][maxn], cur[maxn];
struct EDGE {
  int next, to;
} edge[maxn << 1];
int head[maxn], tot;
inline void addedge(int u, int v) {
  edge[tot] = {head[u], v};
  head[u] = tot++;
}
int sz[maxn];
void dfs(int u, int pre) {
  sz[u] = 1;
  dp[u][1] = 1;
  for (int i = head[u]; ~i; i = edge[i].next) {
    int v = edge[i].to;
    if (v == pre) continue;
    dfs(v, u);
    for (int j = 1; j <= sz[u]; ++j) cur[j] = dp[u][j];
    for (int j = 1; j <= sz[u]; ++j) {
      for (int k = 1; k <= sz[v]; ++k) {
        dp[u][j + k] = max(dp[u][j + k], cur[j] / j * dp[v][k] / k * (j + k));
        dp[u][j] = max(dp[u][j], cur[j] * dp[v][k]);
      }
    }
    sz[u] += sz[v];
  }
}
int main() {
  memset(head, -1, sizeof head);
  int n;
  read(n);
  for (int i = 1; i < n; ++i) {
    int u, v;
    read(u, v);
    addedge(u, v);
    addedge(v, u);
  }
  dfs(1, 0);
  BigInteger ans = 0;
  for (int i = 1; i <= sz[1]; ++i) ans = max(ans, dp[1][i]);
  cout << ans << endl;
}

```