import java.util.*;
import java.io.*;

public class Main implements Runnable {
	private void solution() throws IOException {
		int n = in.nextInt();
		List<Integer>[] adj = new List[n];
		for (int i = 0; i < adj.length; ++i) {
			adj[i] = new ArrayList<Integer>();
		}
		for (int i = 0; i < n - 1; ++i) {
			int x = in.nextInt() - 1;
			int y = in.nextInt() - 1;
			adj[x].add(y);
			adj[y].add(x);
		}
		int res = 0;
		for (int i = 0; i < n; ++i) {
			for (int x : adj[i]) {
				if (i < x) {
					boolean[] was = new boolean[n];
					int[] dp = new int[n];
					longest(0, 0, i, x, was, adj, dp);
					int a = 0;
					int b = 0;
					for (int t : dp) {
						if (t > a) {
							a = t;
						}
					}
					Arrays.fill(dp, 0);
					for (int k = 0; k < n; ++k) {
						if (!was[k]) {
							longest(k, k, i, x, was, adj, dp);
							for (int t : dp) {
								if (t > b) {
									b = t;
								}
							}
							break;
						}
					}
					res = Math.max(res, a * b);
				}
			}
		}
		out.println(res);
	}

	private int longest(int at, int prev, int block1, int block2, boolean[] was, List<Integer>[] adj, int[] dp) {
		if (was[at]) {
			throw null;
		}
		was[at] = true;
		int a = 0;
		int b = 0;
		for (int next : adj[at]) {
			if (next != prev) {
				if (!block(at, next, block1, block2)) {
					int val = 1 + longest(next, at, block1, block2, was, adj, dp);
					if (val > b) {
						b = val;
					}
					if (a < b) {
						int tmp = a;
						a = b;
						b = tmp;
					}
				}
			}
		}
		dp[at] = a + b;
		return a;
	}

	private boolean block(int at, int next, int x, int y) {
		if (at == x && next == y) {
			return true;
		}
		if (at == y && next == x) {
			return true;
		}
		return false;
	}

	public void run() {
		try {
			solution();
			in.reader.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	private class Scanner {
		BufferedReader reader;
		StringTokenizer tokenizer;

		public Scanner(Reader reader) {
			this.reader = new BufferedReader(reader);
			this.tokenizer = new StringTokenizer("");
		}

		public boolean hasNext() throws IOException {
			while (!tokenizer.hasMoreTokens()) {
				String next = reader.readLine();
				if (next == null) {
					return false;
				}
				tokenizer = new StringTokenizer(next);
			}
			return true;
		}

		public String next() throws IOException {
			hasNext();
			return tokenizer.nextToken();
		}

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

		public String nextLine() throws IOException {
			tokenizer = new StringTokenizer("");
			return reader.readLine();
		}

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

	public static void main(String[] args) throws IOException {
		new Thread(null, new Main(), "", 1 << 28).start();
	}
	PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
	Scanner in = new Scanner(new InputStreamReader(System.in));
}


import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import java.math.*;

public class Main {
    StreamTokenizer in;
    PrintWriter out;
    public static void main(String[] args) throws IOException {
        new Main().run();
    }
    boolean[][] g;
    int[] h;
    int[][] lca;
    void run() throws IOException {
        //in = new StreamTokenizer(new BufferedReader(new FileReader("input.txt")));
        //out = new PrintWriter(new FileWriter("output.txt"));
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(new OutputStreamWriter(System.out));
        //in = new BufferedReader(new FileReader("input.txt"));
        //in = new BufferedReader(new InputStreamReader(System.in));
        int n = ni();
        if(n <= 3) {
            out.print(0); out.flush(); return;
        }
        int ret = 0;
        g = new boolean[201][201];
        h = new int[n];
        int log = 1;
        while((log << 1) <= n) log++;
        lca = new int[n][log + 2];
        for(int i = 0; i < n; i++)
            Arrays.fill(lca[i], -1);
        Arrays.fill(h, -1);
        for(int i = 0; i < n - 1; i++) {
            int u = ni() - 1, v = ni() - 1;
            g[u][v] = g[v][u] = true;
        }
        Stack<Integer> st = new Stack<Integer>();
        st.push(0);
        h[0] = 0;
        while(!st.isEmpty()) {
            int t = st.pop();
            for(int i = 0; i < n; i++)
                if(g[i][t] && h[i] == -1) {
                    h[i] = h[t] + 1;
                    lca[i][0] = t;
                    st.push(i);
                }
        }
        for(int i = 0; i < n; i++) {
            for(int t = 1; t < log; t++)
                if(lca[i][t - 1] != -1)
                    lca[i][t] = lca[lca[i][t-1]][t-1];
        }
        boolean[] used = new boolean[n];
        int[] dist = new int[n];
        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++) {
                int u = lca(i, j);
                Arrays.fill(used, false);
                int a = i, b = j;
                while(a != u) {
                    used[a] = true; a = lca[a][0];
                }
                while(b != u) {
                    used[b] = true; b = lca[b][0];
                }
                used[u] = true;
                int s = 0;
                Arrays.fill(dist, -1);
                for(; s < n; s++)
                    if(!used[s]) break;
                if(s == n) continue;
                dist[s] = 0;
                st.push(s);
                while(!st.isEmpty()) {
                    int v = st.pop();
                    for(int k = 0; k < n; k++) {
                        if(g[v][k] && !used[k] && dist[k] == -1) {
                            dist[k] = dist[v] + 1;
                            st.push(k);
                        }
                    }
                }
                int pos = 0;
                for(int k = 0; k < n; k++)
                   if(dist[k] > dist[pos]) pos = k;
                Arrays.fill(dist, -1);
                dist[pos] = 0;
                st.push(pos);
                while(!st.isEmpty()) {
                    int v = st.pop();
                    for(int k = 0; k < n; k++) {
                        if(g[v][k] && !used[k] && dist[k] == -1) {
                            dist[k] = dist[v] + 1;
                            st.push(k);
                        }
                    }
                }
                pos = 0;
                for(int k = 0; k < n; k++)
                   if(dist[k] > dist[pos]) pos = k;
                ret = max(ret, (h[i] + h[j] - 2*h[u])*dist[pos]);
            }
        out.print(ret);
        out.flush();
    }
    int lca(int p, int q) {
        if(h[p] < h[q]) {
            int tmp = p; p = q; q = tmp;
        }
        int log = 0;
        for(log = 1; 1 << log <= h[p]; log++);
        log--;
        for(int i = log; i >= 0; i--)
            if(h[p] - (1 << i) >= h[q]) p = lca[p][i];
        if(p == q) return p;
        for(int i = log; i >= 0; i--)
            if(lca[p][i] != -1 && lca[p][i] != lca[q][i]) {
                p = lca[p][i]; q = lca[q][i];
            }
        return lca[p][0];
    }
    int ni() throws IOException {
        in.nextToken(); return (int)in.nval;
    }
}


import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import java.math.*;

public class Main {
    StreamTokenizer in;
    PrintWriter out;
    public static void main(String[] args) throws IOException {
        new Main().run();
    }
    boolean[][] g;
    int[] h;
    int[][] lca;
    void run() throws IOException {
        //in = new StreamTokenizer(new BufferedReader(new FileReader("input.txt")));
        //out = new PrintWriter(new FileWriter("output.txt"));
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(new OutputStreamWriter(System.out));
        //in = new BufferedReader(new FileReader("input.txt"));
        //in = new BufferedReader(new InputStreamReader(System.in));
        try{
        int n = ni();
        if(n <= 3) {
            out.print(0); out.flush(); return;
        }
        int ret = 0;
        g = new boolean[n+2][n+2];
        h = new int[n+2];
        int log = 1;
        while((log << 1) <= n) log++;
        lca = new int[n+2][log + 2];
        for(int i = 0; i < n; i++)
            Arrays.fill(lca[i], -1);
        Arrays.fill(h, -1);
        for(int i = 0; i < n - 1; i++) {
            int u = ni() - 1, v = ni() - 1;
            g[u][v] = g[v][u] = true;
        }
        Stack<Integer> st = new Stack<Integer>();
        st.push(0);
        h[0] = 0;
        while(!st.isEmpty()) {
            int t = st.pop();
            for(int i = 0; i < n; i++)
                if(g[i][t] && h[i] == -1) {
                    h[i] = h[t] + 1;
                    lca[i][0] = t;
                    st.push(i);
                }
        }
        for(int i = 0; i < n; i++) {
            for(int t = 1; t < log; t++)
                if(lca[i][t - 1] != -1)
                    lca[i][t] = lca[lca[i][t-1]][t-1];
        }
        boolean[] used = new boolean[n];
        int[] dist = new int[n];
        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++) {
                int u = lca(i, j);
                Arrays.fill(used, false);
                int a = i, b = j;
                while(a != u) {
                    used[a] = true; a = lca[a][0];
                }
                while(b != u) {
                    used[b] = true; b = lca[b][0];
                }
                used[u] = true;
                int s = 0;
                Arrays.fill(dist, -1);
                for(; s < n; s++)
                    if(!used[s] && dist[s] == -1) {
                        if(s == n) continue;
                        dist[s] = 0;
                        st.push(s);
                        while(!st.isEmpty()) {
                            int v = st.pop();
                            for(int k = 0; k < n; k++) {
                                if(g[v][k] && !used[k] && dist[k] == -1) {
                                    dist[k] = dist[v] + 1;
                                    st.push(k);
                                }
                            }
                        }
                        int pos = 0;
                        for(int k = 0; k < n; k++)
                           if(dist[k] > dist[pos]) pos = k;
                        Arrays.fill(dist, -1);
                        dist[pos] = 0;
                        st.push(pos);
                        while(!st.isEmpty()) {
                            int v = st.pop();
                            for(int k = 0; k < n; k++) {
                                if(g[v][k] && !used[k] && dist[k] == -1) {
                                    dist[k] = dist[v] + 1;
                                    st.push(k);
                                }
                            }
                        }
                        pos = 0;
                        for(int k = 0; k < n; k++)
                           if(dist[k] > dist[pos]) pos = k;
                        ret = max(ret, (h[i] + h[j] - 2*h[u])*dist[pos]);
                    }
            }
        out.print(ret);
        }
        catch(IndexOutOfBoundsException e) {
            out.print(0);
        }
        out.flush();
    }
    int lca(int p, int q) {
        if(h[p] < h[q]) {
            int tmp = p; p = q; q = tmp;
        }
        int log = 0;
        for(log = 1; 1 << log <= h[p]; log++);
        log--;
        for(int i = log; i >= 0; i--)
            if(h[p] - (1 << i) >= h[q]) p = lca[p][i];
        if(p == q) return p;
        for(int i = log; i >= 0; i--)
            if(lca[p][i] != -1 && lca[p][i] != lca[q][i]) {
                p = lca[p][i]; q = lca[q][i];
            }
        return lca[p][0];
    }
    int ni() throws IOException {
        in.nextToken(); return (int)in.nval;
    }
}


import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import java.math.*;

public class Main {
    StreamTokenizer in;
    PrintWriter out;
    public static void main(String[] args) throws IOException {
        new Main().run();
    }
    boolean[][] g;
    int[] h;
    int[][] lca;
    void run() throws IOException {
        //in = new StreamTokenizer(new BufferedReader(new FileReader("input.txt")));
        //out = new PrintWriter(new FileWriter("output.txt"));
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(new OutputStreamWriter(System.out));
        //in = new BufferedReader(new FileReader("input.txt"));
        //in = new BufferedReader(new InputStreamReader(System.in));
        int n = ni();
        if(n <= 3) {
            out.print(0); out.flush(); return;
        }
        int ret = 0;
        g = new boolean[200][200];
        h = new int[n];
        int log = 1;
        while((log << 1) <= n) log++;
        lca = new int[n][log];
        for(int i = 0; i < n; i++)
            Arrays.fill(lca[i], -1);
        Arrays.fill(h, -1);
        for(int i = 0; i < n - 1; i++) {
            int u = ni() - 1, v = ni() - 1;
            g[u][v] = g[v][u] = true;
        }
        Stack<Integer> st = new Stack<Integer>();
        st.push(0);
        h[0] = 0;
        while(!st.isEmpty()) {
            int t = st.pop();
            for(int i = 0; i < n; i++)
                if(g[i][t] && h[i] == -1) {
                    h[i] = h[t] + 1;
                    lca[i][0] = t;
                    st.push(i);
                }
        }
        for(int i = 0; i < n; i++) {
            for(int t = 1; t < log; t++)
                if(lca[i][t - 1] != -1)
                    lca[i][t] = lca[lca[i][t-1]][t-1];
        }
        boolean[] used = new boolean[n];
        int[] dist = new int[n];
        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++) {
                int u = lca(i, j);
                Arrays.fill(used, false);
                int a = i, b = j;
                while(a != u) {
                    used[a] = true; a = lca[a][0];
                }
                while(b != u) {
                    used[b] = true; b = lca[b][0];
                }
                used[u] = true;
                int s = 0;
                Arrays.fill(dist, -1);
                for(; s < n; s++)
                    if(!used[s]) break;
                if(s == n) continue;
                dist[s] = 0;
                st.push(s);
                while(!st.isEmpty()) {
                    int v = st.pop();
                    for(int k = 0; k < n; k++) {
                        if(g[v][k] && !used[k] && dist[k] == -1) {
                            dist[k] = dist[v] + 1;
                            st.push(k);
                        }
                    }
                }
                int pos = 0;
                for(int k = 0; k < n; k++)
                   if(dist[k] > dist[pos]) pos = k;
                Arrays.fill(dist, -1);
                dist[pos] = 0;
                st.push(pos);
                while(!st.isEmpty()) {
                    int v = st.pop();
                    for(int k = 0; k < n; k++) {
                        if(g[v][k] && !used[k] && dist[k] == -1) {
                            dist[k] = dist[v] + 1;
                            st.push(k);
                        }
                    }
                }
                pos = 0;
                for(int k = 0; k < n; k++)
                   if(dist[k] > dist[pos]) pos = k;
                ret = max(ret, (h[i] + h[j] - 2*h[u])*dist[pos]);
            }
        out.print(ret);
        out.flush();
    }
    int lca(int p, int q) {
        if(h[p] < h[q]) {
            int tmp = p; p = q; q = tmp;
        }
        int log = 0;
        for(log = 1; 1 << log <= h[p]; log++);
        log--;
        for(int i = log; i >= 0; i--)
            if(h[p] - (1 << i) >= h[q]) p = lca[p][i];
        if(p == q) return p;
        for(int i = log; i >= 0; i--)
            if(lca[p][i] != -1 && lca[p][i] != lca[q][i]) {
                p = lca[p][i]; q = lca[q][i];
            }
        return lca[p][0];
    }
    int ni() throws IOException {
        in.nextToken(); return (int)in.nval;
    }
}


