#include <bits/stdc++.h>
using namespace std;
struct Tpoint {
  double x, y;
  Tpoint() {}
  Tpoint(double _x, double _y) {
    x = _x;
    y = _y;
  }
  inline void read() { scanf("%lf%lf", &x, &y); }
  inline void show() { printf("%lf %lf\n", x, y); }
  inline double norm() { return sqrt(((x) * (x)) + ((y) * (y))); }
};
inline Tpoint operator+(const Tpoint &a, const Tpoint &b) {
  return Tpoint(a.x + b.x, a.y + b.y);
}
inline Tpoint operator-(const Tpoint &a, const Tpoint &b) {
  return Tpoint(a.x - b.x, a.y - b.y);
}
inline Tpoint operator*(const Tpoint &a, const double &b) {
  return Tpoint(a.x * b, a.y * b);
}
inline Tpoint operator/(const Tpoint &a, const double &b) {
  return Tpoint(a.x / b, a.y / b);
}
inline double det(const Tpoint &a, const Tpoint &b) {
  return a.x * b.y - a.y * b.x;
}
inline double dot(const Tpoint &a, const Tpoint &b) {
  return a.x * b.x + a.y * b.y;
}
const int maxleng = 50;
class BigInt {
 public:
  int leng;
  int num[maxleng];

 public:
  BigInt() {
    leng = 1;
    memset(num, 0, sizeof(num));
  }
  BigInt(int x) {
    leng = 0;
    memset(num, 0, sizeof(num));
    while (x) {
      num[leng++] = x % 10000;
      x /= 10000;
    }
    if (leng == 0) leng = 1;
  }
  operator int() {
    int x = 0, l = leng - 1;
    while (l >= 0) {
      x = x * 10000 + num[l];
      l--;
    }
    return x;
  }
  operator int *() { return num; }
  int length() { return leng; }
  void read() {
    char s[maxleng + 1];
    scanf("%s", s);
    int l = strlen(s);
    leng = 0;
    for (int i = l - 1; i >= 0;) {
      if (i >= 0) num[leng] += (s[i--] - '0');
      if (i >= 0) num[leng] += (s[i--] - '0') * 10;
      if (i >= 0) num[leng] += (s[i--] - '0') * 100;
      if (i >= 0) num[leng] += (s[i--] - '0') * 1000;
      leng++;
    }
    if (leng == 0) leng = 1;
  }
  void write() {
    int i = leng - 1;
    printf("%d", num[i]);
    i--;
    while (i >= 0) printf("%04d", num[i--]);
  }
  void writeln() {
    write();
    printf("\n");
  }
  void getlength() {
    leng = maxleng - 1;
    while (num[leng] == 0 && leng > 0) leng--;
    leng++;
  }
  friend BigInt operator+(BigInt a, BigInt b);
  friend BigInt operator+(BigInt a, int b);
  friend BigInt operator-(BigInt a, BigInt b);
  friend BigInt operator*(BigInt a, BigInt b);
  friend BigInt operator*(BigInt a, int b);
  friend BigInt operator/(BigInt a, BigInt b);
  friend bool operator<(BigInt a, BigInt b);
};
BigInt operator+(BigInt a, BigInt b) {
  int l = a.leng > b.leng ? a.leng : b.leng, t = 0;
  BigInt ans;
  for (int i = 0; i < l; i++) {
    ans[i] = (a[i] + b[i] + t) % 10000;
    t = (a[i] + b[i] + t) / 10000;
  }
  while (t) {
    ans[l++] = t % 10000;
    t /= 10000;
  }
  ans.leng = l;
  return ans;
}
BigInt operator+(BigInt a, int b) {
  int t = 0;
  BigInt ans;
  memcpy(ans.num, a.num, sizeof(a.num));
  ans[t] += b;
  while (a[t] >= 10000) {
    ans[t + 1] += ans[t] / 10000;
    ans[t] %= 10000;
  }
  ans.getlength();
  return ans;
}
BigInt operator-(BigInt a, BigInt b) {
  int l = a.leng;
  BigInt ans;
  memcpy(ans.num, a.num, sizeof(a.num));
  for (int i = 0; i < l; i++) {
    ans[i] -= b[i];
    if (ans[i] < 0) {
      ans[i] += 10000;
      ans[i + 1]--;
    }
  }
  ans.getlength();
  return ans;
}
BigInt operator*(BigInt a, BigInt b) {
  int la = a.leng, lb = b.leng, t, p;
  BigInt ans;
  for (int i = 0; i < la; i++) {
    t = 0;
    for (int j = 0; j < lb; j++) {
      p = (ans[i + j] + a[i] * b[j] + t) / 10000;
      ans[i + j] = (ans[i + j] + a[i] * b[j] + t) % 10000;
      t = p;
    }
    p = i + lb;
    if (t) {
      ans[p] += t;
      while (ans[p] >= 10000) {
        ans[p + 1] += ans[p] / 10000;
        ans[p] %= 10000;
        p++;
      }
    }
  }
  ans.getlength();
  return ans;
}
BigInt operator*(BigInt a, int b) {
  int t = 0, p = a.leng;
  BigInt ans;
  for (int i = 0; i < p; i++) {
    ans[i] = (a[i] * b + t) % 10000;
    t = (a[i] * b + t) / 10000;
  }
  while (t) {
    ans[p++] = t % 10000;
    t /= 10000;
  }
  ans.getlength();
  return ans;
}
bool operator<(BigInt a, BigInt b) {
  if (a.leng != b.leng) return a.leng < b.leng;
  for (int i = a.leng - 1; i >= 0; i--)
    if (a[i] != b[i]) return a[i] < b[i];
  return false;
}
BigInt ans, f[705][705], g[2][705];
int sum[705], n;
vector<int> Adj[705];
inline void dfs(int u, int fa) {
  sum[u] = 1;
  for (int i = 0; i < Adj[u].size(); ++i) {
    int v = Adj[u][i];
    if (v == fa) continue;
    dfs(v, u);
    sum[u] += sum[v];
  }
  int now = 0, old = 1;
  int s = 1;
  g[now][1] = 1;
  for (int i = 0; i < Adj[u].size(); ++i) {
    int v = Adj[u][i];
    if (v == fa) continue;
    now = 1 - now;
    old = 1 - old;
    for (int j = 1; j <= s + sum[v]; ++j) g[now][j] = 1;
    for (int j = 1; j <= sum[v]; ++j) {
      for (int k = 1; k <= s; ++k) {
        BigInt t = (g[old][k] * f[v][j]);
        BigInt t2 = t * j;
        g[now][k] = max(g[now][k], t2);
        g[now][j + k] = max(g[now][j + k], t);
      }
    }
    s += sum[v];
  }
  for (int i = 1; i <= sum[u]; ++i) f[u][i] = g[now][i];
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    Adj[a].push_back(b);
    Adj[b].push_back(a);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; ++i) ans = max(ans, f[1][i] * i);
  ans.writeln();
  return 0;
}

