You are given a description of a depot. It is a rectangular checkered field of n × m size. Each cell in a field can be empty (".") or it can be occupied by a wall ("*"). You have one bomb. If you lay the bomb at the cell (x, y), then after triggering it will wipe out all walls in the row x and all walls in the column y.You are to determine if it is possible to wipe out all walls in the depot by placing and triggering exactly one bomb. The bomb can be laid both in an empty cell or in a cell occupied by a wall.

The first line contains two positive integers n and m (1 ≤ n, m ≤ 1000) — the number of rows and columns in the depot field.  The next n lines contain m symbols "." and "*" each — the description of the field. j-th symbol in i-th of them stands for cell (i, j). If the symbol is equal to ".", then the corresponding cell is empty, otherwise it equals "*" and the corresponding cell is occupied by a wall.

If it is impossible to wipe out all walls by placing and triggering exactly one bomb, then print "NO" in the first line (without quotes). Otherwise print "YES" (without quotes) in the first line and two integers in the second line — the coordinates of the cell at which the bomb should be laid. If there are multiple answers, print any of them.

import scala.io.StdIn._
import scala.util.control._

object cf699B {
    def main (args:Array[String]) {
        var line = readLine();
        val ss = line.split(" ");
        val n = ss(0).toInt;
        val m = ss(1).toInt;
        var a = new Array[String](1000 + 5);

        for (i <- 0 until n) {
            a(i) = readLine();
        }

        var r = new Array[Int](1000 + 5);
        for (i <- 0 until n) {
            r(i) = 0;
        }

        var c = new Array[Int](1000 + 5);
        for (i <- 0 until m) {
            c(i) = 0;
        }

        var cnt = 0;

        for (i <- 0 until n) {
            for (j <- 0 until m) {
                if (a(i)(j) == '*') {
                    cnt += 1;
                    r(i) += 1;
                    c(j) += 1;
                }
            }
        }

        var res = false;
        var plcx = 0;
        var plcy = 0;

        var ans = 0;
        for (i <- 0 until n) {
            for (j <- 0 until m) {
                ans = cnt;
                if (a(i)(j) == '*') ans += 1;
                ans -= r(i);
                ans -= c(j);
                if (ans == 0) {
                    res = true;
                    plcx = i + 1;
                    plcy = j + 1;
                }
            }
        }
        if (res == true) {
            println("YES");
            println(plcx + " " + plcy);
        } else {
            println("NO");
        }
    }
}

import scala.io._
import java.util.Scanner
import java.io.BufferedReader
import java.io.InputStreamReader
import scala.collection.breakOut

object Main {
    def main(args: Array[String]) {
        val bfReader = new BufferedReader(new InputStreamReader(System.in))
        val scanner = new Scanner(bfReader.readLine())
        val (n, m) = (scanner.nextInt(), scanner.nextInt())
        val a = for (r <- 0 until n; line = bfReader.readLine()) yield line

        def cellVal(ch: Char): Int = if (ch == '*') 1 else 0

        val pr = a.map(chs  => chs.map(cellVal).sum)
        val pc = for (c <- 0 until m) yield a.map(chs => chs(c)).map(cellVal).sum

        val allBombsVal = a.map(chs => chs.map(cellVal).sum).sum
        val validPositions = for (r <- 0 until n; c <- 0 until m if pr(r) + pc(c) - cellVal(a(r)(c)) == allBombsVal) yield (r, c)

        if (validPositions.isEmpty) println("NO")
        else {
            val (r, c) = validPositions(0)
            println(s"YES\n${r + 1} ${c + 1}")
        }
    }
}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val lines = in.take(n).toList
  val linesBig = lines.indices.filter(i => lines(i).count(_ == '*') > 1).toList
  if (linesBig.length > 1) {
    println("NO")
  }
  else if (linesBig.length == 1) {
    val y = linesBig.head
    val columnsBig = lines
      .indices
      .filter(i => i != y && lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .distinct

    if (columnsBig.length > 1)
      println("NO")
    else if (columnsBig.length == 1) {
      println("YES")

      println(s"${y + 1} ${columnsBig.head + 1}")
    } else {
      println("YES")
      println(s"${y + 1} 1")
    }
  } else {
    val columnsBig = lines
      .indices
      .filter(i => lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .groupBy(i => i)
      .map(i => i._1 -> i._2.length)

    if (columnsBig.size > 2)
      println("NO")
    else if (columnsBig.size == 2) {
      val one = columnsBig.find(_._2 == 1)
      if (one.isEmpty) {
        println("NO")
      } else {
        val y = lines.indices.find(i => lines(i)(one.get._1) == '*').get
        val x = columnsBig.find(i => i._1 != one.get._1).get._1
        println("YES")
        println(s"${y + 1} ${x + 1}")
      }
    } else if (columnsBig.size == 1) {
      println("YES")
      println(s"1 ${columnsBig.head._1 + 1}")
    } else {
      println("YES")
      println("1 1")
    }

  }

}

import java.util

import scala.collection.mutable

/**
 * @author pvasilyev
 * @since 11 Aug 2016
 */
object B699 extends App {

  def max(map: mutable.Map[Int, util.ArrayList[Int]]): (Int, Int) = {
    var maxIndex = 0
    var maxValue = 0
    map foreach {
      case (key, value) => {
        if (value.size() > maxValue) {
          maxValue = value.size()
          maxIndex = key
        }
      }
    }
    if (maxValue > 1) {
      map foreach {
        case (key, value) => {
          if (key != maxIndex && value.size > 1) {
            maxValue = 0
          }
        }
      }
    }
    (maxIndex + 1, maxValue)
  }

  def solve() = {
    val Array(n, m): Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
    val maze: Array[Array[Char]] = Array.ofDim[Char](n, m)
    for (i <- 0 until n) {
      maze(i) = scala.io.StdIn.readLine().toCharArray
    }
    val rowList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    val colList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    var starCount = 0
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        if (maze(i)(j) == '*') {
          starCount += 1
          if (!rowList.contains(i)) {
            rowList += (i -> new util.ArrayList[Int]())
          }
          if (!colList.contains(j)) {
            colList += (j -> new util.ArrayList[Int]())
          }
          rowList(i).add(j)
          colList(j).add(i)
        }
      }
    }
    val (maxRowIndex, maxRowValue) = max(rowList)
    val (maxColIndex, maxColValue) = max(colList)

    if (maxRowValue + maxColValue - starCount >= 0) {
      println("YES")
      if (maxRowValue != 1 && maxColValue != 1) {
        println(maxRowIndex + " " + maxColIndex)
      } else if (maxRowValue == 1 && maxColValue == 1) {
        if (starCount == 1) {
          println(maxRowIndex + " " + maxColIndex)
        } else {
          val row = colList(maxColIndex - 1).get(0)
          var rrow = 0
          rowList foreach {
            case (key, value) => {
              if (key != row && !colList(maxColIndex - 1).contains(key)) {
                rrow = key
              }
            }
          }
          val col = rowList(rrow).get(0)
          var ccol = 0
          colList foreach {
            case (key, value) => {
              if (key != col && !rowList(rrow).contains(key)) {
                ccol = key
              }
            }
          }
          println((rrow + 1) + " " + (ccol + 1))
        }
      } else if (maxColValue != 1) {
        val row = colList(maxColIndex - 1).get(0)
        var rrow = 0
        rowList foreach {
          case (key, value) => {
            if (key != row && !colList(maxColIndex - 1).contains(key)) {
              rrow = key
            }
          }
        }
        println((rrow + 1) + " " + maxColIndex)
      } else {
        val col = rowList(maxRowIndex - 1).get(0)
        var ccol = 0
        colList foreach {
          case (key, value) => {
            if (key != col && !rowList(maxRowIndex - 1).contains(key)) {
              ccol = key
            }
          }
        }
        println(maxRowIndex + " " + (ccol + 1))
      }
    } else {
      println("NO")
    }
  }

  solve()

}

