#include <bits/stdc++.h>
using namespace std;
const int MAX_NODES = 2000005;
int children[MAX_NODES][26];
int count_nodes[MAX_NODES];
bool is_end_node[MAX_NODES];
int num_children_nodes[MAX_NODES];
int next_node = 1;
void initialize_trie() {
memset(children[0], -1, sizeof(children[0]));
count_nodes[0] = 0;
is_end_node[0] = false;
num_children_nodes[0] = 0;
}
void insert_string(const string& s) {
int node = 0;
for (char c : s) {
int idx = c - 'a';
if (children[node][idx] == -1) {
children[node][idx] = next_node;
memset(children[next_node], -1, sizeof(children[next_node]));
count_nodes[next_node] = 0;
is_end_node[next_node] = false;
num_children_nodes[next_node] = 0;
next_node++;
if (next_node >= MAX_NODES) {
cerr << "Превышено максимальное количество узлов Trie.\n";
exit(1);
}
}
int child = children[node][idx];
if (count_nodes[child] == 0) {
num_children_nodes[node] += 1;
}
count_nodes[child] += 1;
node = child;
}
is_end_node[node] = true;
}
void remove_string_func(const string& s) {
int node = 0;
for (char c : s) {
int idx = c - 'a';
int child = children[node][idx];
count_nodes[child] -= 1;
if (count_nodes[child] == 0) {
num_children_nodes[node] -= 1;
}
node = child;
}
is_end_node[node] = false;
}
int compute_key_presses_func(const string& s) {
int key_presses = 0;
int pos = 0;
int node = 0;
int n = s.size();
while (pos < n) {
bool is_press_point = (num_children_nodes[node] > 1) || is_end_node[node];
if (is_press_point) {
key_presses += 1;
char c = s[pos];
int idx = c - 'a';
if (children[node][idx] == -1 || count_nodes[children[node][idx]] == 0) {
break;
}
node = children[node][idx];
pos += 1;
}
else {
int run = 0;
int current_node = node;
while (pos + run < n) {
bool is_press_point_here = (num_children_nodes[current_node] > 1) || is_end_node[current_node];
if (is_press_point_here) {
break;
}
char c = s[pos + run];
int idx = c - 'a';
if (children[current_node][idx] == -1 || count_nodes[children[current_node][idx]] == 0) {
break;
}
run += 1;
current_node = children[current_node][idx];
}
if (run > 0) {
key_presses += 1;
node = current_node;
pos += run;
}
else {
key_presses += 1;
char c = s[pos];
int idx = c - 'a';
if (children[node][idx] == -1 || count_nodes[children[node][idx]] == 0) {
break;
}
node = children[node][idx];
pos += 1;
}
}
}
return key_presses;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
initialize_trie();
int q;
cin >> q;
vector<string> file_strings(1);
for (int i = 0; i < q; i++) {
char type;
cin >> type;
if (type == '+') {
string s;
cin >> s;
file_strings.push_back(s);
insert_string(s);
}
else if (type == '-') {
int a_i;
cin >> a_i;
if (a_i >= 1 && a_i < (int)file_strings.size()) {
string s = file_strings[a_i];
remove_string_func(s);
}
}
else if (type == '?') {
int a_i;
cin >> a_i;
if (a_i >= 1 && a_i < (int)file_strings.size()) {
string s = file_strings[a_i];
int res = compute_key_presses_func(s);
cout << res << "\n";
}
}
}
return 0;
}