#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	void build(int v)
	{
		if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			//printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	void build(int v)
	{
		if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			//printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = v->ch[c];
						z += v->cnt1;
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build();
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		int cnt1;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			cnt1 = -1;
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	vector<bool> was;
	void move(int v, char c)
	{
		if (verts[v].ch[c] < 0)
		{
			//printf("move %d %d %d\n", v, (int)c, verts[v].l);
			if (v == 0)
			{
				verts[v].ch[c] = 0;
			}
			else
			{
				link(v);
				int l = verts[v].l;
				move(l, c);
				verts[v].ch[c] = verts[l].ch[c];
			}
		}
	}
	void link(int v)
	{
		//printf("link %d\n", v);
		if (verts[v].l < 0)
		{
			if (verts[v].p == 0)
			{
				verts[v].l = 0;
				return;
			}
			char c = verts[v].c;
			int p = verts[v].p;
			link(p);
			int l = verts[p].l;
			move(l, c);
			verts[v].l = verts[l].ch[c];
		}
	}
	void dcnt(int v)
	{
		if (verts[v].cnt1 < 0)
		{
			link(v);
			int l = verts[v].l;
			dcnt(l);
			verts[v].cnt1 = verts[v].cnt+verts[l].cnt1;
		}
	}
	void build(int v)
	{
		if (!was[v])
		{
			was[v] = true;
			link(v);
			for (int i=0; i<A; ++i)
			{
				move(v,i);
				build(verts[v].ch[i]);
			}
			int z = v;
			while (z != 0)
			{
				verts[v].cnt1 += verts[z].cnt;
				z = verts[z].l;
			}
			dcnt(v);
		}
		/*if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}*/
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt1;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.was.resize(a.verts.size());
						fill(a.was.begin(), a.was.end(), false);
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

const int A = 26;

struct vert
{
	int ch[A];
	int p;
	int l;
	int cnt;
	int cnt1;
	char c;
	bool used;
	void init(){
		p = -1;
		l = -1;
		c = -1;
		cnt = 0;
		used = false;
		cnt1 = int(1<<31);
		for (int i=0; i<A; ++i)
			ch[i] = -1;
	}
};

vert verts[300050*4];

vector<int> free_id;

int new_v()
{
	int r = free_id.back();
	free_id.pop_back();
	return r;
}

void free_v(int v)
{
	free_id.push_back(v);
}

void dfs(int v)
{
	if (verts[v].used)
	{
		verts[v].used = false;
		free_v(v);
		for (int i=0; i<A; ++i)
		{
			int x = verts[v].ch[i];
			if (x >= 0)
				dfs(v);
		}
	}
}

// !!!aho
struct aho
{
	static const int A = 26;
	int root;
	int left, right;
	int leftc, rightc;
	aho()
	{
		clear();
		root = -1;
		left = 0;
		right = 0;
		leftc = 0;
		rightc = 0;
	}
	void clear()
	{
		if (root >= 0)
		{
			dfs(root);
			root = -1;
		}
	}
	void add(const string &s, int w)
	{
		int v = root, tmp;
		if (v < 0)
		{
			v = new_v();
			verts[v].init();
			verts[v].used = true;
			verts[v].p = root;
			verts[v].cnt1 = 0;
			root = v;
		}
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = new_v();
				verts[tmp].init();
				verts[tmp].used = true;
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	int move(int v, char c)
	{
		int &r = verts[v].ch[c];
		if (r < 0)
			r = move(link(v), c);
		return r;
	}
	int link(int v)
	{
		int &r = verts[v].l;
		if (r < 0)
			r = move(link(verts[v].p), verts[v].c);
		return r;
	}
	int dcnt(int v)
	{
		int &r = verts[v].cnt1;
		if (r == int(1<<31))
			r = verts[v].cnt+dcnt(link(v));
		return r;
	}
	void build()
	{
		verts[root].l = root;
		for (int i=0; i<A; ++i)
		{
			if (verts[root].ch[i] < 0)
			{
				verts[root].ch[i] = root;
			}
			else
			{
				verts[verts[root].ch[i]].l = root;
			}
		}
	}
};

void solve()
{
	vector<aho> ah(20);
	free_id.resize(sizeof(verts)/sizeof(verts[0]));
	for (int i=0; i<sizeof(verts)/sizeof(verts[0]); ++i)
		free_id[i] = i;
	int acnt = 0;
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			//printf("? %d\n", acnt);
			for (int p=0; p<acnt; ++p)
			{
				aho &a = ah[p];
				int v = a.root;
				for (int i=0; i<s.length(); ++i)
				{
					char c = s[i]-'a';
					v = a.move(v, c);
					z += a.dcnt(v);
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int qn = q.size();
			ah[acnt].left = qn-1;
			ah[acnt].right = qn;
			ah[acnt].leftc = (acnt ? ah[acnt-1].rightc : 0);
			ah[acnt].rightc = ah[acnt].leftc+s.length();
			for (int p=0; p<=acnt; ++p)
			{
				if (p == acnt || ah[p].rightc-ah[p].leftc <= ah[acnt].rightc-ah[p].rightc)
				{
					//printf("p=%d l=%d r=%d lc=%d rc=%d ac=%d arc=%d\n", p, ah[p].left, ah[p].right, ah[p].leftc, ah[p].rightc, acnt, ah[acnt].rightc);
					aho &a = ah[p];
					a.clear();
					a.right = qn;
					a.rightc = ah[acnt].rightc;
					for (int i=a.left; i<a.right; ++i)
					{
						a.add(q[i].second, q[i].first==1?1:-1);
					}
					//printf("%d %d\n",acnt,a.rightc-a.leftc);
					a.build();
					for (int zz = p+1; zz<acnt; ++zz)
						ah[zz].clear();
					acnt = p+1;
					break;
				}
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

const int A = 26;

struct vert
{
	int ch[A];
	int p;
	int l;
	int cnt;
	int cnt1;
	char c;
	bool used;
	void init(){
		p = -1;
		l = -1;
		c = -1;
		cnt = 0;
		used = false;
		cnt1 = int(1<<31);
		for (int i=0; i<A; ++i)
			ch[i] = -1;
	}
};

vert verts[300050*4];

vector<int> free_id;

int new_v()
{
	int r = free_id.back();
	free_id.pop_back();
	return r;
}

void free_v(int v)
{
	free_id.push_back(v);
}

void dfs(int v)
{
	if (verts[v].used)
	{
		verts[v].used = false;
		free_v(v);
		for (int i=0; i<A; ++i)
		{
			int x = verts[v].ch[i];
			if (x >= 0)
				dfs(v);
		}
	}
}

// !!!aho
struct aho
{
	static const int A = 26;
	int root;
	int left, right;
	int leftc, rightc;
	aho()
	{
		clear();
		root = -1;
		left = 0;
		right = 0;
		leftc = 0;
		rightc = 0;
	}
	void clear()
	{
		if (root >= 0)
		{
			dfs(root);
			root = -1;
		}
	}
	void add(const string &s, int w)
	{
		int v = root, tmp;
		if (v < 0)
		{
			v = new_v();
			verts[v].init();
			verts[v].used = true;
			verts[v].p = root;
			verts[v].cnt1 = 0;
			root = v;
		}
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = new_v();
				verts[tmp].init();
				verts[tmp].used = true;
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	int move(int v, char c)
	{
		int &r = verts[v].ch[c];
		if (r < 0)
			r = move(link(v), c);
		return r;
	}
	int link(int v)
	{
		int &r = verts[v].l;
		if (r < 0)
			r = move(link(verts[v].p), verts[v].c);
		return r;
	}
	int dcnt(int v)
	{
		int r = verts[v].cnt1;
		if (r == int(1<<31))
			r = verts[v].cnt+dcnt(link(v));
		return r;
	}
	void build()
	{
		verts[root].l = root;
		for (int i=0; i<A; ++i)
		{
			if (verts[root].ch[i] < 0)
			{
				verts[root].ch[i] = root;
			}
			else
			{
				verts[verts[root].ch[i]].l = root;
			}
		}
	}
};

void solve()
{
	vector<aho> ah(20);
	free_id.resize(sizeof(verts)/sizeof(verts[0]));
	for (int i=0; i<sizeof(verts)/sizeof(verts[0]); ++i)
		free_id[i] = i;
	int acnt = 0;
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			//printf("? %d\n", acnt);
			for (int p=0; p<acnt; ++p)
			{
				aho &a = ah[p];
				int v = a.root;
				for (int i=0; i<s.length(); ++i)
				{
					char c = s[i]-'a';
					v = a.move(v, c);
					z += a.dcnt(v);
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int qn = q.size();
			ah[acnt].left = qn-1;
			ah[acnt].right = qn;
			ah[acnt].leftc = (acnt ? ah[acnt-1].rightc : 0);
			ah[acnt].rightc = ah[acnt].leftc+s.length();
			for (int p=0; p<=acnt; ++p)
			{
				if (p == acnt || ah[p].rightc-ah[p].leftc <= ah[acnt].rightc-ah[p].rightc)
				{
					//printf("p=%d l=%d r=%d lc=%d rc=%d ac=%d arc=%d\n", p, ah[p].left, ah[p].right, ah[p].leftc, ah[p].rightc, acnt, ah[acnt].rightc);
					aho &a = ah[p];
					a.clear();
					a.right = qn;
					a.rightc = ah[acnt].rightc;
					for (int i=a.left; i<a.right; ++i)
					{
						a.add(q[i].second, q[i].first==1?1:-1);
					}
					a.build();
					for (int zz = p+1; zz<acnt; ++zz)
						ah[zz].clear();
					acnt = p+1;
					break;
				}
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

bool cmp(const pair<int,string> &a, const pair<int,string> &b)
{
	return a.second.length() > b.second.length();
}

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = v->ch[c];
						z += v->cnt1;
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			int qnx = (qn^(qn-1));
			for (int p=18; p>=0; --p)
			{
				if (qnx & (1<<p))
				{
					aho &a = ah[p];
					a.clear();
					//sort(q.begin()+z, q.end(), cmp);
					int nn = (1<<p);
					for (int i=0; i<nn; ++i)
					{
						a.add(q[z+i].second, q[z+i].first==1?1:-1);
					}
					a.build();
					for (--p; p>=0; --p)
						ah[p].clear();
					break;
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = (v == &verts[0] ? &verts[0] : move(link(v), c));
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
		{
			*r = (v->p == &verts[0] ? &verts[0] : move(link(v->p), v->c));
		}
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
		{
			r = v->cnt+dcnt(link(v));
		}
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.move(v, c);
						z += a.dcnt(v);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build();
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		int cnt1;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	vector<bool> was;
	void move(int v, char c)
	{
		if (verts[v].ch[c] < 0)
		{
			//printf("move %d %d %d\n", v, (int)c, verts[v].l);
			if (v == 0)
			{
				verts[v].ch[c] = 0;
			}
			else
			{
				link(v);
				int l = verts[v].l;
				move(l, c);
				verts[v].ch[c] = verts[l].ch[c];
			}
		}
	}
	void link(int v)
	{
		//printf("link %d\n", v);
		if (verts[v].l < 0)
		{
			if (verts[v].p == 0)
			{
				verts[v].l = 0;
				return;
			}
			char c = verts[v].c;
			int p = verts[v].p;
			link(p);
			int l = verts[p].l;
			move(l, c);
			verts[v].l = verts[l].ch[c];
		}
	}
	void dcnt(int v)
	{
		if (verts[v].cnt1 < 0)
		{
			link(v);
			int l = verts[v].l;
			dcnt(l);
			verts[v].cnt1 = verts[v].cnt+verts[l].cnt1;
		}
	}
	void build(int v)
	{
		if (!was[v])
		{
			was[v] = true;
			link(v);
			for (int i=0; i<A; ++i)
			{
				move(v,i);
				build(verts[v].ch[i]);
			}
			int z = v;
			while (z != 0)
			{
				verts[v].cnt1 += verts[z].cnt;
				z = verts[z].l;
			}
			dcnt(v);
		}
		/*if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}*/
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt1;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.was.resize(a.verts.size());
						fill(a.was.begin(), a.was.end(), false);
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		verts.reserve(1024*16);
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = (v == &verts[0] ? &verts[0] : move(link(v), c));
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
		{
			*r = (v->p == &verts[0] ? &verts[0] : move(link(v->p), v->c));
		}
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
		{
			r = v->cnt+dcnt(link(v));
		}
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.move(v, c);
						z += a.dcnt(v);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build();
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

const int A = 26;

struct vert
{
	int ch[A];
	int p;
	int l;
	int cnt;
	int cnt1;
	char c;
	bool used;
	void init(){
		p = -1;
		l = -1;
		c = -1;
		cnt = 0;
		used = false;
		cnt1 = int(1<<31);
		for (int i=0; i<A; ++i)
			ch[i] = -1;
	}
};

vert verts[300050*4];

vector<int> free_id;

int new_v()
{
	int r = free_id.back();
	free_id.pop_back();
	return r;
}

void free_v(int v)
{
	free_id.push_back(v);
}

void dfs(int v)
{
	if (verts[v].used)
	{
		verts[v].used = false;
		free_v(v);
		for (int i=0; i<A; ++i)
		{
			int x = verts[v].ch[i];
			if (x >= 0)
				dfs(v);
		}
	}
}

// !!!aho
struct aho
{
	static const int A = 26;
	int root;
	int left, right;
	int leftc, rightc;
	aho()
	{
		clear();
		root = -1;
		left = 0;
		right = 0;
		leftc = 0;
		rightc = 0;
	}
	void clear()
	{
		if (root >= 0)
		{
			dfs(root);
			root = -1;
		}
	}
	void add(const string &s, int w)
	{
		int v = root, tmp;
		if (v < 0)
		{
			v = new_v();
			verts[v].init();
			verts[v].used = true;
			verts[v].p = root;
			verts[v].cnt1 = 0;
			root = v;
		}
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = new_v();
				verts[tmp].init();
				verts[tmp].used = true;
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	int move(int v, char c)
	{
		int &r = verts[v].ch[c];
		if (r < 0)
			r = move(link(v), c);
		return r;
	}
	int link(int v)
	{
		int &r = verts[v].l;
		if (r < 0)
			r = move(link(verts[v].p), verts[v].c);
		return r;
	}
	int dcnt(int v)
	{
		int &r = verts[v].cnt1;
		if (r == int(1<<31))
			r = verts[v].cnt+dcnt(link(v));
		return r;
	}
	void build()
	{
		verts[root].l = root;
		for (int i=0; i<A; ++i)
		{
			if (verts[root].ch[i] < 0)
			{
				verts[root].ch[i] = root;
			}
			else
			{
				verts[verts[root].ch[i]].l = root;
			}
		}
	}
};

void solve()
{
	vector<aho> ah(20);
	free_id.resize(sizeof(verts)/sizeof(verts[0]));
	for (int i=0; i<sizeof(verts)/sizeof(verts[0]); ++i)
		free_id[i] = i;
	int acnt = 0;
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			//printf("? %d\n", acnt);
			for (int p=0; p<acnt; ++p)
			{
				aho &a = ah[p];
				int v = a.root;
				for (int i=0; i<s.length(); ++i)
				{
					char c = s[i]-'a';
					v = a.move(v, c);
					z += a.dcnt(v);
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int qn = q.size();
			ah[acnt].left = qn-1;
			ah[acnt].right = qn;
			ah[acnt].leftc = (acnt ? ah[acnt-1].rightc : 0);
			ah[acnt].rightc = ah[acnt].leftc+s.length();
			for (int p=0; p<=acnt; ++p)
			{
				if (p == acnt || ah[p].right-ah[p].left <= ah[acnt].right-ah[p].right)
				{
					//printf("p=%d l=%d r=%d lc=%d rc=%d ac=%d arc=%d\n", p, ah[p].left, ah[p].right, ah[p].leftc, ah[p].rightc, acnt, ah[acnt].rightc);
					aho &a = ah[p];
					a.clear();
					a.right = qn;
					a.rightc = ah[acnt].rightc;
					for (int i=a.left; i<a.right; ++i)
					{
						a.add(q[i].second, q[i].first==1?1:-1);
					}
					//printf("%d %d\n",acnt,a.rightc-a.leftc);
					a.build();
					for (int zz = p+1; zz<acnt; ++zz)
						ah[zz].clear();
					acnt = p+1;
					break;
				}
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* ch[A];
		vert* p;
		vert* l;
		int cnt;
		int cnt1;
		char c;
		char d[3];
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	int left, right;
	int leftc, rightc;
	aho()
	{
		clear();
		verts.reserve(1<<17);
		left = 0;
		right = 0;
		leftc = 0;
		rightc = 0;
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		/*for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}*/
	}
};

void solve()
{
	vector<aho> ah(20);
	int acnt = 0;
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			//printf("? %d\n", acnt);
			for (int p=0; p<acnt; ++p)
			{
				aho &a = ah[p];
				aho::vert *v = &a.verts[0];
				for (int i=0; i<s.length(); ++i)
				{
					char c = s[i]-'a';
					v = v->ch[c];
					z += v->cnt1;
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int qn = q.size();
			ah[acnt].left = qn-1;
			ah[acnt].right = qn;
			ah[acnt].leftc = (acnt ? ah[acnt-1].rightc : 0);
			ah[acnt].rightc = ah[acnt].leftc+s.length();
			for (int p=0; p<=acnt; ++p)
			{
				if (p == acnt || ah[p].rightc-ah[p].leftc <= ah[acnt].rightc-ah[p].rightc)
				{
					//printf("p=%d l=%d r=%d lc=%d rc=%d ac=%d arc=%d\n", p, ah[p].left, ah[p].right, ah[p].leftc, ah[p].rightc, acnt, ah[acnt].rightc);
					aho &a = ah[p];
					a.clear();
					a.right = qn;
					a.rightc = ah[acnt].rightc;
					for (int i=a.left; i<a.right; ++i)
					{
						a.add(q[i].second, q[i].first==1?1:-1);
					}
					a.build();
					for (int zz = p+1; zz<acnt; ++zz)
						ah[zz].clear();
					acnt = p+1;
					break;
				}
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	int left, right;
	int leftc, rightc;
	aho()
	{
		clear();
		left = 0;
		right = 0;
		leftc = 0;
		rightc = 0;
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

bool cmp(const pair<int,string> &a, const pair<int,string> &b)
{
	return a.second.length() > b.second.length();
}

void solve()
{
	vector<aho> ah(20);
	int acnt = 0;
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			//printf("? %d\n", acnt);
			for (int p=0; p<acnt; ++p)
			{
				aho &a = ah[p];
				aho::vert *v = &a.verts[0];
				for (int i=0; i<s.length(); ++i)
				{
					char c = s[i]-'a';
					v = v->ch[c];
					z += v->cnt1;
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int qn = q.size();
			ah[acnt].left = qn-1;
			ah[acnt].right = qn;
			ah[acnt].leftc = (acnt ? ah[acnt-1].rightc : 0);
			ah[acnt].rightc = ah[acnt].leftc+s.length();
			for (int p=0; p<=acnt; ++p)
			{
				if (p == acnt || ah[p].rightc-ah[p].leftc <= ah[acnt].rightc-ah[p].rightc)
				{
					//printf("p=%d l=%d r=%d lc=%d rc=%d ac=%d arc=%d\n", p, ah[p].left, ah[p].right, ah[p].leftc, ah[p].rightc, acnt, ah[acnt].rightc);
					aho &a = ah[p];
					a.clear();
					a.right = qn;
					a.rightc = ah[acnt].rightc;
					for (int i=a.left; i<a.right; ++i)
					{
						a.add(q[i].second, q[i].first==1?1:-1);
					}
					a.build();
					for (int zz = p+1; zz<acnt; ++zz)
						ah[zz].clear();
					acnt = p+1;
					break;
				}
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		int cnt1;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	vector<bool> was;
	void move(int v, char c)
	{
		if (verts[v].ch[c] < 0)
		{
			//printf("move %d %d %d\n", v, (int)c, verts[v].l);
			if (v == 0)
			{
				verts[v].ch[c] = 0;
			}
			else
			{
				link(v);
				int l = verts[v].l;
				move(l, c);
				verts[v].ch[c] = verts[l].ch[c];
			}
		}
	}
	void link(int v)
	{
		//printf("link %d\n", v);
		if (verts[v].l < 0)
		{
			if (verts[v].p == 0)
			{
				verts[v].l = 0;
				return;
			}
			char c = verts[v].c;
			int p = verts[v].p;
			link(p);
			int l = verts[p].l;
			move(l, c);
			verts[v].l = verts[l].ch[c];
		}
	}
	void build(int v)
	{
		if (!was[v])
		{
			was[v] = true;
			link(v);
			for (int i=0; i<A; ++i)
			{
				move(v,i);
				build(verts[v].ch[i]);
			}
			int z = v;
			while (z != 0)
			{
				verts[v].cnt1 += verts[z].cnt;
				z = verts[z].l;
			}
		}
		/*if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}*/
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt1;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.was.resize(a.verts.size());
						fill(a.was.begin(), a.was.end(), false);
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.move(v, c);
						z += a.dcnt(v);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build();
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = verts[0];
			}
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.move(v, c);
						z += a.dcnt(v);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build();
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

bool cmp(const pair<int,string> *a, const pair<int,string> *b)
{
	return a->second.length() > b->second.length();
}

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>*> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = v->ch[c];
						z += v->cnt1;
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(new pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			int qnx = (qn^(qn-1));
			for (int p=18; p>=0; --p)
			{
				if (qnx & (1<<p))
				{
					aho &a = ah[p];
					a.clear();
					sort(q.begin()+z, q.end(), cmp);
					int nn = (1<<p);
					for (int i=0; i<nn; ++i)
					{
						a.add(q[z+i]->second, q[z+i]->first==1?1:-1);
					}
					a.build();
					for (--p; p>=0; --p)
						ah[p].clear();
					break;
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = (v == &verts[0] ? &verts[0] : move(link(v), c));
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
		{
			*r = (v->p == &verts[0] ? &verts[0] : move(link(v->p), v->c));
		}
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
		{
			r = v->cnt+dcnt(link(v));
		}
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.move(v, c);
						z += a.dcnt(v);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build();
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	vector<bool> was;
	void move(int v, char c)
	{
		if (verts[v].ch[c] < 0)
		{
			//printf("move %d %d %d\n", v, (int)c, verts[v].l);
			link(v);
			int l = verts[v].l;
			if (v == 0)
			{
				verts[v].ch[c] = 0;
			}
			else
			{
				move(l, c);
				verts[v].ch[c] = verts[l].ch[c];
			}
		}
	}
	void link(int v)
	{
		//printf("link %d\n", v);
		if (verts[v].l < 0)
		{
			if (verts[v].p == 0)
			{
				verts[v].l = 0;
				return;
			}
			char c = verts[v].c;
			int p = verts[v].p;
			link(p);
			int l = verts[p].l;
			move(l, c);
			verts[v].l = verts[l].ch[c];
		}
	}
	void build(int v)
	{
		if (!was[v])
		{
			was[v] = true;
			link(v);
			verts[v].cnt += verts[verts[v].l].cnt;
			for (int i=0; i<A; ++i)
			{
				move(v,i);
				build(verts[v].ch[i]);
			}
		}
		/*if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}*/
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.was.resize(a.verts.size());
						fill(a.was.begin(), a.was.end(), false);
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* ch[A];
		vert* p;
		vert* l;
		int cnt;
		int cnt1;
		char c;
		char d[3];
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	int left, right;
	int leftc, rightc;
	aho()
	{
		clear();
		verts.reserve(1<<17);
		left = 0;
		right = 0;
		leftc = 0;
		rightc = 0;
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		/*for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}*/
	}
};

void solve()
{
	vector<aho> ah(20);
	int acnt = 0;
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			//printf("? %d\n", acnt);
			for (int p=0; p<acnt; ++p)
			{
				aho &a = ah[p];
				aho::vert *v = &a.verts[0];
				for (int i=0; i<s.length(); ++i)
				{
					char c = s[i]-'a';
					v = a.move(v,c);
					z += a.dcnt(v);
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int qn = q.size();
			ah[acnt].left = qn-1;
			ah[acnt].right = qn;
			ah[acnt].leftc = (acnt ? ah[acnt-1].rightc : 0);
			ah[acnt].rightc = ah[acnt].leftc+s.length();
			for (int p=0; p<=acnt; ++p)
			{
				if (p == acnt || ah[p].right-ah[p].left <= ah[acnt].right-ah[p].right)
				{
					//printf("p=%d l=%d r=%d lc=%d rc=%d ac=%d arc=%d\n", p, ah[p].left, ah[p].right, ah[p].leftc, ah[p].rightc, acnt, ah[acnt].rightc);
					aho &a = ah[p];
					a.clear();
					a.right = qn;
					a.rightc = ah[acnt].rightc;
					for (int i=a.left; i<a.right; ++i)
					{
						a.add(q[i].second, q[i].first==1?1:-1);
					}
					a.build();
					for (int zz = p+1; zz<acnt; ++zz)
						ah[zz].clear();
					acnt = p+1;
					break;
				}
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		int cnt1;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	int move(int v, char c)
	{
		int &r = verts[v].ch[c];
		if (r < 0)
			r = (v == 0 ? 0 : move(link(v), c));
		return r;
	}
	int link(int v)
	{
		int &r = verts[v].l;
		if (r < 0)
		{
			r = (verts[v].p == 0 ? 0 : move(link(verts[v].p), verts[v].c));
		}
		return r;
	}
	int dcnt(int v)
	{
		int &r = verts[v].cnt1;
		if (r == int(1<<31))
		{
			r = verts[v].cnt+dcnt(link(v));
		}
		return r;
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.move(v, c);
						z += a.dcnt(v);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* ch[A];
		vert* p;
		vert* l;
		int cnt;
		int cnt1;
		char c;
		char d[3];
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	int left, right;
	int leftc, rightc;
	aho()
	{
		clear();
		verts.reserve(1<<17);
		left = 0;
		right = 0;
		leftc = 0;
		rightc = 0;
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		/*for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}*/
	}
};

void solve()
{
	vector<aho> ah(20);
	int acnt = 0;
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			//printf("? %d\n", acnt);
			for (int p=0; p<acnt; ++p)
			{
				aho &a = ah[p];
				aho::vert *v = &a.verts[0];
				for (int i=0; i<s.length(); ++i)
				{
					char c = s[i]-'a';
					v = move(v,c);
					z += dcnt(v);
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int qn = q.size();
			ah[acnt].left = qn-1;
			ah[acnt].right = qn;
			ah[acnt].leftc = (acnt ? ah[acnt-1].rightc : 0);
			ah[acnt].rightc = ah[acnt].leftc+s.length();
			for (int p=0; p<=acnt; ++p)
			{
				if (p == acnt || ah[p].rightc-ah[p].leftc <= ah[acnt].rightc-ah[p].rightc)
				{
					//printf("p=%d l=%d r=%d lc=%d rc=%d ac=%d arc=%d\n", p, ah[p].left, ah[p].right, ah[p].leftc, ah[p].rightc, acnt, ah[acnt].rightc);
					aho &a = ah[p];
					a.clear();
					a.right = qn;
					a.rightc = ah[acnt].rightc;
					for (int i=a.left; i<a.right; ++i)
					{
						a.add(q[i].second, q[i].first==1?1:-1);
					}
					a.build();
					for (int zz = p+1; zz<acnt; ++zz)
						ah[zz].clear();
					acnt = p+1;
					break;
				}
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		verts.reserve(1024);
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = (v == &verts[0] ? &verts[0] : move(link(v), c));
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
		{
			*r = (v->p == &verts[0] ? &verts[0] : move(link(v->p), v->c));
		}
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
		{
			r = v->cnt+dcnt(link(v));
		}
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.move(v, c);
						z += a.dcnt(v);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.build();
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		int cnt1;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	void move(int v, char c)
	{
		if (verts[v].ch[c] < 0)
		{
			if (v == 0)
			{
				verts[v].ch[c] = 0;
			}
			else
			{
				link(v);
				int l = verts[v].l;
				move(l, c);
				verts[v].ch[c] = verts[l].ch[c];
			}
		}
	}
	void link(int v)
	{
		if (verts[v].l < 0)
		{
			if (verts[v].p == 0)
			{
				verts[v].l = 0;
				return;
			}
			char c = verts[v].c;
			int p = verts[v].p;
			link(p);
			int l = verts[p].l;
			move(l, c);
			verts[v].l = verts[l].ch[c];
		}
	}
	void dcnt(int v)
	{
		if (verts[v].cnt1 == int(1<<31))
		{
			link(v);
			int l = verts[v].l;
			dcnt(l);
			verts[v].cnt1 = verts[v].cnt+verts[l].cnt1;
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						a.move(v, c);
						v = a.verts[v].ch[c];
						a.dcnt(v);
						z += a.verts[v].cnt1;
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
					}
				}
				else
				{
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		int cnt1;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	vector<bool> was;
	void move(int v, char c)
	{
		if (verts[v].ch[c] < 0)
		{
			//printf("move %d %d %d\n", v, (int)c, verts[v].l);
			if (v == 0)
			{
				verts[v].ch[c] = 0;
			}
			else
			{
				link(v);
				int l = verts[v].l;
				move(l, c);
				verts[v].ch[c] = verts[l].ch[c];
			}
		}
	}
	void link(int v)
	{
		//printf("link %d\n", v);
		if (verts[v].l < 0)
		{
			if (verts[v].p == 0)
			{
				verts[v].l = 0;
				return;
			}
			char c = verts[v].c;
			int p = verts[v].p;
			link(p);
			int l = verts[p].l;
			move(l, c);
			verts[v].l = verts[l].ch[c];
		}
	}
	void dcnt(int v)
	{
		if (verts[v].cnt1 == int(1<<31))
		{
			link(v);
			int l = verts[v].l;
			dcnt(l);
			verts[v].cnt1 = verts[v].cnt+verts[l].cnt1;
		}
	}
	void build(int v)
	{
		if (!was[v])
		{
			was[v] = true;
			link(v);
			dcnt(v);
			for (int i=0; i<A; ++i)
			{
				move(v,i);
				build(verts[v].ch[i]);
			}
		}
		/*if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}*/
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt1;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.was.resize(a.verts.size());
						fill(a.was.begin(), a.was.end(), false);
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		vert* p;
		vert* ch[A];
		char c;
		vert* l;
		int cnt;
		int cnt1;
		void init(){
			p = (vert*)-1;
			l = (vert*)-1;
			c = -1;
			cnt = 0;
			cnt1 = int(1<<31);
			for (int i=0; i<A; ++i)
				ch[i] = (vert*)-1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = (vert*)0;
		verts[0].cnt1 = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			char c = s[i]-'a';
			tmp = (int)verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = (vert*)v;
				verts[tmp].c = c;
				verts[v].ch[c] = (vert*)tmp;
			}
			v = tmp;
		}
		verts[v].cnt += w;
	}

	vert* move(vert *v, char c)
	{
		vert **r = &v->ch[c];
		if (*r == 0)
			*r = move(link(v), c);
		return *r;
	}
	vert* link(vert* v)
	{
		vert **r = &v->l;
		if (*r == 0)
			*r = move(link(v->p), v->c);
		return *r;
	}
	int dcnt(vert *v)
	{
		int &r = v->cnt1;
		if (r == int(1<<31))
			r = v->cnt+dcnt(link(v));
		return r;
	}
	void convert(vert **x)
	{
		if (int(*x) < 0)
			*x = 0;
		else
			*x = &verts[int(*x)];
	}
	void build()
	{
		for (int i=0; i<verts.size(); ++i)
		{
			convert(&verts[i].p);
			convert(&verts[i].l);
			for(int j=0; j<A; ++j)
				convert(&verts[i].ch[j]);
		}
		verts[0].l = &verts[0];
		for (int i=0; i<A; ++i)
		{
			if (verts[0].ch[i] == 0)
			{
				verts[0].ch[i] = &verts[0];
			}
			else
			{
				verts[0].ch[i]->l = &verts[0];
			}
		}
		for (int i=0; i<verts.size(); ++i)
		{
			vert *v = &verts[i];
			link(v);
			dcnt(v);
			for (int j=0; j<A; ++j)
				move(v, j);
		}
	}
};

bool cmp(const pair<int,string> &a, const pair<int,string> &b)
{
	return a.second.length() > b.second.length();
}

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					aho &a = ah[p];
					aho::vert *v = &a.verts[0];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = v->ch[c];
						z += v->cnt1;
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			int qnx = (qn^(qn-1));
			for (int p=18; p>=0; --p)
			{
				if (qnx & (1<<p))
				{
					aho &a = ah[p];
					a.clear();
					sort(q.begin()+z, q.end(), cmp);
					int nn = (1<<p);
					for (int i=0; i<nn; ++i)
					{
						a.add(q[z+i].second, q[z+i].first==1?1:-1);
					}
					a.build();
					for (--p; p>=0; --p)
						ah[p].clear();
					break;
				}
				z += qn & (1<<p);
			}
		}
	}
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	vector<bool> was;
	void move(int v, char c)
	{
		if (verts[v].ch[c] < 0)
		{
			//printf("move %d %d %d\n", v, (int)c, verts[v].l);
			if (v == 0)
			{
				verts[v].ch[c] = 0;
			}
			else
			{
				link(v);
				int l = verts[v].l;
				move(l, c);
				verts[v].ch[c] = verts[l].ch[c];
			}
		}
	}
	void link(int v)
	{
		//printf("link %d\n", v);
		if (verts[v].l < 0)
		{
			if (verts[v].p == 0)
			{
				verts[v].l = 0;
				return;
			}
			char c = verts[v].c;
			int p = verts[v].p;
			link(p);
			int l = verts[p].l;
			move(l, c);
			verts[v].l = verts[l].ch[c];
		}
	}
	void build(int v)
	{
		if (!was[v])
		{
			was[v] = true;
			link(v);
			for (int i=0; i<A; ++i)
			{
				move(v,i);
				build(verts[v].ch[i]);
			}
			verts[v].cnt += verts[verts[v].l].cnt;
		}
		/*if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}*/
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.was.resize(a.verts.size());
						fill(a.was.begin(), a.was.end(), false);
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>

typedef long long ll;

using namespace std;

// !!!aho
struct aho
{
	static const int A = 26;
	struct vert
	{
		int p;
		int ch[A];
		char c;
		int l;
		int cnt;
		int cnt1;
		//string s;
		void init(){
			p = 0;
			l = -1;
			c = -1;
			cnt = 0;
			for (int i=0; i<A; ++i)
				ch[i] = -1;
		}
	};
	vector<vert> verts;
	aho()
	{
		clear();
	}
	void clear()
	{
		verts.resize(1);
		verts[0].init();
		verts[0].p = 0;
	}
	void add(const string &s, int w)
	{
		int v = 0, tmp;
		for (int i=0; i<s.length(); ++i)
		{
			//printf("%d ", v);
			char c = s[i]-'a';
			tmp = verts[v].ch[c];
			if (tmp < 0)
			{
				tmp = verts.size();
				verts.resize(tmp+1);
				verts[tmp].init();
				verts[tmp].p = v;
				verts[tmp].c = c;
				verts[v].ch[c] = tmp;
			}
			v = tmp;
		}
		//printf("%d!\n", v);
		verts[v].cnt += w;
		//verts[v].s = s;
	}
	vector<bool> was;
	void move(int v, char c)
	{
		if (verts[v].ch[c] < 0)
		{
			//printf("move %d %d %d\n", v, (int)c, verts[v].l);
			if (v == 0)
			{
				verts[v].ch[c] = 0;
			}
			else
			{
				link(v);
				int l = verts[v].l;
				move(l, c);
				verts[v].ch[c] = verts[l].ch[c];
			}
		}
	}
	void link(int v)
	{
		//printf("link %d\n", v);
		if (verts[v].l < 0)
		{
			if (verts[v].p == 0)
			{
				verts[v].l = 0;
				return;
			}
			char c = verts[v].c;
			int p = verts[v].p;
			link(p);
			int l = verts[p].l;
			move(l, c);
			verts[v].l = verts[l].ch[c];
		}
	}
	void build(int v)
	{
		if (!was[v])
		{
			was[v] = true;
			link(v);
			for (int i=0; i<A; ++i)
			{
				move(v,i);
				build(verts[v].ch[i]);
			}
			int z = v;
			while (z != 0)
			{
				verts[v].cnt1 += verts[z].cnt;
				v = verts[v].l;
			}
		}
		/*if (verts[v].l < 0)
		{
			int l;
			if (verts[v].p == 0)
			{
				l = 0;
			}
			else
			{
				l = verts[verts[v].p].l;
				build(l);
				l = verts[l].ch[verts[v].c];
			}
			printf("link v=%d p=%d c=%d %d\n", v, verts[v].p, int(verts[v].c), l);
			verts[v].l = l;
			if (v == 0)
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[0].ch[i] < 0)
						verts[0].ch[i] = 0;
				}
			}
			else
			{
				for (int i=0; i<A; ++i)
				{
					if (verts[v].ch[i] < 0)
					{
						verts[v].ch[i] = verts[l].ch[i];
						//printf("%d %d %d!\n", v, i, verts[v].ch[i]);
					}
				}
			}
			verts[v].cnt += verts[l].cnt;
			for (int i=0; i<A; ++i)
				build(verts[v].ch[i]);
		}*/
	}
	void print()
	{
		for (int v=0; v<verts.size(); ++v)
		{
			for (int i=0; i<A; ++i)
				printf("%d %d %d\n", v, i, verts[v].ch[i]);
		}
	}
};

void solve()
{
	vector<aho> ah(19);
	vector<pair<int, string>> q;
	int Q;
	scanf("%d", &Q);
	for (int i=0; i<Q; ++i)
	{
		int x;
		string s;
		cin >> x >> s;
		if (x == 3)
		{
			ll z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					int v = 0;
					aho &a = ah[p];
					for (int i=0; i<s.length(); ++i)
					{
						char c = s[i]-'a';
						v = a.verts[v].ch[c];
						//printf("%d %d\n", v, a.verts[v].cnt);
						z += a.verts[v].cnt;
						//if (a.verts[v].cnt)
						//	printf("%d %d\n", p, a.verts[v].cnt);
					}
				}
			}
			printf("%I64d\n", z);
			fflush(stdout);
		}
		else
		{
			q.push_back(pair<int, string>(x, s));
			int z = 0;
			int qn = q.size();
			for (int p=18; p>=0; --p)
			{
				if (qn & (1<<p))
				{
					if (!((qn&(qn-1))&(1<<p)))
					{
						//printf("build %d\n", p);
						aho &a = ah[p];
						a.clear();
						int nn = (1<<p);
						for (int i=0; i<nn; ++i)
						{
							a.add(q[z+i].second, q[z+i].first==1?1:-1);
						}
						a.was.resize(a.verts.size());
						fill(a.was.begin(), a.was.end(), false);
						a.build(0);
					}
				}
				else
				{
					//printf("clear %d\n", p);
					ah[p].clear();
				}
				z += qn & (1<<p);
			}
		}
	}
	/*string s;
	aho a;
	for (;;)
	{
		cin >> s;
		if (s == string("*"))
			break;
		a.add(s);
	}
	printf("build");
	a.build(0);
	a.print();
	cin >> s;
	int v = 0;
	for (int i=0; i<s.length(); ++i)
	{
		char c = s[i]-'a';
		v = a.verts[v].ch[c];
		printf("%d\n", v);
		int tmp = v;
		while (tmp != 0)
		{
			if (a.verts[tmp].cnt)
				printf("%d %s\n",i,a.verts[tmp].s.c_str());
			tmp = a.verts[tmp].l;
		}
	}*/
}

int main()
{
	solve();
	return 0;
}