### Prompt

Develop a solution in CPP to the problem described below:

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 Tpoint {
  double x, y;
  Tpoint() {}
  Tpoint(double _x, double _y) {
    x = _x;
    y = _y;
  }
  inline void read() { scanf("%lf%lf", &x, &y); }
  inline void show() { printf("%lf %lf\n", x, y); }
  inline double norm() { return sqrt(((x) * (x)) + ((y) * (y))); }
};
inline Tpoint operator+(const Tpoint &a, const Tpoint &b) {
  return Tpoint(a.x + b.x, a.y + b.y);
}
inline Tpoint operator-(const Tpoint &a, const Tpoint &b) {
  return Tpoint(a.x - b.x, a.y - b.y);
}
inline Tpoint operator*(const Tpoint &a, const double &b) {
  return Tpoint(a.x * b, a.y * b);
}
inline Tpoint operator/(const Tpoint &a, const double &b) {
  return Tpoint(a.x / b, a.y / b);
}
inline double det(const Tpoint &a, const Tpoint &b) {
  return a.x * b.y - a.y * b.x;
}
inline double dot(const Tpoint &a, const Tpoint &b) {
  return a.x * b.x + a.y * b.y;
}
const int maxleng = 50;
class BigInt {
 public:
  int leng;
  int num[maxleng];

