#include #include #include #define REP(i,a,b) for(i=a;ik);if(i>=j)break;t=d[i];d[i]=d[j];d[j]=t;t=m[i];m[i]=m[j];m[j]=t;}intIntSort(d,m,i);intIntSort(d+j+1,m+j+1,s-j-1);} typedef struct struct_vector_int{ int size,mem; int *d; }intVector; intVector intVectorNull(){ intVector v; v.size=v.mem=0; return v; } void intVectorMemoryExpand(intVector *v){ int i, *t, m; m=v->mem*2; if(m<5) m=5; t=(int*)malloc(m*sizeof(int)); rep(i,v->size) t[i]=v->d[i]; if(v->mem) free(v->d); v->d=t; v->mem=m; } void intVectorPushBack(intVector *v,int add){ if(v->mem==v->size) intVectorMemoryExpand(v); v->d[(v->size)++] = add; } void unionInit(int d[],int s){int i;rep(i,s)d[i]=i;} int unionGet(int d[],int n){int t=n,k;while(d[t]!=t)t=d[t];while(d[n]!=n)k=d[n],d[n]=t,n=k;return n;} int unionConnect(int d[],int a,int b){a=unionGet(d,a);b=unionGet(d,b);if(a==b)return 0;d[a]=b;return 1;} int N, Q; char str[510000]; intVector edge[510000]; int node; int visited[510000], depth[510000], up[510000], label[510000]; int go[510000][26], failed[510000]; int q[510000], q_st, q_size; int ind[510000], val[510000]; ll dp[510000]; char dic[28]; ll X; int uni[1000000]; int main(){ int i,j,k,l; int now, next, now_n, next_n, bef, bef_n, mid_n; char c; rep(i,510000) edge[i] = intVectorNull(); scanf("%d%d%s",&N,&Q,str); unionInit(ind,N); rep(i,N) edge[i].size = 0; REP(k,1,N){ scanf("%d%d",&i,&j); i--; j--; if( unionConnect(ind, i, j)==0 ) return 1; intVectorPushBack(edge+i, j); intVectorPushBack(edge+j, i); } rep(i,N) visited[i] = 0; rep(k,26) go[0][k] = -1; visited[0] = 1; up[0] = -1; failed[0] = -1; depth[0] = 0; q_st = q_size = 0; q[q_st+q_size++] = 0; node = 1; while(q_size){ now = q[q_st++]; q_size--; now_n = label[now] = node++; rep(k,26) go[now_n][k] = -1; c = str[now] - 'a'; if(up[now] >= 0){ bef = up[now]; bef_n = label[bef]; } else { bef = -1, bef_n = 0; } depth[now_n] = depth[bef_n] + 1; i = bef_n; while(i>=0 && go[i][c]==-1) go[i][c] = now_n, i = failed[i]; failed[now_n] = 0; if(i >= 0){ j = go[i][c]; if(depth[j]==depth[i]+1){ failed[now_n] = j; } else { mid_n = node++; failed[mid_n] = failed[j]; depth[mid_n] = depth[i]+1; failed[j] = failed[now_n] = mid_n; rep(k,26) go[mid_n][k] = go[j][k]; while(i>=0 && go[i][c]==j) go[i][c]=mid_n, i=failed[i]; } } rep(k,edge[now].size){ next = edge[now].d[k]; if(visited[next]) continue; visited[next] = 1; q[q_st+q_size++] = next; up[next] = now; } } rep(i,node) ind[i] = i, val[i] = depth[i]; intIntSort(val, ind, node); for(i=node-1; i>=0; i--){ k = ind[i]; dp[k] = 1; rep(j,26) if(go[k][j] >= 0) dp[k] += dp[go[k][j]]; } printf("%lld\n",dp[0]); while(Q--){ scanf("%s%lld",dic,&X); X--; if(X >= dp[0]){ puts("-1"); continue; } i = 0; for(;;){ if(X==0) break; rep(j,26) if(go[i][dic[j]-'a']>=0){ next = go[i][dic[j]-'a']; if(X <= dp[next]){ putchar(dic[j]); X--; i = next; break; } else { X -= dp[next]; } } } puts(""); } return 0; }