#include <bits/stdc++.h>
using namespace std;
struct _ {
  _() { ios_base::sync_with_stdio(0); }
} _;
template <class A, class B>
ostream &operator<<(ostream &o, pair<A, B> t) {
  o << "(" << t.first << ", " << t.second << ")";
  return o;
}
template <class T>
string tostring(T first, int len = 0, char c = '0') {
  stringstream ss;
  ss << first;
  string r = ss.str();
  if (r.length() < len) r = string(len - r.length(), c) + r;
  return r;
}
template <class T>
void PV(T a, T b, int n = 0, int w = 0, string s = " ") {
  int c = 0;
  while (a != b) {
    cout << tostring(*a++, w, ' ');
    if (a != b && (n == 0 || ++c % n))
      cout << s;
    else
      cout << "\n";
    cout.flush();
  }
}
template <class T>
inline bool chmin(T &a, T b) {
  return a > b ? a = b, 1 : 0;
}
template <class T>
inline bool chmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
const long long linf = 0x3f3f3f3f3f3f3f3fLL;
const int inf = 0x3f3f3f3f;
const int mod = int(1e9) + 7;
const int N = 701;
int n;
vector<int> g[N];
struct BigInteger {
  static const int B = 1e9;
  static const int dB = 9;
  vector<int> a;
  int sign;
  BigInteger() : sign(1) {}
  BigInteger(long long v) { *this = v; }
  BigInteger(const string &s) { read(s); }
  void operator=(long long v) {
    if (v < 0)
      sign = -1, v = -v;
    else
      sign = 1;
    a.clear();
    if (v == 0) a.push_back(0);
    for (; v > 0; v = v / B) a.push_back(v % B);
  }
  BigInteger operator+(const BigInteger &v) const {
    if (sign != v.sign) return *this - (-v);
    BigInteger res = v;
    res.a.resize(max(a.size(), v.a.size()) + 1, 0);
    for (int i = 0, carry = 0; i < res.a.size(); i++) {
      res.a[i] += carry + (i < a.size() ? a[i] : 0);
      carry = res.a[i] >= B;
      res.a[i] -= carry * B;
    }
    res.trim();
    return res;
  }
  BigInteger operator-(const BigInteger &v) const {
    if (sign != v.sign) return *this + (-v);
    if (abs() < v.abs()) return -(v - *this);
    BigInteger res = *this;
    for (int i = 0, carry = 0; i < v.a.size() || carry; ++i) {
      res.a[i] -= carry + (i < v.a.size() ? v.a[i] : 0);
      carry = res.a[i] < 0;
      res.a[i] += carry * B;
    }
    res.trim();
    return res;
  }
  void operator*=(int v) {
    if (v < 0) sign = -sign, v = -v;
    a.resize(a.size() + 2, 0);
    for (int i = 0, carry = 0; i < a.size(); i++) {
      long long cur = a[i] * (long long)v + carry;
      carry = cur / B;
      a[i] = cur % B;
    }
    trim();
  }
  BigInteger operator*(int v) const {
    BigInteger res = *this;
    res *= v;
    return res;
  }
  friend pair<BigInteger, BigInteger> divmod(const BigInteger &a1,
                                             const BigInteger &b1) {
    int norm = B / (b1.a.back() + 1);
    BigInteger a = a1.abs() * norm;
    BigInteger b = b1.abs() * norm;
    BigInteger q, r;
    q.a.resize(a.a.size());
    for (int i = a.a.size() - 1; i >= 0; i--) {
      r *= B;
      r += a.a[i];
      int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
      int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
      int d = ((long long)B * s1 + s2) / b.a.back();
      r -= b * d;
      while (r < 0) r += b, --d;
      q.a[i] = d;
    }
    q.sign = a1.sign * b1.sign;
    r.sign = a1.sign;
    q.trim();
    r.trim();
    return make_pair(q, r / norm);
  }
  BigInteger operator/(const BigInteger &v) const {
    return divmod(*this, v).first;
  }
  BigInteger operator%(const BigInteger &v) const {
    return divmod(*this, v).second;
  }
  void operator/=(int v) {
    if (v < 0) sign = -sign, v = -v;
    for (int i = (int)a.size() - 1, rem = 0; i >= 0; --i) {
      long long cur = a[i] + rem * (long long)B;
      a[i] = cur / v;
      rem = cur % v;
    }
    trim();
  }
  BigInteger operator/(int v) const {
    BigInteger res = *this;
    res /= v;
    return res;
  }
  int operator%(int v) const {
    if (v < 0) v = -v;
    int m = 0;
    for (int i = a.size() - 1; i >= 0; --i) m = (a[i] + m * (long long)B) % v;
    return m * sign;
  }
  void operator+=(const BigInteger &v) { *this = *this + v; }
  void operator-=(const BigInteger &v) { *this = *this - v; }
  void operator*=(const BigInteger &v) { *this = *this * v; }
  void operator/=(const BigInteger &v) { *this = *this / v; }
  bool operator<(const BigInteger &v) const {
    if (sign != v.sign) return sign < v.sign;
    if (a.size() != v.a.size()) return a.size() * sign < v.a.size() * v.sign;
    for (int i = (int)a.size() - 1; i >= 0; i--)
      if (a[i] != v.a[i]) return a[i] * sign < v.a[i] * sign;
    return false;
  }
  bool operator>(const BigInteger &v) const { return v < *this; }
  bool operator<=(const BigInteger &v) const { return !(v < *this); }
  bool operator>=(const BigInteger &v) const { return !(*this < v); }
  bool operator==(const BigInteger &v) const {
    return !(*this < v) && !(v < *this);
  }
  bool operator!=(const BigInteger &v) const { return *this < v || v < *this; }
  void trim() {
    while (!a.empty() && a.back() == 0) a.pop_back();
    if (a.empty()) {
      sign = 1;
      a.push_back(0);
    }
  }
  bool isZero() const { return a.empty() || (a.size() == 1 && !a[0]); }
  BigInteger operator-() const {
    BigInteger res = *this;
    res.sign = -sign;
    return res;
  }
  BigInteger abs() const {
    if (sign > 0)
      return *this;
    else
      return -*this;
  }
  long long longValue() const {
    long long res = 0;
    for (int i = (int)a.size() - 1; i >= 0; i--) res = res * B + a[i];
    return res * sign;
  }
  friend BigInteger gcd(const BigInteger &a, const BigInteger &b) {
    return b.isZero() ? a : gcd(b, a % b);
  }
  friend BigInteger lcm(const BigInteger &a, const BigInteger &b) {
    return a / gcd(a, b) * b;
  }
  void read(const string &s) {
    assert(s.length() > 0);
    sign = 1, a.clear();
    int start = 0;
    if (s[0] == '-' || s[0] == '+') {
      if (s[0] == '-') sign = -1;
      start = 1;
    }
    for (int i = s.length() - 1; i >= start; i -= dB) {
      int first = 0;
      for (int j = max(i - dB + 1, start); j <= i; j++)
        first = first * 10 + s[j] - '0';
      a.push_back(first);
    }
    trim();
  }
  string tostring() const {
    stringstream stream;
    if (this->sign == -1) stream << '-';
    stream << (a.empty() ? 0 : a.back());
    for (int i = (int)a.size() - 2; i >= 0; --i)
      stream << setw(dB) << setfill('0') << a[i];
    string res;
    stream >> res;
    return res;
  }
  friend istream &operator>>(istream &stream, BigInteger &v) {
    string s;
    stream >> s;
    v.read(s);
    return stream;
  }
  friend ostream &operator<<(ostream &stream, const BigInteger &v) {
    stream << v.tostring();
    return stream;
  }
  BigInteger operator*(const BigInteger &v) const {
    BigInteger res;
    res.sign = sign * v.sign;
    res.a.resize(a.size() + v.a.size());
    for (int i = 0; i < a.size(); ++i) {
      if (a[i] == 0) continue;
      for (int j = 0, carry = 0; j < v.a.size() || carry; ++j) {
        long long cur = res.a[i + j] +
                        (long long)a[i] * (j < v.a.size() ? v.a[j] : 0) + carry;
        carry = cur / B;
        res.a[i + j] = cur % B;
      }
    }
    res.trim();
    return res;
  }
};
BigInteger dp[N][N];
int sz[N];
void dfs(int u, int par) {
  sz[u] = 1;
  for (int v : g[u]) {
    if (v == par) continue;
    dfs(v, u);
    sz[u] += sz[v];
  }
  int least = 1;
  vector<int> gg = g[u];
  g[u].clear();
  for (auto i : gg) {
    if (i == par) continue;
    if (sz[i] == 1)
      least++;
    else
      g[u].push_back(i);
  }
  if (g[u].size() == 0) {
    dp[u][0] = least;
    dp[u][least] = 1;
    return;
  }
  for (int i = 0; i <= sz[g[u][0]]; i++) dp[u][i] = dp[g[u][0]][i];
  int sum = sz[g[u][0]];
  BigInteger t;
  for (int i = 1; i < g[u].size(); i++) {
    int son = g[u][i];
    sum += sz[son];
    for (int j = sum; j >= 0; j--) {
      t = 0;
      for (int k = 0; k <= sz[son] && k <= j; k++)
        chmax(t, dp[u][j - k] * dp[son][k]);
      dp[u][j] = t;
    }
  }
  for (int i = sz[u] - least; i >= 0; i--) dp[u][i + least] = dp[u][i];
  dp[u][0] = 0;
  for (int i = 1; i <= sz[u]; i++) chmax(dp[u][0], dp[u][i] * i);
}
int main() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(0, -1);
  cout << dp[0][0] << endl;
  return 0;
}

