#include <bits/stdc++.h>
using namespace std;
using namespace rel_ops;
const double PI = acos((double)-1);
int ts, ts2, ts3, ts4;
int n, m;
long long gcd(long long x, long long y) {
  long long t;
  for (; y != 0;) {
    t = x % y;
    x = y;
    y = t;
  }
  return x;
}
const int BNLIM = 600, JW2 = 4, JW = (int)(pow(10., JW2) + 0.1);
bool isnum(char c) {
  if (c >= 48 && c <= 57)
    return 1;
  else
    return 0;
}
long long mod_dan, _flagPositive;
class bignum;
long long pow_(long long x, long long y) {
  long long ans = 1;
  for (; y > 0; y--) ans *= x;
  return ans;
}
class bignum {
 public:
  int a[BNLIM + 1];
  inline void mset() { memset(a, 0, sizeof(a)); }
  inline void clear() {
    int i;
    for (i = 1; i <= a[0]; i++) a[i] = 0;
    a[0] = 0;
  }
  inline bignum(long long x = 0) {
    this->mset();
    int i;
    for (i = 1; x > 0; i++) a[i] = x % JW, x /= JW;
    a[0] = i - 1;
  }
  inline long long getnum() const {
    long long ans = 0, i;
    for (i = a[0]; i >= 1; i--) ans = ans * JW + a[i];
    return ans;
  }
  friend inline long long getnum(const bignum &a) {
    long long ans = 0, i;
    for (i = a.a[0]; i >= 1; i--) ans = ans * JW + a.a[i];
    return ans;
  }
  inline int getws(int sj = BNLIM) const {
    int i;
    for (i = sj; i >= 1; i--)
      if (a[i] > 0) break;
    return i;
  }
  inline friend short comp(const bignum &a, const bignum &b) {
    int i;
    if (a.a[0] != b.a[0]) {
      if (a.a[0] < b.a[0])
        return -1;
      else
        return 1;
    }
    for (i = a.a[0]; i >= 1; i--) {
      if (a.a[i] < b.a[i])
        return -1;
      else if (a.a[i] > b.a[i])
        return 1;
    }
    return 0;
  }
  inline short comp(const bignum &b) const {
    int i;
    if (a[0] != b.a[0]) {
      if (a[0] < b.a[0])
        return -1;
      else
        return 1;
    }
    for (i = a[0]; i >= 1; i--) {
      if (a[i] < b.a[i])
        return -1;
      else if (a[i] > b.a[i])
        return 1;
    }
    return 0;
  }
  inline friend bool operator<(const bignum &a, const bignum &b) {
    return a.comp(b) == -1;
  }
  inline friend bool operator>(const bignum &a, const bignum &b) {
    return b.comp(a) == -1;
  }
  inline friend bool operator==(const bignum &a, const bignum &b) {
    return b.comp(a) == 0;
  }
  inline friend bool operator<=(const bignum &a, const bignum &b) {
    int t1 = a.comp(b);
    return t1 == -1 || t1 == 0;
  }
  inline friend bool operator>=(const bignum &a, const bignum &b) {
    int t1 = b.comp(a);
    return t1 == -1 || t1 == 0;
  }
  friend bignum operator+(const bignum &a, const bignum &b) {
    bignum c;
    int i, j, k, t1, t2, t3;
    t1 = max(a.a[0], b.a[0]);
    for (i = 1; i <= t1; i++) {
      c.a[i] += a.a[i] + b.a[i];
      if (c.a[i] >= JW) c.a[i + 1]++, c.a[i] -= JW;
    }
    c.a[0] = t1;
    if (c.a[t1 + 1] > 0) c.a[0]++;
    return c;
  }
  friend bignum operator-(const bignum &a, const bignum &b) {
    bignum c;
    int i, j, k, t1, t2, t3;
    for (i = 1; i <= a.a[0]; i++) {
      c.a[i] += a.a[i] - b.a[i];
      if (c.a[i] < 0) c.a[i + 1]--, c.a[i] += JW;
    }
    c.a[0] = c.getws(a.a[0]);
    return c;
  }
  friend void operator+=(bignum &a, const bignum &b) { a = a + b; }
  friend void operator-=(bignum &a, const bignum &b) { a = a - b; }
  friend bignum operator*(const bignum &a, long long b2) {
    bignum c;
    long long i, j, k, t1, t2, t3, b;
    b = (long long)b2;
    for (i = 1; i <= a.a[0]; i++) {
      c.a[i] += a.a[i] * b;
      if (c.a[i] >= JW) {
        t1 = c.a[i] / JW;
        c.a[i + 1] += t1;
        c.a[i] -= JW * t1;
      }
    }
    for (; c[i] > 0; i++) {
      if (c.a[i] >= JW) c.a[i + 1] += c.a[i] / JW, c.a[i] %= JW;
    }
    c.a[0] = i - 1;
    return c;
  }
  friend bignum operator*(long long b2, const bignum &a) { return a * b2; }
  friend bignum operator*(const bignum &a, const bignum &b) {
    bignum c;
    int i, j, k;
    for (i = 1; i <= a.a[0]; i++)
      for (j = 1; j <= b.a[0]; j++) {
        c.a[i + j - 1] += a.a[i] * b.a[j];
        if (c.a[i + j - 1] >= JW)
          c.a[i + j - 1 + 1] += c.a[i + j - 1] / JW, c.a[i + j - 1] %= JW;
      }
    c.a[0] = a.a[0] + b.a[0];
    if (c[c[0]] == 0) c[0]--;
    return c;
  }
  friend bignum operator/(const bignum &a, long long b) {
    bignum c;
    long long i, j, k, t1, t2, t3;
    t1 = 0;
    for (i = a.a[0]; i >= 1; i--) {
      t1 = t1 * JW + a.a[i];
      c.a[i] = t1 / b;
      t1 %= b;
    }
    c.a[0] = c.getws(a.a[0]);
    mod_dan = t1;
    return c;
  }
  friend bignum operator/(long long b, const bignum &a) { return a / b; }
  friend long long operator%(const bignum &a, long long b) {
    a / b;
    return mod_dan;
  }
  friend void operator*=(bignum &a, const bignum &b) { a = a * b; }
  friend void operator*=(bignum &a, const long long &b) { a = a * b; }
  friend void operator/=(bignum &a, long long &b) { a = a / b; }
  bignum sheng(int x) {
    bignum b;
    int i;
    if (x >= 0) {
      for (i = 1; i <= a[0]; i++) b.a[i + x] = a[i];
      b.a[0] = a[0] + x;
      return b;
    } else {
      for (i = max(1, x + 1); i <= a[0]; i++) b.a[i - x] = a[i];
      b.a[0] = max(0, a[0] - x);
      return b;
    }
  }
  char input() {
    static int _b_[BNLIM * JW2 + 5];
    int i = 1, j, t1 = 0, t2 = 0;
    char c1;
    _flagPositive = 1;
    char cc[BNLIM * JW2 + 15];
    scanf("%s", cc);
    for (;;) {
      c1 = cc[t2++];
      if (c1 == '-') {
        _flagPositive = -1;
        continue;
      }
      if (!isnum(c1)) break;
      _b_[++t1] = c1 - '0';
    }
    if (t1 == 0) return 0;
    for (i = 1; i <= t1; i += JW2) {
      for (j = max(1, t1 - i - 2); j <= t1 - i + 1; j++)
        a[i / JW2 + 1] = a[i / JW2 + 1] * 10 + _b_[j];
    }
    a[0] = getws();
    return 1;
  }
  void output() {
    int i;
    string str = "%0";
    if (JW2 >= 10) str += JW2 / 10 + 48;
    str += JW2 % 10 + 48;
    str += "d";
    a[0] = max(getws(), 1);
    for (i = a[0]; i >= 1; i--) {
      if (i != a[0])
        printf(str.c_str(), a[i]);
      else
        printf("%d", a[i]);
    }
  }
  inline int &operator[](long long x) { return a[x]; }
} MOD;
bignum operator/(bignum a, const bignum &b) {
  bignum c = 0, d;
  int i, j, k, t1, t2, t3, le, ri, mid;
  t1 = 0;
  if (b.a[0] <= 1 && b.a[1] == 0) return c;
  for (i = a.a[0] - b.a[0] + 1; i >= 1; i--) {
    for (le = 0, ri = JW - 1, mid = (le + ri) / 2; le <= ri;
         mid = (le + ri) / 2) {
      d = (b * mid).sheng(i - 1);
      if (d.comp(a) > 0)
        ri = mid - 1;
      else
        le = mid + 1;
    }
    d = bignum(ri).sheng(i - 1);
    c += d;
    a -= (d * b);
  }
  MOD = a;
  return c;
}
void operator/=(bignum &a, const bignum &b) { a = a / b; }
bignum operator%(const bignum &a, const bignum &b) {
  a / b;
  return MOD;
}
int a[1005][1005];
bignum f[1005], h[1005];
pair<bignum, bignum> p[1005];
int p2, fa[1005];
bool cmp1(pair<bignum, bignum> a, pair<bignum, bignum> b) {
  return a.first * b.second > a.second * b.first;
}
int dep[1005];
void dfs(int k) {
  long long i, j, l, x, t1, t2, t3, t4, t5, t6, t7, t8, t9, t, nw, son[1005],
      son2 = 0;
  if (dep[k] > 100) ts = 0;
  for (i = 1; i <= n; i++)
    if (a[k][i] && i != fa[k]) {
      dep[i] = dep[k] + 1;
      fa[i] = k;
      dfs(i);
      son[++son2] = i;
    }
  if (son2 == 0) {
    f[k] = 1;
    h[k] = 1;
    return;
  }
  f[k] = 1;
  h[k] = 1;
  for (j = 1; j <= son2; j++) {
    i = son[j];
    f[k] = f[k] * h[i];
  }
  p2 = 0;
  for (j = 1; j <= son2; j++) p[++p2] = make_pair(f[son[j]], h[son[j]]);
  sort(p + 1, p + p2 + 1, cmp1);
  bignum tp = 1;
  for (i = 1; i <= son2; i++) tp *= h[son[i]];
  if (k == 1) ts = 0;
  for (j = 0; j <= son2; j++) {
    i = son[j];
    if (j) {
      tp = tp / p[j].second;
      tp = tp * p[j].first;
    }
    h[k] = max(h[k], tp * (j + 1));
  }
  int sn[1005], sn2;
  for (int l1 = 1; l1 <= son2; l1++) {
    bignum tq = 1;
    l = son[l1];
    for (i = 1; i <= son2; i++)
      if (i != l1) tq *= h[son[i]];
    for (sn2 = 0, i = 1; i <= n; i++)
      if (a[l][i] && fa[i] == l) sn[++sn2] = i;
    p2 = 0;
    for (j = 1; j <= sn2; j++) p[++p2] = make_pair(f[sn[j]], h[sn[j]]);
    sort(p + 1, p + p2 + 1, cmp1);
    bignum tp = 1;
    if (k == 1) ts = 0;
    for (i = 1; i <= sn2; i++) tp *= h[sn[i]];
    for (j = 1; j <= sn2; j++) {
      i = sn[j];
      if (j) tp = tp / p[j].second * p[j].first;
      h[k] = max(h[k], tp * tq * (j + 2));
    }
  }
}
int main() {
  long long i, j, k, l, t1, t2, t3, t4, t5, t6, t7, t8, t9, t, nw;
  int tt1, tt2, tt3, tt4;
  double u1, u2, u3, u4, u5, u6, u7, u8, u9;
  char c1, c2, c3;
  srand((unsigned)time(0));
  cin >> n;
  for (i = 1; i < n; i++) {
    cin >> t1 >> t2;
    a[t1][t2] = 1;
    a[t2][t1] = 1;
  }
  dfs(1);
  h[1].output();
  cout << endl;
  return 0;
}