import scala.util.control.Breaks._

object main extends App{
  val Array(n, m) = readLine.split(" ").map(_.toInt)
  var area = new Array[String](n)
  var rows = new Array[Int](n)
  var cols = new Array[Int](m)
  var count = 0
  for (i <- 0 until n) {
  	area(i) = readLine
  	rows(i) = area(i).toArray.foldLeft(0)((count: Int, char: Char) => if (char == '*') count + 1 else count)
  	count += rows(i)
  	List.range(0, m).foreach((j: Int) => if (area(i)(j) == '*') cols(j) += 1 )
  }
  val r = () => {
  	var result: Any = "NO";
  	for (i <- 0 until n) {
	  	for (j <- 0 until m) {
	  		val res = rows(i) + cols(j) - (if (area(i)(j) == '*') 1 else 0)
	  		if (res >= count) {
	  			result = Array(i+1, j+1)
	  		}
	  	}
  	}
  	result;
  }
  r() match {
  	case s: String => println(s)
  	case Array(x, y) => {
  		println("YES")
  		println("%d %d".format(x, y))
  	}
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _699B extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val n, m = read[Int]
    val room = read[Vector, String](n)

    val rowCount, colCount = map[Int] to 0
    var bombs = 0

    until(n, m) foreach { case (r, c) =>
      if (room(r)(c) == '*') {
        rowCount(r) += 1
        colCount(c) += 1
        bombs += 1
      }
    }

    val ans = until(n, m) find { case (r, c) =>
      rowCount(r) + colCount(c) - (room(r)(c) == '*').to[Int] == bombs
    }

    ans match {
      case None => write(false.toEnglish)
      case Some((i, j)) => write(true.toEnglish).writeOnNextLine(i + 1, j + 1)
    }
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
    def X[B](s: Traversable[B]): Iterator[(A, B)] = for {a <- t.toIterator; b <- s} yield (a, b)
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def until(until: Int): Range = 0 until until
  def until(d1: Int, d2: Int): Iterator[(Int, Int)] = (0 until d1) X (0 until d2)
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _699B extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val n, m = read[Int]
    val room = read[Vector, String](n)

    val rowCount, colCount = map[Int] to 0
    var bombs = 0

    until(n, m) foreach { case (r, c) =>
      if (room(r)(c) == '*') {
        rowCount(r) += 1
        colCount(c) += 1
        bombs += 1
      }
    }

    val ans = until(n, m) find { case (r, c) =>
      rowCount(r) + colCount(c) - (room(r)(c) == '*').to[Int] == bombs
    }

    ans match {
      case None => write(false.toEnglish)
      case Some((i, j)) => write(true.toEnglish).writeOnNextLine(i + 1, j + 1)
    }
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
    def X[B](s: Iterable[B]): Iterator[(A, B)] = for {a <- t.toIterator; b <- s} yield (a, b)
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def until(until: Int): Range = 0 until until
  def until(d1: Int, d2: Int): Iterator[(Int, Int)] = (0 until d1) X (0 until d2)
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _699B extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val n, m = read[Int]
    val room = read[Vector, String](n)

    val rowCount, colCount = map[Int] to 0
    var bombs = 0

    for {
      r <- 0 until n
      c <- 0 until m
      if room(r)(c) == '*'
    } {
      rowCount(r) += 1
      colCount(c) += 1
      bombs += 1
    }

    val ans = for {
      r <- 0 until n
      c <- 0 until m
      if rowCount(r) + colCount(c) - (room(r)(c) == '*').to[Int] == bombs
    } yield r -> c

    ans.headOption match {
      case None => write(false.toEnglish)
      case Some((i, j)) => write(true.toEnglish).writeOnNextLine(i + 1, j + 1)
    }
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
    def X[B](bs: Iterable[B]): Iterable[(A, B)] = for {a <- s; b <- bs} yield (a, b)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _699B extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val n, m = read[Int]
    val room = read[Vector, String](n)

    val rowCount, colCount = map[Int] to 0
    var bombs = 0

    n X m foreach { case (r, c) =>
      if (room(r)(c) == '*') {
        rowCount(r) += 1
        colCount(c) += 1
        bombs += 1
      }
    }

    val ans = n X m find { case (r, c) =>
      rowCount(r) + colCount(c) - (room(r)(c) == '*').to[Int] == bombs
    }

    ans match {
      case None => write(false.toEnglish)
      case Some((i, j)) => write(true.toEnglish).writeOnNextLine(i + 1, j + 1)
    }
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
    def X[B](s: Traversable[B]): Iterator[(A, B)] = for {a <- t.toIterator; b <- s} yield (a, b)
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
    def X(y: Int): Iterator[(Int, Int)] = until(x) X until(y)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def until(until: Int): Range = 0 until until
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import scala.util.Sorting
import scala.io.StdIn

object App {

  def main(args: Array[String]) {

    val Array(n,m) = StdIn.readLine().split(" ").map(_.toInt)

    var N:Array[Int] = new Array[Int](n)
    var M:Array[Int] = new Array[Int](m)

    var TD = Array.ofDim[Array[Int]](n)
    var sum = 0
    for(i <- 0 to n - 1) {
      TD(i) = StdIn.readLine().toCharArray.map(t=> if(t == '*') 1 else 0);
      TD(i)
        .zipWithIndex
        .foreach((a) => {
            sum+=TD(i)(a._2)
            N(i)+=TD(i)(a._2)
            M(a._2)+=TD(i)(a._2)
        })
    }

    for(i <- 0 to n - 1) {
      for(j <- 0 to m - 1) {
        if(M(j) + N(i) - TD(i)(j) == sum) {
          println("YES")
          println((i+1) + " " + (j+1))
          return
        }
      }
    }
    println("NO")

  }

}

import scala.io.StdIn._
import scala.util.control._

object cf699B {
    def main (args:Array[String]) {
        var line = readLine();
        val ss = line.split(" ");
        val n = ss(0).toInt;
        val m = ss(1).toInt;
        var a = new Array[String](1000 + 5);

        for (i <- 0 until n) {
            a(i) = readLine();
        }

        var r = new Array[Int](1000 + 5);
        for (i <- 0 until n) {
            r(i) = 0;
        }

        var c = new Array[Int](1000 + 5);
        for (i <- 0 until m) {
            c(i) = 0;
        }

        var cnt = 0;

        for (i <- 0 until n) {
            for (j <- 0 until m) {
                if (a(i)(j) == '*') {
                    cnt += 1;
                    r(i) += 1;
                    c(j) += 1;
                }
            }
        }

        var res = false;
        var plcx = 0;
        var plcy = 0;

        var ans = 0;
        for (i <- 0 until n) {
            for (j <- 0 until m) {
                ans = cnt;
                if (a(i)(j) == '*') ans += 1;
                ans -= r(i);
                ans -= c(j);
                if (ans == 0) {
                    res = true;
                    plcx = i;
                    plcy = j;
                }
            }
        }
        if (res == true) {
            println("YES");
            println(plcx + 1 + " " + plcy + 1);
        } else {
            println("NO");
        }
    }
}

import scala.io._
import java.util.Scanner
import java.io.BufferedReader
import java.io.InputStreamReader
import scala.collection.breakOut

object Main {
    def main(args: Array[String]) {
        case class Cell(r: Int, c: Int, ch: Char)

        val bfReader = new BufferedReader(new InputStreamReader(System.in))
        val scanner = new Scanner(bfReader.readLine())
        val (n, m) = (scanner.nextInt(), scanner.nextInt())
        val a = for(r <- 0 until n; (ch, c) <- bfReader.readLine().zipWithIndex) yield Cell(r, c, ch)

        def cellVal(c: Cell): Int = c.ch match { case '*' => 1; case '.' => 0 }

        val pr = a.groupBy{ _.r }.map{ case(r, xs) => (r, xs.map(cellVal).sum) }
        val pc = a.groupBy{ _.c }.map{ case(c, xs) => (c, xs.map(cellVal).sum) }

        val allBombsVal = a.map(cellVal).sum
        val validPositions = a.filter(x => x.ch == '*' && pr(x.r) + pc(x.c) - 1 == allBombsVal)

        if (validPositions.isEmpty) println("NO")
        else {
            val x = validPositions(0)
            println(s"YES\n${x.r + 1} ${x.c + 1}")
        }
    }
}

import scala.io._
import java.util.Scanner
import java.io.BufferedReader
import java.io.InputStreamReader
import scala.collection.breakOut

object Main {
    def main(args: Array[String]) {
        case class Cell(r: Int, c: Int, ch: Char)

        val bfReader = new BufferedReader(new InputStreamReader(System.in))
        val scanner = new Scanner(bfReader.readLine())
        val (n, m) = (scanner.nextInt(), scanner.nextInt())
        val a = for(r <- 0 until n; (ch, c) <- bfReader.readLine().zipWithIndex) yield Cell(r, c, ch)

        def cellVal(c: Cell): Int = if (c.ch == "*") 1 else 0

        val pr: Vector[Int] = a.groupBy{ _.r }.map{ case(r, xs) => (r, xs.map(cellVal).sum) }.to[Vector].sorted.map{ case (r, s) => s }
        val pc = a.groupBy{ _.c }.map{ case(c, xs) => (c, xs.map(cellVal).sum) }.to[Vector].sorted.map{ case (c, s) => s }

        val allBombsVal = a.map(cellVal).sum
        val validPositions = a.filter(x => pr(x.r) + pc(x.c) - cellVal(x) == allBombsVal)

        if (validPositions.isEmpty) println("NO")
        else {
            val x = validPositions(0)
            println(s"YES\n${x.r + 1} ${x.c + 1}")
        }
    }
}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val lines = in.take(n).toList
  val linesBig = lines.indices.filter(i => lines(i).count(_ == '*') > 1).toList
  if (linesBig.length > 1) {
    println("NO")
  }
  else if (linesBig.length == 1) {
    val y = linesBig.head
    val columnsBig = lines
      .indices
      .filter(i => i != y && lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .distinct

    if (columnsBig.length > 1)
      println("NO")
    else if (columnsBig.length == 1) {
      println("YES")

      println(s"${y + 1} ${columnsBig.head + 1}")
    } else {
      println("YES")
      println(s"${y + 1} 1")
    }
  } else {
    val columnsBig = lines
      .indices
      .filter(i => lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .groupBy(i => i)
      .map(i => i._1 -> i._2.length)

    if (columnsBig.size > 2)
      println("NO")
    else if (columnsBig.size == 2) {
      val one = columnsBig.find(_._2 == 1)
      if (one.isEmpty) {
        println("NO")
      } else {
        val y = lines.indices.find(i => lines(i)(one.get._1) == '*').get
        val x = columnsBig.find(i => i._1 != one.get._1).get._1
        println("YES")
        println(s"${x + 1} ${y + 1}")
      }
    } else if (columnsBig.size == 1) {
      println("YES")
      println(s"1 ${columnsBig.head._1 + 1}")
    } else {
      println("YES")
      println("1 1")
    }

  }

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val lines = in.take(n).toList
  val linesBig = lines.indices.filter(i => lines(i).count(_ == '*') > 1)
  if (linesBig.length > 1) {
    println("NO")
  }
  else if (linesBig.length == 1) {
    val y = linesBig.head
    val columnsBig = lines
      .indices
      .filter(i => i != y && lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .distinct

    if (columnsBig.length > 1)
      println("NO")
    else if (columnsBig.length == 1) {
      println("YES")
      println(s"${columnsBig.head + 1} ${y + 1}")
    } else {
      println("YES")
      println(s"1 ${y + 1}")
    }
  } else {
    val columnsBig = lines
      .indices
      .filter(i => lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .groupBy(i => i)
      .map(i => i._1 -> i._2.length)

    if (columnsBig.size > 2)
      println("NO")
    else if (columnsBig.size == 2) {
      val one = columnsBig.find(_._2 == 1)
      if (one.isEmpty) {
        println("NO")
      } else {
        val y = linesBig.find(i => lines(i)(one.get._1) == '*')
        val x = linesBig.find(_ != one.get).get
        println("YES")
        println(s"$x $y")
      }
    } else if (columnsBig.size == 1) {
      println("YES")
      println(s"1 ${columnsBig.head._1 + 1}")
    } else {
      println("YES")
      println("1 1")
    }

  }

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val lines = in.take(n).toList
  val linesBig = lines.indices.filter(i => lines(i).count(_ == '*') > 1).toList
  if (linesBig.length > 1) {
    println("NO")
  }
  else if (linesBig.length == 1) {
    val y = linesBig.head
    val columnsBig = lines
      .indices
      .filter(i => i != y && lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .distinct

    if (columnsBig.length > 1)
      println("NO")
    else if (columnsBig.length == 1) {
      println("YES")

      println(s"${y + 1} ${columnsBig.head + 1}")
    } else {
      println("YES")
      println(s"${y + 1} 1")
    }
  } else {
    val columnsBig = lines
      .indices
      .filter(i => lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .groupBy(i => i)
      .map(i => i._1 -> i._2.length)

    if (columnsBig.size > 2)
      println("NO")
    else if (columnsBig.size == 2) {
      val one = columnsBig.find(_._2 == 1)
      if (one.isEmpty) {
        println("NO")
      } else {
        val y = lines.indices.find(i => lines(i)(one.get._1) == '*').get
        val x = columnsBig.find(i => i._1 != y).get
        println("YES")
        println(s"$y $x ")
      }
    } else if (columnsBig.size == 1) {
      println("YES")
      println(s"1 ${columnsBig.head._1 + 1}")
    } else {
      println("YES")
      println("1 1")
    }

  }

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val lines = in.take(n).toList
  val linesBig = lines.indices.filter(i => lines(i).count(_ == '*') > 1).toList
  if (linesBig.length > 1) {
    println("NO")
  }
  else if (linesBig.length == 1) {
    val y = linesBig.head
    val columnsBig = lines
      .indices
      .filter(i => i != y && lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .distinct

    if (columnsBig.length > 1)
      println("NO")
    else if (columnsBig.length == 1) {
      println("YES")

      println(s"${y + 1} ${columnsBig.head + 1}")
    } else {
      println("YES")
      println(s"${y + 1} 1")
    }
  } else {
    val columnsBig = lines
      .indices
      .filter(i => lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .groupBy(i => i)
      .map(i => i._1 -> i._2.length)

    if (columnsBig.size > 2)
      println("NO")
    else if (columnsBig.size == 2) {
      val one = columnsBig.find(_._2 == 1)
      if (one.isEmpty) {
        println("NO")
      } else {
        val y = lines.indices.find(i => lines(i)(one.get._1) == '*').get
        val x = columnsBig.find(i => i._1 != y).get._1
        println("YES")
        println(s"${y + 1} ${x + 1}")
      }
    } else if (columnsBig.size == 1) {
      println("YES")
      println(s"1 ${columnsBig.head._1 + 1}")
    } else {
      println("YES")
      println("1 1")
    }

  }

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val lines = in.take(n).toList
  val linesBig = lines.indices.filter(i => lines(i).count(_ == '*') > 1)
  if (linesBig.length > 1) {
    println("NO")
  }
  else if (linesBig.length == 1) {
    val y = linesBig.head
    val columnsBig = lines
      .indices
      .filter(i => i != y && lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .distinct

    if (columnsBig.length > 1)
      println("NO")
    else if (columnsBig.length == 1) {
      println("YES")

      println(s"${y + 1} ${columnsBig.head + 1}")
    } else {
      println("YES")
      println(s"${y + 1} 1")
    }
  } else {
    val columnsBig = lines
      .indices
      .filter(i => lines(i).count(_ == '*') != 0)
      .map(i => lines(i).indexOf('*'))
      .groupBy(i => i)
      .map(i => i._1 -> i._2.length)

    if (columnsBig.size > 2)
      println("NO")
    else if (columnsBig.size == 2) {
      val one = columnsBig.find(_._2 == 1)
      if (one.isEmpty) {
        println("NO")
      } else {
        val y = linesBig.find(i => lines(i)(one.get._1) == '*')
        val x = linesBig.find(_ != one.get).get
        println("YES")
        println(s"$y $x ")
      }
    } else if (columnsBig.size == 1) {
      println("YES")
      println(s"${columnsBig.head._1 + 1} 1")
    } else {
      println("YES")
      println("1 1")
    }

  }

}

import java.util

import scala.collection.mutable

/**
 * @author pvasilyev
 * @since 11 Aug 2016
 */
object B699 extends App {

  def max(map: mutable.Map[Int, util.ArrayList[Int]]): (Int, Int) = {
    var maxIndex = 0
    var maxValue = 0
    map foreach {
      case (key, value) => {
        if (value.size() > maxValue) {
          maxValue = value.size()
          maxIndex = key
        }
      }
    }
    if (maxValue > 1) {
      map foreach {
        case (key, value) => {
          if (key != maxIndex && value.size > 1) {
            maxValue = 0
          }
        }
      }
    }
    (maxIndex + 1, maxValue)
  }

  def solve() = {
    val Array(n, m): Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
    val maze: Array[Array[Char]] = Array.ofDim[Char](n, m)
    for (i <- 0 until n) {
      maze(i) = scala.io.StdIn.readLine().toCharArray
    }
    val rowList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    val colList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    var starCount = 0
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        if (maze(i)(j) == '*') {
          starCount += 1
          if (!rowList.contains(i)) {
            rowList += (i -> new util.ArrayList[Int]())
          }
          if (!colList.contains(j)) {
            colList += (j -> new util.ArrayList[Int]())
          }
          rowList(i).add(j)
          colList(j).add(i)
        }
      }
    }
    val (maxRowIndex, maxRowValue) = max(rowList)
    val (maxColIndex, maxColValue) = max(colList)

    if (maxRowValue + maxColValue - starCount >= 0) {
      println("YES")
      if (maxRowValue != 1 && maxColValue != 1) {
        println(maxRowIndex + " " + maxColIndex)
      } else if (maxRowValue == 1 && maxColValue == 1) {
        if (starCount == 1) {
          println(maxRowIndex + " " + maxColIndex)
        } else {
          val row = colList(maxColIndex - 1).get(0)
          var rrow = 0
          rowList foreach {
            case (key, value) => {
              if (key != row && !colList(maxColIndex - 1).contains(key)) {
                rrow = key
              }
            }
          }
          val col = rowList(rrow).get(0)
          var ccol = 0
          colList foreach {
            case (key, value) => {
              if (key != col && !rowList(maxRowIndex - 1).contains(key)) {
                ccol = key
              }
            }
          }
          println((rrow + 1) + " " + (ccol + 1))
        }
      } else if (maxColValue != 1) {
        val row = colList(maxColIndex - 1).get(0)
        var rrow = 0
        rowList foreach {
          case (key, value) => {
            if (key != row && !colList(maxColIndex - 1).contains(key)) {
              rrow = key
            }
          }
        }
        println((rrow + 1) + " " + maxColIndex)
      } else {
        val col = rowList(maxRowIndex - 1).get(0)
        var ccol = 0
        colList foreach {
          case (key, value) => {
            if (key != col && !rowList(maxRowIndex - 1).contains(key)) {
              ccol = key
            }
          }
        }
        println(maxRowIndex + " " + (ccol + 1))
      }
    } else {
      println("NO")
    }
  }

  solve()

}

import java.util

import scala.collection.mutable

/**
 * @author pvasilyev
 * @since 11 Aug 2016
 */
object B699 extends App {

  def max(map: mutable.Map[Int, util.ArrayList[Int]]): (Int, Int) = {
    var maxIndex = 0
    var maxValue = 0
    map foreach {
      case (key, value) => {
        if (value.size() > maxValue) {
          maxValue = value.size()
          maxIndex = key
        }
      }
    }
    if (maxValue > 1) {
      map foreach {
        case (key, value) => {
          if (key != maxIndex && value.size > 1) {
            maxValue = 0
          }
        }
      }
    }
    (maxIndex + 1, maxValue)
  }

  def solve() = {
    val Array(n, m): Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
    val maze: Array[Array[Char]] = Array.ofDim[Char](n, m)
    for (i <- 0 until n) {
      maze(i) = scala.io.StdIn.readLine().toCharArray
    }
    val rowList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    val colList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    var starCount = 0
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        if (maze(i)(j) == '*') {
          starCount += 1
          if (!rowList.contains(i)) {
            rowList += (i -> new util.ArrayList[Int]())
          }
          if (!colList.contains(j)) {
            colList += (j -> new util.ArrayList[Int]())
          }
          rowList(i).add(j)
          colList(j).add(i)
        }
      }
    }
    val (maxRowIndex, maxRowValue) = max(rowList)
    val (maxColIndex, maxColValue) = max(colList)

    if (maxRowValue + maxColValue - starCount >= 0) {
      println("YES")
      if ((maxRowValue == 1 && maxColValue == 1) || (maxRowValue != 1 && maxColValue != 1)) {
        println(maxRowIndex + " " + maxColIndex)
      } else if (maxColValue != 1) {
        var row = colList(maxColIndex-1).get(0)
        rowList foreach {
          case (key, value) => {
            if (key != row) {
              row = key
            }
          }
        }
        println((row + 1) + " " + maxColIndex)
      } else {
        var col = rowList(maxRowIndex-1).get(0)
        colList foreach {
          case (key, value) => {
            if (key != col) {
              col = key
            }
          }
        }
        println(maxRowIndex + " " + (col + 1))
      }
    } else {
      println("NO")
    }
  }

  solve()

}

import java.util

import scala.collection.mutable

/**
 * @author pvasilyev
 * @since 11 Aug 2016
 */
object B699 extends App {

  def max(map: mutable.Map[Int, util.ArrayList[Int]]): (Int, Int) = {
    var maxIndex = 0
    var maxValue = 0
    map foreach {
      case (key, value) => {
        if (value.size() > maxValue) {
          maxValue = value.size()
          maxIndex = key
        }
      }
    }
    if (maxValue > 1) {
      map foreach {
        case (key, value) => {
          if (key != maxIndex && value.size > 1) {
            maxValue = 0
          }
        }
      }
    }
    (maxIndex + 1, maxValue)
  }

  def solve() = {
    val Array(n, m): Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
    val maze: Array[Array[Char]] = Array.ofDim[Char](n, m)
    for (i <- 0 until n) {
      maze(i) = scala.io.StdIn.readLine().toCharArray
    }
    val rowList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    val colList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    var starCount = 0
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        if (maze(i)(j) == '*') {
          starCount += 1
          if (!rowList.contains(i)) {
            rowList += (i -> new util.ArrayList[Int]())
          }
          if (!colList.contains(j)) {
            colList += (j -> new util.ArrayList[Int]())
          }
          rowList(i).add(j)
          colList(j).add(i)
        }
      }
    }
    val (maxRowIndex, maxRowValue) = max(rowList)
    val (maxColIndex, maxColValue) = max(colList)

    if (maxRowValue + maxColValue - starCount >= 0) {
      println("YES")
      println(maxRowIndex + " " + maxColIndex)

    } else {
      println("NO")
    }
  }

  solve()

}

import java.util

import scala.collection.mutable

/**
 * @author pvasilyev
 * @since 11 Aug 2016
 */
object B699 extends App {

  def max(map: mutable.Map[Int, util.ArrayList[Int]]): (Int, Int) = {
    var maxIndex = 0
    var maxValue = 0
    map foreach {
      case (key, value) => {
        if (value.size() > maxValue) {
          maxValue = value.size()
          maxIndex = key
        }
      }
    }
    if (maxValue > 1) {
      map foreach {
        case (key, value) => {
          if (key != maxIndex && value.size > 1) {
            maxValue = 0
          }
        }
      }
    }
    (maxIndex + 1, maxValue)
  }

  def solve() = {
    val Array(n, m): Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
    val maze: Array[Array[Char]] = Array.ofDim[Char](n, m)
    for (i <- 0 until n) {
      maze(i) = scala.io.StdIn.readLine().toCharArray
    }
    val rowList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    val colList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    var starCount = 0
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        if (maze(i)(j) == '*') {
          starCount += 1
          if (!rowList.contains(i)) {
            rowList += (i -> new util.ArrayList[Int]())
          }
          if (!colList.contains(j)) {
            colList += (j -> new util.ArrayList[Int]())
          }
          rowList(i).add(j)
          colList(j).add(i)
        }
      }
    }
    val (maxRowIndex, maxRowValue) = max(rowList)
    val (maxColIndex, maxColValue) = max(colList)

    if (maxRowValue + maxColValue - starCount >= 0) {
      println("YES")
      if ((maxRowValue == 1 && maxColValue == 1) || (maxRowValue != 1 && maxColValue != 1)) {
        println(maxRowIndex + " " + maxColIndex)
      } else if (maxColValue != 1) {
        val row = colList(maxColIndex-1).get(0)
        var rrow = 0
        rowList foreach {
          case (key, value) => {
            if (key != row) {
              rrow = key
            }
          }
        }
        println((rrow + 1) + " " + maxColIndex)
      } else {
        val col = rowList(maxRowIndex-1).get(0)
        var ccol = 0
        colList foreach {
          case (key, value) => {
            if (key != col) {
              ccol = key
            }
          }
        }
        println(maxRowIndex + " " + (ccol + 1))
      }
    } else {
      println("NO")
    }
  }

  solve()

}

import java.util

import scala.collection.mutable

/**
 * @author pvasilyev
 * @since 11 Aug 2016
 */
object B699 extends App {

  def max(map: mutable.Map[Int, util.ArrayList[Int]]): (Int, Int) = {
    var maxIndex = 0
    var maxValue = 0
    map foreach {
      case (key, value) => {
        if (value.size() > maxValue) {
          maxValue = value.size()
          maxIndex = key
        }
      }
    }
    if (maxValue > 1) {
      map foreach {
        case (key, value) => {
          if (key != maxIndex && value.size > 1) {
            maxValue = 0
          }
        }
      }
    }
    (maxIndex + 1, maxValue)
  }

  def solve() = {
    val Array(n, m): Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
    val maze: Array[Array[Char]] = Array.ofDim[Char](n, m)
    for (i <- 0 until n) {
      maze(i) = scala.io.StdIn.readLine().toCharArray
    }
    val rowList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    val colList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    var starCount = 0
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        if (maze(i)(j) == '*') {
          starCount += 1
          if (!rowList.contains(i)) {
            rowList += (i -> new util.ArrayList[Int]())
          }
          if (!colList.contains(j)) {
            colList += (j -> new util.ArrayList[Int]())
          }
          rowList(i).add(j)
          colList(j).add(i)
        }
      }
    }
    val (maxRowIndex, maxRowValue) = max(rowList)
    val (maxColIndex, maxColValue) = max(colList)

    if (maxRowValue + maxColValue - starCount >= 0) {
      println("YES")
      if ((maxRowValue == 1 && maxColValue == 1) || (maxRowValue != 1 && maxColValue != 1)) {
        println(maxRowIndex + " " + maxColIndex)
      } else if (maxColValue != 1) {
        var row = colList(maxColIndex-1).get(0)
        rowList foreach {
          case (key, value) => {
            if (key != row) {
              row = key
            }
          }
        }
        println((row + 1) + " " + maxColIndex)
      } else {
        var col = rowList(maxRowIndex-1).get(0)
        colList foreach {
          case (key, value) => {
            if (key != col) {
              col = key
            }
          }
        }
        println(maxRowValue + " " + (col + 1))
      }
    } else {
      println("NO")
    }
  }

