#include <bits/stdc++.h>
using namespace std;
struct TrieNode {
int count;
int children[26];
int num_children;
TrieNode() : count(0), num_children(0) {
for (int i = 0; i < 26; i++) children[i] = -1;
}
};
class Trie {
public:
vector<TrieNode> trie;
Trie() {
trie.emplace_back();
}
void insert(const string& s) {
int node = 0;
for (char c : s) {
int idx = c - 'a';
if (trie[node].children[idx] == -1) {
trie[node].children[idx] = trie.size();
trie.emplace_back();
}
int child = trie[node].children[idx];
if (trie[child].count == 0) {
trie[node].num_children += 1;
}
trie[child].count += 1;
node = child;
}
}
void remove_string(const string& s) {
int node = 0;
for (char c : s) {
int idx = c - 'a';
int child = trie[node].children[idx];
trie[child].count -= 1;
if (trie[child].count == 0) {
trie[node].num_children -= 1;
}
node = child;
}
}
int compute_key_presses(const string& s) {
int key_presses = 0;
int pos = 0;
int node = 0;
while (pos < s.size()) {
int run = 0;
int current_node = node;
while (pos + run < s.size()) {
if (trie[current_node].num_children != 1) {
break;
}
char c = s[pos + run];
int idx = c - 'a';
if (trie[current_node].children[idx] == -1 || trie[trie[current_node].children[idx]].count == 0) {
break;
}
run += 1;
current_node = trie[current_node].children[idx];
}
if (run > 0) {
key_presses += 1;
pos += run;
node = current_node;
}
else {
key_presses += 1;
char c = s[pos];
int idx = c - 'a';
int child = trie[node].children[idx];
node = child;
pos += 1;
}
}
return key_presses;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int q;
cin >> q;
Trie trie;
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);
trie.insert(s);
}
else if (type == '-') {
int a_i;
cin >> a_i;
string s = file_strings[a_i];
trie.remove_string(s);
}
else if (type == '?') {
int a_i;
cin >> a_i;
string s = file_strings[a_i];
int res = trie.compute_key_presses(s);
cout << res << "\n";
}
}
}