#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 100005

struct Data{

	bool operator<(const struct Data &arg) const{

		return line < arg.line;
	}
	int index;
	string line;
};

struct Node{
	int children[26];
	bool finish_FLG;
};


int N;
int length[SIZE];
int L[SIZE],R[SIZE];
int num_node;
map<int,int> MAP,rev_MAP,TAIL;
set<int> SET;
Data data[SIZE];
Node nodes[1000005];

int main(){

	scanf("%d",&N);

	for(int i = 0; i < N; i++){

		cin >> data[i].line;
		data[i].index = i;
		length[i] = data[i].line.length();
	}

	sort(data,data+N);

	for(int i = 0; i < N; i++){

		MAP[data[i].index] = i; //文字列がdataのどこにあるか
		rev_MAP[i] = data[i].index; //dataのi番目の文字列は何か

		L[i] = BIG_NUM; //自分を含む最小のindex
		R[i] = -BIG_NUM; //自分を含む細大のindex
	}

	num_node = 0;

	for(int i = 0; i < 1000005; i++){

		for(int k = 0; k < 26; k++){

			nodes[i].children[k] = -1;
		}
		nodes[i].finish_FLG = false;
	}

	int root = 0;

	for(int i = 0; i < N; i++){

		int tmp_index = 0; //文字列のインデックス
		int tmp_ch = data[i].line[tmp_index]-'a';

		int tmp_loc = root; //トライ木上の位置
		tmp_index = 0;

		while(true){

			if(nodes[tmp_loc].finish_FLG){ //終端する文字列あり

				int k = TAIL[tmp_loc];
				R[k] = i;
			}

			if(nodes[tmp_loc].children[tmp_ch] == -1){

				nodes[tmp_loc].children[tmp_ch] = ++num_node;
			}
			//子ノードに移動
			tmp_loc = nodes[tmp_loc].children[tmp_ch];
			tmp_index++;

			if(tmp_index == length[rev_MAP[i]]){ //今回の数字が最後の文字だった場合
				nodes[tmp_loc].finish_FLG = true;
				TAIL[tmp_loc] = rev_MAP[i];
				L[rev_MAP[i]] = i;
				R[rev_MAP[i]] = i;
				break;
			}
			tmp_ch = data[i].line[tmp_index]-'a';
		}
	}

	int num_query;
	scanf("%d",&num_query);

	int command,num;

	set<int>::iterator it;

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d",&command,&num);
		num--;

		switch(command){
		case 1:

			SET.insert(MAP[num]);
			break;

		case 2:

			SET.erase(MAP[num]);
			break;

		case 3:

			if(L[num] == BIG_NUM){ //元々自分を含む文字列なし

				printf("-1\n");
				break;
			}

			it = SET.lower_bound(L[num]);

			if (it == SET.end() || *it > R[num]){

				printf("-1\n");

			}else{

				printf("%d\n", rev_MAP[*it]+1);
			}
			break;
		}
	}

	return 0;
}