### Prompt

Generate 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;
using namespace rel_ops;
const double PI = acos((double)-1);
int ts, ts2, ts3, ts4;
int n, m;
long long gcd(long long x, long long y) {
  long long t;
  for (; y != 0;) {
    t = x % y;
    x = y;
    y = t;
  }
  return x;
}
const int BNLIM = 600, JW2 = 4, JW = (int)(pow(10., JW2) + 0.1);
bool isnum(char c) {
  if (c >= 48 && c <= 57)
    return 1;
  else
    return 0;
}
long long mod_dan, _flagPositive;
class bignum;
long long pow_(long long x, long long y) {
  long long ans = 1;
  for (; y > 0; y--) ans *= x;
  return ans;
}
class bignum {
 public:
  int a[BNLIM + 1];
  inline void mset() { memset(a, 0, sizeof(a)); }
  inline void clear() {
    int i;
    for (i = 1; i <= a[0]; i++) a[i] = 0;
    a[0] = 0;
  }
  inline bignum(long long x = 0) {
    this->mset();
    int i;
    for (i = 1; x > 0; i++) a[i] = x % JW, x /= JW;
    a[0] = i - 1;
  }
  inline long long getnum() const {
    long long ans = 0, i;
    for (i = a[0]; i >= 1; i--) ans = ans * JW + a[i];
    return ans;
  }
  friend inline long long getnum(const bignum &a) {
    long long ans = 0, i;
    for (i = a.a[0]; i >= 1; i--) ans = ans * JW + a.a[i];
    return ans;
  }
  inline int getws(int sj = BNLIM) const {
    int i;
    for (i = sj; i >= 1; i--)
      if (a[i] > 0) break;
    return i;
  }
  inline friend short comp(const bignum &a, const bignum &b) {
    int i;
    if (a.a[0] != b.a[0]) {
      if (a.a[0] < b.a[0])
        return -1;
      else
        return 1;
    }
    for (i = a.a[0]; i >= 1; i--) {
      if (a.a[i] < b.a[i])
        return -1;
      else if (a.a[i] > b.a[i])
        return 1;
    }
    return 0;
  }
  inline short comp(const bignum &b) const {
    int i;
    if (a[0] != b.a[0]) {
      if (a[0] < b.a[0])
        return -1;
      else
        return 1;
    }
    for (i = a[0]; i >= 1; i--) {
      if (a[i] < b.a[i])
        return -1;
      else if (a[i] > b.a[i])
        return 1;
    }
    return 0;
  }
  inline friend bool operator<(const bignum &a, const bignum &b) {
    return a.comp(b) == -1;
  }
  inline friend bool operator>(const bignum &a, const bignum &b) {
    return b.comp(a) == -1;
  }
  inline friend bool operator==(const bignum &a, const bignum &b) {
    return b.comp(a) == 0;
  }
  inline friend bool operator<=(const bignum &a, const bignum &b) {
    int t1 = a.comp(b);
    return t1 == -1 || t1 == 0;
  }
  inline friend bool operator>=(const bignum &a, const bignum &b) {
    int t1 = b.comp(a);
    return t1 == -1 || t1 == 0;
  }
  friend bignum operator+(const bignum &a, const bignum &b) {
    bignum c;
    int i, j, k, t1, t2, t3;
    t1 = max(a.a[0], b.a[0]);
    for (i = 1; i <= t1; i++) {
      c.a[i] += a.a[i] + b.a[i];
      if (c.a[i] >= JW) c.a[i + 1]++, c.a[i] -= JW;
    }
    c.a[0] = t1;
    if (c.a[t1 + 1] > 0) c.a[0]++;
    return c;
  }
  friend bignum operator-(const bignum &a, const bignum &b) {
    bignum c;
    int i, j, k, t1, t2, t3;
    for (i = 1; i <= a.a[0]; i++) {
      c.a[i] += a.a[i] - b.a[i];
      if (c.a[i] < 0) c.a[i + 1]--, c.a[i] += JW;
    }
    c.a[0] = c.getws(a.a[0]);
    return c;
  }
  friend void operator+=(bignum &a, const bignum &b) { a = a + b; }
  friend void operator-=(bignum &a, const bignum &b) { a = a - b; }
  friend bignum operator*(const bignum &a, long long b2) {
    bignum c;
    long long i, j, k, t1, t2, t3, b;
    b = (long long)b2;
    for (i = 1; i <= a.a[0]; i++) {
      c.a[i] += a.a[i] * b;
      if (c.a[i] >= JW) {
        t1 = c.a[i] / JW;
        c.a[i + 1] += t1;
        c.a[i] -= JW * t1;
      }
    }
    for (; c[i] > 0; i++) {
      if (c.a[i] >= JW) c.a[i + 1] += c.a[i] / JW, c.a[i] %= JW;
    }
    c.a[0] = i - 1;
    return c;
  }
  friend bignum operator*(long long b2, const bignum &a) { return a * b2; }
  friend bignum operator*(const bignum &a, const bignum &b) {
    bignum c;
    int i, j, k;
    for (i = 1; i <= a.a[0]; i++)
      for (j = 1; j <= b.a[0]; j++) {
        c.a[i + j - 1] += a.a[i] * b.a[j];
        if (c.a[i + j - 1] >= JW)
          c.a[i + j - 1 + 1] += c.a[i + j - 1] / JW, c.a[i + j - 1] %= JW;
      }
    c.a[0] = a.a[0] + b.a[0];
    if (c[c[0]] == 0) c[0]--;
    return c;
  }
  friend bignum operator/(const bignum &a, long long b) {
    bignum c;
    long long i, j, k, t1, t2, t3;
    t1 = 0;
    for (i = a.a[0]; i >= 1; i--) {
      t1 = t1 * JW + a.a[i];
      c.a[i] = t1 / b;
      t1 %= b;
    }
    c.a[0] = c.getws(a.a[0]);
    mod_dan = t1;
    return c;
  }
  friend bignum operator/(long long b, const bignum &a) { return a / b; }
  friend long long operator%(const bignum &a, long long b) {
    a / b;
    return mod_dan;
  }
  friend void operator*=(bignum &a, const bignum &b) { a = a * b; }
  friend void operator*=(bignum &a, const long long &b) { a = a * b; }
  friend void operator/=(bignum &a, long long &b) { a = a / b; }
  bignum sheng(int x) {
    bignum b;
    int i;
    if (x >= 0) {
      for (i = 1; i <= a[0]; i++) b.a[i + x] = a[i];
      b.a[0] = a[0] + x;
      return b;
    } else {
      for (i = max(1, x + 1); i <= a[0]; i++) b.a[i - x] = a[i];
      b.a[0] = max(0, a[0] - x);
      return b;
    }
  }
  char input() {
    static int _b_[BNLIM * JW2 + 5];
    int i = 1, j, t1 = 0, t2 = 0;
    char c1;
    _flagPositive = 1;
    char cc[BNLIM * JW2 + 15];
    scanf("%s", cc);
    for (;;) {
      c1 = cc[t2++];
      if (c1 == '-') {
        _flagPositive = -1;
        continue;
      }
      if (!isnum(c1)) break;
      _b_[++t1] = c1 - '0';
    }
    if (t1 == 0) return 0;
    for (i = 1; i <= t1; i += JW2) {
      for (j = max(1, t1 - i - 2); j <= t1 - i + 1; j++)
        a[i / JW2 + 1] = a[i / JW2 + 1] * 10 + _b_[j];
    }
    a[0] = getws();
    return 1;
  }
  void output() {
    int i;
    string str = "%0";
    if (JW2 >= 10) str += JW2 / 10 + 48;
    str += JW2 % 10 + 48;
    str += "d";
    a[0] = max(getws(), 1);
    for (i = a[0]; i >= 1; i--) {
      if (i != a[0])
        printf(str.c_str(), a[i]);
      else
        printf("%d", a[i]);
    }
  }
  inline int &operator[](long long x) { return a[x]; }
} MOD;
bignum operator/(bignum a, const bignum &b) {
  bignum c = 0, d;
  int i, j, k, t1, t2, t3, le, ri, mid;
  t1 = 0;
  if (b.a[0] <= 1 && b.a[1] == 0) return c;
  for (i = a.a[0] - b.a[0] + 1; i >= 1; i--) {
    for (le = 0, ri = JW - 1, mid = (le + ri) / 2; le <= ri;
         mid = (le + ri) / 2) {
      d = (b * mid).sheng(i - 1);
      if (d.comp(a) > 0)
        ri = mid - 1;
      else
        le = mid + 1;
    }
    d = bignum(ri).sheng(i - 1);
    c += d;
    a -= (d * b);
  }
  MOD = a;
  return c;
}
void operator/=(bignum &a, const bignum &b) { a = a / b; }
bignum operator%(const bignum &a, const bignum &b) {
  a / b;
  return MOD;
}
int a[1005][1005];
bignum f[1005], h[1005];
pair<bignum, bignum> p[1005];
int p2, fa[1005];
bool cmp1(pair<bignum, bignum> a, pair<bignum, bignum> b) {
  return a.first * b.second > a.second * b.first;
}
int dep[1005];
void dfs(int k) {
  long long i, j, l, x, t1, t2, t3, t4, t5, t6, t7, t8, t9, t, nw, son[1005],
      son2 = 0;
  if (dep[k] > 100) ts = 0;
  for (i = 1; i <= n; i++)
    if (a[k][i] && i != fa[k]) {
      dep[i] = dep[k] + 1;
      fa[i] = k;
      dfs(i);
      son[++son2] = i;
    }
  if (son2 == 0) {
    f[k] = 1;
    h[k] = 1;
    return;
  }
  f[k] = 1;
  h[k] = 1;
  for (j = 1; j <= son2; j++) {
    i = son[j];
    f[k] = f[k] * h[i];
  }
  p2 = 0;
  for (j = 1; j <= son2; j++) p[++p2] = make_pair(f[son[j]], h[son[j]]);
  sort(p + 1, p + p2 + 1, cmp1);
  bignum tp = 1;
  for (i = 1; i <= son2; i++) tp *= h[son[i]];
  if (k == 1) ts = 0;
  for (j = 0; j <= son2; j++) {
    i = son[j];
    if (j) {
      tp = tp / p[j].second;
      tp = tp * p[j].first;
    }
    h[k] = max(h[k], tp * (j + 1));
  }
  int sn[1005], sn2;
  for (int l1 = 1; l1 <= son2; l1++) {
    bignum tq = 1;
    l = son[l1];
    for (i = 1; i <= son2; i++)
      if (i != l1) tq *= h[son[i]];
    for (sn2 = 0, i = 1; i <= n; i++)
      if (a[l][i] && fa[i] == l) sn[++sn2] = i;
    p2 = 0;
    for (j = 1; j <= sn2; j++) p[++p2] = make_pair(f[sn[j]], h[sn[j]]);
    sort(p + 1, p + p2 + 1, cmp1);
    bignum tp = 1;
    if (k == 1) ts = 0;
    for (i = 1; i <= sn2; i++) tp *= h[sn[i]];
    for (j = 1; j <= sn2; j++) {
      i = sn[j];
      if (j) tp = tp / p[j].second * p[j].first;
      h[k] = max(h[k], tp * tq * (j + 2));
    }
  }
}
int main() {
  long long i, j, k, l, t1, t2, t3, t4, t5, t6, t7, t8, t9, t, nw;
  int tt1, tt2, tt3, tt4;
  double u1, u2, u3, u4, u5, u6, u7, u8, u9;
  char c1, c2, c3;
  srand((unsigned)time(0));
  cin >> n;
  for (i = 1; i < n; i++) {
    cin >> t1 >> t2;
    a[t1][t2] = 1;
    a[t2][t1] = 1;
  }
  dfs(1);
  h[1].output();
  cout << endl;
  return 0;
}

```