import java.math.BigInteger;
import java.util.*;

public class Euler936 {

    static BigInteger multisetWeightedCount(BigInteger[] countsBySize, int childCount, int sizeSum) {
        BigInteger[][] dp = new BigInteger[childCount + 1][sizeSum + 1];
        for (int i = 0; i <= childCount; i++) {
            Arrays.fill(dp[i], BigInteger.ZERO);
        }
        dp[0][0] = BigInteger.ONE;

        for (int s = 1; s <= sizeSum; ++s) {
            BigInteger c = countsBySize[s];
            if (c.equals(BigInteger.ZERO)) {
                continue;
            }

            int qMax = Math.min(childCount, sizeSum / s);
            BigInteger[] choose = new BigInteger[qMax + 1];
            choose[0] = BigInteger.ONE;
            for (int q = 1; q <= qMax; ++q) {
                choose[q] = choose[q - 1].multiply(c.add(BigInteger.valueOf(q - 1))).divide(BigInteger.valueOf(q));
            }

            BigInteger[][] next = new BigInteger[childCount + 1][sizeSum + 1];
            for (int i = 0; i <= childCount; i++) {
                System.arraycopy(dp[i], 0, next[i], 0, sizeSum + 1);
            }

            for (int used = 0; used <= childCount; ++used) {
                for (int w = 0; w <= sizeSum; ++w) {
                    BigInteger base = dp[used][w];
                    if (base.equals(BigInteger.ZERO)) {
                        continue;
                    }
                    for (int q = 1; q <= qMax; ++q) {
                        int nUsed = used + q;
                        int nW = w + q * s;
                        if (nUsed > childCount || nW > sizeSum) {
                            break;
                        }
                        next[nUsed][nW] = next[nUsed][nW].add(base.multiply(choose[q]));
                    }
                }
            }
            dp = next;
        }

        return dp[childCount][sizeSum];
    }

    static BigInteger[] computePeerlessUnrooted(int N) {
        BigInteger[][] planted = new BigInteger[N + 1][N + 1];
        for (int i = 0; i <= N; i++)
            Arrays.fill(planted[i], BigInteger.ZERO);

        BigInteger[] plantedTotalBySize = new BigInteger[N + 1];
        Arrays.fill(plantedTotalBySize, BigInteger.ZERO);

        for (int n = 1; n <= N; ++n) {
            for (int d = 1; d <= n; ++d) {
                int childCount = d - 1;
                int childSizeSum = n - 1;
                if (childCount > childSizeSum) {
                    continue;
                }

                BigInteger[] allowedBySize = new BigInteger[n];
                for (int s = 1; s < n; ++s) {
                    allowedBySize[s] = plantedTotalBySize[s].subtract(planted[d][s]);
                }
                planted[d][n] = multisetWeightedCount(allowedBySize, childCount, childSizeSum);
            }

            BigInteger total = BigInteger.ZERO;
            for (int d = 1; d <= n; ++d) {
                total = total.add(planted[d][n]);
            }
            plantedTotalBySize[n] = total;
        }

        BigInteger[] vertexRooted = new BigInteger[N + 1];
        Arrays.fill(vertexRooted, BigInteger.ZERO);
        for (int n = 1; n <= N; ++n) {
            BigInteger total = BigInteger.ZERO;
            for (int d = 1; d <= n; ++d) {
                int childCount = d;
                int childSizeSum = n - 1;
                if (childCount > childSizeSum) {
                    continue;
                }

                BigInteger[] allowedBySize = new BigInteger[n];
                for (int s = 1; s < n; ++s) {
                    allowedBySize[s] = plantedTotalBySize[s].subtract(planted[d][s]);
                }
                total = total.add(multisetWeightedCount(allowedBySize, childCount, childSizeSum));
            }
            vertexRooted[n] = total;
        }

        BigInteger[] peerlessUnrooted = new BigInteger[N + 1];
        Arrays.fill(peerlessUnrooted, BigInteger.ZERO);
        for (int n = 1; n <= N; ++n) {
            BigInteger directedEdgeRooted = BigInteger.ZERO;

            for (int left = 1; left < n; ++left) {
                int right = n - left;
                directedEdgeRooted = directedEdgeRooted
                        .add(plantedTotalBySize[left].multiply(plantedTotalBySize[right]));
            }

            BigInteger sameDegree = BigInteger.ZERO;
            for (int d = 1; d <= N; ++d) {
                for (int left = 1; left < n; ++left) {
                    int right = n - left;
                    sameDegree = sameDegree.add(planted[d][left].multiply(planted[d][right]));
                }
            }
            directedEdgeRooted = directedEdgeRooted.subtract(sameDegree);

            peerlessUnrooted[n] = vertexRooted[n].subtract(directedEdgeRooted.divide(BigInteger.valueOf(2)));
        }

        return peerlessUnrooted;
    }

    static BigInteger prefixSumFrom3(BigInteger[] values, int N) {
        BigInteger total = BigInteger.ZERO;
        for (int n = 3; n <= N; ++n) {
            total = total.add(values[n]);
        }
        return total;
    }

    public static String solve() {
        BigInteger[] peerless = computePeerlessUnrooted(50);
        return prefixSumFrom3(peerless, 50).toString();
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