### 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>
using namespace std;
struct _ {
  _() { ios_base::sync_with_stdio(0); }
} _;
template <class A, class B>
ostream &operator<<(ostream &o, pair<A, B> t) {
  o << "(" << t.first << ", " << t.second << ")";
  return o;
}
template <class T>
string tostring(T first, int len = 0, char c = '0') {
  stringstream ss;
  ss << first;
  string r = ss.str();
  if (r.length() < len) r = string(len - r.length(), c) + r;
  return r;
}
template <class T>
void PV(T a, T b, int n = 0, int w = 0, string s = " ") {
  int c = 0;
  while (a != b) {
    cout << tostring(*a++, w, ' ');
    if (a != b && (n == 0 || ++c % n))
      cout << s;
    else
      cout << "\n";
    cout.flush();
  }
}
template <class T>
inline bool chmin(T &a, T b) {
  return a > b ? a = b, 1 : 0;
}
template <class T>
inline bool chmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
const long long linf = 0x3f3f3f3f3f3f3f3fLL;
const int inf = 0x3f3f3f3f;
const int mod = int(1e9) + 7;
const int N = 701;
int n;
vector<int> g[N];
struct BigInteger {
  static const int B = 1e9;
  static const int dB = 9;
  vector<int> a;
  int sign;
  BigInteger() : sign(1) {}
  BigInteger(long long v) { *this = v; }
  BigInteger(const string &s) { read(s); }
  void operator=(long long v) {
    if (v < 0)
      sign = -1, v = -v;
    else
      sign = 1;
    a.clear();
    if (v == 0) a.push_back(0);
    for (; v > 0; v = v / B) a.push_back(v % B);
  }
  BigInteger operator+(const BigInteger &v) const {
    if (sign != v.sign) return *this - (-v);
    BigInteger res = v;
    res.a.resize(max(a.size(), v.a.size()) + 1, 0);
    for (int i = 0, carry = 0; i < res.a.size(); i++) {
      res.a[i] += carry + (i < a.size() ? a[i] : 0);
      carry = res.a[i] >= B;
      res.a[i] -= carry * B;
    }
    res.trim();
    return res;
  }
  BigInteger operator-(const BigInteger &v) const {
    if (sign != v.sign) return *this + (-v);
    if (abs() < v.abs()) return -(v - *this);
    BigInteger res = *this;
    for (int i = 0, carry = 0; i < v.a.size() || carry; ++i) {
      res.a[i] -= carry + (i < v.a.size() ? v.a[i] : 0);
      carry = res.a[i] < 0;
      res.a[i] += carry * B;
    }
    res.trim();
    return res;
  }
  void operator*=(int v) {
    if (v < 0) sign = -sign, v = -v;
    a.resize(a.size() + 2, 0);
    for (int i = 0, carry = 0; i < a.size(); i++) {
      long long cur = a[i] * (long long)v + carry;
      carry = cur / B;
      a[i] = cur % B;
    }
    trim();
  }
  BigInteger operator*(int v) const {
    BigInteger res = *this;
    res *= v;
    return res;
  }
  friend pair<BigInteger, BigInteger> divmod(const BigInteger &a1,
                                             const BigInteger &b1) {
    int norm = B / (b1.a.back() + 1);
    BigInteger a = a1.abs() * norm;
    BigInteger b = b1.abs() * norm;
    BigInteger q, r;
    q.a.resize(a.a.size());
    for (int i = a.a.size() - 1; i >= 0; i--) {
      r *= B;
      r += a.a[i];
      int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
      int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
      int d = ((long long)B * s1 + s2) / b.a.back();
      r -= b * d;
      while (r < 0) r += b, --d;
      q.a[i] = d;
    }
    q.sign = a1.sign * b1.sign;
    r.sign = a1.sign;
    q.trim();
    r.trim();
    return make_pair(q, r / norm);
  }
  BigInteger operator/(const BigInteger &v) const {
    return divmod(*this, v).first;
  }
  BigInteger operator%(const BigInteger &v) const {
    return divmod(*this, v).second;
  }
  void operator/=(int v) {
    if (v < 0) sign = -sign, v = -v;
    for (int i = (int)a.size() - 1, rem = 0; i >= 0; --i) {
      long long cur = a[i] + rem * (long long)B;
      a[i] = cur / v;
      rem = cur % v;
    }
    trim();
  }
  BigInteger operator/(int v) const {
    BigInteger res = *this;
    res /= v;
    return res;
  }
  int operator%(int v) const {
    if (v < 0) v = -v;
    int m = 0;
    for (int i = a.size() - 1; i >= 0; --i) m = (a[i] + m * (long long)B) % v;
    return m * sign;
  }
  void operator+=(const BigInteger &v) { *this = *this + v; }
  void operator-=(const BigInteger &v) { *this = *this - v; }
  void operator*=(const BigInteger &v) { *this = *this * v; }
  void operator/=(const BigInteger &v) { *this = *this / v; }
  bool operator<(const BigInteger &v) const {
    if (sign != v.sign) return sign < v.sign;
    if (a.size() != v.a.size()) return a.size() * sign < v.a.size() * v.sign;
    for (int i = (int)a.size() - 1; i >= 0; i--)
      if (a[i] != v.a[i]) return a[i] * sign < v.a[i] * sign;
    return false;
  }
  bool operator>(const BigInteger &v) const { return v < *this; }
  bool operator<=(const BigInteger &v) const { return !(v < *this); }
  bool operator>=(const BigInteger &v) const { return !(*this < v); }
  bool operator==(const BigInteger &v) const {
    return !(*this < v) && !(v < *this);
  }
  bool operator!=(const BigInteger &v) const { return *this < v || v < *this; }
  void trim() {
    while (!a.empty() && a.back() == 0) a.pop_back();
    if (a.empty()) {
      sign = 1;
      a.push_back(0);
    }
  }
  bool isZero() const { return a.empty() || (a.size() == 1 && !a[0]); }
  BigInteger operator-() const {
    BigInteger res = *this;
    res.sign = -sign;
    return res;
  }
  BigInteger abs() const {
    if (sign > 0)
      return *this;
    else
      return -*this;
  }
  long long longValue() const {
    long long res = 0;
    for (int i = (int)a.size() - 1; i >= 0; i--) res = res * B + a[i];
    return res * sign;
  }
  friend BigInteger gcd(const BigInteger &a, const BigInteger &b) {
    return b.isZero() ? a : gcd(b, a % b);
  }
  friend BigInteger lcm(const BigInteger &a, const BigInteger &b) {
    return a / gcd(a, b) * b;
  }
  void read(const string &s) {
    assert(s.length() > 0);
    sign = 1, a.clear();
    int start = 0;
    if (s[0] == '-' || s[0] == '+') {
      if (s[0] == '-') sign = -1;
      start = 1;
    }
    for (int i = s.length() - 1; i >= start; i -= dB) {
      int first = 0;
      for (int j = max(i - dB + 1, start); j <= i; j++)
        first = first * 10 + s[j] - '0';
      a.push_back(first);
    }
    trim();
  }
  string tostring() const {
    stringstream stream;
    if (this->sign == -1) stream << '-';
    stream << (a.empty() ? 0 : a.back());
    for (int i = (int)a.size() - 2; i >= 0; --i)
      stream << setw(dB) << setfill('0') << a[i];
    string res;
    stream >> res;
    return res;
  }
  friend istream &operator>>(istream &stream, BigInteger &v) {
    string s;
    stream >> s;
    v.read(s);
    return stream;
  }
  friend ostream &operator<<(ostream &stream, const BigInteger &v) {
    stream << v.tostring();
    return stream;
  }
  BigInteger operator*(const BigInteger &v) const {
    BigInteger res;
    res.sign = sign * v.sign;
    res.a.resize(a.size() + v.a.size());
    for (int i = 0; i < a.size(); ++i) {
      if (a[i] == 0) continue;
      for (int j = 0, carry = 0; j < v.a.size() || carry; ++j) {
        long long cur = res.a[i + j] +
                        (long long)a[i] * (j < v.a.size() ? v.a[j] : 0) + carry;
        carry = cur / B;
        res.a[i + j] = cur % B;
      }
    }
    res.trim();
    return res;
  }
};
BigInteger dp[N][N];
int sz[N];
void dfs(int u, int par) {
  sz[u] = 1;
  for (int v : g[u]) {
    if (v == par) continue;
    dfs(v, u);
    sz[u] += sz[v];
  }
  int least = 1;
  vector<int> gg = g[u];
  g[u].clear();
  for (auto i : gg) {
    if (i == par) continue;
    if (sz[i] == 1)
      least++;
    else
      g[u].push_back(i);
  }
  if (g[u].size() == 0) {
    dp[u][0] = least;
    dp[u][least] = 1;
    return;
  }
  for (int i = 0; i <= sz[g[u][0]]; i++) dp[u][i] = dp[g[u][0]][i];
  int sum = sz[g[u][0]];
  BigInteger t;
  for (int i = 1; i < g[u].size(); i++) {
    int son = g[u][i];
    sum += sz[son];
    for (int j = sum; j >= 0; j--) {
      t = 0;
      for (int k = 0; k <= sz[son] && k <= j; k++)
        chmax(t, dp[u][j - k] * dp[son][k]);
      dp[u][j] = t;
    }
  }
  for (int i = sz[u] - least; i >= 0; i--) dp[u][i + least] = dp[u][i];
  dp[u][0] = 0;
  for (int i = 1; i <= sz[u]; i++) chmax(dp[u][0], dp[u][i] * i);
}
int main() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(0, -1);
  cout << dp[0][0] << endl;
  return 0;
}

```