#include <bits/stdc++.h>
using namespace std;
inline bool SR(int &x) { return scanf("%d", &x) == 1; }
inline bool SR(long long &x) { return scanf("%lld", &x) == 1; }
inline bool SR(double &x) { return scanf("%lf", &x); }
inline bool SR(char *s) { return scanf("%s", s); }
inline bool RI() { return 1; }
template <typename I, typename... T>
bool RI(I &x, T &...tail) {
  return SR(x) && RI(tail...);
}
inline void SP(const int x) { printf("%d", x); }
inline void SP(const long long x) { printf("%lld", x); }
inline void SP(const double x) { printf("%.10f", x); }
inline void SP(const char *s) { printf("%s", s); }
inline void PL() { puts(""); }
template <typename I, typename... T>
void PL(const I x, const T... tail) {
  SP(x);
  if (sizeof...(tail)) putchar(' ');
  PL(tail...);
}
template <typename I>
inline void _DOING(const char *s, I &&x) {
  cerr << s << " = " << x << '\n';
}
template <typename I, typename... T>
void _DOING(const char *s, I &&x, T &&...tail) {
  int c = 0;
  while (*s != ',' || c != 0) {
    if (*s == '(' || *s == '[' || *s == '{') c++;
    if (*s == ')' || *s == ']' || *s == '}') c--;
    cerr << *s++;
  }
  cerr << " = " << x << " , ";
  _DOING(s + 1, tail...);
}
const int INF = 0x3f3f3f3f;
const long long INF64 = 0x3f3f3f3f3f3f3f3fll;
inline int RAND() {
  static int x = 880301;
  return x = (x * 0xdefacedll + 1ll) % 0x7fffffffll;
}
const int MAX_N = 700 + 7;
struct Bign {
  vector<int> num;
  Bign() {
    num.clear();
    num.push_back(0);
  }
  Bign(int x) {
    num.clear();
    while (x) {
      num.push_back(x % 10);
      x /= 10;
    }
    if (num.empty()) num.push_back(0);
  }
  void print() {
    for (int i = (((int)num.size())) - 1; i >= 0; i--) putchar('0' + num[i]);
  }
  void println() {
    print();
    PL();
  }
  bool operator<(const Bign &rhs) const {
    if (((int)num.size()) != ((int)rhs.num.size()))
      return ((int)num.size()) < ((int)rhs.num.size());
    for (int i = (((int)num.size())) - 1; i >= 0; i--)
      if (num[i] != rhs.num[i]) return num[i] < rhs.num[i];
    return 0;
  }
  bool operator>(const Bign &rhs) const {
    if (((int)num.size()) != ((int)rhs.num.size()))
      return ((int)num.size()) > ((int)rhs.num.size());
    for (int i = (((int)num.size())) - 1; i >= 0; i--)
      if (num[i] != rhs.num[i]) return num[i] > rhs.num[i];
    return 0;
  }
  bool operator==(const Bign &rhs) const {
    if (((int)num.size()) != ((int)rhs.num.size())) return 0;
    for (int i = 0; i < int(((int)num.size())); i++)
      if (num[i] != rhs.num[i]) return 0;
    return 1;
  }
  bool operator!=(const Bign &rhs) const { return !(*this == rhs); }
  bool operator<=(const Bign &rhs) const { return *this < rhs || *this == rhs; }
  bool operator>=(const Bign &rhs) const { return *this > rhs || *this == rhs; }
};
inline Bign operator+(Bign a, Bign b) {
  Bign c;
  for (int i = 0; i < int(max(((int)a.num.size()), ((int)b.num.size()))); i++) {
    if (((int)c.num.size()) <= i) c.num.push_back(0);
    if (i < ((int)a.num.size())) c.num[i] += a.num[i];
    if (i < ((int)b.num.size())) c.num[i] += b.num[i];
    if (c.num[i] >= 10) {
      if (((int)c.num.size()) <= i + 1) c.num.push_back(0);
      c.num[i + 1] += c.num[i] / 10;
      c.num[i] %= 10;
    }
  }
  while (!c.num.empty() && c.num.back() == 0) c.num.pop_back();
  if (c.num.empty()) c.num.push_back(0);
  return c;
}
inline Bign operator*(Bign a, Bign b) {
  Bign c;
  for (int i = 0; i < int(((int)a.num.size())); i++) {
    for (int j = 0; j < int(((int)b.num.size())); j++) {
      if (((int)c.num.size()) <= i + j) c.num.push_back(0);
      c.num[i + j] += a.num[i] * b.num[j];
    }
  }
  for (int i = 0; i < int(((int)c.num.size())); i++) {
    if (c.num[i] >= 10) {
      if (((int)c.num.size()) <= i + 1) c.num.push_back(0);
      c.num[i + 1] += c.num[i] / 10;
      c.num[i] %= 10;
    }
  }
  while (!c.num.empty() && c.num.back() == 0) c.num.pop_back();
  if (c.num.empty()) c.num.push_back(0);
  return c;
}
vector<int> G[MAX_N];
int sz[MAX_N];
Bign dp[MAX_N][MAX_N];
void dfs(int u, int fa) {
  sz[u] = 1;
  dp[u][0] = Bign(0);
  dp[u][1] = Bign(1);
  for (int v : G[u]) {
    if (v == fa) continue;
    dfs(v, u);
    for (int i = (sz[u]); i >= int(1); i--) {
      for (int j = (sz[v]); j >= int(0); j--)
        dp[u][i + j] = max(dp[u][i + j], dp[v][j] * dp[u][i]);
    }
    sz[u] += sz[v];
  }
  for (int i = (1); i <= int(sz[u]); i++)
    dp[u][0] = max(dp[u][0], dp[u][i] * Bign(i));
}
int main() {
  int n;
  RI(n);
  for (int i = 0; i < int(n - 1); i++) {
    int u, v;
    RI(u, v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  dfs(1, -1);
  dp[1][0].println();
  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;
inline bool SR(int &x) { return scanf("%d", &x) == 1; }
inline bool SR(long long &x) { return scanf("%lld", &x) == 1; }
inline bool SR(double &x) { return scanf("%lf", &x); }
inline bool SR(char *s) { return scanf("%s", s); }
inline bool RI() { return 1; }
template <typename I, typename... T>
bool RI(I &x, T &...tail) {
  return SR(x) && RI(tail...);
}
inline void SP(const int x) { printf("%d", x); }
inline void SP(const long long x) { printf("%lld", x); }
inline void SP(const double x) { printf("%.10f", x); }
inline void SP(const char *s) { printf("%s", s); }
inline void PL() { puts(""); }
template <typename I, typename... T>
void PL(const I x, const T... tail) {
  SP(x);
  if (sizeof...(tail)) putchar(' ');
  PL(tail...);
}
template <typename I>
inline void _DOING(const char *s, I &&x) {
  cerr << s << " = " << x << '\n';
}
template <typename I, typename... T>
void _DOING(const char *s, I &&x, T &&...tail) {
  int c = 0;
  while (*s != ',' || c != 0) {
    if (*s == '(' || *s == '[' || *s == '{') c++;
    if (*s == ')' || *s == ']' || *s == '}') c--;
    cerr << *s++;
  }
  cerr << " = " << x << " , ";
  _DOING(s + 1, tail...);
}
const int INF = 0x3f3f3f3f;
const long long INF64 = 0x3f3f3f3f3f3f3f3fll;
inline int RAND() {
  static int x = 880301;
  return x = (x * 0xdefacedll + 1ll) % 0x7fffffffll;
}
const int MAX_N = 700 + 7;
struct Bign {
  vector<int> num;
  Bign() {
    num.clear();
    num.push_back(0);
  }
  Bign(int x) {
    num.clear();
    while (x) {
      num.push_back(x % 10);
      x /= 10;
    }
    if (num.empty()) num.push_back(0);
  }
  void print() {
    for (int i = (((int)num.size())) - 1; i >= 0; i--) putchar('0' + num[i]);
  }
  void println() {
    print();
    PL();
  }
  bool operator<(const Bign &rhs) const {
    if (((int)num.size()) != ((int)rhs.num.size()))
      return ((int)num.size()) < ((int)rhs.num.size());
    for (int i = (((int)num.size())) - 1; i >= 0; i--)
      if (num[i] != rhs.num[i]) return num[i] < rhs.num[i];
    return 0;
  }
  bool operator>(const Bign &rhs) const {
    if (((int)num.size()) != ((int)rhs.num.size()))
      return ((int)num.size()) > ((int)rhs.num.size());
    for (int i = (((int)num.size())) - 1; i >= 0; i--)
      if (num[i] != rhs.num[i]) return num[i] > rhs.num[i];
    return 0;
  }
  bool operator==(const Bign &rhs) const {
    if (((int)num.size()) != ((int)rhs.num.size())) return 0;
    for (int i = 0; i < int(((int)num.size())); i++)
      if (num[i] != rhs.num[i]) return 0;
    return 1;
  }
  bool operator!=(const Bign &rhs) const { return !(*this == rhs); }
  bool operator<=(const Bign &rhs) const { return *this < rhs || *this == rhs; }
  bool operator>=(const Bign &rhs) const { return *this > rhs || *this == rhs; }
};
inline Bign operator+(Bign a, Bign b) {
  Bign c;
  for (int i = 0; i < int(max(((int)a.num.size()), ((int)b.num.size()))); i++) {
    if (((int)c.num.size()) <= i) c.num.push_back(0);
    if (i < ((int)a.num.size())) c.num[i] += a.num[i];
    if (i < ((int)b.num.size())) c.num[i] += b.num[i];
    if (c.num[i] >= 10) {
      if (((int)c.num.size()) <= i + 1) c.num.push_back(0);
      c.num[i + 1] += c.num[i] / 10;
      c.num[i] %= 10;
    }
  }
  while (!c.num.empty() && c.num.back() == 0) c.num.pop_back();
  if (c.num.empty()) c.num.push_back(0);
  return c;
}
inline Bign operator*(Bign a, Bign b) {
  Bign c;
  for (int i = 0; i < int(((int)a.num.size())); i++) {
    for (int j = 0; j < int(((int)b.num.size())); j++) {
      if (((int)c.num.size()) <= i + j) c.num.push_back(0);
      c.num[i + j] += a.num[i] * b.num[j];
    }
  }
  for (int i = 0; i < int(((int)c.num.size())); i++) {
    if (c.num[i] >= 10) {
      if (((int)c.num.size()) <= i + 1) c.num.push_back(0);
      c.num[i + 1] += c.num[i] / 10;
      c.num[i] %= 10;
    }
  }
  while (!c.num.empty() && c.num.back() == 0) c.num.pop_back();
  if (c.num.empty()) c.num.push_back(0);
  return c;
}
vector<int> G[MAX_N];
int sz[MAX_N];
Bign dp[MAX_N][MAX_N];
void dfs(int u, int fa) {
  sz[u] = 1;
  dp[u][0] = Bign(0);
  dp[u][1] = Bign(1);
  for (int v : G[u]) {
    if (v == fa) continue;
    dfs(v, u);
    for (int i = (sz[u]); i >= int(1); i--) {
      for (int j = (sz[v]); j >= int(0); j--)
        dp[u][i + j] = max(dp[u][i + j], dp[v][j] * dp[u][i]);
    }
    sz[u] += sz[v];
  }
  for (int i = (1); i <= int(sz[u]); i++)
    dp[u][0] = max(dp[u][0], dp[u][i] * Bign(i));
}
int main() {
  int n;
  RI(n);
  for (int i = 0; i < int(n - 1); i++) {
    int u, v;
    RI(u, v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  dfs(1, -1);
  dp[1][0].println();
  return 0;
}

```