#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
const int maxN = 666666, maxTS = 1 << 21, INF = 1 << 30, E = 26;
struct BigNum {
  static const int B = 1000000000;
  vector<int> a;
  int sign;
  BigNum(long long n = 0) {
    sign = 1;
    if (n < 0) sign = -1, n *= -1;
    a.resize(0);
    if (n == 0) a.push_back(0);
    for (; n != 0; n /= B) a.push_back(n % B);
  }
  int operator[](int i) const { return a[i]; }
  void operator+=(const BigNum& other) {
    a.resize(max(a.size(), other.a.size()));
    int carry = 0;
    for (int i = (0); i < (int)(a.size()); i++) {
      int b = a[i] + carry + (i < other.a.size() ? other[i] : 0);
      a[i] = b % B;
      carry = b >= B;
    }
    if (carry == 1) a.push_back(1);
  }
  int operator%(int m) {
    long long b = 1;
    int res = 0;
    for (int i = (0); i < (int)(a.size()); i++)
      res = (b * a[i] + res) % m, b = b * B % m;
    if (sign == -1 and res != 0) res = m - res;
    return res;
  }
  void print() {
    printf("%d", a.back());
    for (int i = a.size() - 2; i > (int)(-1); i--) printf("%09d", a[i]);
    printf("\n");
  }
} A(0);
struct Tree {
  int offset, qbegin, qend, T[maxTS], res;
  void qpriv(int v, int left, int right) {
    if (left >= qend or right <= qbegin) return;
    if (left >= qbegin and right <= qend) {
      res = min(res, T[v]);
      return;
    }
    qpriv(v * 2, left, (left + right) / 2);
    qpriv(v * 2 + 1, (left + right) / 2, right);
  }
  void init(int n) {
    for (offset = 1; offset < n; offset *= 2)
      ;
    for (int i = (1); i < (int)(offset * 2); i++) T[i] = INF;
  }
  int query(int a, int b) {
    qbegin = a + offset;
    qend = b + offset;
    res = INF;
    qpriv(1, offset, offset * 2);
    return res;
  }
  void updt(int v, int val) {
    for (v += offset; v != 0; v /= 2) T[v] = min(T[v], val);
  }
} tree;
int W[maxN], pi[maxN], jp[maxN];
char S[maxN];
map<int, int> M;
long long B = 0;
bool remin(int x) {
  if (M.empty()) return false;
  int y, ile;
  tie(y, ile) = *M.rbegin();
  if (y > x) {
    long long C = 1ll * ile * (y - x);
    B -= C;
    M[x] += ile;
    M.erase(y);
  }
  return y > x;
}
void usun(int a, int b) {
  int kto = tree.query(a, b);
  M[kto]--;
  B -= kto;
}
char readCH() {
  char buf[42];
  scanf("%s", buf);
  return buf[0];
}
int main() {
  int n;
  scanf("%d", &n);
  tree.init(n + 1);
  for (int i = (1); i < (int)(n + 1); i++) {
    int c = (readCH() - 'a') + (A % E);
    S[i] = 'a' + c % E;
    scanf("%d", W + i);
    W[i] ^= (int)(A % INF);
    tree.updt(i, W[i]);
    0;
    0;
    0;
    for (int q = pi[i - 1]; q != 0;) {
      if (S[i] != S[q + 1])
        usun(i - q, i), 0, q = pi[q];
      else
        q = jp[q];
    }
    0;
    while (remin(W[i]))
      ;
    if (S[i] == S[1]) {
      M[W[i]]++;
      B += W[i];
    }
    0;
    A += BigNum(B);
    A.print();
    int q = pi[i - 1];
    while (q != 0 and S[q + 1] != S[i]) q = pi[q];
    if (S[q + 1] == S[i] and i != 1) q++;
    pi[i] = q;
    jp[i - 1] = S[pi[i - 1] + 1] == S[i] ? jp[pi[i - 1]] : pi[i - 1];
  }
  return 0;
}
