import java.util.*

fun getDistanceArray(graph: Array<IntArray>, s: Int): IntArray {
  val n = graph.size
  val distanceArray = IntArray(n, { -1 })
  fun dfs(v: Int, d: Int) {
    distanceArray[v] = d
    for (u in graph[v]) {
      if (distanceArray[u] >= 0) continue
      dfs(u, d + 1)
    }
  }
  dfs(s, 0)
  return distanceArray
}

fun getDistanceArray(graph: Array<IntArray>, cs: List<Int>): IntArray {
  val n = graph.size
  val distanceArray = IntArray(n, { -1 })
  data class BFSState(val v: Int, val d: Int)
  val queue = ArrayDeque<BFSState>()
  for (c in cs) {
    queue.offerLast(BFSState(c, 0))
    distanceArray[c] = 0
  }
  while (queue.isNotEmpty()) {
    val s = queue.pollFirst()
    for (u in graph[s.v]) {
      if (distanceArray[u] == -1) {
        queue.offerLast(BFSState(u, s.d + 1))
        distanceArray[u] = s.d + 1
      }
    }
  }
  return distanceArray
}

fun main(args: Array<String>) {
  val n = readLine()!!.toInt()
  val mutableGraph = Array(n, { mutableListOf<Int>() })
  repeat(n - 1) {
    val (v1Raw, v2Raw) = readLine()!!.split(" ").map { it.toInt() }
    val v1 = v1Raw - 1
    val v2 = v2Raw - 1
    mutableGraph[v1].add(v2)
    mutableGraph[v2].add(v1)
  }
  val graph = mutableGraph.map { it.toIntArray() }.toTypedArray()
  val x0 = 0
  val x0DistanceArray = getDistanceArray(graph, x0)
  val x1 = x0DistanceArray.indexOf(x0DistanceArray.max()!!)
  val x1DistanceArray = getDistanceArray(graph, x1)
  val x2 = x1DistanceArray.indexOf(x1DistanceArray.max()!!)
  val x2DistanceArray = getDistanceArray(graph, x2)

  val diameter = x2DistanceArray.max()!!
  val radius = diameter / 2
  // println("diameter: $diameter")
  // println("radius: $radius")
  val centroids = (0 until n).filter {
    if (diameter % 2 == 1) {
      (x1DistanceArray[it] == radius && x2DistanceArray[it] == radius + 1) ||
          (x1DistanceArray[it] == radius + 1 && x2DistanceArray[it] == radius)
    } else {
      x1DistanceArray[it] == radius && x2DistanceArray[it] == radius
    }
  }
  // println("centroids: $centroids")

  fun leafCountForCentroids(inputCentroids: List<Int>): Long {
    val distanceArray = getDistanceArray(graph, inputCentroids)
    val maxChildren = IntArray(radius)
    for (v in 0 until n) {
      val d = distanceArray[v]
      if (d == radius) continue
      val childrenCount = graph[v].count { distanceArray[it] == d + 1 }
      maxChildren[d] = Math.max(maxChildren[d], childrenCount)
    }

    val leafCount = inputCentroids.size.toLong() *
        maxChildren.fold(1L, { l: Long, r: Int -> l * r.toLong() })
    return leafCount
  }

  val colorCount = radius + 1
  if (centroids.size == 2) {
    val leafCount = leafCountForCentroids(centroids)
    println("$colorCount $leafCount")
  } else if (centroids.size == 1) {
    val c = centroids[0]
    var minLeafCount = leafCountForCentroids(centroids)
    for (v in graph[c]) {
      minLeafCount = Math.min(minLeafCount, leafCountForCentroids(listOf(c, v)))
    }
    println("$colorCount $minLeafCount")
  } else {
    throw RuntimeException()
  }
}