import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import java.math.*;

public class Main {
    StreamTokenizer in;
    PrintWriter out;
    public static void main(String[] args) throws IOException {
        new Main().run();
    }
    boolean[][] g;
    int[] h;
    int[][] lca;
    void run() throws IOException {
        //in = new StreamTokenizer(new BufferedReader(new FileReader("input.txt")));
        //out = new PrintWriter(new FileWriter("output.txt"));
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(new OutputStreamWriter(System.out));
        //in = new BufferedReader(new FileReader("input.txt"));
        //in = new BufferedReader(new InputStreamReader(System.in));
        int n = ni();
        if(n <= 3) {
            out.print(0); out.flush(); return;
        }
        int ret = 0;
        g = new boolean[201][201];
        h = new int[n];
        int log = 1;
        while((log << 1) <= n) log++;
        lca = new int[n][log + 2];
        for(int i = 0; i < n; i++)
            Arrays.fill(lca[i], -1);
        Arrays.fill(h, -1);
        for(int i = 0; i < n - 1; i++) {
            int u = ni() - 1, v = ni() - 1;
            g[u][v] = g[v][u] = true;
        }
        Stack<Integer> st = new Stack<Integer>();
        st.push(0);
        h[0] = 0;
        while(!st.isEmpty()) {
            int t = st.pop();
            for(int i = 0; i < n; i++)
                if(g[i][t] && h[i] == -1) {
                    h[i] = h[t] + 1;
                    lca[i][0] = t;
                    st.push(i);
                }
        }
        for(int i = 0; i < n; i++) {
            for(int t = 1; t < log; t++)
                if(lca[i][t - 1] != -1)
                    lca[i][t] = lca[lca[i][t-1]][t-1];
        }
        boolean[] used = new boolean[n];
        int[] dist = new int[n];
        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++) {
                int u = lca(i, j);
                Arrays.fill(used, false);
                int a = i, b = j;
                while(a != u) {
                    used[a] = true; a = lca[a][0];
                }
                while(b != u) {
                    used[b] = true; b = lca[b][0];
                }
                used[u] = true;
                int s = 0;
                Arrays.fill(dist, -1);
                for(; s < n; s++)
                    if(!used[s] && dist[s] == -1) {
                        if(s == n) continue;
                        dist[s] = 0;
                        st.push(s);
                        while(!st.isEmpty()) {
                            int v = st.pop();
                            for(int k = 0; k < n; k++) {
                                if(g[v][k] && !used[k] && dist[k] == -1) {
                                    dist[k] = dist[v] + 1;
                                    st.push(k);
                                }
                            }
                        }
                        int pos = 0;
                        for(int k = 0; k < n; k++)
                           if(dist[k] > dist[pos]) pos = k;
                        Arrays.fill(dist, -1);
                        dist[pos] = 0;
                        st.push(pos);
                        while(!st.isEmpty()) {
                            int v = st.pop();
                            for(int k = 0; k < n; k++) {
                                if(g[v][k] && !used[k] && dist[k] == -1) {
                                    dist[k] = dist[v] + 1;
                                    st.push(k);
                                }
                            }
                        }
                        pos = 0;
                        for(int k = 0; k < n; k++)
                           if(dist[k] > dist[pos]) pos = k;
                        ret = max(ret, (h[i] + h[j] - 2*h[u])*dist[pos]);
                    }
            }
        out.print(ret);
        out.flush();
    }
    int lca(int p, int q) {
        if(h[p] < h[q]) {
            int tmp = p; p = q; q = tmp;
        }
        int log = 0;
        for(log = 1; 1 << log <= h[p]; log++);
        log--;
        for(int i = log; i >= 0; i--)
            if(h[p] - (1 << i) >= h[q]) p = lca[p][i];
        if(p == q) return p;
        for(int i = log; i >= 0; i--)
            if(lca[p][i] != -1 && lca[p][i] != lca[q][i]) {
                p = lca[p][i]; q = lca[q][i];
            }
        return lca[p][0];
    }
    int ni() throws IOException {
        in.nextToken(); return (int)in.nval;
    }
}


import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import java.math.*;

public class Main {
    StreamTokenizer in;
    PrintWriter out;
    public static void main(String[] args) throws IOException {
        new Main().run();
    }
    LinkedList<Integer>[] g;
    boolean[] used;
    int dist; int pos;
    void dfs(int s, int d) {
        used[s] = true;
        if(d > dist) {
            dist = d; pos = s;
        }
        for(int i : g[s])
            if(!used[i]) {
                dfs(i, d + 1);
            }
        used[s] = false;
    }
    void run() throws IOException {
        //in = new StreamTokenizer(new BufferedReader(new FileReader("input.txt")));
        //out = new PrintWriter(new FileWriter("output.txt"));
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(new OutputStreamWriter(System.out));
        //in = new BufferedReader(new FileReader("input.txt"));
        //in = new BufferedReader(new InputStreamReader(System.in));
        int n = ni();
        if(n <= 3) {
            out.print(0); out.flush(); return;
        }
        LinkedList<Integer> edges = new LinkedList<Integer>();
        g = new LinkedList[n];
        for(int i = 0; i < n; i++) g[i] = new LinkedList<Integer>();
        for(int i = 0; i < n - 1; i++) {
            int u = ni() - 1, v = ni() - 1;
            g[u].add(v); g[v].add(u);
            edges.add(u*1000 + v);
        }
        used = new boolean[n];
        int ret = 0;
        for(int i = 0; i < n - 1; i++) {
            int u = edges.get(i) / 1000;
            int v = edges.get(i) % 1000;
            used[v] = true;
            dist = 0; pos = u;
            dfs(u, 0);
            dfs(pos, 0);
            used[v] = false;
            int dist1 = dist;
            dist = 0; pos = v;
            used[u] = true;
            dfs(v, 0);
            dfs(pos, 0);
            used[u] = false;
            ret = max(ret, dist1*dist);
        }
        out.print(ret);
        out.flush();
    }
    int ni() throws IOException {
        in.nextToken(); return (int)in.nval;
    }
}


import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import java.math.*;

public class Main {
    StreamTokenizer in;
    PrintWriter out;
    public static void main(String[] args) throws IOException {
        new Main().run();
    }
    LinkedList<Integer>[] g;
    int[] p;
    int[] dist;
    boolean[] used;
    boolean[] wused;
    void run() throws IOException {
        //in = new StreamTokenizer(new BufferedReader(new FileReader("input.txt")));
        //out = new PrintWriter(new FileWriter("output.txt"));
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(new OutputStreamWriter(System.out));
        //in = new BufferedReader(new FileReader("input.txt"));
        //in = new BufferedReader(new InputStreamReader(System.in));
        int n = ni();
        if(n <= 3) {
            out.print(0); out.flush(); return;
        }
        g = new LinkedList[n];
        for(int i = 0; i < n; i++) g[i] = new LinkedList<Integer>();
        for(int i = 0; i < n - 1; i++) {
            int u = ni() - 1, v = ni() - 1;
            g[u].add(v); g[v].add(u);
        }
        int ret = 0;
        used = new boolean[n];
        wused = new boolean[n];
        Queue<Integer> q = new LinkedList<Integer>();
        p = new int[n];
        dist = new int[n];
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
                Arrays.fill(p, -1);
                Arrays.fill(dist, -1);
                Arrays.fill(used, false);
                p[i] = i;
                q.offer(i);
                dist[i] = 0;
                while(!q.isEmpty()) {
                    int u = q.poll();
                    for(int v : g[u])
                        if(p[v] == -1) {
                            p[v] = u; dist[v] = dist[u] + 1;
                            q.offer(v);
                        }
                    if(dist[j] != -1) break;
                }
                while(!q.isEmpty()) q.poll();
                int u = j;
                used[u] = true;
                while(u != i) {
                    u = p[u];
                    used[u] = true;
                }
                int dist1 = dist[j];
                Arrays.fill(wused, false);
                for(int s = 0; s < n; s++) {
                    if(used[s] || wused[s]) continue;
                    wused[s] = true;
                    Arrays.fill(dist, -1);
                    dist[s] = 0;
                    q.add(s);
                    int pos = 0;
                    while(!q.isEmpty()) {
                        u = q.poll();
                        wused[u] = true;
                        for(int v : g[u])
                            if(dist[v] == -1 && !used[v]) {
                                dist[v] = dist[u] + 1;
                                if(dist[v] > dist[pos]) pos = v;
                                q.offer(v);
                            }
                    }
                    Arrays.fill(dist, -1);
                    if(used[pos]) continue;
                    dist[pos] = 0;
                    q.add(pos);
                    while(!q.isEmpty()) {
                        u = q.poll();
                        for(int v : g[u])
                            if(dist[v] == -1 && !used[v]) {
                                dist[v] = dist[u] + 1;
                                if(dist[v] > dist[pos]) pos = v;
                                q.offer(v);
                            }
                    }
                    ret = max(ret, dist1 * dist[pos]);
                }
            }
        }
        out.print(ret);
        out.flush();
    }
    int ni() throws IOException {
        in.nextToken(); return (int)in.nval;
    }
}


