#include <bits/stdc++.h>
using namespace std;
namespace Fastio {
enum io_flags {
  ignore_int = 1 << 0,
  flush_stdout = 1 << 1,
  flush_stderr = 1 << 2,
};
enum number_type_flags {
  output_double_stable = 1 << 0,
  output_double_faster = 1 << 1
};
struct Reader {
  char endch;
  Reader() { endch = '\0'; }
  Reader& operator>>(io_flags f) {
    if (f & ignore_int) {
      endch = getchar();
      while ((!isdigit(endch)) && endch != '-' && endch != EOF)
        endch = getchar();
      while (isdigit(endch = getchar()))
        ;
    }
    return *this;
  }
  Reader& operator>>(char& ch) {
    ch = getchar();
    while (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t') ch = getchar();
    return *this;
  }
  Reader& operator>>(double& lf) {
    bool flag = 0;
    endch = getchar();
    while ((!isdigit(endch)) && endch != '-' && endch != EOF) endch = getchar();
    if (endch == '-') flag = 1, endch = getchar();
    lf = endch & 15;
    while (isdigit(endch = getchar())) lf = lf * 10 + (endch & 15);
    if (endch == '.') {
      double digit = 0.1;
      while (isdigit(endch = getchar())) {
        lf += (endch & 15) * digit;
        digit *= 0.1;
      }
    }
    if (flag) lf = -lf;
    return *this;
  }
  template <typename Int>
  Reader& operator>>(Int& d) {
    bool flag = 0;
    endch = getchar();
    while ((!isdigit(endch)) && endch != '-' && endch != EOF) endch = getchar();
    if (endch == '-') flag = 1, endch = getchar();
    d = endch & 15;
    while (isdigit(endch = getchar())) d = (d << 3) + (d << 1) + (endch & 15);
    if (flag) d = -d;
    return *this;
  }
  template <typename Int>
  inline Int get() {
    bool flag = 0;
    endch = getchar();
    while ((!isdigit(endch)) && endch != '-' && endch != EOF) endch = getchar();
    if (endch == '-') flag = 1, endch = getchar();
    Int d = endch & 15;
    while (isdigit(endch = getchar())) d = (d << 3) + (d << 1) + (endch & 15);
    if (flag) d = -d;
    return d;
  }
} read;
struct Writer {
  Writer& operator<<(io_flags f) {
    if (f & flush_stdout) fflush(stdout);
    if (f & flush_stderr) fflush(stderr);
    return *this;
  }
  Writer& operator<<(const char* ch) {
    while (*ch) putchar(*(ch++));
    return *this;
  }
  Writer& operator<<(const char ch) {
    putchar(ch);
    return *this;
  }
  template <typename Int>
  Writer& operator<<(Int x) {
    static char buffer[33];
    static int top = 0;
    if (!x) {
      putchar('0');
      return *this;
    }
    if (x < 0) putchar('-'), x = ~x + 1;
    while (x) {
      buffer[++top] = '0' | (x % 10);
      x /= 10;
    }
    while (top) putchar(buffer[top--]);
    return *this;
  }
  inline void operator()(double val, int eps_digit = 6, char endch = '\0',
                         number_type_flags flg = output_double_faster) {
    if (flg & output_double_stable) {
      static char output_format[10];
      sprintf(output_format, "%%.%dlf", eps_digit);
      printf(output_format, val);
    } else if (flg & output_double_faster) {
      if (val < 0) {
        putchar('-');
        val = -val;
      }
      double eps_number = 0.5;
      for (int i = 1; i <= eps_digit; i++) eps_number /= 10;
      val += eps_number;
      (*this) << (long long)val;
      val -= (long long)val;
      if (eps_digit) putchar('.');
      while (eps_digit--) {
        val *= 10;
        putchar((int)val | '0');
        val -= (int)val;
      }
    } else {
      (*this) << '1';
      if (eps_digit) {
        (*this) << ".E";
        for (int i = 2; i <= eps_digit; i++) (*this) << '0';
      }
    }
    if (endch) putchar(endch);
  }
} write;
}  // namespace Fastio
using namespace Fastio;
namespace File_IO {
void init_IO(const char* file_name) {
  char buff[107];
  sprintf(buff, "%s.in", file_name);
  freopen(buff, "r", stdin);
  sprintf(buff, "%s.out", file_name);
  freopen(buff, "w", stdout);
}
}  // namespace File_IO
const int N = 700 + 3, DigByte = 100000000;
struct Bint {
  unsigned long long atom[17];
  int len;
  Bint(int number = 0) : len(0) {
    while (number) {
      atom[len++] = number % DigByte;
      number /= DigByte;
    }
  }
  Bint operator*(const Bint& b) const {
    Bint ret;
    memset(ret.atom, 0, sizeof(ret.atom));
    ret.len = len + b.len;
    for (int i = 0; i < len; i++)
      for (int j = 0; j < b.len; j++) ret.atom[i + j] += atom[i] * b.atom[j];
    for (int i = 1; i < ret.len; i++) {
      ret.atom[i] += ret.atom[i - 1] / DigByte;
      ret.atom[i - 1] %= DigByte;
    }
    if (!ret.atom[ret.len - 1]) --ret.len;
    return ret;
  }
  bool operator<(const Bint& b) const {
    if (len ^ b.len) return len < b.len;
    for (int i = len - 1; i >= 0; i--)
      if (atom[i] ^ b.atom[i]) return atom[i] < b.atom[i];
    return false;
  }
  void print(char endch = '\0') const {
    if (len <= 0) {
      putchar('0');
      if (endch) putchar(endch);
      return;
    }
    printf("%llu", atom[len - 1]);
    int i = len - 2;
    while (i >= 0) printf("%08llu", atom[i--]);
    if (endch) putchar(endch);
  }
};
int n;
Bint f[N][N], g[N];
vector<int> G[N];
int siz[N];
void sol(int u, int fa) {
  f[u][1] = f[u][0] = siz[u] = 1;
  for (size_t eid = 0; eid < G[u].size(); eid++) {
    int v = G[u][eid];
    if (v == fa) continue;
    sol(v, u);
    for (int i = 0; i <= siz[u] + siz[v]; i++) g[i] = 0;
    for (int i = 0; i <= siz[v]; i++)
      for (int j = 0; j <= siz[u]; j++)
        g[i + j] = max(g[i + j], f[u][j] * f[v][i]);
    siz[u] += siz[v];
    for (int i = 0; i <= siz[u]; i++) f[u][i] = g[i];
  }
  for (int i = 1; i <= siz[u]; i++) f[u][0] = max(f[u][0], f[u][i] * i);
}
signed main() {
  read >> n;
  for (int i = 1, u, v; i < n; i++) {
    read >> u >> v;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  sol(1, -1);
  f[1][0].print('\n');
  return 0;
}

### Prompt

Please formulate a Cpp solution 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;
namespace Fastio {
enum io_flags {
  ignore_int = 1 << 0,
  flush_stdout = 1 << 1,
  flush_stderr = 1 << 2,
};
enum number_type_flags {
  output_double_stable = 1 << 0,
  output_double_faster = 1 << 1
};
struct Reader {
  char endch;
  Reader() { endch = '\0'; }
  Reader& operator>>(io_flags f) {
    if (f & ignore_int) {
      endch = getchar();
      while ((!isdigit(endch)) && endch != '-' && endch != EOF)
        endch = getchar();
      while (isdigit(endch = getchar()))
        ;
    }
    return *this;
  }
  Reader& operator>>(char& ch) {
    ch = getchar();
    while (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t') ch = getchar();
    return *this;
  }
  Reader& operator>>(double& lf) {
    bool flag = 0;
    endch = getchar();
    while ((!isdigit(endch)) && endch != '-' && endch != EOF) endch = getchar();
    if (endch == '-') flag = 1, endch = getchar();
    lf = endch & 15;
    while (isdigit(endch = getchar())) lf = lf * 10 + (endch & 15);
    if (endch == '.') {
      double digit = 0.1;
      while (isdigit(endch = getchar())) {
        lf += (endch & 15) * digit;
        digit *= 0.1;
      }
    }
    if (flag) lf = -lf;
    return *this;
  }
  template <typename Int>
  Reader& operator>>(Int& d) {
    bool flag = 0;
    endch = getchar();
    while ((!isdigit(endch)) && endch != '-' && endch != EOF) endch = getchar();
    if (endch == '-') flag = 1, endch = getchar();
    d = endch & 15;
    while (isdigit(endch = getchar())) d = (d << 3) + (d << 1) + (endch & 15);
    if (flag) d = -d;
    return *this;
  }
  template <typename Int>
  inline Int get() {
    bool flag = 0;
    endch = getchar();
    while ((!isdigit(endch)) && endch != '-' && endch != EOF) endch = getchar();
    if (endch == '-') flag = 1, endch = getchar();
    Int d = endch & 15;
    while (isdigit(endch = getchar())) d = (d << 3) + (d << 1) + (endch & 15);
    if (flag) d = -d;
    return d;
  }
} read;
struct Writer {
  Writer& operator<<(io_flags f) {
    if (f & flush_stdout) fflush(stdout);
    if (f & flush_stderr) fflush(stderr);
    return *this;
  }
  Writer& operator<<(const char* ch) {
    while (*ch) putchar(*(ch++));
    return *this;
  }
  Writer& operator<<(const char ch) {
    putchar(ch);
    return *this;
  }
  template <typename Int>
  Writer& operator<<(Int x) {
    static char buffer[33];
    static int top = 0;
    if (!x) {
      putchar('0');
      return *this;
    }
    if (x < 0) putchar('-'), x = ~x + 1;
    while (x) {
      buffer[++top] = '0' | (x % 10);
      x /= 10;
    }
    while (top) putchar(buffer[top--]);
    return *this;
  }
  inline void operator()(double val, int eps_digit = 6, char endch = '\0',
                         number_type_flags flg = output_double_faster) {
    if (flg & output_double_stable) {
      static char output_format[10];
      sprintf(output_format, "%%.%dlf", eps_digit);
      printf(output_format, val);
    } else if (flg & output_double_faster) {
      if (val < 0) {
        putchar('-');
        val = -val;
      }
      double eps_number = 0.5;
      for (int i = 1; i <= eps_digit; i++) eps_number /= 10;
      val += eps_number;
      (*this) << (long long)val;
      val -= (long long)val;
      if (eps_digit) putchar('.');
      while (eps_digit--) {
        val *= 10;
        putchar((int)val | '0');
        val -= (int)val;
      }
    } else {
      (*this) << '1';
      if (eps_digit) {
        (*this) << ".E";
        for (int i = 2; i <= eps_digit; i++) (*this) << '0';
      }
    }
    if (endch) putchar(endch);
  }
} write;
}  // namespace Fastio
using namespace Fastio;
namespace File_IO {
void init_IO(const char* file_name) {
  char buff[107];
  sprintf(buff, "%s.in", file_name);
  freopen(buff, "r", stdin);
  sprintf(buff, "%s.out", file_name);
  freopen(buff, "w", stdout);
}
}  // namespace File_IO
const int N = 700 + 3, DigByte = 100000000;
struct Bint {
  unsigned long long atom[17];
  int len;
  Bint(int number = 0) : len(0) {
    while (number) {
      atom[len++] = number % DigByte;
      number /= DigByte;
    }
  }
  Bint operator*(const Bint& b) const {
    Bint ret;
    memset(ret.atom, 0, sizeof(ret.atom));
    ret.len = len + b.len;
    for (int i = 0; i < len; i++)
      for (int j = 0; j < b.len; j++) ret.atom[i + j] += atom[i] * b.atom[j];
    for (int i = 1; i < ret.len; i++) {
      ret.atom[i] += ret.atom[i - 1] / DigByte;
      ret.atom[i - 1] %= DigByte;
    }
    if (!ret.atom[ret.len - 1]) --ret.len;
    return ret;
  }
  bool operator<(const Bint& b) const {
    if (len ^ b.len) return len < b.len;
    for (int i = len - 1; i >= 0; i--)
      if (atom[i] ^ b.atom[i]) return atom[i] < b.atom[i];
    return false;
  }
  void print(char endch = '\0') const {
    if (len <= 0) {
      putchar('0');
      if (endch) putchar(endch);
      return;
    }
    printf("%llu", atom[len - 1]);
    int i = len - 2;
    while (i >= 0) printf("%08llu", atom[i--]);
    if (endch) putchar(endch);
  }
};
int n;
Bint f[N][N], g[N];
vector<int> G[N];
int siz[N];
void sol(int u, int fa) {
  f[u][1] = f[u][0] = siz[u] = 1;
  for (size_t eid = 0; eid < G[u].size(); eid++) {
    int v = G[u][eid];
    if (v == fa) continue;
    sol(v, u);
    for (int i = 0; i <= siz[u] + siz[v]; i++) g[i] = 0;
    for (int i = 0; i <= siz[v]; i++)
      for (int j = 0; j <= siz[u]; j++)
        g[i + j] = max(g[i + j], f[u][j] * f[v][i]);
    siz[u] += siz[v];
    for (int i = 0; i <= siz[u]; i++) f[u][i] = g[i];
  }
  for (int i = 1; i <= siz[u]; i++) f[u][0] = max(f[u][0], f[u][i] * i);
}
signed main() {
  read >> n;
  for (int i = 1, u, v; i < n; i++) {
    read >> u >> v;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  sol(1, -1);
  f[1][0].print('\n');
  return 0;
}

```