import scala.annotation.tailrec
import scala.io.StdIn._
object Main extends App {
  readLine.trim match {
    case Formula(f) ⇒
      println(s"${f.minCostToBeFalse} ${f.minCostToBeTrue}")
    case _ ⇒ ???
  }

  object Formula {
    def unapply(arg: String): Option[Formula] = {
      arg.toList match {
        case o OrExpression Nil ⇒ Some(o)
        case _ ⇒ None
      }
    }
  }
  object OrExpression {
    def unapply(arg: List[Char]): Option[(OrExpression, List[Char])] = {
      arg match {
        case a AndExpression r ⇒ Some(takeAll(r, List(a)))
        case _ ⇒ None
      }
    }

    private def apply(arg: List[AndExpression]): OrExpression = {
      val trues = arg.map(_.minCostToBeTrue)
      val falses = arg.map(_.minCostToBeFalse)
      val (trueCost, falseCost) = falses.zip(trues).foldLeft((Int.MaxValue, 0)){
        case ((current, left), (f, t)) ⇒ (math.min(left + t, current), left + f)
      }
      new Impl(trueCost, falseCost)
    }

    @tailrec private[this] def takeAll(arg: List[Char], expression: List[AndExpression]): (OrExpression, List[Char]) = {
      arg match {
        case '|' :: (o AndExpression r) ⇒ takeAll(r, o :: expression)
        case _ ⇒ (OrExpression(expression.reverse), arg)
      }
    }

    class Impl(override val minCostToBeTrue: Int,
               override val minCostToBeFalse: Int) extends OrExpression
  }
  object AndExpression {
    def unapply(arg: List[Char]): Option[(AndExpression, List[Char])] = {
      arg match {
        case a Term r ⇒ Some(takeAll(r, List(a)))
        case _ ⇒ None
      }
    }
    private def apply(arg: List[Term]): AndExpression = {
      val trues = arg.map(_.minCostToBeTrue)
      val falses = arg.map(_.minCostToBeFalse)
      val (falseCost, trueCost) = trues.zip(falses).foldLeft((Int.MaxValue, 0)){
        case ((current, left), (t, f)) ⇒ (math.min(left + f, current), left + t)
      }
      new Impl(trueCost, falseCost)
    }
    @tailrec private[this] def takeAll(arg: List[Char], expression: List[Term]): (AndExpression, List[Char]) = {
      arg match {
        case '&':: (a Term r) ⇒ takeAll(r, a::expression)
        case _ ⇒ (AndExpression(expression.reverse), arg)
      }
    }
    class Impl(override val minCostToBeTrue: Int,
               override val minCostToBeFalse: Int) extends AndExpression
  }
  object Term {
    def unapply(arg: List[Char]): Option[(Term, List[Char])] = {
      arg match {
        case '('::(o OrExpression ')'::t) ⇒ Some(WithPer(o), t)
        case '?'::t ⇒ Some(Undefined, t)
        case _ ⇒ None
      }
    }
  }
  sealed trait Formula {
    val minCostToBeTrue: Int
    val minCostToBeFalse: Int
  }
  sealed trait OrExpression extends Formula
  sealed trait AndExpression extends OrExpression
  sealed trait Term extends AndExpression
  case object Undefined extends Term {
    val minCostToBeTrue: Int = 1
    val minCostToBeFalse: Int = 1
  }
  case class WithPer(inner: Formula) extends Term {
    val minCostToBeTrue: Int = inner.minCostToBeTrue
    val minCostToBeFalse: Int = inner.minCostToBeFalse
  }
  implicit class Scope[T](val value: T) extends AnyVal {
    def let[A](@inline func: T ⇒ A): A = func(value)
    def also(@inline func: T ⇒ Unit): T = {func(value);value}
    def minOption[A](implicit ev: T ⇒ Iterable[A], ord: Ordering[A]): Option[A] = if (value.isEmpty) None else Some(value.min)
  }
}


Measured memory_bytes: 149032