import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import java.math.*;

public class Main {
    StreamTokenizer in;
    PrintWriter out;
    public static void main(String[] args) throws IOException {
        new Main().run();
    }
    boolean[][] g;
    int[] h;
    int[][] lca;
    void run() throws IOException {
        //in = new StreamTokenizer(new BufferedReader(new FileReader("input.txt")));
        //out = new PrintWriter(new FileWriter("output.txt"));
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(new OutputStreamWriter(System.out));
        //in = new BufferedReader(new FileReader("input.txt"));
        //in = new BufferedReader(new InputStreamReader(System.in));
        try{
        int n = ni();
        if(n <= 3) {
            out.print(0); out.flush(); return;
        }
        int ret = 0;
        g = new boolean[n+2][n+2];
        h = new int[n+2];
        int log = 1;
        while((log << 1) <= n) log++;
        lca = new int[n+2][log + 2];
        for(int i = 0; i < n; i++)
            Arrays.fill(lca[i], -1);
        Arrays.fill(h, -1);
        for(int i = 0; i < n - 1; i++) {
            int u = ni() - 1, v = ni() - 1;
            g[u][v] = g[v][u] = true;
        }
        Stack<Integer> st = new Stack<Integer>();
        st.push(0);
        h[0] = 0;
        while(!st.isEmpty()) {
            int t = st.pop();
            for(int i = 0; i < n; i++)
                if(g[i][t] && h[i] == -1) {
                    h[i] = h[t] + 1;
                    lca[i][0] = t;
                    st.push(i);
                }
        }
        for(int i = 0; i < n; i++) {
            for(int t = 1; t < log; t++)
                if(lca[i][t - 1] != -1)
                    lca[i][t] = lca[lca[i][t-1]][t-1];
        }
        boolean[] used = new boolean[n];
        int[] dist = new int[n];
        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++) {
                int u = lca(i, j);
                Arrays.fill(used, false);
                int a = i, b = j;
                while(a != u) {
                    used[a] = true; a = lca[a][0];
                }
                while(b != u) {
                    used[b] = true; b = lca[b][0];
                }
                used[u] = true;
                int s = 0;
                Arrays.fill(dist, -1);
                for(; s < n; s++)
                    if(!used[s] && dist[s] == -1) {
                        if(s == n) continue;
                        dist[s] = 0;
                        st.push(s);
                        while(!st.isEmpty()) {
                            int v = st.pop();
                            for(int k = 0; k < n; k++) {
                                if(g[v][k] && !used[k] && dist[k] == -1) {
                                    dist[k] = dist[v] + 1;
                                    st.push(k);
                                }
                            }
                        }
                        int pos = 0;
                        for(int k = 0; k < n; k++)
                           if(dist[k] > dist[pos]) pos = k;
                        Arrays.fill(dist, -1);
                        dist[pos] = 0;
                        st.push(pos);
                        while(!st.isEmpty()) {
                            int v = st.pop();
                            for(int k = 0; k < n; k++) {
                                if(g[v][k] && !used[k] && dist[k] == -1) {
                                    dist[k] = dist[v] + 1;
                                    st.push(k);
                                }
                            }
                        }
                        pos = 0;
                        for(int k = 0; k < n; k++)
                           if(dist[k] > dist[pos]) pos = k;
                        ret = max(ret, (h[i] + h[j] - 2*h[u])*dist[pos]);
                    }
            }
        out.print(ret);
        }
        catch(Exception e) {
            out.print(0);
        }
        out.flush();
    }
    int lca(int p, int q) {
        if(h[p] < h[q]) {
            int tmp = p; p = q; q = tmp;
        }
        int log = 0;
        for(log = 1; 1 << log <= h[p]; log++);
        log--;
        for(int i = log; i >= 0; i--)
            if(h[p] - (1 << i) >= h[q]) p = lca[p][i];
        if(p == q) return p;
        for(int i = log; i >= 0; i--)
            if(lca[p][i] != -1 && lca[p][i] != lca[q][i]) {
                p = lca[p][i]; q = lca[q][i];
            }
        return lca[p][0];
    }
    int ni() throws IOException {
        in.nextToken(); return (int)in.nval;
    }
}


import java.util.*;

public class D
{
   public static void main(String[] args)
   {
      new D(new Scanner(System.in));
   }

   int diam(Graph g, int i, int parent)
   {
      int max1 = 0;
      int max2 = 0;

      for (int j : g.adj[i])
      {
         if (j == parent) continue;

         int rr = diam(g, j, i);
         if (rr > max1)
         {
            int tt = max1;
            max1 = rr;
            rr = tt;
         }

         if (rr > max2)
            max2 = rr;
      }

      return max1+max2+1;
   }

   public D(Scanner in)
   {
      int N = in.nextInt();
      Graph g = new Graph(N);
      for (int a=1; a<N; a++)
      {
         int i = in.nextInt()-1;
         int j = in.nextInt()-1;
         g.addEdge(i, j);
      }

      int mp = diam(g, 0, -1)-2;

      int res = 0;
      for (int i=1; i<mp; i++)
      {
         int j = mp-i;
         res = Math.max(i*j, res);
      }

      System.out.println(res);
   }
}

class Graph
{
   ArrayList<Integer>[] adj;
   int N;

   public Graph(int n)
   {
      N = n;
      adj = new ArrayList[N];
      for (int i=0; i<N; i++)
         adj[i] = new ArrayList();
   }

   void addEdge(int i, int j)
   {
      adj[i].add(j);
      adj[j].add(i);
   }
}


import java.util.*;

public class D
{
   public static void main(String[] args)
   {
      new D(new Scanner(System.in));
   }

   boolean[] visited;
   int diam(Graph g, int i, int parent)
   {
      int max1 = 0;
      visited[i] = true;

      for (int j : g.adj[i])
      {
         if (j == parent) continue;

         int rr = diam(g, j, i);
         if (rr > max1)
            max1 = rr;
      }

      return max1+1;
   }

   public D(Scanner in)
   {
      int N = in.nextInt();
      Edge[] edges = new Edge[N];
      for (int a=1; a<N; a++)
      {
         int i = in.nextInt()-1;
         int j = in.nextInt()-1;
         edges[a] = new Edge(i, j);
      }

      // Find all paths to cut
      Graph g = new Graph(N);
      int[] cnt = new int[N];
      visited = new boolean[N];
      int res = 0;
      for (int j=1; j<N; j++)
      {
         g.clear();
         Arrays.fill(cnt, 0);
         Arrays.fill(visited, false);

         for (int i=1; i<N; i++)
         {
            if (i == j) continue;
            Edge e = edges[i];
            cnt[e.i]++;
            cnt[e.j]++;
            g.addEdge(e.i,e.j);
         }

         ArrayList<Integer> diams = new ArrayList<Integer>();
         for (int i=0; i<N; i++)
         {
            if (visited[i]) continue;
            if (cnt[i] != 1) continue;
            diams.add(diam(g, i, -1)-1);
         }
         Collections.sort(diams);

         int dn = diams.size();
         if (dn < 2) continue;
         int r2 = diams.get(dn-1)*diams.get(dn-2);
         res = Math.max(res, r2);
      }

      System.out.println(res);
   }
}

class Graph
{
   ArrayList<Integer>[] adj;
   int N;

   public Graph(int n)
   {
      N = n;
      adj = new ArrayList[N];
      for (int i=0; i<N; i++)
         adj[i] = new ArrayList();
   }

   void clear()
   {
      for (ArrayList<Integer> a : adj)
         a.clear();
   }

   void addEdge(int i, int j)
   {
      adj[i].add(j);
      adj[j].add(i);
   }
}

class Edge
{
   int i, j;

   public Edge(int a, int b)
   {
      i=a; j=b;
   }
}


import java.util.*;

public class D
{
   public static void main(String[] args)
   {
      new D(new Scanner(System.in));
   }

   int furthest;
   int fdist;
   void dfs(Graph g, int i, int parent, int dist)
   {
      visited[i] = true;
      if (dist > fdist)
      {
         furthest = i;
         fdist = dist;
      }

      for (int j : g.adj[i])
         if (j != parent)
            dfs(g, j, i, dist+1);
   }

   boolean[] visited;
   int diam(Graph g, int i)
   {
      int max1 = 0;
      furthest = -1;
      fdist = -1;
      dfs(g, i, -1, 0);
      dfs(g, furthest, -1, 0);
      return fdist;
   }

   public D(Scanner in)
   {
      int N = in.nextInt();
      Edge[] edges = new Edge[N];
      for (int a=1; a<N; a++)
      {
         int i = in.nextInt()-1;
         int j = in.nextInt()-1;
         edges[a] = new Edge(i, j);
      }

      // Find all paths to cut
      Graph g = new Graph(N);
      int[] cnt = new int[N];
      visited = new boolean[N];
      int res = 0;
      for (int j=1; j<N; j++)
      {
         g.clear();
         Arrays.fill(cnt, 0);
         Arrays.fill(visited, false);

         for (int i=1; i<N; i++)
         {
            if (i == j) continue;
            Edge e = edges[i];
            cnt[e.i]++;
            cnt[e.j]++;
            g.addEdge(e.i,e.j);
         }

         ArrayList<Integer> diams = new ArrayList<Integer>();
         for (int i=0; i<N; i++)
         {
            if (visited[i]) continue;
            if (cnt[i] != 1) continue;
            int d = diam(g, i);
            diams.add(d);
         }
         Collections.sort(diams);
         int dn = diams.size();
         if (dn < 2) continue;
         int r2 = diams.get(dn-1)*diams.get(dn-2);
         res = Math.max(res, r2);
      }

      System.out.println(res);
   }
}

class Graph
{
   ArrayList<Integer>[] adj;
   int N;

   public Graph(int n)
   {
      N = n;
      adj = new ArrayList[N];
      for (int i=0; i<N; i++)
         adj[i] = new ArrayList();
   }

   void clear()
   {
      for (ArrayList<Integer> a : adj)
         a.clear();
   }

   void addEdge(int i, int j)
   {
      adj[i].add(j);
      adj[j].add(i);
   }
}

class Edge
{
   int i, j;

   public Edge(int a, int b)
   {
      i=a; j=b;
   }

