import java.util.*
import kotlin.collections.ArrayList

fun main(args: Array<String>) {
    val (width, height) = readLine()!!.trim().split(' ').map(String::toInt)
    val state = List(height){ readLine()!!.trim()}
    val gain = Array(10){ readLine()!!.trim().split(' ').map(String::toInt).toIntArray()}
    val barriers = ArrayList<Coordinate>()
    val items = Array(10){Coordinate(0, 0)}
    var start = Coordinate(0, 0)
    var goal = Coordinate(0, 0)
    for (i in state.indices) for (j in state[i].indices) {
        when(state[i][j]) {
            '.' -> {}
            '#' -> {}
            'S' -> start = Coordinate(i, j)
            'T' -> goal = Coordinate(i, j)
            else ->
                if (state[i][j].isDigit()) {
                    items[state[i][j] - '0'] = Coordinate(i, j)
                }else if (state[i][j].isUpperCase()) {
                    barriers.add(Coordinate(i, j))
                }else {
                    barriers.add(Coordinate(i, j))
                }
        }
    }
    val id = Array(height){IntArray(width){-1} }
    val specialCell = Array(12 + barriers.size){
        when {
            it < 10 -> Cell(items[it], CellType(state[items[it]]))
            it == 10 -> Cell(start, CellType.Start)
            it == 11 -> Cell(goal, CellType.Goal)
            else -> Cell(barriers[it - 12], CellType(state[barriers[it - 12]]))
        }
    }
    for (i in specialCell.indices) {
        id[specialCell[i].coordinate] = i
    }
    val minDistanceWithoutThroughBarrier = Array(specialCell.size){ IntArray(specialCell.size){Int.MAX_VALUE} }.also {
        for (i in specialCell.indices) it[i][i] = 0
    }
    val step = Array(height){IntArray(width){-1} }
    val queue: Queue<Coordinate> = ArrayDeque<Coordinate>()
    for (from in specialCell.indices) {
        step.forEach { it.fill(-1) }
        step[specialCell[from].coordinate] = 0
        queue.add(specialCell[from].coordinate)
        while(queue.isNotEmpty()) {
            val top = queue.poll()
            for (next in top.neighbors) if (next.x in 0 until height && next.y in 0 until width && step[next.x][next.y] == -1) {
                step[next.x][next.y] = step[top.x][top.y] + 1
                when {
                    state[next.x][next.y].isDigit() || state[next.x][next.y] == '.' || state[next.x][next.y] == 'S' || state[next.x][next.y] == 'T' -> queue.add(next)
                }
                if (id[next.x][next.y] != -1) {
                    minDistanceWithoutThroughBarrier[from][id[next]] = step[next]
                }
            }
        }
    }
    val minDistance = Array(1024){Array(specialCell.size){IntArray(specialCell.size){Int.MAX_VALUE} } }
    for (s in minDistance.indices) {
        for (x in specialCell.indices) for (y in specialCell.indices) {
            minDistance[s][x][y] = minDistanceWithoutThroughBarrier[x][y]
        }
        for (k in specialCell.indices) if (specialCell[k].type.canPass(s)) {
            for (i in specialCell.indices) if (minDistance[s][i][k] != Int.MAX_VALUE) {
                for (j in specialCell.indices) if (minDistance[s][k][j] != Int.MAX_VALUE){
                    if (minDistance[s][i][j] > minDistance[s][i][k] + minDistance[s][k][j]) {
                        minDistance[s][i][j] = minDistance[s][i][k] + minDistance[s][k][j]
                    }
                }
            }
        }
    }
    val memo = Array(1024){Array(10){Pair(-1, -1)} }
    val result = calMinMax(0, 0, minDistance, memo, gain)
    println(
            when {
                result.first == Int.MAX_VALUE -> -1
                else -> "${result.first} ${result.second}"
            }
    )
}
fun calMinMax(state: Int, last: Int, minDistance: Array<Array<IntArray>>, memo: Array<Array<Pair<Int, Int>>>, score: Array<IntArray>): Pair<Int, Int> {
    if (memo[state][last].first >= 0) return memo[state][last]
    if (state == 1023) {
        val result = Pair(minDistance[state][last][11], 0)
        memo[state][last] = result
        return result
    }
    if (state == 0) {
        var result = Pair(Int.MAX_VALUE, 0)
        for (i in 0 until 10) if (minDistance[state][10][i] != Int.MAX_VALUE) {
            val next = calMinMax(state or (1 shl i), i, minDistance, memo, score)
            if (next.first == Int.MAX_VALUE) continue
            val dist = minDistance[state][10][i]
            if (result.first > dist + next.first) {
                result = Pair(dist + next.first, next.second)
            }else if (result.first == dist + next.first) {
                result = Pair(result.first, maxOf(next.second, result.second))
            }
        }
        return result
    }
    var result = Pair(Int.MAX_VALUE, 0)
    for (i in 0 until 10) if ((state and (1 shl i)) == 0 && minDistance[state][last][i] != Int.MAX_VALUE) {
        val next = calMinMax(state or (1 shl i), i, minDistance, memo, score)
        if (next.first == Int.MAX_VALUE) continue
        val dist = minDistance[state][last][i]
        val s = score[last][i]
        if (result.first > dist + next.first) {
            result = Pair(dist + next.first, s + next.second)
        }else if (result.first == dist + next.first) {
            result = Pair(result.first, maxOf(s + next.second, result.second))
        }
    }
    memo[state][last] = result
    return result
}
operator fun <T> List<List<T>>.get(coordinate: Coordinate): T {
    return this[coordinate.x][coordinate.y]
}
operator fun List<String>.get(coordinate: Coordinate): Char {
    return this[coordinate.x][coordinate.y]
}
operator fun Array<IntArray>.get(coordinate: Coordinate): Int {
    return this[coordinate.x][coordinate.y]
}
operator fun Array<IntArray>.set(coordinate: Coordinate, value: Int): Unit {
    this[coordinate.x][coordinate.y] = value
}
sealed class CellType {
    open fun canPass(state: Int): Boolean = true
    object Wall: CellType() {
        override fun canPass(state: Int): Boolean {
            return false
        }
    }
    class BarrierIf(private val item: Int): CellType() {
        override fun canPass(state: Int): Boolean {
            return (state and (1 shl item)) != 0
        }
    }
    class BarrierUnless(private val item: Int): CellType() {
        override fun canPass(state: Int): Boolean {
            return (state and (1 shl item)) == 0
        }
    }

    object Empty: CellType()
    object Start: CellType()
    object Goal: CellType()
    class Item(val item: Int): CellType()
    companion object {
        operator fun invoke(char: Char): CellType {
            return when(char) {
                '.' -> Empty
                '#'->Wall
                'S' -> Start
                'T' -> Goal
                else ->
                    if (char.isDigit()) Item(char - '0')
                    else if (char.isUpperCase()) BarrierUnless(char - 'A')
                    else BarrierIf(char - 'a')
            }
        }
    }
}
data class Cell(val coordinate: Coordinate, val type: CellType)
data class Coordinate(val x: Int, val y: Int) {
    val neighbors: List<Coordinate>
        get() = listOf(Coordinate(x + 1, y), Coordinate(x - 1, y), Coordinate(x, y + 1), Coordinate(x, y - 1))
}



Measured memory_bytes: 703612