  solve()

}

import java.util

import scala.collection.mutable

/**
 * @author pvasilyev
 * @since 11 Aug 2016
 */
object B699 extends App {

  def max(map: mutable.Map[Int, util.ArrayList[Int]]): (Int, Int) = {
    var maxIndex = 0
    var maxValue = 0
    map foreach {
      case (key, value) => {
        if (value.size() > maxValue) {
          maxValue = value.size()
          maxIndex = key
        }
      }
    }
    (maxIndex+1, maxValue)
  }

  def solve() = {
    val Array(n, m): Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
    val maze: Array[Array[Char]] = Array.ofDim[Char](n, m)
    for (i <- 0 until n) {
      maze(i) = scala.io.StdIn.readLine().toCharArray
    }
    val rowList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    val colList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    var starCount = 0
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        if (maze(i)(j) == '*') {
          starCount += 1
          if (!rowList.contains(i)) {
            rowList += (i -> new util.ArrayList[Int]())
          }
          if (!colList.contains(j)) {
            colList += (j -> new util.ArrayList[Int]())
          }
          rowList(i).add(j)
          colList(j).add(i)
        }
      }
    }
    val (maxRowIndex, maxRowValue) = max(rowList)
    val (maxColIndex, maxColValue) = max(colList)

    if (maxRowValue + maxColValue - starCount >= 0) {
      println("YES")
      println(maxRowIndex + " " + maxColIndex)
    } else {
      println("NO")
    }
  }

  solve()

}