   public String toString()
   {
      return (i+1)+"<->"+(j+1);
   }
}


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;

public class D {
    static boolean[] visited;
    static int[] L;
    static LinkedList<Integer>[] E;

    public static int dfs(int x) {
        if (visited[x])
            return 0;
        visited[x] = true;
        int max = 0;
        int maxP1 = -2;
        int maxP2 = -2;
        for (int y : E[x]) {
            max = Math.max(max, dfs(y));
            if (L[y] > maxP1) {
                maxP2 = maxP1;
                maxP1 = L[y];
            } else if (L[y] > maxP2)
                maxP2 = L[y];
        }
        L[x] = 0;
        for (int y : E[x])
            L[x] = Math.max(L[x], L[y] + 1);
        max = Math.max(max, L[x]);
        return Math.max(max, maxP1 + maxP2 + 2);
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        E = new LinkedList[n];
        int[][] P = new int[n][n];
        for (int i = 0; i < n; i++) {
            Arrays.fill(P[i], 2 * n);
            P[i][i] = 0;
            E[i] = new LinkedList<Integer>();
        }
        for (int i = 0; i < n - 1; i++) {
            int x = in.nextInt() - 1;
            int y = in.nextInt() - 1;
            P[x][y] = P[y][x] = 1;
            E[x].add(y);
            E[y].add(x);
        }
        int[][] prev = new int[n][n];
        for (int i = 0; i < n; i++)
            Arrays.fill(prev[i], i);
        for (int k = 0; k < n; k++)
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    if (P[i][k] + P[k][j] < P[i][j]) {
                        P[i][j] = P[i][k] + P[k][j];
                        prev[i][j] = prev[k][j];
                    }
        int ans = 0;
        for (int i = 0; i < n; i++)
            for (int j = i + 1; j < n; j++) {
                visited = new boolean[n];
                int start = j;
                while (start != i) {
                    visited[start] = true;
                    start = prev[i][start];
                }
                visited[i] = true;
                L = new int[n];
                Arrays.fill(L, -5);
                int p1 = P[i][j];
                int p2 = 0;
                for (int k = 0; k < n; k++)
                    p2 = Math.max(p2, dfs(k));
                ans = Math.max(ans, p1 * p2);
            }
        System.out.println(ans);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class D {
    public static void main(String[] args) {
        new D().solve();
    }

    private int dfs(int x, int[] a, int[] b, boolean[] v, boolean[] pv) {
        int res = 0;
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            v[i] = false;
            pv[a[i]] = false;
            pv[b[i]] = false;
            res = Math.max(res, dfs(x, a, b, v, pv) + 1);
            v[i] = true;
            pv[a[i]] = true;
            pv[b[i]] = true;
            pv[x] = false;
        }

        return res;
    }

    public void solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n-1];
        int[] b = new int[n-1];
        for (int i=0; i<n-1; i++) {
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
        }

        int res = -1000;
        for (int i=0; i<n-1; ++i) {
            boolean[] v = new boolean[n-1];
            Arrays.fill(v, true);
            boolean[] pv = new boolean[n+1];
            Arrays.fill(pv, true);
            v[i] = false;
            pv[a[i]] = pv[b[i]] = false;

            int a1 = dfs(a[i], a, b, v, pv);
            int b1 = dfs(b[i], a, b, v, pv);
            if (res < a1*b1)
                res = a1*b1;
        }
        System.out.println(res);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class D {
    public static void main(String[] args) {
        new D().solve();
    }

    private void dfs(int x, int[] a, int[] b, boolean[] v, boolean[] pv) {
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            int next = a[i] == x ? b[i] : a[i];
            v[i] = false;
            pv[next] = false;
            dfs(next, a, b, v, pv);
            v[i] = true;
        }
    }

    private int dfs2(int x, int[] a, int[] b, boolean[] v) {
        int res = 0;
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            int next = a[i] == x ? b[i] : a[i];
            v[i] = false;
            res = Math.max(res, dfs2(next, a, b, v)+1);
            v[i] = true;
        }
        return res;
    }

    public void solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n-1];
        int[] b = new int[n-1];
        for (int i=0; i<n-1; i++) {
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
        }

        int res = -1000;
        for (int i=0; i<n-1; ++i) {
            boolean[] v = new boolean[n-1];
            Arrays.fill(v, true);
            v[i] = false;
            boolean[] pv = new boolean[n+1];
            Arrays.fill(pv, true);
            pv[a[i]] = false;
            dfs(a[i], a, b, v, pv);
            int s1 = 0;
            for (int j=1; j<n+1; ++j) if (!pv[j]) {
                Arrays.fill(v, true);
                v[i] = false;
                s1 = Math.max(s1, dfs2(j, a, b, v));
            }

//          Arrays.fill(v, true);
//          v[i] = false;
//          Arrays.fill(pv, true);
//          pv[b[i]] = false;
//          dfs(b[i], a, b, v, pv);
            int s2 = 0;
            for (int j=1; j<n+1; ++j) if (pv[j]) {
                Arrays.fill(v, true);
                v[i] = false;
                s2 = Math.max(s2, dfs2(j, a, b, v));
            }
            if (res < s1*s2)
                res = s1*s2;
        }
        System.out.println(res);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class D {
    public static void main(String[] args) {
        new D().solve();
    }

    private void dfs(int x, int[] a, int[] b, boolean[] v, boolean[] pv) {
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            int next = a[i] == x ? b[i] : a[i];
            v[i] = false;
            pv[next] = false;
            dfs(next, a, b, v, pv);
            v[i] = true;
        }
    }

    private int dfs2(int x, int[] a, int[] b, boolean[] v) {
        int res = 0;
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            int next = a[i] == x ? b[i] : a[i];
            v[i] = false;
            res = Math.max(res, dfs2(next, a, b, v)+1);
            v[i] = true;
        }
        return res;
    }

    public void solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n-1];
        int[] b = new int[n-1];
        for (int i=0; i<n-1; i++) {
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
        }

        int res = -1000;
        for (int i=0; i<n-1; ++i) {
            boolean[] v = new boolean[n-1];
            Arrays.fill(v, true);
            v[i] = false;
            boolean[] pv = new boolean[n+1];
            Arrays.fill(pv, true);
            pv[a[i]] = false;
            dfs(a[i], a, b, v, pv);
            int s1 = 0;
            for (int j=1; j<n+1; ++j) if (!pv[j]) {
                Arrays.fill(v, true);
                v[i] = false;
                s1 = Math.max(s1, dfs2(j, a, b, v));
            }

            Arrays.fill(v, true);
            v[i] = false;
            Arrays.fill(pv, true);
            pv[b[i]] = false;
            dfs(b[i], a, b, v, pv);
            int s2 = 0;
            for (int j=1; j<n+1; ++j) if (!pv[j]) {
                Arrays.fill(v, true);
                v[i] = false;
                s2 = Math.max(s2, dfs2(j, a, b, v));
            }
            if (res < s1*s2)
                res = s1*s2;
        }
        System.out.println(res);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class D {
    public static void main(String[] args) {
        new D().solve();
    }

    private int dfs(int x, int[] a, int[] b, boolean[] v) {
        int res = 0;
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            v[i] = false;
            res = Math.max(res, dfs(x, a, b, v) + 1);
            v[i] = true;
        }

        return res;
    }

    public void solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n-1];
        int[] b = new int[n-1];
        for (int i=0; i<n-1; i++) {
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
        }

        int res = -1000;
        for (int i=0; i<n-1; ++i) {
            boolean[] v = new boolean[n-1];
            Arrays.fill(v, true);
            v[i] = false;

            int a1 = dfs(a[i], a, b, v);
            int b1 = dfs(b[i], a, b, v);
            if (res < a1*b1)
                res = a1*b1;
        }
        System.out.println(res);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class D {
    public static void main(String[] args) {
        new D().solve();
    }

    private void dfs(int x, int[] a, int[] b, boolean[] v, boolean[] pv) {
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            v[i] = false;
            pv[a[i]] = pv[b[i]] = false;
            dfs(x, a, b, v, pv);
            v[i] = true;
        }
    }

    private int dfs2(int x, int[] a, int[] b, boolean[] v) {
        int res = 0;
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            v[i] = false;
            res = Math.max(res, dfs2(x, a, b, v)+1);
            v[i] = true;
        }
        return res;
    }

    public void solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n-1];
        int[] b = new int[n-1];
        for (int i=0; i<n-1; i++) {
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
        }

        int res = -1000;
        for (int i=0; i<n-1; ++i) {
            boolean[] v = new boolean[n-1];
            Arrays.fill(v, true);
            v[i] = false;
            boolean[] pv = new boolean[n+1];
            Arrays.fill(pv, true);
            pv[a[i]] = false;
            dfs(a[i], a, b, v, pv);
            int s1 = 0;
            for (int j=1; j<n+1; ++j) if (!pv[j]) {
                Arrays.fill(v, true);
                v[i] = false;
                s1 = Math.max(s1, dfs2(j, a, b, v));
            }

            Arrays.fill(pv, true);
            pv[b[i]] = false;
            dfs(b[i], a, b, v, pv);
            int s2 = 0;
            for (int j=1; j<n+1; ++j) if (!pv[j]) {
                Arrays.fill(v, true);
                v[i] = false;
                s2 = Math.max(s2, dfs2(j, a, b, v));
            }
            if (res < s1*s2)
                res = s1*s2;
        }
        System.out.println(res);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class D {
    public static void main(String[] args) {
        new D().solve();
    }

    private void dfs(int x, int[] a, int[] b, boolean[] v, boolean[] pv) {
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            v[i] = false;
            pv[a[i]] = pv[b[i]] = false;
            dfs(x, a, b, v, pv);
            v[i] = true;
        }
    }

    private int dfs2(int x, int[] a, int[] b, boolean[] v) {
        int res = 0;
        for (int i=0; i<a.length; ++i) if (v[i] && (a[i] == x || b[i] == x)){
            v[i] = false;
            res = Math.max(res, dfs2(x, a, b, v)+1);
            v[i] = true;
        }
        return res;
    }

    public void solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n-1];
        int[] b = new int[n-1];
        for (int i=0; i<n-1; i++) {
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
        }

        int res = -1000;
        for (int i=0; i<n-1; ++i) {
            boolean[] v = new boolean[n-1];
            Arrays.fill(v, true);
            v[i] = false;
            boolean[] pv = new boolean[n+1];
            Arrays.fill(pv, true);
            pv[a[i]] = false;
            dfs(a[i], a, b, v, pv);
            int s1 = 0;
            for (int j=1; j<n+1; ++j) if (!pv[j]) {
                Arrays.fill(v, true);
                v[i] = false;
                s1 = Math.max(s1, dfs2(j, a, b, v));
            }

            Arrays.fill(v, true);
            v[i] = false;
            Arrays.fill(pv, true);
            pv[b[i]] = false;
            dfs(b[i], a, b, v, pv);
            int s2 = 0;
            for (int j=1; j<n+1; ++j) if (!pv[j]) {
                Arrays.fill(v, true);
                v[i] = false;
                s2 = Math.max(s2, dfs2(j, a, b, v));
            }
            if (res < s1*s2)
                res = s1*s2;
        }
        System.out.println(res);
    }
}


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;

public class D14 {
	public static void main(String[] args) {
		new D14().solve();
	}

