#include <iostream>
#include <vector>
#include <string>
#include <stack>

using namespace std;

// 矩阵结构
struct Matrix {
    int rows;
    int cols;
};

// 读取矩阵信息
vector<Matrix> readMatrices(int n) {
    vector<Matrix> matrices(n);
    for (int i = 0; i < n; i++) {
        cin >> matrices[i].rows >> matrices[i].cols;
    }
    return matrices;
}

// 处理右括号的逻辑
void processParenthesis(stack<int>& indices, vector<Matrix>& matrices, int& totalCost) {
    int rightIndex = indices.top();
    indices.pop();
    int leftIndex = indices.top();
    indices.pop();

    // 计算当前乘法的运算量
    int cost = matrices[leftIndex].rows * matrices[leftIndex].cols * matrices[rightIndex].cols;
    totalCost += cost;

    // 更新左矩阵的列数为右矩阵的列数
    matrices[leftIndex].cols = matrices[rightIndex].cols;

    // 将更新后的左矩阵索引重新压入栈
    indices.push(leftIndex);
}

// 解析表达式并计算运算量
int parseExpression(const string& expression, vector<Matrix>& matrices) {
    stack<int> indices; // 存储矩阵索引
    int totalCost = 0;  // 总运算量

    for (size_t i = 0; i < expression.size(); ++i) {
        if (expression[i] == '(') {
            // 遇到左括号,直接跳过
            continue;
        } else if (expression[i] == ')') {
            // 遇到右括号,调用封装的函数处理
            processParenthesis(indices, matrices, totalCost);
        } else if (isalpha(expression[i])) {
            // 遇到矩阵,记录其索引
            int index = expression[i] - 'A';
            indices.push(index);
        }
    }

    return totalCost;
}

int main() {
    int n;
    cin >> n;
    vector<Matrix> matrices = readMatrices(n);
    string expression;
    cin >> expression;

    int totalCost = parseExpression(expression, matrices);

    cout << totalCost << endl;

    return 0;
}