import java.util

import scala.collection.mutable

/**
 * @author pvasilyev
 * @since 11 Aug 2016
 */
object B699 extends App {

  def max(map: mutable.Map[Int, util.ArrayList[Int]]): (Int, Int) = {
    var maxIndex = 0
    var maxValue = 0
    map foreach {
      case (key, value) => {
        if (value.size() > maxValue) {
          maxValue = value.size()
          maxIndex = key
        }
      }
    }
    if (maxValue > 1) {
      map foreach {
        case (key, value) => {
          if (key != maxIndex && value.size > 1) {
            maxValue = 0
          }
        }
      }
    }
    (maxIndex + 1, maxValue)
  }

  def solve() = {
    val Array(n, m): Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
    val maze: Array[Array[Char]] = Array.ofDim[Char](n, m)
    for (i <- 0 until n) {
      maze(i) = scala.io.StdIn.readLine().toCharArray
    }
    val rowList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    val colList: mutable.Map[Int, util.ArrayList[Int]] = mutable.Map.empty
    var starCount = 0
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        if (maze(i)(j) == '*') {
          starCount += 1
          if (!rowList.contains(i)) {
            rowList += (i -> new util.ArrayList[Int]())
          }
          if (!colList.contains(j)) {
            colList += (j -> new util.ArrayList[Int]())
          }
          rowList(i).add(j)
          colList(j).add(i)
        }
      }
    }
    val (maxRowIndex, maxRowValue) = max(rowList)
    val (maxColIndex, maxColValue) = max(colList)

    if (maxRowValue + maxColValue - starCount >= 0) {
      println("YES")
      if (maxRowValue != 1 && maxColValue != 1) {
        println(maxRowIndex + " " + maxColIndex)
      } else if (maxRowValue == 1 && maxColValue == 1) {
        if (starCount == 1) {
          println(maxRowIndex + " " + maxColIndex)
        } else {
          val row = colList(maxColIndex - 1).get(0)
          var rrow = 0
          rowList foreach {
            case (key, value) => {
              if (key != row) {
                rrow = key
              }
            }
          }
          val col = rowList(rrow).get(0)
          var ccol = 0
          colList foreach {
            case (key, value) => {
              if (key != col) {
                ccol = key
              }
            }
          }
          println((rrow + 1) + " " + (ccol + 1))
        }
      } else if (maxColValue != 1) {
        val row = colList(maxColIndex - 1).get(0)
        var rrow = 0
        rowList foreach {
          case (key, value) => {
            if (key != row) {
              rrow = key
            }
          }
        }
        println((rrow + 1) + " " + maxColIndex)
      } else {
        val col = rowList(maxRowIndex - 1).get(0)
        var ccol = 0
        colList foreach {
          case (key, value) => {
            if (key != col) {
              ccol = key
            }
          }
        }
        println(maxRowIndex + " " + (ccol + 1))
      }
    } else {
      println("NO")
    }
  }

  solve()

}