	LinkedList<Integer> ct[];
	int[] d;
	public void solve() {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		ct = new LinkedList[n];
		for (int i=0; i<n; ++i)
			ct[i] = new LinkedList<Integer>();

		for (int i=1; i<n; i++) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			ct[a-1].add(b-1);
			ct[b-1].add(a-1);
		}

		int res = 0;
		boolean[] m = new boolean[n];
		d = new int[n];
		for (int i=0; i<n; ++i)
			for (int j=0; j<ct[i].size(); ++j) if (ct[i].get(j) > i) {
				Arrays.fill(m, false);
				m[i] = true;
				Arrays.fill(d, 0);
				dfs(ct[i].get(j), m, 0);
				int t = 0;
				int w = 0;
				for (int k=0; k<n; ++k)
					if (d[k] > t) {
						t = d[k];
						w = k;
					}
				Arrays.fill(m, false);
				m[i] = true;
				int m1 = 0;
				if (d[w] != 0)
					m1 = dfs(w, m, 0);

				Arrays.fill(m, false);
				m[ct[i].get(j)] = true;
				Arrays.fill(d, 0);
				dfs(i, m, 0);
				t = w = 0;
				for (int k=0; k<n; ++k) if (d[k] > t)
				{
					t = d[k];
					w = k;
				}
				Arrays.fill(m, false);
				m[ct[i].get(j)] = true;
				int m2 = 0;
				if (d[w] != 0)
					m2 = dfs(w, m, 0);
				if (res < m1*m2)
					res = m1 * m2;
			}
		System.out.println(res);
	}

	private int dfs(int n, boolean[] m, int depth) {
		int res = 0;
		m[n] = true;
		d[n] = depth;
		for (int i=0; i<ct[n].size(); ++i) if (!m[ct[n].get(i)])
			res = Math.max(res, dfs(ct[n].get(i), m, depth+1) + 1);
		m[n] = false;
		return res;
	}
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class TwoWays {
	static BufferedReader reader;
	static StringTokenizer tokenizer;
	static ArrayList<Integer> childs[];
	static ArrayList<Integer> al[];
	static int max_depth[][];
	static int max_chain[][];
	static void dfs(int v, boolean used[]) {
		if (used[v])
			return;
		used[v] = true;
		for (int i = 0; i < al[v].size(); ++i) {
			int v2 = al[v].get(i);
			if (!used[v2]) {
				childs[v].add(v2);
				dfs(v2, used);
			}
		}
	}
	public static void main(String[] args) throws IOException {
		  reader = new BufferedReader(new InputStreamReader(System.in));
		  int n = NextInt();
		  al = new ArrayList[n];
		  childs = new ArrayList[n];
		  for (int i = 0; i < n; ++i) {
			  al[i] = new ArrayList<Integer>();
			  childs[i] = new ArrayList<Integer>();
		  }
		  for (int i = 0; i < n - 1; ++i) {
			  int a = NextInt() - 1;
			  int b = NextInt() - 1;
			  al[a].add(b);
			  al[b].add(a);
		  }
		  boolean used[] = new boolean[n];
		  dfs(0, used);
		  max_depth = new int[n][n];
		  max_chain = new int[n][n];
		  for (int i = 0; i < n; ++i)
			  for (int j = 0; j < n; ++j)
				  max_depth[i][j] = -1;
		  for (int i = 0; i < n; ++i)
			  for (int j = 0; j < n; ++j)
				  max_chain[i][j] = -1;
		  int res = 0;
		  for (int i = 0; i < n; ++i)
			  for (int j = i + 1; j < n; ++j) {
				  res = Math.max(res, CountMaxChain(i, j) * CountMaxChain(j, i));
			  }
		  System.out.println(res);
	}
	private static int CountMaxChain(int root, int without) {
		if (max_chain[root][without] >= 0)
			return max_chain[root][without] ;
		max_chain[root][without] = 0;
		for (int i = 0; i < childs[root].size(); ++i) {
			int v2 = childs[root].get(i);
			if (v2 != without) {
				max_chain[root][without] = Math.max(max_chain[root][without], 1 + CountMaxDepth(v2, without));
			}
		}
		for (int i = 0; i < childs[root].size(); ++i)
			for (int j = i + 1; j < childs[root].size(); ++j)
			{
				int v2 = childs[root].get(i);
				int v3 = childs[root].get(j);
				if (v2 != without && v3 != without)
					max_chain[root][without] = Math.max(max_chain[root][without], 2 + CountMaxDepth(v2, without) + CountMaxDepth(v3, without));
			}
		return max_chain[root][without];
	}
	private static int CountMaxDepth(int a, int without) {
		if (childs[a].size() == 0) return 0;
		if (max_depth[a][without] >= 0)
			return max_depth[a][without];
		max_depth[a][without] = 0;
		for (int i = 0; i < childs[a].size(); ++i) {
			int v2 = childs[a].get(i);
			if (v2 != without)
				max_depth[a][without] = Math.max(max_depth[a][without], 1 + CountMaxDepth(v2, without));
		}
		return max_depth[a][without];
	}
	static int NextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(NextToken());
	}
	static double NextDouble() throws NumberFormatException, IOException {
		return Double.parseDouble(NextToken());
	}
	static long NextLong() throws NumberFormatException, IOException {
		return Long.parseLong(NextToken());
	}
	static String NextToken() throws IOException {
		while(tokenizer == null || !tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class ProblemD {

	static boolean[][] graph;

	static final int INF = 1000000;

	public static void main(String[] args) throws IOException {
		BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(System.out);

		int n = Integer.valueOf(s.readLine());
		graph = new boolean[n][n];

		for (int i = 0; i < n - 1 ; i++) {
			String[] data = s.readLine().split(" ");
			int a = Integer.valueOf(data[0])-1;
			int b = Integer.valueOf(data[1])-1;
			graph[a][b] = graph[b][a] = true;
		}

		int ans = 0;
		for (int i = 0 ; i < n ; i++) {
			for (int j = i+1 ; j < n ; j++) {
				if (graph[i][j]) {
					graph[i][j] = false;
					graph[j][i] = false;
					ans = Math.max(ans, doit(i) * doit(j));
					graph[i][j] = true;
					graph[j][i] = true;
				}
			}
		}

		out.println(ans);
		out.flush();
	}

	private static int doit(int i) {
		return farthest(farthest(i)[0])[1];
	}

	private static int[] farthest(int from) {
		int n = graph.length;
		int[] dp = new int[n];
		Arrays.fill(dp, INF);
		dp[from] = 0;
		Queue<Integer> q = new ArrayBlockingQueue<Integer>(10000);
		q.add(from);
		q.add(0);
		while (q.size() >= 1) {
			int now = q.poll();
			int time = q.poll();
			for (int next = 0 ; next < n ; next++) {
				if (graph[now][next] && dp[next] > time+1) {
					dp[next] = time+1;
					q.add(next);
					q.add(time+1);
				}
			}
		}

		int max = -1;
		int maxid = -1;
		for (int i = 0 ; i < n ; i++) {
			if (dp[i] < INF && max < dp[i]) {
				max = dp[i];
				maxid = i;
			}
		}
		return new int[]{maxid, max};
	}

	public static void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}
}


import java.io.*;
import java.util.*;

public class Main implements Runnable {

	public void _main() throws IOException {
		int n = nextInt();
		int[] a = new int[n];
		int[] b = new int[n];
		for (int i = 0; i < n - 1; i++) {
			a[i] = nextInt() - 1;
			b[i] = nextInt() - 1;
		}
		int res = 0;
		for (int i = 0; i < n - 1; i++) {
			List[] graph = new List[n];
			for (int j = 0; j < n; j++)
				graph[j] = new ArrayList<Integer>();
			for (int j = 0; j < n - 1; j++)
				if (i != j) {
					graph[a[j]].add(b[j]);
					graph[b[j]].add(a[j]);
				}
			List<Integer> d = diameters(n, graph);
			if (d.size() >= 2)
				res = Math.max(res, d.get(d.size() - 1) * d.get(d.size() - 2));
		}
		out.print(res);
	}

	void bfs(int n, List[] graph, int start, int[] dist, int[] prev, List<Integer> comp) {
		dist[start] = 1;
		int[] q = new int[n];
		q[0] = start;
		int qt = 0, qh = 1;
		while (qt < qh) {
			int v = q[qt++];
			comp.add(v);
			for (int i = 0; i < graph[v].size(); i++) {
				int u = (Integer)graph[v].get(i);
				if (dist[u] == 0) {
					dist[u] = 1 + dist[v];
					prev[u] = v;
					q[qh++] = u;
				}
			}
		}
	}

	List<Integer> diameters(int n, List[] graph) { //the largest diameter of a connected component
		boolean[] was = new boolean[n];
		int[] dist = new int[n];
		int[] prev = new int[n];
		List<Integer> res = new ArrayList<Integer>();
		for (int i = 0; i < n; i++)
			if (dist[i] == 0) {
				List<Integer> comp = new ArrayList<Integer>();
				bfs(n, graph, i, dist, prev, comp);
				int best = 0;
				int bestAt = -1;
				for (int x : comp) {
					if (dist[x] > best) {
						best = dist[x];
						bestAt = x;
					}
					dist[x] = 0;
					prev[x] = 0;
				}
				comp = new ArrayList<Integer>();
				bfs(n, graph, bestAt, dist, prev, comp);
				int cur = 0;
				for (int x : comp)
					cur = Math.max(cur, dist[x] - 1);
				res.add(cur);
			}
		return res;
	}

	private BufferedReader in;
	private PrintWriter out;
	private StringTokenizer st;

	private String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	private int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	private long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	private double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public static void main(String[] args) {
		new Thread(new Main()).start();
	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);

			_main();

			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(202);
		}
	}

}


import java.io.*;
import java.util.*;

public class Main implements Runnable {

	public void _main() throws IOException {
		int n = nextInt();
		int[] a = new int[n];
		int[] b = new int[n];
		List[] graph = new List[n];
		for (int i = 0; i < n; i++)
			graph[i] = new ArrayList<Integer>();
		for (int i = 0; i < n - 1; i++) {
			a[i] = nextInt() - 1;
			b[i] = nextInt() - 1;
			graph[a[i]].add(b[i]);
			graph[b[i]].add(a[i]);
		}
		int res = 0;
		for (int i = 0; i < n; i++) {
			int[] dist = new int[n];
			int[] prev = new int[n];
			List<Integer> dummy = new ArrayList<Integer>();
			bfs(n, graph, i, dist, prev, dummy);
			for (int j = 0; j < n; j++) {
				if (i == j) continue;
				List[] edges = new List[n];
				for (int k = 0; k < n; k++)
					edges[k] = new ArrayList<Integer>();
				boolean[] dead = new boolean[n];
				dead[i] = true;
				for (int k = j; k != i; k = prev[k])
					dead[k] = true;
				for (int k = 0; k < n; k++)
					if (!dead[a[k]] && !dead[b[k]]) {
						edges[a[k]].add(b[k]);
						edges[b[k]].add(a[k]);
					}
				res = Math.max(res, (dist[j] - 1) * diameter(n, edges));
			}
		}
		out.print(res);
	}

