import scala.collection.mutable.ArrayBuffer

object Main {

  def main(args: Array[String]): Unit = {

    class UnionSet(par: Array[Int]) {
      def root(x: Int): Int =
        if (par(x) == x) x
        else {
          par(x) = root(par(x))
          par(x)
        }
      def unite(x: Int, y: Int): Unit = {
        val rx = root(x)
        val ry = root(y)
        if (rx != ry)
          par(rx) = ry
      }
      def same(x: Int, y: Int): Boolean =
        root(x) == root(y)
    }
    object UnionSet {
      def apply(n: Int): UnionSet =
        new UnionSet(Array.range(0, n))
    }

    val sc = new java.util.Scanner(System.in)

    val N = sc.nextInt()
    val W = Array.fill(N, N)(sc.nextInt())

    val _E = new ArrayBuffer[(Int, Int)]() // (辺(u,v), 重みw)
    (0 until N) foreach { i =>
      (0 until N) foreach { j =>
        if (W(i)(j) >= 0) {
          _E.append((i, j))
        }
      }
    }
    val E: List[(Int, Int)] = _E.sortBy(e => W(e._1)(e._2)).toList // 辺(軽い順)

    // 最初, 全ての頂点は別の木として初期化する
    val unionset = UnionSet(N)
    var count = 0
    // 軽い辺から見ていき
    E foreach { e =>
      val (u, v) = e
      // u, v が別の木ならば, これは軽い辺なので安全に追加できる.
      if (!unionset.same(u, v)) {
        unionset.unite(u, v)
        count += W(u)(v)
      }
    }

    // 入力が連結グラフであることから,最終的に出来上がった木は1本となり, これが最小全域木である
    // 加えた辺の重さの合計が最小全域木の重さの合計
    println(count)
  }

}

