import scala.annotation.tailrec
import scala.collection.mutable
import scala.io.StdIn._
object Main extends App {
  val Array(w, h) = readLine.trim.split(' ').map(_.toInt)
  val arg = Array.tabulate(h){ _ ⇒ readLine.trim}
  val start = (0 until h).flatMap(y ⇒ (0 until w).find(x ⇒ arg(y)(x) == 's').map(x ⇒ Coordinate(x, y))).head
  val goal = (0 until h).flatMap(y ⇒ (0 until w).find(x ⇒ arg(y)(x) == 'g').map(x ⇒ Coordinate(x, y))).head
  val state = arg.map{line ⇒ line.map{
    case '#' ⇒ Wall
    case '.' | 's' ⇒ Empty
    case 'g' ⇒ Stair
    case '*' ⇒ Spring
    case _ ⇒ ???
  }.toArray}
  val minFromGoal = Array.fill(h){Array.fill(w){Double.MaxValue / 3}}
  minFromGoal(goal.y)(goal.x) = 0
  val queue = mutable.Queue[Coordinate](goal)
  while (queue.nonEmpty) {
    val current = queue.dequeue()
    for (next ← current.neighbor if (0 until h).contains(next.y) && (0 until w).contains(next.x) && state(next.y)(next.x) == Empty) {
      if (minFromGoal(next.y)(next.x) > minFromGoal(current.y)(current.x) + 1) {
        minFromGoal(next.y)(next.x) = minFromGoal(current.y)(current.x) + 1
        queue.enqueue(next)
      }
    }
  }
  val minToSpring = Array.fill(h){Array.fill(w){Double.MaxValue / 3}}
  for (spring ← (0 until h).flatMap(y ⇒ (0 until w).collect{case x if state(y)(x) == Spring ⇒ Coordinate(x, y)})){
    minToSpring(spring.y)(spring.x) = 0
    queue.enqueue(spring)
  }
  while(queue.nonEmpty) {
    val current = queue.dequeue()
    for (next ← current.neighbor if (0 until h).contains(next.y) && (0 until w).contains(next.x) && state(next.y)(next.x) == Empty) {
      if (minToSpring(next.y)(next.x) > minToSpring(current.y)(current.x) + 1) {
        minToSpring(next.y)(next.x) = minToSpring(current.y)(current.x) + 1
        queue.enqueue(next)
      }
    }
  }
  val empties = (0 until h).flatMap(y ⇒ (0 until w).collect{case x if state(y)(x) == Empty ⇒ Coordinate(x, y)})
  var min = 0d
  var max = Double.MaxValue / 2
  while (min * 1.000000000000001d < max) {
    val mid = (min + max) / 2
    if (canReach(mid)) max = mid
    else min = mid
  }
  println(f"${math.min(minToSpring(start.y)(start.x) + max, minFromGoal(start.y)(start.x))}%.12f")
  def canReach(estimated: Double): Boolean = empties.map{case Coordinate(x, y) ⇒ math.min(minToSpring(y)(x) + estimated, minFromGoal(y)(x))}.sum <= estimated * empties.length
  sealed trait State
  case object Spring extends State
  case object Wall extends State
  case object Empty extends State
  case object Stair extends State
  case class Coordinate(x: Int, y: Int) {
    def neighbor: List[Coordinate] = List(Coordinate(x + 1, y), Coordinate(x - 1, y), Coordinate(x, y + 1), Coordinate(x, y - 1))
  }
}