	void bfs(int n, List[] graph, int start, int[] dist, int[] prev, List<Integer> comp) {
		dist[start] = 1;
		int[] q = new int[n];
		q[0] = start;
		int qt = 0, qh = 1;
		while (qt < qh) {
			int v = q[qt++];
			comp.add(v);
			for (int i = 0; i < graph[v].size(); i++) {
				int u = (Integer)graph[v].get(i);
				if (dist[u] == 0) {
					dist[u] = 1 + dist[v];
					prev[u] = v;
					q[qh++] = u;
				}
			}
		}
	}

	int diameter(int n, List[] graph) { //the largest diameter of a connected component
		boolean[] was = new boolean[n];
		int[] dist = new int[n];
		int[] prev = new int[n];
		int res = 0;
		for (int i = 0; i < n; i++)
			if (dist[i] == 0) {
				List<Integer> comp = new ArrayList<Integer>();
				bfs(n, graph, i, dist, prev, comp);
				int best = 0;
				int bestAt = -1;
				for (int x : comp) {
					if (dist[x] > best) {
						best = dist[x];
						bestAt = x;
					}
					dist[x] = 0;
					prev[x] = 0;
				}
				comp = new ArrayList<Integer>();
				bfs(n, graph, bestAt, dist, prev, comp);
				for (int x : comp)
					res = Math.max(res, dist[x] - 1);
			}
		return res;
	}

	private BufferedReader in;
	private PrintWriter out;
	private StringTokenizer st;

	private String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	private int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	private long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	private double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public static void main(String[] args) {
		new Thread(new Main()).start();
	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);

			_main();

			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(202);
		}
	}

}


import java.awt.Point;
import java.util.ArrayList;
import java.util.Scanner;

public class D {
    static ArrayList<ArrayList<Integer>> grid;
    static int maxDepth, maxIdx, forbidden;

    public static void dfs(int cur, int parent, int depth) {
        if (depth > maxDepth) {
            maxDepth = depth;
            maxIdx = cur;
        }
        for (Integer I : grid.get(cur)) {
            if (I != parent && I != forbidden) {
                dfs(I, cur, depth + 1);
            }
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        grid = new ArrayList<ArrayList<Integer>>();
        for (int i = 0; i < n; i++) {
            grid.add(new ArrayList<Integer>());
        }
        Point[] ar = new Point[n - 1];
        for (int i = 1; i < n; i++) {
            int f = sc.nextInt() - 1;
            int s = sc.nextInt() - 1;
            grid.get(f).add(s);
            grid.get(s).add(f);
            ar[i-1] = new Point(f, s);
        }
        int max = 0;
        for (int i = 0; i < ar.length; i++) {
            maxDepth = -1;
            forbidden = -1;
            dfs(ar[i].x, ar[i].y, 0);
            //System.out.println(maxIdx+" "+maxDepth);
            maxDepth = -1;
            forbidden = ar[i].y;
            dfs(maxIdx, -1, 0);
            int fir = maxDepth;
            //System.out.println(maxIdx+" "+maxDepth);
            maxDepth = -1;
            forbidden = -1;
            dfs(ar[i].y, ar[i].x, 0);
            //System.out.println(maxIdx+" "+maxDepth+" "+ar[i].y+" "+ar[i].x);
            maxDepth = -1;
            forbidden = ar[i].x;

            dfs(maxIdx, -1, 0);
            //System.out.println(maxIdx+" "+maxDepth);
            int sec = maxDepth;
            //System.out.println(i+" "+fir+" "+sec);
            max = Math.max(max, fir * sec);
        }
        System.out.println(max);
    }
}


import java.io.*;
import java.math.*;
import java.util.*;

public class TwoPaths
{
	static Scanner in = new Scanner( new BufferedReader( new InputStreamReader( System.in ) ) );
	static int inf = 10001;

	public static void main( String[] args )
	{
		int n = in.nextInt(), m = n-1, e[][] = new int[m][2];
		HashSet<Integer>[] g = (HashSet<Integer>[])(new HashSet[n]);
		for( int i = 0; i < n; i++ ) g[i] = new HashSet<Integer>();
		for( int i = 0; i < m; i++ )
		{
			int a = in.nextInt()-1, b = in.nextInt()-1;
			g[a].add(b); g[b].add(a);
			e[i][0] = a; e[i][1] = b;
		}
		int ans = 0;
		for( int i = 0; i < m; i++ )
		{
			int a = e[i][0], b = e[i][1], maxa = 0, maxb = 0;
			g[a].remove(b); g[b].remove(a);
			for( int j = 0; j < n; j++ )
			{
				int[] d = new int[n];
				boolean[] seen = new boolean[n];
				LinkedList<Integer> q = new LinkedList<Integer>();
				q.add(j);
				seen[j] = true;
				while( !q.isEmpty() )
				{
					int ptr = q.poll();
					for( int c : g[ptr] )
					if( !seen[c] )
					{
						seen[c] = true;
						d[c] = d[ptr]+1;
						q.add(c);
					}
				}
				for( int k = 0; k < n; k++ )
				{
					if( seen[a] && d[k]>maxa ) maxa = d[k];
					if( seen[b] && d[k]>maxb ) maxb = d[k];
				}
			}
			g[a].add(b); g[b].add(a);
			if( maxa*maxb>ans ) ans = maxa*maxb;
		}
		System.out.println( ans );
	}
}


import java.util.*;

public class TwoPaths{
	static int[] dj;
	public static void main(String[] args){
		Scanner reader = new Scanner(System.in);
		int n = reader.nextInt();

		int[][] g = new int[n][n];
		Edge[] e = new Edge[n-1];

		for(int i = 0; i < n-1; i++){
			e[i] = new Edge(reader.nextInt()-1, reader.nextInt()-1);
			g[e[i].s][e[i].t] = 1;
			g[e[i].t][e[i].s] = 1;
		}

		int max = 0;
		for(int i = 0; i < n-1; i++){
			//System.out.println("Cutting " + i);
			g[e[i].s][e[i].t] = 0;
			g[e[i].t][e[i].s] = 0;

			//dfs the two halves
			//int p = dfs(e[i].s, e[i].s, g, new boolean[n]) * dfs(e[i].t, e[i].t, g, new boolean[n]);
			//max = Math.max(max, p);

			//System.out.println(max);

			dj = new int[n];

			for(int j = 0; j < n; j++)
				dj[j] = j;

			for(int j = 0; j < n; j++){
				for(int k = 0; k < n; k++){
					if(g[j][k] == 1)
						union(j,k);
				}
			}
			int min = n+1;

			for(int j = 0; j < n; j++)
				min = Math.min(min, find(j));

			int maxLeft = 0;
			int maxRight = 0;

			for(int j = 0; j < n; j++){
				//int[] d = new int[n];
				//Edge[] d = new Edge[n];
				ArrayList<Node<Edge>> d = new ArrayList<Node<Edge>>();
				//Node<Edge>[] d = new Node<Edge>[n];
				for(int k = 0; k < n; k++)
					d.add(new Node<Edge>(new Edge(k, (int)1e9), (int)1e9));
				//Arrays.fill(d, (int)1e9);
				d.get(j).data.t = 0;
				d.get(j).key = 0;

				FibonacciHeap<Edge> q = new FibonacciHeap<Edge>();
				boolean[] visited = new boolean[n];

				for(Node x:d)
					q.insert(x, x.key);

				while(!q.isEmpty()){
					Node<Edge> cur = q.removeMin();

					int c = cur.data.s;
					int p = cur.data.t;

					visited[c] = true;

					for(int k = 0; k < n; k++){
						if(g[c][k] == 1 && !visited[k]){
							if(d.get(k).data.t > p+1){
								d.get(k).data.t = p+1;
								q.decreaseKey(d.get(k), p+1);
							}
						}
					}
				}

				//take two longest paths on each side

				int maximus = 0;
				for(Node<Edge> x:d)
					if(x.data.t < (int)1e9)
						maximus = Math.max(maximus, x.data.t);

				if(find(j)==min){
					maxLeft = Math.max(maxLeft, maximus);
				}else{
					maxRight = Math.max(maxRight, maximus);
				}
			}

			max = Math.max(max, maxLeft*maxRight);

			g[e[i].s][e[i].t] = 1;
			g[e[i].t][e[i].s] = 1;
		}

		System.out.println(max);
	}

	public static void union(int s, int t){
		dj[find(s)] = find(t);
	}

	public static int find(int x){
		if(dj[x] == x){
			return x;
		}
		return dj[x] = find(dj[x]);
	}

	public static class Edge implements Comparable<Edge>{
		int s, t;
		public Edge(int _s, int _t){
			s = _s;
			t = _t;
		}

		public int compareTo(Edge e){
			return (int)Math.signum(t-e.t);
		}
	}

	public static class FibonacciHeap<T>{

		private static final double oneOverLogPhi =
        1.0 / Math.log((1.0 + Math.sqrt(5.0)) / 2.0);

		private Node<T> minNode;
    	private int nNodes;

		public FibonacciHeap(){
		}

		/**
     * Decreases the key value for a heap node, given the new value to take on.
     * The structure of the heap may be changed and will not be consolidated.
     *
     *
Running time: O(1) amortized

     *
     * @param x node to decrease the key of
     * @param k new key value for node x
     *
     * @exception IllegalArgumentException Thrown if k is larger than x.key
     * value.
     */
    public void decreaseKey(Node<T> x, int k)
    {
        if (k > x.key) {
            throw new IllegalArgumentException(
                "decreaseKey() got larger key value");
        }

        x.key = k;

        Node<T> y = x.parent;

        if ((y != null) && (x.key < y.key)) {
            cut(x, y);
            cascadingCut(y);
        }

        if (x.key < minNode.key) {
            minNode = x;
        }
    }

    // decreaseKey

    /**
     * Deletes a node from the heap given the reference to the node. The trees
     * in the heap will be consolidated, if necessary. This operation may fail
     * to remove the correct element if there are nodes with key value
     * -Infinity.
     *
     *
Running time: O(log n) amortized

     *
     * @param x node to remove from heap
     */
    public void delete(Node<T> x)
    {
        // make x as small as possible
        decreaseKey(x, -(int)1e9);

        // remove the smallest, which decreases n also
        removeMin();
    }

    // delete

    /**
     * Inserts a new data element into the heap. No heap consolidation is
     * performed at this time, the new node is simply inserted into the root
     * list of this heap.
     *
     *
Running time: O(1) actual

     *
     * @param node new node to insert into heap
     * @param key key value associated with data object
     */
    public void insert(Node<T> node, int key)
    {
        node.key = key;

        // concatenate node into min list
        if (minNode != null) {
            node.left = minNode;
            node.right = minNode.right;
            minNode.right = node;
            node.right.left = node;

            if (key < minNode.key) {
                minNode = node;
            }
        } else {
            minNode = node;
        }

        nNodes++;
    }

    // insert

    /**
     * Returns the smallest element in the heap. This smallest element is the
     * one with the minimum key value.
     *
     *
Running time: O(1) actual

     *
     * @return heap node with the smallest key
     */
    public Node<T> min()
    {
        return minNode;
    }

    // min

