#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <algorithm>
#include <set>
#include <cmath>
#include <map>
#include <unordered_map>
//#define lson x<<1
//#define rson x<<1|1
//#define mid ((lt[x].l+lt[x].r)/2)
//#define ID(x, y) ((x)*m+(y))
//#define CHECK(x, y) ((x)>=0 && (x)<n && (y)>=0 && (y)<m)
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
typedef unsigned long long ULL;
typedef pair<ULL, ULL> PUU;
const LL INF=0x3f3f3f3f;
void Open()
{
    #ifndef ONLINE_JUDGE
        freopen("F:/in.txt","r",stdin);
        //freopen("F:/my.txt","w",stdout);
    #endif // ONLINE_JUDGE
}
const LL N = 10010;
const LL MAGIC = 998244353;
char str[N], sss[N];
ULL base[N];
ULL h[N];
ULL rh[N];
map<PUU, string> m;
map<PUU, string> m1;

inline void init_hash(char *s, ULL *h, LL l)
{
    h[0]= 0;
    for(LL i = 1; i <= l;++i)
        h[i] = h[i-1] * MAGIC + s[i-1] - 'a';
    base[0] = 1;
    for(LL i = 1; i <= l; ++i)
        base[i] = base[i-1] * MAGIC;
}
inline ULL string_hash(ULL *h, LL l, LL r) //[0-base)
{
    return h[r] - h[l] * base[r-l];
}
struct word
{
    char ori[1111];
    char cur[1111];
    ULL hvalue;
    void update(LL id)
    {
        strcpy(cur, ori);
        LL len = strlen(cur);
        for(LL i = 0; i < len; i++)
            if(cur[i] > 'z' || cur[i] < 'a')
                cur[i] -= 'A' - 'a';
        reverse(cur, cur+len);
        hvalue = 0;
        for(LL i = 1; i <= len;i++)
            hvalue = hvalue * MAGIC + cur[i-1] - 'a';
        ULL rvalue = 0;
        for(int i = len; i >= 1; i--)
            rvalue = rvalue * MAGIC + cur[i-1] - 'a';
        //if(m.find(PUU(hvalue, rvalue)) != m.end() && string(cur).compare(m[PUU(hvalue, rvalue)])) hvalue /= 0;
        m[PUU(hvalue, rvalue)] = string(cur);
        m1[PUU(hvalue, rvalue)] = string(ori);
    }
}s[N*10];
string pre[N];
string sta[N*10];
int main()
{
    //Open();
    //memset(pre, 0, sizeof(pre));
    LL len = 0;
    scanf("%I64d", &len);
    scanf("%s", str);
    LL n;
    scanf("%I64d", &n);
    LL ma = 0;
    for(LL i = 0; i < n; i++)
    {
        scanf("%s", s[i].ori);
        s[i].update(i);
        ma = max(ma, (LL)strlen(s[i].ori));
    }
    init_hash(str, h, len);
    reverse(str, str+len);
    init_hash(str, rh, len);
    reverse(str, str+len);
    for(LL i = 0; i < len; i++)
    {
        for(LL j = max(0LL, i - ma - 1); j <= i; j++)
        {
            if(m1.find(PUU(string_hash(h, j, i+1), string_hash(rh, len-i-1, len-j))) != m1.end() && (j == 0 || !pre[j-1].empty()))
            {
                //cout<<m[string_hash(h, j, i+1)]<<endl;
                pre[i] = m1[PUU(string_hash(h, j, i+1), string_hash(rh, len-i-1, len-j))];
                break;
            }
        }
    }
    LL tail = 0;
    LL idx = len-1;
    while(true)
    {
        if(idx < 0) break;
        sta[tail++] = pre[idx];
        if(idx + 1 == pre[idx].length()) break;
        else idx -= pre[idx].length();

    }
    for(LL i = tail-1; i>= 0; i--)
        printf("%s%c", sta[i].c_str(), " \n"[i == 0]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <algorithm>
#include <set>
#include <cmath>
#include <map>
#include <unordered_map>
//#define lson x<<1
//#define rson x<<1|1
//#define mid ((lt[x].l+lt[x].r)/2)
//#define ID(x, y) ((x)*m+(y))
//#define CHECK(x, y) ((x)>=0 && (x)<n && (y)>=0 && (y)<m)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
void Open()
{
    #ifndef ONLINE_JUDGE
        freopen("F:/in.txt","r",stdin);
        //freopen("F:/my.txt","w",stdout);
    #endif // ONLINE_JUDGE
}
const int N = 10010;
const int MAGIC = 131;
char str[N];
unordered_map<ULL, int> m;
struct word
{
    char ori[1111];
    char cur[1111];
    ULL hvalue;
    void update(int id)
    {
        strcpy(cur, ori);
        int len = strlen(cur);
        for(int i = 0; i < len; i++)
            cur[i] = tolower(cur[i]);
        //reverse(cur, cur+strlen(cur));
        //cout<<cur<<endl;
        len = strlen(cur);
        hvalue = 0;
        for(int i = 1; i <= len;i++)
            hvalue = hvalue * MAGIC + cur[i-1] - 'a';
        m[hvalue] = id;
    }
}s[N*10];
int pre[N], sta[N*10];
int main()
{
    //Open();
    memset(pre, -1, sizeof(pre));
    int len = 0;
    scanf("%d", &len);
    scanf("%s", str);
//    strcpy(sss, str);
//    reverse(sss, sss+len);
//    cout<<str<<endl;
//    cout<<sss<<endl;
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%s", s[i].ori);
        s[i].update(i);
    }
    //init_hash(str, h, len);
    for(int i = 0; i < len; i++)
    {
        ULL ch = 0;
        for(int j = i; j >= max(0, i-1001); j--)
        {
            ch = ch * MAGIC + str[j] - 'a';
            if(m.find(ch) != m.end() && (j == 0 || pre[j-1] != -1))
                pre[i] = m[ch];
        }
    }
    int tail = 0;
    int idx = len-1;
    while(idx >= 0)
    {
        sta[tail++] = pre[idx];
        //if(idx + 1 == strlen(s[pre[idx]].cur)) break;
        idx -= strlen(s[pre[idx]].ori);

    }
    for(int i = tail-1; i>= 0; i--)
        printf("%s%c", s[sta[i]].ori, " \n"[i == 0]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <algorithm>
#include <set>
#include <cmath>
#include <map>
#include <unordered_map>
//#define lson x<<1
//#define rson x<<1|1
//#define mid ((lt[x].l+lt[x].r)/2)
//#define ID(x, y) ((x)*m+(y))
//#define CHECK(x, y) ((x)>=0 && (x)<n && (y)>=0 && (y)<m)
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
typedef unsigned long long ULL;
typedef pair<ULL, ULL> PUU;
const LL INF=0x3f3f3f3f;
void Open()
{
    #ifndef ONLINE_JUDGE
        freopen("F:/in.txt","r",stdin);
        //freopen("F:/my.txt","w",stdout);
    #endif // ONLINE_JUDGE
}
const LL N = 10010;
const LL MAGIC = 179;
char str[N], sss[N];
ULL base[N];
ULL h[N];
ULL rh[N];
map<PUU, string> m;
map<PUU, string> m1;

inline void init_hash(char *s, ULL *h, LL l)
{
    h[0]= 0;
    for(LL i = 1; i <= l;++i)
        h[i] = h[i-1] * MAGIC + s[i-1] - 'a';
    base[0] = 1;
    for(LL i = 1; i <= l; ++i)
        base[i] = base[i-1] * MAGIC;
}
inline ULL string_hash(ULL *h, LL l, LL r) //[0-base)
{
    return h[r] - h[l] * base[r-l];
}
struct word
{
    char ori[1111];
    char cur[1111];
    ULL hvalue;
    void update(LL id)
    {
        strcpy(cur, ori);
        LL len = strlen(cur);
        for(LL i = 0; i < len; i++)
            if(cur[i] > 'z' || cur[i] < 'a')
                cur[i] -= 'A' - 'a';
        reverse(cur, cur+len);
        hvalue = 0;
        for(LL i = 1; i <= len;i++)
            hvalue = hvalue * MAGIC + cur[i-1] - 'a';
        ULL rvalue = 0;
        for(int i = len; i >= 1; i--)
            rvalue = rvalue * MAGIC + cur[i-1] - 'a';
        if(m.find(PUU(hvalue, rvalue)) != m.end() && string(cur).compare(m[PUU(hvalue, rvalue)])) hvalue /= 0;
        m[PUU(hvalue, rvalue)] = string(cur);
        m1[PUU(hvalue, rvalue)] = string(ori);
    }
}s[N*10];
string pre[N];
string sta[N*10];
int main()
{
    //Open();
    //memset(pre, 0, sizeof(pre));
    LL len = 0;
    scanf("%I64d", &len);
    scanf("%s", str);
    LL n;
    scanf("%I64d", &n);
    LL ma = 0;
    for(LL i = 0; i < n; i++)
    {
        scanf("%s", s[i].ori);
        s[i].update(i);
        ma = max(ma, (LL)strlen(s[i].ori));
    }
    init_hash(str, h, len);
    reverse(str, str+len);
    init_hash(str, rh, len);
    reverse(str, str+len);
    for(LL i = 0; i < len; i++)
    {
        for(LL j = max(0LL, i - ma - 1); j <= i; j++)
        {
            if(m1.find(PUU(string_hash(h, j, i+1), string_hash(rh, len-i-1, len-j))) != m1.end() && (j == 0 || !pre[j-1].empty()))
            {
                //cout<<m[string_hash(h, j, i+1)]<<endl;
                pre[i] = m1[PUU(string_hash(h, j, i+1), string_hash(rh, len-i-1, len-j))];
                break;
            }
        }
    }
    LL tail = 0;
    LL idx = len-1;
    while(true)
    {
        if(idx < 0) break;
        sta[tail++] = pre[idx];
        if(idx + 1 == pre[idx].length()) break;
        else idx -= pre[idx].length();

    }
    for(LL i = tail-1; i>= 0; i--)
        printf("%s%c", sta[i].c_str(), " \n"[i == 0]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <algorithm>
#include <set>
#include <cmath>
#include <map>
#include <unordered_map>
//#define lson x<<1
//#define rson x<<1|1
//#define mid ((lt[x].l+lt[x].r)/2)
//#define ID(x, y) ((x)*m+(y))
//#define CHECK(x, y) ((x)>=0 && (x)<n && (y)>=0 && (y)<m)
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
typedef unsigned long long ULL;
const LL INF=0x3f3f3f3f;
void Open()
{
    #ifndef ONLINE_JUDGE
        freopen("F:/in.txt","r",stdin);
        //freopen("F:/my.txt","w",stdout);
    #endif // ONLINE_JUDGE
}
const LL N = 10010;
const LL MAGIC = 37;
char str[N], sss[N];
ULL base[N];
ULL h[N];
unordered_map<ULL, string> m;
unordered_map<ULL, string> m1;

inline void init_hash(char *s, ULL *h, LL l)
{
    h[0]= 0;
    for(LL i = 1; i <= l;++i)
        h[i] = h[i-1] * MAGIC + s[i-1] - 'a';
    base[0] = 1;
    for(LL i = 1; i <= l; ++i)
        base[i] = base[i-1] * MAGIC;
}
inline ULL string_hash(ULL *h, LL l, LL r) //[0-base)
{
    return h[r] - h[l] * base[r-l];
}
struct word
{
    char ori[1111];
    char cur[1111];
    ULL hvalue;
    void update(LL id)
    {
        strcpy(cur, ori);
        LL len = strlen(cur);
        for(LL i = 0; i < len; i++)
            if(cur[i] > 'z' || cur[i] < 'a')
                cur[i] -= 'A' - 'a';
        reverse(cur, cur+len);
        hvalue = 0;
        for(LL i = 1; i <= len;i++)
            hvalue = hvalue * MAGIC + cur[i-1] - 'a';
        //if(m.find(hvalue) != m.end() && string(cur).compare(m[hvalue])) hvalue /= 0;
        m[hvalue] = string(cur);
        m1[hvalue] = string(ori);
    }
}s[N*10];
string pre[N];
string sta[N*10];
int main()
{
    //Open();
    //memset(pre, 0, sizeof(pre));
    LL len = 0;
    scanf("%I64d", &len);
    scanf("%s", str);
    LL n;
    scanf("%I64d", &n);
    for(LL i = 0; i < n; i++)
    {
        scanf("%s", s[i].ori);
        s[i].update(i);
    }
    init_hash(str, h, len);
    for(LL i = 0; i < len; i++)
    {
        for(LL j = 0; j <= i; j++)
        {
            if(m.find(string_hash(h, j, i+1)) != m.end() && (j == 0 || !pre[j-1].empty()))
            {
                //cout<<m[string_hash(h, j, i+1)]<<endl;
                pre[i] = m1[string_hash(h, j, i+1)];
                break;
            }
        }
    }
    LL tail = 0;
    LL idx = len-1;
    while(true)
    {
        if(idx < 0) break;
        sta[tail++] = pre[idx];
        if(idx + 1 == pre[idx].length()) break;
        else idx -= pre[idx].length();

    }
    for(LL i = tail-1; i>= 0; i--)
        printf("%s%c", sta[i].c_str(), " \n"[i == 0]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <algorithm>
#include <set>
#include <cmath>
#include <map>
#include <unordered_map>
//#define lson x<<1
//#define rson x<<1|1
//#define mid ((lt[x].l+lt[x].r)/2)
//#define ID(x, y) ((x)*m+(y))
//#define CHECK(x, y) ((x)>=0 && (x)<n && (y)>=0 && (y)<m)
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
typedef unsigned long long ULL;
const LL INF=0x3f3f3f3f;
void Open()
{
    #ifndef ONLINE_JUDGE
        freopen("F:/in.txt","r",stdin);
        //freopen("F:/my.txt","w",stdout);
    #endif // ONLINE_JUDGE
}
const LL N = 10010;
const LL MAGIC = 37;
char str[N], sss[N];
ULL base[N];
ULL h[N];
unordered_map<ULL, string> m;
unordered_map<ULL, string> m1;

inline void init_hash(char *s, ULL *h, LL l)
{
    h[0]= 0;
    for(LL i = 1; i <= l;++i)
        h[i] = h[i-1] * MAGIC + s[i-1] - 'a';
    base[0] = 1;
    for(LL i = 1; i <= l; ++i)
        base[i] = base[i-1] * MAGIC;
}
inline ULL string_hash(ULL *h, LL l, LL r) //[0-base)
{
    return h[r] - h[l] * base[r-l];
}
struct word
{
    char ori[1111];
    char cur[1111];
    ULL hvalue;
    void update(LL id)
    {
        strcpy(cur, ori);
        LL len = strlen(cur);
        for(LL i = 0; i < len; i++)
            if(cur[i] > 'z' || cur[i] < 'a')
                cur[i] -= 'A' - 'a';
        reverse(cur, cur+len);
        hvalue = 0;
        for(LL i = 1; i <= len;i++)
            hvalue = hvalue * MAGIC + cur[i-1] - 'a';
        if(m.find(hvalue) != m.end() && string(cur).compare(m[hvalue])) hvalue /= 0;
        m[hvalue] = string(cur);
        m1[hvalue] = string(ori);
    }
}s[N*10];
string pre[N];
string sta[N*10];
int main()
{
    //Open();
    //memset(pre, 0, sizeof(pre));
    LL len = 0;
    scanf("%I64d", &len);
    scanf("%s", str);
    LL n;
    scanf("%I64d", &n);
    for(LL i = 0; i < n; i++)
    {
        scanf("%s", s[i].ori);
        s[i].update(i);
    }
    init_hash(str, h, len);
    for(LL i = 0; i < len; i++)
    {
        for(LL j = 0; j <= i; j++)
        {
            if(m.find(string_hash(h, j, i+1)) != m.end() && (j == 0 || !pre[j-1].empty()))
            {
                //cout<<m[string_hash(h, j, i+1)]<<endl;
                pre[i] = m1[string_hash(h, j, i+1)];
                break;
            }
        }
    }
    LL tail = 0;
    LL idx = len-1;
    while(true)
    {
        if(idx < 0) break;
        sta[tail++] = pre[idx];
        if(idx + 1 == pre[idx].length()) break;
        else idx -= pre[idx].length();

    }
    for(LL i = tail-1; i>= 0; i--)
        printf("%s%c", sta[i].c_str(), " \n"[i == 0]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <algorithm>
#include <set>
#include <cmath>
#include <map>
#include <unordered_map>
//#define lson x<<1
//#define rson x<<1|1
//#define mid ((lt[x].l+lt[x].r)/2)
//#define ID(x, y) ((x)*m+(y))
//#define CHECK(x, y) ((x)>=0 && (x)<n && (y)>=0 && (y)<m)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
void Open()
{
    #ifndef ONLINE_JUDGE
        freopen("F:/in.txt","r",stdin);
        //freopen("F:/my.txt","w",stdout);
    #endif // ONLINE_JUDGE
}
const int N = 10010;
const int MAGIC = 31;
char str[N];
unordered_map<ULL, int> m;
struct word
{
    char ori[1111];
    char cur[1111];
    ULL hvalue;
    void update(int id)
    {
        strcpy(cur, ori);
        int len = strlen(cur);
        for(int i = 0; i < len; i++)
            cur[i] = tolower(cur[i]);
        //reverse(cur, cur+strlen(cur));
        //cout<<cur<<endl;
        len = strlen(cur);
        hvalue = 0;
        for(int i = 1; i <= len;i++)
            hvalue = hvalue * MAGIC + cur[i-1] - 'a';
        m[hvalue] = id;
    }
}s[N*10];
int pre[N], sta[N*10];
int main()
{
    //Open();
    memset(pre, -1, sizeof(pre));
    int len = 0;
    scanf("%d", &len);
    scanf("%s", str);
//    strcpy(sss, str);
//    reverse(sss, sss+len);
//    cout<<str<<endl;
//    cout<<sss<<endl;
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%s", s[i].ori);
        s[i].update(i);
    }
    //init_hash(str, h, len);
    for(int i = 0; i < len; i++)
    {
        ULL ch = 0;
        for(int j = i; j >= max(0, i-1001); j--)
        {
            ch = ch * MAGIC + str[j] - 'a';
            if(m.find(ch) != m.end() && (j == 0 || pre[j-1] != -1))
                pre[i] = m[ch];
        }
    }
    int tail = 0;
    int idx = len-1;
    while(idx >= 0)
    {
        sta[tail++] = pre[idx];
        //if(idx + 1 == strlen(s[pre[idx]].cur)) break;
        idx -= strlen(s[pre[idx]].ori);

    }
    for(int i = tail-1; i>= 0; i--)
        printf("%s%c", s[sta[i]].ori, " \n"[i == 0]);
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 47ULL;
const uint64_t PINV = 5887258746928580303ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -10);
    if (i == n) return std::make_pair(true,  -10);
    if (dp[i].second != -1) return dp[i];
    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, it->second);
        }
    }
    return dp[i] = std::make_pair(false, -10);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a' + 1;
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a' + 1);
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> words[i];
        words[i].shrink_to_fit();
        std::string t = words[i];
        std::transform(t.begin(), t.end(), t.begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = t[0] - 'a' + 1;
        for (int j = 1; j < t.length(); ++j) {
            h = h + pow_P[j]*(t[j] - 'a' + 1);
        }
        hash_to_word[h] = i;
    }
    std::vector<int> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(p.second);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << words[answer[k]];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 47ULL;
const uint64_t PINV = 5887258746928580303ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];
    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }
    return dp[i] = std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> words[i];
        words[i].shrink_to_fit();
        std::string t = words[i];
        std::transform(t.begin(), t.end(),
                       t.begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = t[0] - 'a';
        for (int j = 1; j < t.length(); ++j) {
            h = h + pow_P[j]*(t[j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(words[p.second]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 47ULL;
const uint64_t PINV = 5887258746928580303ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -10);
    if (i == n) return std::make_pair(true,  -10);
    if (dp[i].second != -1) return dp[i];
    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, it->second);
        }
    }
    return dp[i] = std::make_pair(false, -10);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> words[i];
        words[i].shrink_to_fit();
        std::string t = words[i];
        std::transform(t.begin(), t.end(), t.begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = t[0] - 'a';
        for (int j = 1; j < t.length(); ++j) {
            h = h + pow_P[j]*(t[j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<int> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(p.second);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << words[answer[k]];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <unordered_map>
#include <utility>

const uint64_t P = 53ULL;
const uint64_t PINV = 2436362424829563421ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::vector<std::string> words;
std::unordered_map<std::string, std::string> fixed_case;
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::unordered_map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];

    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }

    return std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::string t; std::cin >> t;
        std::string tl = t;
        std::transform(tl.begin(), tl.end(), tl.begin(), ::tolower);
        words.push_back(tl);
        fixed_case[tl] = t;
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = tl[0] - 'a';
        for (int i = 1; i < tl.length(); ++i) {
            h = h + pow_P[i]*(tl[i] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(fixed_case[words[p.second]]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 53ULL;
const uint64_t PINV = 2436362424829563421ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];
    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }
    return dp[i] = std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> words[i];
        std::string t = words[i];
        std::transform(t.begin(), t.end(),
                       t.begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = t[0] - 'a';
        for (int j = 1; j < t.length(); ++j) {
            h = h + pow_P[j]*(t[j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(words[p.second]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 47ULL;
const uint64_t PINV = 2436362424829563421ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];
    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }
    return dp[i] = std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> words[i];
        words[i].shrink_to_fit();
        std::string t = words[i];
        std::transform(t.begin(), t.end(),
                       t.begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = t[0] - 'a';
        for (int j = 1; j < t.length(); ++j) {
            h = h + pow_P[j]*(t[j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(words[p.second]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 53ULL;
const uint64_t PINV = 2436362424829563421ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
std::string fixed_case[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];
    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }
    return dp[i] = std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> fixed_case[i];
        words[i] = fixed_case[i];
        std::transform(words[i].begin(), words[i].end(),
                       words[i].begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(words[i].length()));
        uint64_t h = words[i][0] - 'a';
        for (int j = 1; j < words[i].length(); ++j) {
            h = h + pow_P[j]*(words[i][j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(fixed_case[p.second]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 53ULL;
const uint64_t PINV = 2436362424829563421ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
std::string fixed_case[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];

    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            std::cout << fixed_case[index] << ' ';
            return dp[i] = std::make_pair(true, index);
        }
    }

    return std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> fixed_case[i];
        words[i] = fixed_case[i];
        std::transform(words[i].begin(), words[i].end(),
                       words[i].begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(words[i].length()));
        uint64_t h = words[i][0] - 'a';
        for (int j = 1; j < words[i].length(); ++j) {
            h = h + pow_P[j]*(words[i][j] - 'a');
        }
        hash_to_word[h] = i;
    }
    f(0);
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 53ULL;
const uint64_t PINV = 2436362424829563421ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
std::string fixed_case[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];

    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }

    return std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> fixed_case[i];
        words[i] = fixed_case[i];
        std::transform(words[i].begin(), words[i].end(),
                       words[i].begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(words[i].length()));
        uint64_t h = words[i][0] - 'a';
        for (int j = 1; j < words[i].length(); ++j) {
            h = h + pow_P[j]*(words[i][j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(fixed_case[p.second]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 53ULL;
const uint64_t PINV = 2436362424829563421ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];
    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }
    return dp[i] = std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::cin >> words[i]; words[i].shrink_to_fit();
        std::string t = words[i];
        std::transform(t.begin(), t.end(),
                       t.begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = t[0] - 'a';
        for (int j = 1; j < t.length(); ++j) {
            h = h + pow_P[j]*(t[j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(words[p.second]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <map>

const uint64_t P = 53ULL;
const uint64_t PINV = 2436362424829563421ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
std::map<std::string, std::string> fixed_case;
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];

    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }

    return std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    for (int i = 0; i < m; ++i) {
        std::string t; std::cin >> t;
        words[i] = t;
        std::transform(words[i].begin(), words[i].end(),
                       words[i].begin(), ::tolower);
        fixed_case[words[i]] = t;
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = words[i][0] - 'a';
        for (int j = 1; j < t.length(); ++j) {
            h = h + pow_P[j]*(words[i][j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(fixed_case[words[p.second]]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <unordered_map>

const uint64_t P = 47ULL;
const uint64_t PINV = 5887258746928580303ULL;
uint64_t pow_P[10001];
uint64_t pow_PINV[10001];

std::string words[100000];
int n; std::string s;
std::pair<bool, int> dp[10000];
int max_word_length = 0;
uint64_t hash[10000];
std::unordered_map<uint64_t, int> hash_to_word;

/*
*   Is it possible to construct a sentence starting from i?
*   If so, what is the index of the word we start with?
*/
std::pair<bool, int> f(int i) {
    if (i >  n) return std::make_pair(false, -1);
    if (i == n) return std::make_pair(true,  -1);
    if (dp[i].second != -1) return dp[i];
    for (int len = 1; len <= max_word_length; ++len) {
        if (i + len - 1 >= s.length()) break;
        const uint64_t h0 = (hash[i + len - 1] - (i? hash[i - 1] : 0))*pow_PINV[i];
        const auto it = hash_to_word.find(h0);
        if (it == hash_to_word.end()) continue;
        const int index = it->second;
        if (f(i + len).first) {
            return dp[i] = std::make_pair(true, index);
        }
    }
    return dp[i] = std::make_pair(false, -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    for (int i = 0; i < 10000; ++i) {
        dp[i].second = -1;
    }
    pow_P[0] = pow_PINV[0] = 1;
    for (int i = 1; i <= 10000; ++i) {
        pow_P[i] = pow_P[i-1]*P;
        pow_PINV[i] = pow_PINV[i-1]*PINV;
    }
    std::cin >> n >> s;
    std::reverse(s.begin(), s.end());
    hash[0] = s[0] - 'a';
    for (int i = 1; i < n; ++i) {
        hash[i] = hash[i - 1] + pow_P[i]*(s[i] - 'a');
    }
    int m; std::cin >> m;
    hash_to_word.reserve(m);
    hash_to_word.max_load_factor(5);
    for (int i = 0; i < m; ++i) {
        std::cin >> words[i];
        words[i].shrink_to_fit();
        std::string t = words[i];
        std::transform(t.begin(), t.end(),
                       t.begin(), ::tolower);
        max_word_length = std::max(max_word_length, int(t.length()));
        uint64_t h = t[0] - 'a';
        for (int j = 1; j < t.length(); ++j) {
            h = h + pow_P[j]*(t[j] - 'a');
        }
        hash_to_word[h] = i;
    }
    std::vector<std::string> answer;
    int i = 0;
    while (i != n) {
        auto p = f(i);
        answer.push_back(words[p.second]);
        i += words[p.second].length();
    }
    std::reverse(answer.begin(), answer.end());
    for (int k = 0; k < answer.size(); ++k) {
        if (k > 0) std::cout << ' ';
        std::cout << answer[k];
    }
    std::cout << '\n';
    return 0;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)2e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int a[maxn  ]    , b[maxn]  ,dp[ maxn ] ;
string str[maxn  ]  ;
map< int  ,int > ma  ;
int p  = 239  ;
void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        int now = 1  ;
        sum =  0;
        rep(j ,sz(ts) )  {

            sum = add( sum ,   mul (now ,(ts[j]-'a' )*1LL ) )  ;
            now = mul(now , p ) ;

        }
        ma[sum ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 1 ;

    s =  '-' + s ;

    forn(i,1,sz(s)-1) {
        string ts ;
        int cnt  = 0 ;
        int now = 1 ;
         sum =  0;
        ford( j ,i ,1 )  {

            sum = add( sum ,   mul (now ,(s[j]-'a' )*1LL ) )  ;
            now = mul(now , p ) ;

            cnt++  ;
            if(cnt> 1007)  break  ;
            if(ma.find(sum) != ma.end()  and dp[j-1] > -1 )   {

                dp[i] =  ma[  sum ]  ;
                break  ;
            }
        }
    }
   curr =    n    ;

    while(  curr>0 )  {
        int id = dp[curr]  ;
        curr -=  sz( str[id])   ;
        res.pb(  str[id]  ) ;

    }

    reverse(all(res ) )  ;
    rep(i, sz(res)   )  cout << res[i]  <<  ' ' ;

    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)2e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int a[maxn  ]    , b[maxn]  ,dp[ maxn ] ;
string str[maxn  ]  ;
map<string  ,int > ma  ;

void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        // reverse(all (ts)   )  ;
        ma[ts ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 1 ;

    s =  '-' + s ;
    forn(i,1,sz(s)-1) {
        string ts ;
        int cnt  = 0 ;
        ford( j ,i ,1 )  {
            ts += s[ j]  ;
            cnt++  ;
            if(cnt> 1007)  break  ;
            if(ma[ts ] > 0  and dp[j-1] > -1 )   {

                res.pb( str[ ma[ts ] ] ) ;
                dp[i] =  ma[ts ]  ;
                break  ;
            }
        }

    }

    rep(i, sz(res) ) {
        cout << res[i]  << ' ' ;
    }
    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)2e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int a[maxn  ]    , b[maxn]  ,dp[ maxn ] ;
string str[maxn  ]  ;
map< int  ,int > ma  ;
int p  = 29  ;
void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        int now = 1  ;
        sum =  0;
        rep(j ,sz(ts) )  {

            sum = add( sum ,   mul (now ,(ts[j]-'a' )*1LL ) )  ;
            now = mul(now , p ) ;

        }
        ma[sum ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 1 ;

    s =  '-' + s ;

    forn(i,1,sz(s)-1) {
        string ts ;
        int cnt  = 0 ;
        int now = 1 ;
         sum =  0;
        ford( j ,i ,1 )  {

            sum = add( sum ,   mul (now ,(s[j]-'a' )*1LL ) )  ;
            now = mul(now , p ) ;

            cnt++  ;
            if(cnt> 1007)  break  ;
            if(ma[ sum ] > 0  and dp[j-1] > -1 )   {

                res.pb( str[ ma[ sum ] ] ) ;
                dp[i] =  ma[  sum ]  ;
                break  ;
            }
        }
    }

    rep(i, sz(res) ) {
        cout << res[i]  << ' ' ;
    }
    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)2e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int a[maxn  ]    , b[maxn]  ,dp[ maxn ] ;
string str[maxn  ]  ;
map<string  ,int > ma  ;

void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        // reverse(all (ts)   )  ;
        ma[ts ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 1 ;

    s =  '-' + s ;
    forn(i,1,sz(s)-1) {
        string ts ;
        int cnt  = 0 ;
        ford( j ,i ,1 )  {
            ts += s[ j]  ;
            cnt++  ;
            if(cnt> 1007)  break  ;
            if(ma.find(ts ) !=  ma.end()    and dp[j-1] > -1 )   {

                dp[i] =  ma[ts ]  ;
                break  ;
            }
        }

    }
  curr =    n    ;

    while(  curr>0 )  {
        int id = dp[curr]  ;
        curr -=  sz( str[id])   ;
        res.pb(  str[id]  ) ;

    }

    reverse(all(res ) )  ;
    rep(i, sz(res)   )  cout << res[i]  <<  ' ' ;

    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)2e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int a[maxn  ]    , b[maxn]  ,dp[ maxn ] ;
string str[maxn  ]  ;
map<string  ,int > ma  ;

void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        // reverse(all (ts)   )  ;
        ma[ts ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 1 ;

    s =  '-' + s ;
    forn(i,1,sz(s)-1) {
        string ts ;
        int cnt  = 0 ;
        ford( j ,i ,1 )  {
            ts += s[ j]  ;
            cnt++  ;
            if(cnt> 1007)  break  ;
            if(ma.find(ts ) !=  ma.end()    and dp[j-1] > -1 )   {

                res.pb( str[ ma[ts ] ] ) ;
                dp[i] =  ma[ts ]  ;
                break  ;
            }
        }

    }

    rep(i, sz(res) ) {
        cout << res[i]  << ' ' ;
    }
    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)2e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int a[maxn  ]    , b[maxn]  ,dp[ maxn ] ;
string str[maxn  ]  ;
map<string  ,int > ma  ;

void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        // reverse(all (ts)   )  ;
        ma[ts ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 0 ;

    s =  '-' + s ;
    forn(i,1,sz(s)-1) {
        string ts ;

        ford( j ,i ,1 )  {
            ts += s[ j]  ;

            if(ma[ts ] > 0  and dp[j-1] > -1 )   {

                res.pb( str[ ma[ts ] ] ) ;
                dp[i] =  ma[ts ]  ;
                break  ;
            }
        }

    }

    rep(i, sz(res) ) {
        cout << res[i]  << ' ' ;
    }
    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)1e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int dp[ maxn ] ;
string str[maxn  ]  ;
map< int  ,int > ma  ;
int p  = 29  ;

void go(int  n)  {
    if( n<1) return  ;
    string t =  str[dp[n] ]  ;
    go(n-sz( t  ));
    cout <<t << ' '  ;
}

void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        int hash = 0  ;
        rep(j ,sz(ts) )  {
            hash =  hash* p +  ts[j]  ;

        }
        ma[ hash ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 1 ;

    s =  '-' + s ;

    forn(i,1,sz(s)-1) {
        string ts ;
        int cnt  =  0 , hash = 0 ;
        ford( j ,i ,1 )  {

            hash =  hash* p+ s[j]  ;
            cnt++  ;
            if(cnt> 1007)  break  ;
            if(ma.find(hash ) != ma.end()  and dp[j-1] > -1 )   {

                dp[i] =  ma[ hash  ]  ;
                break  ;
            }
        }
    }
    go(n )   ;
    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)1e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int dp[ maxn ] ;
string str[maxn  ]  ;
map< int  ,int > ma  ;
int p  = 239  ;
void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        int now = 1  ;
        sum =  0;
        rep(j ,sz(ts) )  {

            sum = add( sum ,   mul (now ,(ts[j]-'a' )*1LL ) )  ;
            now = mul(now , p ) ;

        }
        ma[sum ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 1 ;

    s =  '-' + s ;

    forn(i,1,sz(s)-1) {
        string ts ;
        int cnt  = 0 ;
        int now = 1 ;
         sum =  0;
        ford( j ,i ,1 )  {

            sum = add( sum ,   mul (now ,(s[j]-'a' )*1LL ) )  ;
            now = mul(now , p ) ;

            cnt++  ;
            if(cnt> 1007)  break  ;
            if(ma.find(sum) != ma.end()  and dp[j-1] > -1 )   {

                dp[i] =  ma[  sum ]  ;
                break  ;
            }
        }
    }
   curr =    n    ;

    while(  curr>0 )  {
        int id = dp[curr]  ;
        curr -=  sz( str[id])   ;
        res.pb(  str[id]  ) ;

    }

    reverse(all(res ) )  ;
    rep(i, sz(res)   )  cout << res[i]  <<  ' ' ;

    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ff              first
#define ss              second
#define pb(x)           push_back(x)
#define mp              make_pair
#define sz(x)           (int)x.size()
#define mem(x ,y)       memset(x , y , sizeof x )
#define all(a )         a.begin() , a.end()
#define endl            "\n"
#define pii             pair<int,int>
#define piii            pair<int,pair<int,int > >
#define clr(x)          x.clear()
#define sl(x )          scanf("%I64d" ,&x)
#define sll(x,y )       scanf("%I64d%I64d" ,&x ,&y)
#define si(x )          scanf("%d" ,&x)
#define forn(i,x,y )    for(int i= x; i<=y ; i++ )
#define ford(i,x,y )    for(int i= x; i>=y ; i-- )
#define rep(i,n )       for(int i= 0; i<n ; i++ )
#define repi(i,n )      for(int i= 1; i<=n ; i++ )
#define repit(i, c)     for( __typeof((c).begin()) i = (c).begin(); i != (c).end();++i )

#ifndef ONLINE_JUDGE
    #define dbg(args...)    do {   cout << #args << ' ' ;  print(args); } while(0); cerr<< endl ;
#else
    #define dbg(args...)   ;
#endif

typedef long long ll  ;
typedef unsigned long long ull  ;

#define  int  ll
ll  mod =  1e9+7, mod2 =     998244353;
int setbit(int n, int pos  ) { return n = n|(1LL<< pos) ; }
int resetbit(int n,int pos ) { return n = n & ~(1LL<<pos ); }
bool checkbit(int n,int pos) { return (bool ) (n&(1LL<<pos))  ; }
template<typename T> void print(const T& v) {    cerr << v << ' ' ;}
template<typename T>T add(T x, T y, T mod = mod ){ x%= mod ;  y%= mod ;   return (x+y)%mod ;  }
template<typename T>T sub(T x, T y, T mod = mod ){ return ((x-y)%mod+mod )%mod;  }
template<typename T>T mul(T x, T y, T mod = mod ){ x %= mod ; y %= mod ; return (x*y)%mod  ;  }
template<typename T1,typename... T2> void print( const T1& first, const T2&... rest ){ print(first); print(rest...) ;}
template<typename T> void dbg_a(T a[] ,int n=10 ) {cerr << "[ "; for(int i=0;i <= n ; i++ )cerr<<a[i]<<' ' ; cerr<< " ]" <<  endl; }
template<typename F,typename S>ostream& operator<<( ostream& os, const pair< F, S > & p ){return os << "[ " << p.first << ", " << p.second << " ]";}
template<typename T>ostream &operator<<(ostream & os, const vector< T > &v ){os << "[ "; for(int i=0; i<sz(v) ; i++ )  os << v[i] << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const map< T ,T> &Map ){os << "[ "; repit(it , Map ) os << "[" <<(*it).ff << ' ' << (*it).ss << "] "    ; return os << "]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const set< T > &Set  ){os << "[ "; repit(it , Set ) os <<  *it  << ' ' ; return os << " ]\n" ; }
template<typename T>ostream &operator<<(ostream & os, const multiset< T > &Set) {os << "[ "; repit(it , Set )os <<  *it  << ' ' ; return os << " ]\n" ; }
template<class T> string to_str(T t){stringstream ss; ss<<t; return ss.str();}
// typedef tree<   int ,     // change type
//               null_type,
//               less_equal  < int  >  ,  // change type ..
//               rb_tree_tag,
//               tree_order_statistics_node_update> ordered_set;

    // order_of_key (k) : Number of items strictly smaller than k .
    // find_by_order(k) : K-th element in a set (counting from zero).
template < typename T >
T bigmod(T A,T B ,T mod = mod ) {
    if(!B)return 1;
    if(B%2)return bigmod(A,B-1)*A%mod;
    T C=bigmod(A,B/2);
    return C*C%mod;
}

template < typename T >
T  invmod( T x , T m = mod) {
    return bigmod(x,m-2 , m) ;
}
const int maxn  = (int)2e5  +123 ;
const ll inf  =  1e18; //  0xc0  ; //0x3f ; //
////////////////////////////////////////////////

int n ,m  ;
int a[maxn  ]    , b[maxn]  ,dp[ maxn ] ;
string str[maxn  ]  ;
map< int  ,int > ma  ;
int p  = 29  ;
void  solve() {
    int x,y,z   ,ans = 0,k,  curr , sum=0   ,pos = 0 ,want  ;
    string s ;

    cin >> n >> s ;
    cin >> m  ;
    forn(i, 1, m )  {
        cin  >> str[i]  ;

        string ts  = str[i]  ;
        rep(j , sz(ts ))  {
            if(ts[j]<97)  ts[j]  +=32 ;
        }
        int now = 1  ;
        sum =  0;
        rep(j ,sz(ts) )  {

            sum = add( sum ,   mul (now ,(ts[j]-'a' )*1LL ) )  ;
            now = mul(now , p ) ;

        }
        ma[sum ] =  i ;

    }

    vector<string  > res;
    rep(i ,sz( s) +5  )  dp[i]  =  -1 ;
    dp[0]  = 1 ;

    s =  '-' + s ;

    forn(i,1,sz(s)-1) {
        string ts ;
        int cnt  = 0 ;
        int now = 1 ;
         sum =  0;
        ford( j ,i ,1 )  {

            sum = add( sum ,   mul (now ,(s[j]-'a' )*1LL ) )  ;
            now = mul(now , p ) ;

            cnt++  ;
            if(cnt> 1007)  break  ;
            if(ma.find(sum) != ma.end()  and dp[j-1] > -1 )   {

                res.pb( str[ ma[ sum ] ] ) ;
                dp[i] =  ma[  sum ]  ;
                break  ;
            }
        }
    }

    rep(i, sz(res) ) {
        cout << res[i]  << ' ' ;
    }
    cout<< endl ;

}
signed main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    ios :: sync_with_stdio(false);  cin.tie(0);  cout.tie(0) ;
    // cout << fixed << setprecision( 12) ;
    int t = 1 , cs =0   ;
    // cin  >>t ;
    while(t--)   {
        solve( )  ;
    }
    return 0 ;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e4+10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int n, m;
char s[N], ss[N];
char w[N * 110];
char t[1010];
int f[N];
int p[N * 10];
int l[N * 10];
map<string, int>mop;
void print(int pos)
{
	if (pos == 0)return;
	int o = f[pos];
	print(pos - l[o]);
	printf("%s ", w+p[o]);
}
int main()
{
	while (~scanf("%d", &n))
	{
		MS(w, 0);
		mop.clear();
		scanf("%s", s + 1); MC(ss, s);
		scanf("%d", &m);
		p[0] = 0;
		for (int i = 1; i <= m; ++i)
		{
			scanf("%s", w + p[i]);
			l[i]= strlen(w + p[i]);
			p[i + 1] = p[i] + l[i] + 1;

			strcpy(t, w + p[i]); t[l[i]] = 0;
			for (int j = 0; j < l[i]; ++j)t[j] = tolower(t[j]);
			for (int j = 0; j < l[i] / 2;++j)swap(t[j],t[l[i] - 1 - j]);
			mop[t] = i;
		}
		MS(f, 0); f[0] = -1;
		for (int i = 1; i <= n; ++i)
		{
			int top = min(i, 1000);
			s[i + 1] = 0;
			for (int j = 1; j <= top; ++j)
			{
				if (f[i - j] == 0)continue;
				if (mop.find(s + (i - j + 1)) == mop.end())continue;
				int o = mop[s + (i - j + 1)];
				if (o == 0)continue;
				f[i] = o;
				break;
			}
			s[i + 1] = ss[i + 1];
		}
		print(n);
		puts("");
	}
	return 0;
}
/*
【trick&&吐槽】
1，这道题有一个细节一定要再次警醒！
我在查询一个字符串是否在单词中的时候，
第一次用到的是查看mop[字符串]是否为0，
然而这样子必然会把这个查询字符串也添加入map中，导致map膨胀过大，造成MLE或TLE
比赛的时候就是因为这个浪费了15mins与增加了2次罚时。

2，用string存字符串就可以
用一个长字符串分开存多个小字符串的方法自然也是有优化作用的，然而优化程度却并不大。

【题意】
有一个长度为n（1<=n<=1e4）的加密字符串
这个字符串是由一个若干单词穿成的句子，经过以下的规则加密而成的。

1，单词来源于单词库，单词库会告诉你。
这个单词库内会有m（1<=m<=1e5）个单词，
每个单词的长度都不超过1e3，所有单词的总长度不超过1e6.
2，我们先会把所有选出的单词连乘串（同一个单词可以选择多次），两两之间一个空格
3，对于所有的单词做字符串reverse操作（即前后倒置）。
4，去掉所有的空格
5，转化为小写

现在已知加密字符串和单词库。
让你还原加密前的句子。

【类型】
DP SET-MAP

【分析】
我们可以把所有的单词都倒过来，再转化为小写，加入SET-MAP中
然后我们再枚举一个字符串的尾端点，向前拓展，记录最后一个延展的字符串编号。
这样这道题就做完了。

时间复杂度可达O( n*1000 *log(n*1000) )

*/


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e4+10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int n, m;
char s[N], ss[N];
int f[N];
char w[N * 110];
int p[N * 10];
int l[N * 10];
char t[1010];
map<string, int>mop;
void print(int pos)
{
	if (pos == 0)return;
	int o = f[pos];
	print(pos - l[o]);
	printf("%s ", w+p[o]);
}
int main()
{
	while (~scanf("%d", &n))
	{
		MS(w, 0);
		mop.clear();
		scanf("%s", s + 1); MC(ss, s);
		scanf("%d", &m);
		p[0] = 0;
		for (int i = 1; i <= m; ++i)
		{
			scanf("%s", w + p[i]);
			l[i]= strlen(w + p[i]);
			p[i + 1] = p[i] + l[i] + 1;

			strcpy(t, w + p[i]); t[l[i]] = 0;
			for (int j = 0; j < l[i]; ++j)t[j] = tolower(t[j]);
			for (int j = 0; j < l[i] / 2;++j)swap(t[j],t[l[i] - 1 - j]);
			mop[t] = i;
		}
		MS(f, 0); f[0] = -1;
		for (int i = 1; i <= n; ++i)
		{
			int top = min(i, 1000);
			s[i + 1] = 0;
			for (int j = 1; j <= top; ++j)
			{
				if (f[i - j] == 0)continue;
				int o = mop[s + (i - j + 1)];
				if (o == 0)continue;
				f[i] = o;
				break;
			}
			s[i + 1] = ss[i + 1];
		}
		print(n);
		puts("");
	}
	return 0;
}
/*
【trick&&吐槽】

【题意】

【类型】

【分析】

【时间复杂度&&优化】

【数据】

*/


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e4 + 10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int n, m;
char s[N], ss[N], t[1010], tt[1010];
int f[N];
string a[N * 10];
int l[N * 10];
map<string, int>mop;
void print(int p)
{
	if (p == 0)return;
	print(p - l[f[p]]);
	cout << a[f[p]] << " ";
}
int main()
{
	while (~scanf("%d", &n))
	{
		mop.clear();
		scanf("%s", s + 1); MC(ss, s);
		scanf("%d", &m);
		for (int i = 1; i <= m; ++i)
		{
			cin >> a[i];
			string t;//string t = a[i];
			l[i] = a[i].size();
			for (int j = 0; j < l[i]; ++j)t += tolower(a[i][l[i] - 1 - j]);
			mop[t] = i;
		}
		MS(f, 0); f[0] = -1;
		for (int i = 1; i <= n; ++i)
		{
			int top = min(i, 1000);
			s[i + 1] = 0;
			for (int j = 1; j <= top; ++j)
			{
				if (f[i - j] == 0)continue;
				if (mop.find(s + (i - j + 1)) == mop.end())continue;
				int o = mop[s + (i - j + 1)];
				if (o == 0)continue;
				f[i] = o;
				break;
			}
			s[i + 1] = ss[i + 1];
		}
		print(n);
		puts("");
	}
	return 0;
}
/*
【trick&&吐槽】

【题意】

【类型】

【分析】

【时间复杂度&&优化】

【数据】

*/