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
import java.util.*;
import java.math.*;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        AC solver = new AC();
        solver.solve(in, out);
        out.close();
    }
}

class AC {
    class Node {
        BigInteger h, f;
    }
    Comparator<Integer> cmp = new Comparator<Integer>() {
        public int compare(Integer a,Integer b) {   
            return dp[b].f.multiply(dp[a].h).compareTo(dp[a].f.multiply(dp[b].h));
        }
    };
    ArrayList<Integer> edge[] = new ArrayList[710];
    Node dp[] = new Node[710];
    int size[] = new int[710];
    void dfs(int u, int f,PrintWriter out) {
        dp[u].f = dp[u].h = BigInteger.ONE;
        size[u] = 1;
     // case 1 : u's component is only u
        for(int v:edge[u]) { 
            if(v == f) continue;
            dfs(v,u,out);
            dp[u].f = dp[u].f.multiply(dp[v].h);
            size[u] += size[v];
        }
        
  /*      for(int i = 0 ; i < edge[u].size(); i++) {
            int to  =  edge[u].get(i); 
            if(to == f) continue;
            BigInteger a = dp[to].f;
            BigInteger b = dp[to].h;
            out.println(a+" "+b);
        }*/
        Collections.sort(edge[u],cmp);
     // case 2 : u is with some of its children
        dp[u].h = dp[u].f;
        BigInteger cur;
        cur = dp[u].f;
        int son = 0; 
        for(int v:edge[u]){
            if(v==f) continue;
            son ++;
            cur = cur.divide(dp[v].h).multiply(dp[v].f);
            BigInteger tmp = cur.multiply(BigInteger.valueOf(son+1));
            if(tmp.compareTo(dp[u].h) > 0) dp[u].h = tmp;
        }
     // case 3: u is with only one of its children and some children's children        
        for(int v :edge[u]) {
            if(v==f) continue;
            cur = dp[u].f.divide(dp[v].h).multiply(dp[v].f);
            son = 0;
            for(int w : edge[v]) {
                if(w == u) continue;
                son++;
                cur = cur.divide(dp[w].h).multiply(dp[w].f);
                BigInteger tmp = cur.multiply(BigInteger.valueOf(son+2));
                if(tmp.compareTo(dp[u].h) > 0) dp[u].h = tmp;
            }
        }
 
    }
    public void solve(InputReader in, PrintWriter out) { 
        int n, a, b;
        n = in.nextInt();
        for (int i = 1; i <= n; i++){
            edge[i] = new ArrayList<Integer>();
            dp[i] = new Node();
        }
        for (int i = 1; i < n; i++) {
            a = in.nextInt();
            b = in.nextInt();
            edge[a].add(b);
            edge[b].add(a);
        }
        dfs(1,0,out);
        out.println(dp[1].h);
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public double nextDouble() {
        return Double.parseDouble(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }
}

class ArrayUtils {
    public static void fill(long[][] array, long value) {
        for (long[] row : array)
            Arrays.fill(row, value);
    }

    public static void fill(long[][][] array, long value) {
        for (long[][] row : array)
            fill(row, value);
    }

    public static void fill(long[][][][] array, long value) {
        for (long[][][] row : array)
            fill(row, value);
    }
}