    /**
     * Removes the smallest element from the heap. This will cause the trees in
     * the heap to be consolidated, if necessary.
     *
     *
Running time: O(log n) amortized

     *
     * @return node with the smallest key
     */
    public Node<T> removeMin()
    {
        Node<T> z = minNode;

        if (z != null) {
            int numKids = z.degree;
            Node<T> x = z.child;
            Node<T> tempRight;

            // for each child of z do...
            while (numKids > 0) {
                tempRight = x.right;

                // remove x from child list
                x.left.right = x.right;
                x.right.left = x.left;

                // add x to root list of heap
                x.left = minNode;
                x.right = minNode.right;
                minNode.right = x;
                x.right.left = x;

                // set parent[x] to null
                x.parent = null;
                x = tempRight;
                numKids--;
            }

            // remove z from root list of heap
            z.left.right = z.right;
            z.right.left = z.left;

            if (z == z.right) {
                minNode = null;
            } else {
                minNode = z.right;
                consolidate();
            }

            // decrement size of heap
            nNodes--;
        }

        return z;
    }

    // removeMin

    /**
     * Returns the size of the heap which is measured in the number of elements
     * contained in the heap.
     *
     *
Running time: O(1) actual

     *
     * @return number of elements in the heap
     */
    public int size()
    {
        return nNodes;
    }

    // size

    /**
     * Joins two Fibonacci heaps into a new one. No heap consolidation is
     * performed at this time. The two root lists are simply joined together.
     *
     *
Running time: O(1) actual

     *
     * @param h1 first heap
     * @param h2 second heap
     *
     * @return new heap containing h1 and h2
     */
    public static <T> FibonacciHeap<T> union(
        FibonacciHeap<T> h1,
        FibonacciHeap<T> h2)
    {
        FibonacciHeap<T> h = new FibonacciHeap<T>();

        if ((h1 != null) && (h2 != null)) {
            h.minNode = h1.minNode;

            if (h.minNode != null) {
                if (h2.minNode != null) {
                    h.minNode.right.left = h2.minNode.left;
                    h2.minNode.left.right = h.minNode.right;
                    h.minNode.right = h2.minNode;
                    h2.minNode.left = h.minNode;

                    if (h2.minNode.key < h1.minNode.key) {
                        h.minNode = h2.minNode;
                    }
                }
            } else {
                h.minNode = h2.minNode;
            }

            h.nNodes = h1.nNodes + h2.nNodes;
        }

        return h;
    }

    /**
     * Performs a cascading cut operation. This cuts y from its parent and then
     * does the same for its parent, and so on up the tree.
     *
     *
Running time: O(log n); O(1) excluding the recursion

     *
     * @param y node to perform cascading cut on
     */
    protected void cascadingCut(Node<T> y)
    {
        Node<T> z = y.parent;

        // if there's a parent...
        if (z != null) {
            // if y is unmarked, set it marked
            if (!y.mark) {
                y.mark = true;
            } else {
                // it's marked, cut it from parent
                cut(y, z);

                // cut its parent as well
                cascadingCut(z);
            }
        }
    }

    // cascadingCut

    protected void consolidate()
    {
        int arraySize =
            ((int) Math.floor(Math.log(nNodes) * oneOverLogPhi)) + 1;

        List<Node<T>> array =
            new ArrayList<Node<T>>(arraySize);

        // Initialize degree array
        for (int i = 0; i < arraySize; i++) {
            array.add(null);
        }

        // Find the number of root nodes.
        int numRoots = 0;
        Node<T> x = minNode;

        if (x != null) {
            numRoots++;
            x = x.right;

            while (x != minNode) {
                numRoots++;
                x = x.right;
            }
        }

        // For each node in root list do...
        while (numRoots > 0) {
            // Access this node's degree..
            int d = x.degree;
            Node<T> next = x.right;

            // ..and see if there's another of the same degree.
            for (;;) {
                Node<T> y = array.get(d);
                if (y == null) {
                    // Nope.
                    break;
                }

                // There is, make one of the nodes a child of the other.
                // Do this based on the key value.
                if (x.key > y.key) {
                    Node<T> temp = y;
                    y = x;
                    x = temp;
                }

                // FibonacciHeapNode<T> y disappears from root list.
                link(y, x);

                // We've handled this degree, go to next one.
                array.set(d, null);
                d++;
            }

            // Save this node for later when we might encounter another
            // of the same degree.
            array.set(d, x);

            // Move forward through list.
            x = next;
            numRoots--;
        }

        // Set min to null (effectively losing the root list) and
        // reconstruct the root list from the array entries in array[].
        minNode = null;

        for (int i = 0; i < arraySize; i++) {
            Node<T> y = array.get(i);
            if (y == null) {
                continue;
            }

            // We've got a live one, add it to root list.
            if (minNode != null) {
                // First remove node from root list.
                y.left.right = y.right;
                y.right.left = y.left;

                // Now add to root list, again.
                y.left = minNode;
                y.right = minNode.right;
                minNode.right = y;
                y.right.left = y;

                // Check if this is a new min.
                if (y.key < minNode.key) {
                    minNode = y;
                }
            } else {
                minNode = y;
            }
        }
    }

		//Cut a child (x) from the child list of its parent (y)
		public void cut(Node<T> x, Node<T> y){
			//Remove x from the childlist of y, decrement y
			x.left.right = x.right;
			x.right.left = x.left;
			y.degree--;

			//Reset y if no more children
			if(y.child == x){
				y.child = x.right;
			}

			if(y.degree == 0){
				y.child = null;
			}

			//Add x to the root list
			x.left = minNode;
			x.right = minNode.right;
			minNode.right = x;
			x.right.left = x;

			x.parent = null;
			x.mark = false;
		}

		//Make y a child of x
		public void link(Node<T> y, Node<T> x){
			//Remove y from the root list
			y.left.right = y.right;
			y.right.left = y.left;

			y.parent = x;

			if(x.child == null){
				x.child = y;
				y.right = y;
				y.left = y;
			}else{
				y.left = x.child;
				y.right = x.child.right;
				x.child.right = y;
				y.right.left = y; //this is bananas
			}

			x.degree++;
			y.mark = false;
		}

		public boolean isEmpty(){
			return nNodes == 0;
		}

		public void clear(){
			minNode = null;
			nNodes = 0;
		}
	}

	public static class Node<T>{
		public T data;
		public Node<T> parent;
		public Node<T> left;
		public Node<T> right;
		public Node<T> child;
		public int degree,key; //number of children, key
		public boolean mark;

		public Node(T data, int key){
			left = this;
			right = this;
			this.data = data;
			this.key = key;
		}
	}
}


import java.util.*;

public class TwoPaths{
	public static void main(String[] args){
		Scanner reader = new Scanner(System.in);
		int n = reader.nextInt();

		int[][] g = new int[n][n];
		Edge[] e = new Edge[n-1];

		for(int i = 0; i < n-1; i++){
			e[i] = new Edge(reader.nextInt()-1, reader.nextInt()-1);
			g[e[i].s][e[i].t] = 1;
			g[e[i].t][e[i].s] = 1;
		}

		int max = 0;
		for(int i = 0; i < n-1; i++){
			g[e[i].s][e[i].t] = 0;
			g[e[i].t][e[i].s] = 0;

			//dfs the two halves
			int p = dfs(e[i].s, e[i].s, g, new boolean[n]) * dfs(e[i].t, e[i].t, g, new boolean[n]);
			max = Math.max(max, p);

			//System.out.println(max);

			g[e[i].s][e[i].t] = 1;
			g[e[i].t][e[i].s] = 1;
		}

		System.out.println(max);
	}

	public static int dfs(int s, int at, int[][] g, boolean[] visited){
		visited[at] = true;

		if(s==at){
			int[] d = new int[g.length];
			//int max = 0;
			for(int i = 0; i < g.length; i++){
				if(g[at][i] == 1 && !visited[i]){
					d[i] = 1+dfs(s, i, g, visited);
				}
			}
			Arrays.sort(d);
			return d[g.length-1]+d[g.length-2];
		}else{
			int max = 0;
			for(int i = 0; i < g.length; i++){
				if(g[at][i] == 1 && !visited[i]){
					max = Math.max(max, 1+dfs(s, i, g, visited));
				}
			}
			return max;
		}
	}

	public static class Edge{
		int s, t;
		public Edge(int _s, int _t){
			s = _s;
			t = _t;
		}
	}
}


import java.util.*;

public class TwoPaths{
	static int[] best;
	public static void main(String[] args){
		Scanner reader = new Scanner(System.in);
		int n = reader.nextInt();

		int[][] g = new int[n][n];
		Edge[] e = new Edge[n-1];

		for(int i = 0; i < n-1; i++){
			e[i] = new Edge(reader.nextInt()-1, reader.nextInt()-1);
			g[e[i].s][e[i].t] = 1;
			g[e[i].t][e[i].s] = 1;
		}

		int max = 0;
		for(int i = 0; i < n-1; i++){
			//System.out.println("Cutting " + i);
			g[e[i].s][e[i].t] = 0;
			g[e[i].t][e[i].s] = 0;

			//dfs the two halves

			best = new int[n];
			dfs(e[i].s, e[i].s, g, new boolean[n]);
			int maxLeft = 0;
			for(int j = 0; j < n; j++)
				maxLeft = Math.max(maxLeft, best[j]);
			best = new int[n];
			int maxRight = 0;
			dfs(e[i].t, e[i].t, g, new boolean[n]);
			for(int j = 0; j < n; j++)
				maxRight = Math.max(maxRight, best[j]);

			//int p = dfs(e[i].s, e[i].s, g, new boolean[n]) * dfs(e[i].t, e[i].t, g, new boolean[n]);
			//max = Math.max(max, p);

			int p = maxLeft*maxRight;
			max = Math.max(max, p);

			//System.out.println(max);

			g[e[i].s][e[i].t] = 1;
			g[e[i].t][e[i].s] = 1;
		}

		System.out.println(max);
	}

	public static int dfs(int s, int at, int[][] g, boolean[] visited){
		visited[at] = true;
		int[] d = new int[g.length];

		int max = 0;
		for(int i = 0; i < g.length; i++){
			if(g[at][i] == 1 && !visited[i]){
				d[i] = 1+dfs(s, i, g, visited);
				max = Math.max(max, d[i]);
			}
		}

		Arrays.sort(d);
		best[at] = d[g.length-1]+d[g.length-2];

		return max;
	}

	public static class Edge implements Comparable<Edge>{
		int s, t;
		public Edge(int _s, int _t){
			s = _s;
			t = _t;
		}

		public int compareTo(Edge e){
			return (int)Math.signum(t-e.t);
		}
	}
}


import java.util.*;
import java.util.regex.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.lang.Integer.*;
import static java.lang.Double.*;
import static java.util.Collections.*;

import java.awt.Point;
import java.io.*;

public class _14_D_Two_Paths {
	//->solution screencast http://youtu.be/oHg5SJYRHA0
	public void solve() {
		n = ni();
		m=new boolean[n][n];
		ArrayList<Point> roads = new ArrayList<Point>();
//		node root = new node();
		HashMap<Integer,node> map = new HashMap<Integer, _14_D_Two_Paths.node>();
		for (int i = 0; i < n-1; i++) {
			int a=ni()-1,b=ni()-1;
			roads.add(new Point(a,b));
			m[a][b]=m[b][a]=true;
//			if(map.containsKey(a)){
//				node anode=map.get(a);
//				if(map.containsKey(b)){
//					anode.add(map.get(b));
//				}else{
//					node bnode = new node(b);
//					anode.add(bnode);
//				}
//			}else{
//				node anode=new node(a);
//				if(map.containsKey(b)){
//					anode.add(map.get(b));
//				}else{
//					node bnode = new node(b);
//					anode.add(bnode);
//				}
//			}
		}
//		pr(left);
		int max=0;
		for (int i = 0; i < n-1 ; i++) {
			int a = roads.get(i).x;
			int b = roads.get(i).y;
			m[a][b]=m[b][a]=false;
			ArrayList<Integer> sa = new ArrayList<Integer>();
			boolean [] me = new boolean[n];
//			me[a]=true;
			getNe(a,me,sa);
			int dp[]=new int[n];
			fill(dp,-1);
			int maxa=0;
			for (int j = 0; j < sa.size(); j++) {
				maxa=max(maxa,go(sa.get(j),new boolean[n]));
			}
			ArrayList<Integer> sb = new ArrayList<Integer>();
			me = new boolean[n];
//			me[b]=true;
			getNe(b,me,sb);

			int maxb=0;
			dp=new int[n];
			fill(dp,-1);
			for (int j = 0; j < sb.size(); j++) {
				maxb=max(maxb,go(sb.get(j),new boolean[n]));
			}
			pr(sa,sb);
			pr(maxa,maxb);
//			pr();
			max=max(max,maxa*maxb);
			m[a][b]=m[b][a]=true;
		}
		out.println(max);
	}
	boolean [][]m;
	int []left;
	int []right;
	int n;

