#include <bits/stdc++.h>
using namespace std;
long long a[1000100], mod = 1000000000000000000ll, n, m, sum, cnt, cnt2,
                      c[1000100], w[1000100];
int s[1000100], top, p, q[1000100], Nxt[1000100], fa[1000100][30];
pair<long long, long long> ans;
map<long long, long long> Map;
pair<long long, long long> operator+(pair<long long, long long> x,
                                     long long y) {
  return make_pair(((x.first + y) % mod), (x.second + (x.first + y) / mod));
}
long long operator%(pair<long long, long long> x, long long y) {
  return (x.first % y + (x.second % y) * (mod % y) % y) % y;
}
struct node {
  int left, right, Min;
  node *ch[2];
} pool[4 * 1000100], *root;
void buildtree(node *p, long long left, long long right) {
  p->left = left;
  p->right = right;
  if (left == right) return;
  long long mid = (left + right) / 2;
  node *lson = &pool[++cnt2], *rson = &pool[++cnt2];
  p->ch[0] = lson;
  p->ch[1] = rson;
  buildtree(lson, left, mid);
  buildtree(rson, mid + 1, right);
}
void change(node *p, long long left, long long right, long long s) {
  if (p->left == left && p->right == right) {
    p->Min = s;
    return;
  }
  if (p->ch[0]->right >= right)
    change(p->ch[0], left, right, s);
  else
    change(p->ch[1], left, right, s);
  p->Min = min(p->ch[0]->Min, p->ch[1]->Min);
}
long long query(node *p, long long left, long long right) {
  if (p->left == left && p->right == right) return p->Min;
  if (p->ch[0]->right >= right)
    return query(p->ch[0], left, right);
  else if (p->ch[1]->left <= left)
    return query(p->ch[1], left, right);
  else
    return min(query(p->ch[0], left, p->ch[0]->right),
               query(p->ch[1], p->ch[1]->left, right));
}
void pl(long long u, long long cc) {
  Map[u] += cc;
  sum += u * cc;
}
void solve(long long u) {
  top = 0;
  for (map<long long, long long>::iterator it = Map.upper_bound(u);
       it != Map.end(); ++it) {
    q[++top] = it->first;
    cnt += it->second;
    sum -= it->first * it->second;
  }
  while (top) {
    Map.erase(q[top]);
    top--;
  }
}
int main() {
  char s1[5];
  scanf("%lld", &n);
  scanf("%s", s1 + 1);
  scanf("%lld", &a[1]);
  ans = ans + a[1];
  s[1] = s1[1] - 'a';
  root = &pool[++cnt2];
  buildtree(root, 1, n);
  change(root, 1, 1, a[1]);
  printf("%lld\n", a[1]);
  for (long long i = 2; i <= n; i++) {
    scanf("%s", s1 + 1);
    scanf("%lld", &a[i]);
    s[i] = ((long long)(s1[1] - 'a') + (ans % 26)) % 26;
    a[i] = (a[i] ^ (ans % (1ll << 30)));
    if (s[i] == s[1]) pl(a[i], 1);
    change(root, i, i, a[i]);
    ans = ans + query(root, 1, i);
    p = Nxt[i - 1];
    while (p != 0 && s[i] != s[p + 1]) p = Nxt[p];
    if (s[p + 1] == s[i]) p++;
    Nxt[i] = p;
    w[i - 1] = s[i];
    for (long long j = 0; j <= 25; j++) fa[i][j] = fa[Nxt[i]][j];
    fa[i][w[Nxt[i]]] = Nxt[i];
    for (long long j = 0; j <= 25; j++) {
      if (s[i] == j) continue;
      for (long long k = fa[i - 1][j]; k; k = fa[k][j])
        pl(query(root, i - k, i - 1), -1);
    }
    cnt = 0;
    solve(a[i]);
    pl(a[i], cnt);
    ans = ans + sum;
    if (ans.second != 0)
      printf("%lld%018lld\n", ans.second, ans.first);
    else
      printf("%lld\n", ans.first);
  }
  return 0;
}