import scala.util.control.Breaks._

object main extends App{
  val Array(n, m) = readLine.split(" ").map(_.toInt)
  var area = new Array[String](n)
  var rows = new Array[Int](n)
  var cols = new Array[Int](m)
  var count = 0
  for (i <- 0 until n) {
  	area(i) = readLine
  	rows(i) = area(i).toArray.foldLeft(0)((count: Int, char: Char) => if (char == '*') count + 1 else count)
  	count += rows(i)
  	List.range(0, m).foreach((j: Int) => if (area(i)(j) == '*') cols(j) += 1 )
  }
  println("Count ", count);
  val r = () => {
  	var result: Any = "NO";
  	for (i <- 0 until n) {
	  	for (j <- 0 until m) {
	  		val res = rows(i) + cols(j)
	  		if (res >= count) {
	  			println("Count rows(i) ", rows(i), "count cols(j)", cols(j))
	  			result = Array(i+1, j+1)
	  		}
	  	}
  	}
  	result;
  }
  r() match {
  	case s: String => println(s)
  	case Array(x, y) => {
  		println("YES")
  		println("%d %d".format(x, y))
  	}
  }
}

import scala.util.control.Breaks._

object main extends App{
  val Array(n, m) = readLine.split(" ").map(_.toInt)
  var area = new Array[String](n)
  var rows = new Array[Int](n)
  var cols = new Array[Int](m)
  var count = 0
  for (i <- 0 until n) {
  	area(i) = readLine
  	rows(i) = area(i).toArray.foldLeft(0)((count: Int, char: Char) => if (char == '*') count + 1 else count)
  	count += rows(i)
  	List.range(0, m).foreach((j: Int) => if (area(i)(j) == '*') cols(j) += 1 )
  }
  val r = () => {
  	var result: Any = "NO";
  	for (i <- 0 until n) {
	  	for (j <- 0 until m) {
	  		val res = rows(i) + cols(j)
	  		if (res >= count) {
	  			result = Array(i+1, j+1)
	  		}
	  	}
  	}
  	result;
  }
  r() match {
  	case s: String => println(s)
  	case Array(x, y) => {
  		println("YES")
  		println("%d %d".format(x, y))
  	}
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _699B extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val n, m = read[Int]
    val map = read[Vector, String](n)

    val bombs = for {
      r <- 0 until n
      c <- 0 until m
      if map(r)(c) == '*'
    } yield (r, c)

    val ans = if (bombs.length >= n+m) {
      None
    } else if (bombs.isEmpty) {
      Some(0 -> 0)
    } else {
      val rb = bombs.groupBy(_._1) collect {
        case (r, bs) if bs.length > 1 => r
      }

      val rc = bombs.groupBy(_._2) collect {
        case (c, bs) if bs.length > 1 => c
      }

      val (cx, cy) = (rb.headOption getOrElse 0) -> (rc.headOption getOrElse 0)
      when(bombs forall {case (i, j) => cx == i || cy == j}) {
        cx -> cy
      }
    }

    ans.map{case (i, j) => (i+1) -> (j+1)} match {
      case None => write(false.toYesNo)
      case Some((i, j)) =>
        write(true.toYesNo).writeLine().write(i, j)
    }
    io
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
    def X[B](bs: Iterable[B]): Iterable[(A, B)] = for {a <- s; b <- bs} yield (a, b)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toYesNo = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeLine(obj: Any*): this.type = {
    if (obj.isEmpty) printer.println() else obj foreach printer.println
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}