	void getNe(int i, boolean vis[], ArrayList<Integer> s){
		s.add(i);
		vis[i]=true;
		for (int j = 0; j < m.length; j++) {
				if(j!=i && m[i][j] && !vis[j] ){
//					vis[j]=true;
//					s.add(j);
					getNe(j, vis, s);
				}
		}
	}

	int go(int i,boolean memo[]){
		memo[i]=true;
//		if(dp[i][clock]!=-1)
//			return dp[i][clock];
		int r=0;
		for (int j= 0; j < n; j++) {
			if(j!=i && m[i][j] && !memo[j]){
//				memo[i][j]=true;
				r = max(r,1+go(j,memo));
			}
		}
		return r;
	}

	class node{
		public node(int n) {
			this.idx=n;
		}
		int idx;
		Set<node> neis=new  HashSet<_14_D_Two_Paths.node>();
		void add(node n){
			neis.add(n);
		}

		@Override
		public boolean equals(Object obj) {
			node b = (node)obj;
			return idx==b.idx;
		}
	}

	// IO methods

	void run() throws Exception {
		long s = System.currentTimeMillis();
		solve();
		out.flush();
		pr(System.currentTimeMillis() - s + "ms");
	}
	public static void main(String[] args) throws Exception {new _14_D_Two_Paths().run();}

	InputStream in=System.in;
	PrintWriter out=new PrintWriter(System.out);

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = in.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {return !(c >= 33 && c <= 126);}
	private int skip() {int b;while ((b = readByte()) != -1 && isSpaceChar(b));return b;}

	public String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != // ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	public char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	public char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	public int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	public int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	public long nl(){
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}
		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	void pr(Object... ob) {if (!oj)System.out.println(Arrays.deepToString(ob).replace("],", "],\n"));}
}


import java.util.*;
import java.util.regex.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.lang.Integer.*;
import static java.lang.Double.*;
import static java.util.Collections.*;

import java.awt.Point;
import java.io.*;

public class _14_D_Two_Paths {
	//->solution screencast http://youtu.be/oHg5SJYRHA0
	public void solve() {
		n = ni();
		m=new boolean[n][n];
		ArrayList<Point> roads = new ArrayList<Point>();
//		node root = new node();
		HashMap<Integer,node> map = new HashMap<Integer, _14_D_Two_Paths.node>();
		for (int i = 0; i < n-1; i++) {
			int a=ni()-1,b=ni()-1;
			roads.add(new Point(a,b));
			m[a][b]=m[b][a]=true;
//			if(map.containsKey(a)){
//				node anode=map.get(a);
//				if(map.containsKey(b)){
//					anode.add(map.get(b));
//				}else{
//					node bnode = new node(b);
//					anode.add(bnode);
//				}
//			}else{
//				node anode=new node(a);
//				if(map.containsKey(b)){
//					anode.add(map.get(b));
//				}else{
//					node bnode = new node(b);
//					anode.add(bnode);
//				}
//			}
		}
//		pr(left);
		int max=0;
		for (int i = 0; i < n-1 ; i++) {
			int a = roads.get(i).x;
			int b = roads.get(i).y;
			m[a][b]=m[b][a]=false;
			ArrayList<Integer> sa = new ArrayList<Integer>();
			boolean [] me = new boolean[n];
//			me[a]=true;
			getNe(a,me,sa);
			int dp[]=new int[n];
			fill(dp,-1);
			int maxa=0;
			for (int j = 0; j < sa.size(); j++) {
				maxa=max(maxa,go(sa.get(j),dp,new boolean[n]));
			}
			ArrayList<Integer> sb = new ArrayList<Integer>();
			me = new boolean[n];
//			me[b]=true;
			getNe(b,me,sb);

			int maxb=0;
			dp=new int[n];
			fill(dp,-1);
			for (int j = 0; j < sb.size(); j++) {
				maxb=max(maxb,go(sb.get(j),dp,new boolean[n]));
			}
			pr(sa,sb);
			pr(maxa,maxb);
//			pr();
			max=max(max,maxa*maxb);
			m[a][b]=m[b][a]=true;
		}
		out.println(max);
	}
	boolean [][]m;
	int []left;
	int []right;
	int n;

	void getNe(int i, boolean vis[], ArrayList<Integer> s){
		s.add(i);
		vis[i]=true;
		for (int j = 0; j < m.length; j++) {
				if(j!=i && m[i][j] && !vis[j] ){
//					vis[j]=true;
//					s.add(j);
					getNe(j, vis, s);
				}
		}
	}

	int go(int i, int []dp, boolean memo[]){
		memo[i]=true;
		if(dp[i]!=-1)
			return dp[i];
		int r=0;
		for (int j = 0; j < n; j++) {
			if(i!=j && m[i][j] && !memo[j]){
//				memo[i][j]=true;
				r = 1+max(r,go(j,dp,memo));
			}
		}
		return dp[i]=r;
	}

	class node{
		public node(int n) {
			this.idx=n;
		}
		int idx;
		Set<node> neis=new  HashSet<_14_D_Two_Paths.node>();
		void add(node n){
			neis.add(n);
		}

		@Override
		public boolean equals(Object obj) {
			node b = (node)obj;
			return idx==b.idx;
		}
	}

	// IO methods

	void run() throws Exception {
		long s = System.currentTimeMillis();
		solve();
		out.flush();
		pr(System.currentTimeMillis() - s + "ms");
	}
	public static void main(String[] args) throws Exception {new _14_D_Two_Paths().run();}

	InputStream in=System.in;
	PrintWriter out=new PrintWriter(System.out);

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = in.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {return !(c >= 33 && c <= 126);}
	private int skip() {int b;while ((b = readByte()) != -1 && isSpaceChar(b));return b;}

	public String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != // ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	public char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	public char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	public int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	public int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	public long nl(){
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}
		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	void pr(Object... ob) {if (!oj)System.out.println(Arrays.deepToString(ob).replace("],", "],\n"));}
}


import java.util.*;
import java.util.regex.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.lang.Integer.*;
import static java.lang.Double.*;
import static java.util.Collections.*;

import java.awt.Point;
import java.io.*;

public class _14_D_Two_Paths {
	//->solution screencast http://youtu.be/oHg5SJYRHA0
	public void solve() {
		n = ni();
		m=new boolean[n][n];
		ArrayList<Point> roads = new ArrayList<Point>();
//		node root = new node();
		HashMap<Integer,node> map = new HashMap<Integer, _14_D_Two_Paths.node>();
		for (int i = 0; i < n-1; i++) {
			int a=ni()-1,b=ni()-1;
			roads.add(new Point(a,b));
			m[a][b]=m[b][a]=true;
//			if(map.containsKey(a)){
//				node anode=map.get(a);
//				if(map.containsKey(b)){
//					anode.add(map.get(b));
//				}else{
//					node bnode = new node(b);
//					anode.add(bnode);
//				}
//			}else{
//				node anode=new node(a);
//				if(map.containsKey(b)){
//					anode.add(map.get(b));
//				}else{
//					node bnode = new node(b);
//					anode.add(bnode);
//				}
//			}
		}
//		pr(left);
		int max=0;
		for (int i = 0; i < n-1 ; i++) {
			int a = roads.get(i).x;
			int b = roads.get(i).y;
			m[a][b]=m[b][a]=false;
			ArrayList<Integer> sa = new ArrayList<Integer>();
			boolean [] me = new boolean[n];
//			me[a]=true;
			getNe(a,me,sa);
			int dp[][]=new int[n+1][n+1];
			for (int j = 0; j < dp.length; j++) {
				fill(dp[j],-1);
			}

			int maxa=0;
			for (int j = 0; j < sa.size(); j++) {
				maxa=max(maxa,go(n,sa.get(j),dp,new boolean[n]));
			}
			ArrayList<Integer> sb = new ArrayList<Integer>();
			me = new boolean[n];
//			me[b]=true;
			getNe(b,me,sb);

			int maxb=0;
			dp=new int[n+1][n+1];
			for (int j = 0; j < dp.length; j++) {
				fill(dp[j],-1);
			}
			for (int j = 0; j < sb.size(); j++) {
				maxb=max(maxb,go(n,sb.get(j),dp,new boolean[n]));
			}
			pr(sa,sb);
			pr(maxa,maxb);
//			pr();
			max=max(max,maxa*maxb);
			m[a][b]=m[b][a]=true;
		}
		out.println(max);
	}
	boolean [][]m;
	int []left;
	int []right;
	int n;

	void getNe(int i, boolean vis[], ArrayList<Integer> s){
		s.add(i);
		vis[i]=true;
		for (int j = 0; j < m.length; j++) {
				if(j!=i && m[i][j] && !vis[j] ){
//					vis[j]=true;
//					s.add(j);
					getNe(j, vis, s);
				}
		}
	}

	int go(int k, int i,  int [][] dp,boolean memo[]){
		memo[i]=true;
		if(dp[k][i]!=-1)
			return dp[k][i];
		int r=0;
		for (int j= 0; j < n; j++) {
			if(j!=i && m[i][j] && !memo[j]){
//				memo[i][j]=true;
				r = max(r,1+go(i,j,dp,memo));
			}
		}
		return dp[k][i]=r;
	}

	class node{
		public node(int n) {
			this.idx=n;
		}
		int idx;
		Set<node> neis=new  HashSet<_14_D_Two_Paths.node>();
		void add(node n){
			neis.add(n);
		}

		@Override
		public boolean equals(Object obj) {
			node b = (node)obj;
			return idx==b.idx;
		}
	}

	// IO methods

	void run() throws Exception {
		long s = System.currentTimeMillis();
		solve();
		out.flush();
		pr(System.currentTimeMillis() - s + "ms");
	}
	public static void main(String[] args) throws Exception {new _14_D_Two_Paths().run();}

	InputStream in=System.in;
	PrintWriter out=new PrintWriter(System.out);

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = in.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {return !(c >= 33 && c <= 126);}
	private int skip() {int b;while ((b = readByte()) != -1 && isSpaceChar(b));return b;}

	public String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != // ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	public char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	public char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	public int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	public int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	public long nl(){
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}
		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	void pr(Object... ob) {if (!oj)System.out.println(Arrays.deepToString(ob).replace("],", "],\n"));}
}