/*
CodeForces - 1437G
*/
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e5+10;
multiset<int> heap[MAXN];
int son[MAXN][26], val[MAXN], fail[MAXN], last[MAXN], pos[MAXN], size;
void insert(const char s[], int id) {
int len = strlen(s), u = 0;
for (int i = 0, v; i < len; i++, u = son[u][v])
if (!son[u][v = s[i]-'a']) son[u][v] = ++size;
val[u] = 1;
pos[id] = u;
heap[u].insert(0);
}
void build() {
static int Q[MAXN]; int head = 0, tail = 0;
for (int c = fail[0] = 0; c < 26; c++)
if (son[0][c]) Q[tail++] = son[0][c];
while (head < tail) {
int u, v = Q[head++];
for (int c = 0; c < 26; c++) {
if (!(u = son[v][c])) {
son[v][c] = son[fail[v]][c];
} else {
Q[tail++] = u,
fail[u] = son[fail[v]][c],
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
}
}
char s[MAXN];
int num[MAXN];
void work(int u, int &ans){
if (!val[u]) u = last[u];
for (; u; u = last[u]){
auto it = heap[u].end(); it--;
ans = max(ans, *it);
}
}
int main(){
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++){
scanf("%s", s);
insert(s, i);
}
build();
//cout << size << endl;
for (int i = 1; i <= m; i++){
int op;
scanf("%d", &op);
if (op == 1) {
int x, y;
scanf("%d%d", &x, &y);
heap[pos[x]].erase(heap[pos[x]].find(num[x]));
heap[pos[x]].insert(y);
num[x] = y;
}else{
scanf("%s", s);
int len = strlen(s);
int u = 0, ans = -1;
for (int j = 0; j < len; j++) {
u = son[u][s[j] - 'a'];
work(u, ans);
}
printf("%d\n", ans);
}
}
}