// copied palindromic tree code from https://g...content-available-to-author-only...b.com/ADJA/algos/blob/master/Strings/PalindromeTree.cpp
/**************************************************************************************
Palindrome tree. Useful structure to deal with palindromes in strings. O(N)
This code counts number of palindrome substrings of the string.
Based on problem 1750 from informatics.mccme.ru:
http://i...content-available-to-author-only...e.ru/moodle/mod/statements/view.php?chapterid=1750
**************************************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <utility>
#include <cstring>
#include <cassert>
#include <cmath>
#include <stack>
#include <queue>
using namespace std;
const int MAXN = 1005000;
struct node {
int next[2];
int len;
int sufflink;
int quicklink;
int num;
};
int len;
int s[MAXN];
node tree[MAXN];
int num; // node 1 - root with len -1, node 2 - root with len 0
int suff; // max suffix palindrome
bool addLetter(int pos) {
int cur = suff, curlen = 0;
int let = s[pos];
while(true) {
curlen = tree[cur].len;
if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos])
break;
int tmpcur = cur;
cur = tree[cur].sufflink;
curlen = tree[cur].len;
if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos])
break;
cur = tree[tmpcur].quicklink;
}
if (tree[cur].next[let]) {
suff = tree[cur].next[let];
return false;
}
num++;
suff = num;
tree[num].len = tree[cur].len + 2;
tree[cur].next[let] = num;
if (tree[num].len == 1) {
tree[num].sufflink = 2;
tree[num].quicklink = 2;
return true;
}
//puts(">>");
while (true) {
//printf("cur = %d -> %d, curlen = %d\n", cur, tree[cur].sufflink,curlen);
if(cur == 0 && curlen == 0) while(true);
cur = tree[cur].sufflink;
curlen = tree[cur].len;
if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) {
tree[num].sufflink = tree[cur].next[let];
break;
}
}
if(tree[num].sufflink > 0 && tree[tree[num].sufflink].sufflink > 0) {
if(s[pos - tree[tree[num].sufflink].len] == s[pos - tree[tree[tree[num].sufflink].sufflink].len]) {
tree[num].quicklink = tree[tree[num].sufflink].quicklink;
}else {
tree[num].quicklink = tree[tree[num].sufflink].sufflink;
}
}
if(tree[num].quicklink == 0) {
tree[num].quicklink = tree[num].sufflink;
}
return true;
}
void initTree() {
suff = 2;
tree[1].len = -1; tree[1].sufflink = 1; tree[1].quicklink = 1;
tree[2].len = 0; tree[2].sufflink = 1; tree[2].quicklink = 1;
}
int main() {
#ifdef IN_MY_COMPUTER
freopen("example.in.txt", "r", stdin);
freopen("example.out.txt", "w", stdout);
#endif
int Q; scanf("%d", &Q);
num = 2;
initTree();
std::stack<std::pair<int, int>> suffs;
suffs.emplace(0, 0);
for(int q = 0; q < Q; q++) {
int type; scanf("%d", &type);
if(type == 1) {
int c; scanf("%d" ,&c);
s[len++] = c;
addLetter(len-1);
suffs.emplace(suff, std::max(suffs.top().second, tree[suff].len));
}else {
len--;
suffs.pop();
suff = suffs.top().first;
if(len == 0) initTree();
}
printf("%d\n", suffs.top().second);
}
return 0;
}