import scala.annotation.tailrec
import scala.collection.mutable
object Main extends App {
  import scala.io.StdIn._

  val Array(r, c) = readLine.trim.split(' ').map(_.toInt)
  val state = Array.fill(r){readLine.trim.toCharArray}
  val start = (0 until r).flatMap(y ⇒ (0 until c).find(x ⇒ state(y)(x) == 'S').map(x ⇒ Coordinate(x, y))).head
  val goal = (0 until r).flatMap(y ⇒ (0 until c).find(x ⇒ state(y)(x) == 'G').map(x ⇒ Coordinate(x, y))).head
  val minStep = Array.fill(r){Array.fill(c){Int.MaxValue}}.wrap
  minStep(start) = 0
  val queue = mutable.PriorityQueue[(Coordinate, Int)]((start, 0))(Ordering.by[(Coordinate, Int), Int](_._2).reverse)
  while (queue.nonEmpty) {
    val (current, cost) = queue.dequeue()
    if (minStep(current) == cost) {
      for (direction ← Direction.all.map(_.asCoordinate)) if (state.isDefinedAt(current + direction)) {
        if (state(current + direction) != '#' && state(current + direction) != 'x') {
          if (state(current + direction) == 'o') {
            if (minStep(current + direction) > minStep(current) + 1) {
              minStep(current + direction) = minStep(current) + 1
              queue.enqueue((current + direction, minStep(current + direction)))
            }
          }else {
            if (minStep(current + direction) > minStep(current) + 2) {
              minStep(current + direction) = minStep(current) + 2
              queue.enqueue((current + direction, minStep(current + direction)))
            }
          }
        }
        val line = (0 until 3).scanLeft(current){case (c, _) ⇒ c + direction}.tail.takeWhile(c ⇒ state.isDefinedAt(c) && state(c) != '#').zipWithIndex
        for ((next, distance) ← line) {
          if (minStep(next) > minStep(current) + 3 + distance) {
            minStep(next) = minStep(current) + 3 + distance
            queue.enqueue((next, minStep(next)))
          }
        }
      }
    }
  }
  println(minStep(goal))


  implicit class Wrap[T](val array: Array[Array[T]]) extends AnyVal {
    def apply(coordinate: Coordinate): T = array(coordinate.y)(coordinate.x)
    def update(coordinate: Coordinate, value: T): Unit = array(coordinate.y)(coordinate.x) = value
    def isDefinedAt(coordinate: Coordinate): Boolean = array.indices.contains(coordinate.y) && array(coordinate.y).indices.contains(coordinate.x)
    def wrap: Wrap[T] = this
  }
}

case class Coordinate(x: Int, y: Int) {
  def +(that: Coordinate): Coordinate = Coordinate(x + that.x, y + that.y)
}
sealed trait Direction {
  def asCoordinate: Coordinate
}
object Direction {
  def all: List[Direction] = List(Up, Right, Down, Left)
}
object Up extends Direction {
  override def asCoordinate: Coordinate = Coordinate(0, -1)
}
object Right extends Direction {
  override def asCoordinate: Coordinate = Coordinate(1, 0)
}
object Down extends Direction {
  override def asCoordinate: Coordinate = Coordinate(0, 1)
}
object Left extends Direction {
  override def asCoordinate: Coordinate = Coordinate(-1, 0)
}