 public:
  BigInt() {
    leng = 1;
    memset(num, 0, sizeof(num));
  }
  BigInt(int x) {
    leng = 0;
    memset(num, 0, sizeof(num));
    while (x) {
      num[leng++] = x % 10000;
      x /= 10000;
    }
    if (leng == 0) leng = 1;
  }
  operator int() {
    int x = 0, l = leng - 1;
    while (l >= 0) {
      x = x * 10000 + num[l];
      l--;
    }
    return x;
  }
  operator int *() { return num; }
  int length() { return leng; }
  void read() {
    char s[maxleng + 1];
    scanf("%s", s);
    int l = strlen(s);
    leng = 0;
    for (int i = l - 1; i >= 0;) {
      if (i >= 0) num[leng] += (s[i--] - '0');
      if (i >= 0) num[leng] += (s[i--] - '0') * 10;
      if (i >= 0) num[leng] += (s[i--] - '0') * 100;
      if (i >= 0) num[leng] += (s[i--] - '0') * 1000;
      leng++;
    }
    if (leng == 0) leng = 1;
  }
  void write() {
    int i = leng - 1;
    printf("%d", num[i]);
    i--;
    while (i >= 0) printf("%04d", num[i--]);
  }
  void writeln() {
    write();
    printf("\n");
  }
  void getlength() {
    leng = maxleng - 1;
    while (num[leng] == 0 && leng > 0) leng--;
    leng++;
  }
  friend BigInt operator+(BigInt a, BigInt b);
  friend BigInt operator+(BigInt a, int b);
  friend BigInt operator-(BigInt a, BigInt b);
  friend BigInt operator*(BigInt a, BigInt b);
  friend BigInt operator*(BigInt a, int b);
  friend BigInt operator/(BigInt a, BigInt b);
  friend bool operator<(BigInt a, BigInt b);
};
BigInt operator+(BigInt a, BigInt b) {
  int l = a.leng > b.leng ? a.leng : b.leng, t = 0;
  BigInt ans;
  for (int i = 0; i < l; i++) {
    ans[i] = (a[i] + b[i] + t) % 10000;
    t = (a[i] + b[i] + t) / 10000;
  }
  while (t) {
    ans[l++] = t % 10000;
    t /= 10000;
  }
  ans.leng = l;
  return ans;
}
BigInt operator+(BigInt a, int b) {
  int t = 0;
  BigInt ans;
  memcpy(ans.num, a.num, sizeof(a.num));
  ans[t] += b;
  while (a[t] >= 10000) {
    ans[t + 1] += ans[t] / 10000;
    ans[t] %= 10000;
  }
  ans.getlength();
  return ans;
}
BigInt operator-(BigInt a, BigInt b) {
  int l = a.leng;
  BigInt ans;
  memcpy(ans.num, a.num, sizeof(a.num));
  for (int i = 0; i < l; i++) {
    ans[i] -= b[i];
    if (ans[i] < 0) {
      ans[i] += 10000;
      ans[i + 1]--;
    }
  }
  ans.getlength();
  return ans;
}
BigInt operator*(BigInt a, BigInt b) {
  int la = a.leng, lb = b.leng, t, p;
  BigInt ans;
  for (int i = 0; i < la; i++) {
    t = 0;
    for (int j = 0; j < lb; j++) {
      p = (ans[i + j] + a[i] * b[j] + t) / 10000;
      ans[i + j] = (ans[i + j] + a[i] * b[j] + t) % 10000;
      t = p;
    }
    p = i + lb;
    if (t) {
      ans[p] += t;
      while (ans[p] >= 10000) {
        ans[p + 1] += ans[p] / 10000;
        ans[p] %= 10000;
        p++;
      }
    }
  }
  ans.getlength();
  return ans;
}
BigInt operator*(BigInt a, int b) {
  int t = 0, p = a.leng;
  BigInt ans;
  for (int i = 0; i < p; i++) {
    ans[i] = (a[i] * b + t) % 10000;
    t = (a[i] * b + t) / 10000;
  }
  while (t) {
    ans[p++] = t % 10000;
    t /= 10000;
  }
  ans.getlength();
  return ans;
}
bool operator<(BigInt a, BigInt b) {
  if (a.leng != b.leng) return a.leng < b.leng;
  for (int i = a.leng - 1; i >= 0; i--)
    if (a[i] != b[i]) return a[i] < b[i];
  return false;
}
BigInt ans, f[705][705], g[2][705];
int sum[705], n;
vector<int> Adj[705];
inline void dfs(int u, int fa) {
  sum[u] = 1;
  for (int i = 0; i < Adj[u].size(); ++i) {
    int v = Adj[u][i];
    if (v == fa) continue;
    dfs(v, u);
    sum[u] += sum[v];
  }
  int now = 0, old = 1;
  int s = 1;
  g[now][1] = 1;
  for (int i = 0; i < Adj[u].size(); ++i) {
    int v = Adj[u][i];
    if (v == fa) continue;
    now = 1 - now;
    old = 1 - old;
    for (int j = 1; j <= s + sum[v]; ++j) g[now][j] = 1;
    for (int j = 1; j <= sum[v]; ++j) {
      for (int k = 1; k <= s; ++k) {
        BigInt t = (g[old][k] * f[v][j]);
        BigInt t2 = t * j;
        g[now][k] = max(g[now][k], t2);
        g[now][j + k] = max(g[now][j + k], t);
      }
    }
    s += sum[v];
  }
  for (int i = 1; i <= sum[u]; ++i) f[u][i] = g[now][i];
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    Adj[a].push_back(b);
    Adj[b].push_back(a);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; ++i) ans = max(ans, f[1][i] * i);
  ans.writeln();
  return 0;
}

```