#include <bits/stdc++.h>
using std::pair;
using std::queue;
using std::unordered_set;
using std::vector;
struct Edge {
  int to, index, flow, cost;
  Edge(int to, int index, int flow, int cost)
      : to(to), index(index), flow(flow), cost(cost) {}
};
vector<vector<Edge>> edgesList;
vector<vector<int>> heightList;
vector<unsigned int> isEnqueued, state;
vector<int> excess, height, hCount;
int epsilon = 0;
int N, S, T;
void addEdge(int from, int to, int cap, int cost) {
  cost *= N;
  epsilon = std::max(epsilon, cost);
  edgesList[from].emplace_back(to, edgesList[to].size(), cap, cost);
  edgesList[to].emplace_back(from, edgesList[from].size() - 1, 0, -cost);
}
void push(Edge &e, int amt) {
  amt = std::min(amt, e.flow);
  e.flow -= amt;
  edgesList[e.to][e.index].flow += amt;
  excess[e.to] += amt;
  excess[edgesList[e.to][e.index].to] -= amt;
}
inline void relabel(int v) {
  int newHeight = (((int)1e9) >> 1) * -1;
  for (int i = 0; i < edgesList[v].size(); i++) {
    Edge &e = edgesList[v][i];
    if (e.flow && newHeight < height[e.to] - e.cost) {
      newHeight = height[e.to] - e.cost;
      state[v] = i;
    }
  }
  height[v] = newHeight - epsilon;
}
void addFlow(Edge &e, int f) {
  Edge &back = edgesList[e.to][e.index];
  if (!excess[e.to] && f) {
    heightList[height[e.to]].push_back(e.to);
  }
  e.flow -= f;
  back.flow += f;
  excess[e.to] += f;
  excess[back.to] -= f;
}
int maxFlow() {
  excess.assign(N, 0);
  height.assign(N, 0);
  heightList.resize(2 * N);
  hCount.assign(2 * N, 0);
  state.assign(N, 0);
  height[S] = N;
  excess[T] = 1;
  hCount[0] = N - 1;
  for (Edge &e : edgesList[S]) {
    addFlow(e, e.flow);
  }
  if (heightList[0].size()) {
    int curh = 0;
    while (curh >= 0) {
      int v = heightList[curh].back();
      heightList[curh].pop_back();
      while (excess[v] > 0) {
        if (state[v] == edgesList[v].size()) {
          height[v] = (int)1e9;
          for (int i = 0; i < edgesList[v].size(); i++) {
            Edge &e = edgesList[v][i];
            if (e.flow && height[v] > height[e.to] + 1) {
              height[v] = height[e.to] + 1;
              state[v] = i;
            }
          }
          if (++hCount[height[v]], !--hCount[curh] && curh < N) {
            for (int i = 0; i < N; i++)
              if (curh < height[i] && height[i] < N) {
                --hCount[height[i]];
                height[i] = N + 1;
              }
          }
          curh = height[v];
        } else if (edgesList[v][state[v]].flow &&
                   height[v] == height[edgesList[v][state[v]].to] + 1) {
          addFlow(edgesList[v][state[v]],
                  std::min(excess[v], edgesList[v][state[v]].flow));
        } else {
          ++state[v];
        }
      }
      while (curh >= 0 && heightList[curh].empty()) {
        --curh;
      }
    }
  }
  return -excess[S];
}
pair<int, int> minCostMaxFlow() {
  int cost = 0;
  for (int i = 0; i < N; i++)
    for (Edge e : edgesList[i]) {
      cost += e.flow * e.cost;
    }
  int flow = maxFlow();
  height.assign(N, 0);
  excess.assign(N, 0);
  isEnqueued.assign(N, 0);
  state.assign(N, 0);
  queue<int> q;
  int scale = 2;
  for (; epsilon; epsilon >>= scale) {
    std::fill(state.begin(), state.end(), 0);
    for (int i = 0; i < N; i++)
      for (Edge &e : edgesList[i])
        if (height[i] + e.cost - height[e.to] < 0 && e.flow) {
          push(e, e.flow);
        }
    for (int i = 0; i < N; i++)
      if (excess[i] > 0) {
        q.push(i);
        isEnqueued[i] = true;
      }
    while (!q.empty()) {
      int v = q.front();
      q.pop();
      isEnqueued[v] = false;
      while (excess[v] > 0) {
        if (state[v] == edgesList[v].size()) {
          relabel(v);
        }
        for (unsigned int &i = state[v]; i < edgesList[v].size(); i++) {
          Edge &e = edgesList[v][i];
          if (height[v] + e.cost - height[e.to] < 0) {
            push(e, excess[v]);
            if (excess[e.to] > 0 && !isEnqueued[e.to]) {
              q.push(e.to);
              isEnqueued[e.to] = true;
            }
            if (excess[v] == 0) {
              break;
            }
          }
        }
      }
    }
    if (epsilon > 1 && epsilon >> scale == 0) {
      epsilon = 1 << scale;
    }
  }
  for (int i = 0; i < N; i++)
    for (Edge &e : edgesList[i]) {
      cost -= e.cost * e.flow;
    }
  return std::make_pair(flow, cost / 2 / N);
}
char buffer[101];
vector<int> performString(char buffer[]) {
  vector<int> str(27, 0);
  for (int i = 0; buffer[i] != '\0'; i++) {
    int index = buffer[i] - 'a';
    str[index]++;
  }
  return str;
}
int main() {
  int n;
  scanf("%s[100]", buffer);
  scanf("%d", &n);
  unordered_set<char> sequence;
  int size = 0;
  do {
    sequence.insert(buffer[size]);
  } while (buffer[++size] != '\0');
  S = n + 27 + 1, T = S + 1, N = T + 1;
  edgesList.resize(N);
  auto seq = performString(buffer);
  for (int i = 0; i < seq.size(); i++) {
    if (seq[i]) {
      int cap = seq[i];
      addEdge(i + n, T, cap, 0);
    }
  }
  for (int i = 0; i < n; i++) {
    int sCap;
    scanf("%s %d", buffer, &sCap);
    addEdge(S, i, sCap, 0);
    seq = performString(buffer);
    for (int j = 0; j < seq.size(); j++) {
      if (seq[j]) {
        auto got = sequence.find(j + 'a');
        if (got != sequence.end()) {
          int cap = seq[j];
          addEdge(i, j + n, cap, i + 1);
        }
      }
    }
  }
  pair<int, int> ans = minCostMaxFlow();
  if (ans.first != size) {
    printf("-1");
    return 0;
  }
  printf("%d", ans.second);
  return 0;
}
