object Main extends App{
  import scala.io.Source.stdin
  for (line ← stdin.getLines()){
    line.toList match{
      case e Expression Nil ⇒ e match{
        case Some(c) ⇒ println(c)
        case None ⇒ println("overflow")
      }
      case _ ⇒ ???
    }
  }
}
import Complex._
object Digits{
  def unapply(arg: List[Char]): Option[(List[Char], List[Char])] = arg match{
    case h::t if h.isDigit ⇒ t match{
      case Digits(l, r) ⇒ Some(h::l, r)
      case _ ⇒ Some(List(h), t)
    }
    case _ ⇒ None
  }
}
object Number {
  def unapply(arg: List[Char]): Option[(Int, List[Char])] = arg match {
    case Digits(l, r) ⇒ Some(l.mkString.toInt, r)
    case _ ⇒ None
  }
}
object Real{
  def unapply(arg: List[Char]): Option[(Option[Complex], List[Char])] = arg match{
    case n Number r ⇒ Some(n.toReal, r)
    case _ ⇒ None
  }
}
object Image{
  def unapply(arg: List[Char]): Option[(Option[Complex], List[Char])] = arg match{
    case 'i'::t ⇒ Some(1.toImage, t)
    case _ ⇒ None
  }
}
object Numeric{
  def unapply(arg: List[Char]): Option[(Option[Complex], List[Char])] = arg match{
    case r Real t ⇒ Some(r, t)
    case i Image t ⇒ Some(i, t)
    case _ ⇒ None
  }
}
object Expression{
  def unapply(arg: List[Char]): Option[(Option[Complex], List[Char])] = arg match{
    case p PriorityOperation r ⇒ Some(calAdd(r, p))
    case _ ⇒ ???
  }
  private def calAdd(arg:List[Char], left:Option[Complex]):(Option[Complex], List[Char]) = arg match{
    case '+'::(p PriorityOperation r) ⇒ calAdd(r, left + p)
    case '-'::(p PriorityOperation r) ⇒ calAdd(r, left - p)
    case _ ⇒ (left, arg)
  }
}
object Brace{
  def unapply(arg: List[Char]): Option[(Option[Complex], List[Char])] = arg match{
    case '('::(e Expression (')'::t)) ⇒ Some(e, t)
    case _ ⇒ None
  }
}
object Term{
  def unapply(arg: List[Char]): Option[(Option[Complex], List[Char])] = arg match{
    case n Numeric t ⇒ Some(n, t)
    case b Brace t ⇒ Some(b, t)
    case _ ⇒ None
  }
}
object PriorityOperation{
  def unapply(arg: List[Char]):Option[(Option[Complex], List[Char])] = arg match{
    case l Term t ⇒ Some(calMultiple(t, l))
    case _ ⇒ None
  }
  private def calMultiple(arg:List[Char], left:Option[Complex]):(Option[Complex], List[Char]) = arg match{
    case '*'::(t Term r) ⇒ calMultiple(r, left * t)
    case _ ⇒ (left, arg)
  }
}
class Complex private (private val real:Int, private val image:Int){
  private def checkOverflow:Option[Complex] = if ((-10000 to 10000).contains(real) && (-10000 to 10000).contains(image)) Some(this) else None

  override def toString: String = (real, image) match {
    case (_, 0) ⇒ real.toString
    case (0, _) ⇒ s"${image}i"
    case (_, i) if (i > 0) ⇒ s"$real+${image}i"
    case _ ⇒ s"$real${image}i"
  }
}
object Complex{
  private def apply(real:Int, image:Int):Option[Complex] = new Complex(real, image).checkOverflow
  implicit class Converter(val value:Int){
    def toReal:Option[Complex] = Complex(value, 0)
    def toImage:Option[Complex] = Complex(0, value)
  }
  implicit class ConverterOpt(val a:Option[Complex]){
    def +(b:Option[Complex]):Option[Complex] = (a, b) match{
      case (Some(l), Some(r)) ⇒ Complex(l.real + r.real, l.image + r.image)
      case _ ⇒ None
    }
    def -(b:Option[Complex]):Option[Complex] = (a, b) match{
      case (Some(l), Some(r)) ⇒ Complex(l.real - r.real, l.image - r.image)
      case _ ⇒ None
    }
    def *(b:Option[Complex]):Option[Complex] = (a, b) match {
      case (Some(l), Some(r)) ⇒ Complex(l.real * r.real - l.image * r.image, l.real * r.image + l.image * r.real)
      case _ ⇒ None
    }
  }
}
