#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define double LL
#define eps 1e-8
#define maxn 5100
#define mod 1000000007
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
struct Point{
    double x,y;
    Point(){}
    Point(double tx,double ty) {x=tx;y=ty;}
}p[maxn];
double xmul(Point p0,Point p1,Point p2){
	return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double triangle_area(Point a,Point b,Point c) {
    return abs(xmul(a,b,c));
}
int main()
{
    int n; LL S;
    while(scanf("%d %I64d", &n,&S) != EOF)
    {
        for(int i=1; i<=n; i++)
            scanf("%I64d %I64d", &p[i].x,&p[i].y);
        bool flag = 1;
        int a=1, b=2, c=3;
        double ans = triangle_area(p[a],p[b],p[c]);
        while(flag) {
            flag = 0;
            for(int i=1; i<=n; i++) {
                double tmp;
                tmp = triangle_area(p[a],p[b],p[i]);
                if(tmp > ans) {
                    ans = tmp; c = i; flag = 1;
                }
                tmp = triangle_area(p[a],p[i],p[c]);
                if(tmp > ans) {
                    ans = tmp; b = i; flag = 1;
                }
                tmp = triangle_area(p[i],p[b],p[c]);
                if(tmp > ans) {
                    ans = tmp; a = i; flag = 1;
                }
            }
        }
        cout << p[a].x+p[b].x-p[c].x << ' ' << p[b].y+p[a].y-p[c].y << endl;
        cout << p[a].x+p[c].x-p[b].x << ' ' << p[c].y+p[a].y-p[b].y << endl;
        cout << p[c].x+p[b].x-p[a].x << ' ' << p[b].y+p[c].y-p[a].y << endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N=5005;
struct point
{
    int x,y;
    point(){}
    point(int _x,int _y):x(_x),y(_y){}
    inline friend point operator - (const point &a,const point &b)
    {return point(a.x-b.x,a.y-b.y);}
    inline friend point operator + (const point &a,const point &b)
    {return point(a.x+b.x,a.y+b.y);}
    inline friend ll operator * (const point &a,const point &b)
    {return 1ll*a.x*b.y-1ll*a.y*b.x;}
    inline ll dis(){return 1ll*x*x+1ll*y*y;}
}p[N],A,B,C;
int n,top;
ll S;

inline bool cmp(const point &a,const point &b)
{
    ll res=(a-p[1])*(b-p[1]);
    if(res)return res>0;
    return (a-p[1]).dis()<(b-p[1]).dis();
}

inline ll area(int i,int j,int k)
{
    return abs((p[j]-p[i])*(p[k]-p[i]));
}

void graham()
{
    for(int i=2;i<=n;i++)
        if((p[i].x<p[1].x)||(p[i].x==p[1].x&&p[i].y<p[1].y))swap(p[1],p[i]);
    sort(p+2,p+n+1,cmp),top=1;
    for(int i=2;i<=n;i++)
    {
        while(top>1&&(p[top-1]-p[i])*(p[top]-p[i])<0)top--;
        p[++top]=p[i];
    }n=top;
}

int main()
{
    //freopen("lx.in","r",stdin);
    scanf("%d%lld",&n,&S);
    for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y);
    graham();
    S=0;point a,b,c;
    for(int i=1;i<=n-2;i++)
        for(int j=i+1,k=j+1;j<=n-1;j++)
        {
            while(k<=n&&area(i,j,k+1)>=area(i,j,k))k++;
            if(area(i,j,k)>S)S=area(i,j,k),a=p[i],b=p[j],c=p[k];
        }
    A=a+(b-c),B=b+(c-a),C=c+(a-b);
    printf("%d %d\n%d %d\n%d %d\n",A.x,A.y,B.x,B.y,C.x,C.y);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define double LL
#define eps 1e-8
#define maxn 5100
#define mod 1000000007
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
struct Point{
    double x,y;
    Point(){}
    Point(double tx,double ty) {x=tx;y=ty;}
}p[maxn];
double xmul(Point p0,Point p1,Point p2){
	return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double triangle_area(Point a,Point b,Point c) {
    return abs(xmul(a,b,c));
}
int main()
{
    int n; LL S;
    while(scanf("%d %I64d", &n,&S) != EOF)
    {
        for(int i=1; i<=n; i++)
            scanf("%I64d %I64d", &p[i].x,&p[i].y);
        bool flag = 1;
        int a=1, b=2, c=3;
        double ans = triangle_area(p[a],p[b],p[c]);
        while(flag) {
            flag = 0;
            for(int i=4; i<=n; i++) {
                double tmp;
                tmp = triangle_area(p[a],p[b],p[i]);
                if(tmp > ans) {
                    ans = tmp; c = i; flag = 1;
                }
                tmp = triangle_area(p[a],p[i],p[c]);
                if(tmp > ans) {
                    ans = tmp; b = i; flag = 1;
                }
                tmp = triangle_area(p[i],p[b],p[c]);
                if(tmp > ans) {
                    ans = tmp; a = i; flag = 1;
                }
            }
        }
        cout << p[a].x+p[b].x-p[c].x << ' ' << p[b].y+p[a].y-p[c].y << endl;
        cout << p[a].x+p[c].x-p[b].x << ' ' << p[c].y+p[a].y-p[b].y << endl;
        cout << p[c].x+p[b].x-p[a].x << ' ' << p[b].y+p[c].y-p[a].y << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for (int i = (a); i < (b); i++)
#define N 5678
typedef long long ll;

ll n, s, x[N], y[N];
ll ar(int a, int b, int c) {
	return abs((x[b]-x[a])*(y[c]-y[a]) - (y[b]-y[a])*(x[c]-x[a]));
}
int main() {
	scanf("%lld %lld", &n, &s);
	fo(i,0,n) scanf("%lld %lld", x+i, y+i);
	int a = 0, b = 1, c = 2;
	while (1) {
		char g = 1;
		fo(i,0,n) {
			if (ar(i,b,c) > ar(a,b,c)) a = i, g = 0;
			if (ar(a,i,c) > ar(a,b,c)) b = i, g = 0;
			if (ar(a,b,i) > ar(a,b,c)) c = i, g = 0;
		}
		if (g) break;
	}
	printf("%lld %lld\n%lld %lld\n%lld %lld\n",
		x[a] + x[b] - x[c], y[a] + y[b] - y[c],
		x[b] + x[c] - x[a], y[b] + y[c] - y[a],
		x[c] + x[a] - x[b], y[c] + y[a] - y[b]);

	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5002;
pair<int,int> pts[N];
vector<int> hull,hull1;
bool comp(int x,int y,int z){
	int x1=pts[y].first-pts[x].first,x2=pts[z].first-pts[x].first,y1=pts[y].second-pts[x].second,y2=pts[z].second-pts[x].second;
	return x2*y1<=x1*y2;
}
long long area(int x,int y,int z){
return abs(pts[x].first*(pts[y].second-pts[z].second)+pts[y].first*(pts[z].second-pts[x].second)+pts[z].first*(pts[x].second-pts[y].second));
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n,i,j,k,l,x,y,z;
	long long s,max1=0;
	cin>>n>>s;
	s*=2;
	for(i=1;i<=n;i++){
		cin>>pts[i].first>>pts[i].second;
	}
	sort(pts+1,pts+1+n);
	hull.push_back(1);
	for(i=2;i<=n;i++){
		if(hull.size()>=2){
			while(hull.size()>=2&&comp(hull[hull.size()-2],hull[hull.size()-1],i)){
				hull.pop_back();
			}
		}
		hull.push_back(i);
	}
	//cout<<hull.size()<<endl;
	hull1.push_back(n);
	for(i=n-1;i>=1;i--){
		if(hull1.size()>=2){
			while(hull1.size()>=2&&comp(hull1[hull1.size()-2],hull1[hull1.size()-1],i)){
				hull1.pop_back();
			}
		}
		hull1.push_back(i);
	}
	for(i=hull1.size()-2;i>0;i--){
		hull.push_back(hull1[i]);
	}
	for(i=0;i<hull.size()-2;i++){
		k=i+2;
		for(j=i+1;j<hull.size()-1;j++){
			while(k+1<hull.size()&&area(hull[i],hull[j],hull[k+1])>area(hull[i],hull[j],hull[k])){
				k++;
			}
			if(max1<area(hull[i],hull[j],hull[k])){
				max1=area(hull[i],hull[j],hull[k]);
				x=hull[i];
				y=hull[j];
				z=hull[k];
			}
		}
	}
//	cout<<hull.size()<<endl;
//	for(i=0;i<hull.size();i++){
//		cout<<pts[hull[i]].first<<' '<<pts[hull[i]].second<<endl;
//	}
//	cout<<x<<' '<<y<<' '<<z<<endl;
	assert(max1<=s);
	cout<<pts[x].first-pts[y].first+pts[z].first<<' '<<pts[x].second-pts[y].second+pts[z].second<<'\n';
	cout<<pts[x].first+pts[y].first-pts[z].first<<' '<<pts[x].second+pts[y].second-pts[z].second<<'\n';
	cout<<pts[y].first+pts[z].first-pts[x].first<<' '<<pts[y].second+pts[z].second-pts[x].second;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5002;
pair<int,int> pts[N];
vector<int> hull,hull1;
bool comp(int x,int y,int z){
	int x1=pts[y].first-pts[x].first,x2=pts[z].first-pts[x].first,y1=pts[y].second-pts[x].second,y2=pts[z].second-pts[x].second;
	return x2*y1<=x1*y2;
}
long long area(int x,int y,int z){
return abs(pts[x].first*(pts[y].second-pts[z].second)+pts[y].first*(pts[z].second-pts[x].second)+pts[z].first*(pts[x].second-pts[y].second));
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n,i,j,k,l,x,y,z;
	long long s,max1=0;
	cin>>n>>s;
	s*=2;
	for(i=1;i<=n;i++){
		cin>>pts[i].first>>pts[i].second;
	}
	sort(pts+1,pts+1+n);
	hull.push_back(1);
	for(i=2;i<=n;i++){
		if(hull.size()>=2){
			while(hull.size()>=2&&comp(hull[hull.size()-2],hull[hull.size()-1],i)){
				hull.pop_back();
			}
		}
		hull.push_back(i);
	}
	hull1.push_back(n);
	for(i=2;i<=n;i++){
		if(hull1.size()>=2){
			while(hull1.size()>=2&&comp(hull1[hull1.size()-2],hull1[hull1.size()-1],i)){
				hull1.pop_back();
			}
		}
		hull1.push_back(i);
	}
	for(i=hull1.size()-2;i>0;i--){
		hull.push_back(hull1[i]);
	}
	for(i=0;i<hull.size()-2;i++){
		k=i+2;
		for(j=i+1;j<hull.size()-1;j++){
			while(k+1<hull.size()&&area(hull[i],hull[j],hull[k+1])>area(hull[i],hull[j],hull[k])){
				k++;
			}
			if(max1<area(hull[i],hull[j],hull[k])){
				max1=area(hull[i],hull[j],hull[k]);
				x=hull[i];
				y=hull[j];
				z=hull[k];
			}
		}
	}
	assert(max1<=s);
	cout<<pts[x].first-(pts[y].first-pts[z].first)<<' '<<pts[x].second-(pts[y].second-pts[z].second)<<'\n';
	cout<<pts[x].first+(pts[y].first-pts[z].first)<<' '<<pts[x].second+(pts[y].second-pts[z].second)<<'\n';
	cout<<pts[y].first+pts[z].first-pts[x].first<<' '<<pts[y].second+pts[z].second-pts[x].second;
}


/***************************************
      zzblack                         **
      2016-02-27                      **
      Orz                             **
****************************************/
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
typedef long long ll ;
typedef pair<int,int> pii ;
const int maxn = 1e5 + 50 ;
const double eps = 1e-10;
const int max_index = 26;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;

inline int read(){
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    int x = 0;
    while (isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

int ch[maxn * 20][max_index];
int f[maxn * 20], last[maxn * 20], val[maxn * 20];
map<string, int> mp;
int T, n, Hash[10005];

int idx(char c) { return c - 'a'; }

class AC_Automation {
private:
    int sz;
public :
    AC_Automation() { sz = 1; CLR(ch[0]); }
    ~AC_Automation() {}

    void Insert(char *s, int v) {
        int u = 0;
        for (int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            if (!ch[u][c]) {
                CLR(ch[sz]);
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
        mp[string(s)] = v;
    }

    void get_fail(){
        f[0] = 0;
        queue<int> q;
        for (int i = 0; i < max_index; i++) {
            int u = ch[0][i];
            if (!u) continue ;
            q.push(u);
            f[u] = 0;
            last[u] = 0;
        }
        while (q.size()) {
            int r = q.front();q.pop();
            for (int i = 0; i < max_index; i++) {
                int u = ch[r][i];
                if (!u) {ch[r][i] = ch[f[r]][i];  continue;}
                q.push(u);
                int v = f[r];
                while (v && !ch[v][i]) v = f[v];
                f[u] = ch[v][i];
                last[u] = val[f[u]] ? f[u] : last[f[u]];
            }
        }
    }

    int Find(char *t){
        int j = 0, res = 0;
        for (int i = 0; t[i]; i++) {
            int c = idx(t[i]);
//            while (j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            if (val[j]) print(j);
            else if (last[j]) print(last[j]);
        }
        return res;
    }

    void print(int j) {
        if (!j) return ;
        Hash[val[j]] = 1;
        print(last[j]);
    }

};

char s[maxn], p[maxn];
string test[maxn];
int dp[maxn], ans[maxn];

bool flag;

bool dfs(int cur, int id) {
    if (!id || flag) return 1;
//    if (dp[id]) return 0;
//    cout << cur << "\n";
    int ID = idx(s[id]);

    int nxt = ch[cur][ID];
    if (nxt == 0 && id > 1) return 0;

//    cout << nxt << "**\n";

    if (val[nxt]) {
        ans[id] = val[nxt];
//        cout << "test" << test[val[nxt]] << "\n";
        if (dfs(0, id - 1)) return flag = 1;
        ans[id] = 0;
    }

    if (dfs(nxt, id - 1)) return flag = 1;
    return 0;

}

int main () {
#ifdef LOCAL
	freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
//      freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);
#endif
    int n = read();
    scanf("%s", s + 1);
    AC_Automation Ac;
    int m = read();
    flag = 0;
    for (int i = 1; i <= m; i++) {
        scanf("%s", p);
        test[i] = string(p);
        int len = test[i].size();
        for (int j = 0; p[j]; j++) p[j] = tolower(p[j]);
//        printf("%s\n", p);
        Ac.Insert(p, i);
    }
    Ac.get_fail();

    dfs(0, n);

    for (int i = 1; i <= n; i++) if (ans[i]) cout << test[ans[i]] << " " ;

	return 0;
}


/***************************************
      zzblack                         **
      2016-02-27                      **
      Orz                             **
****************************************/
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
typedef long long ll ;
typedef pair<int,int> pii ;
const int maxn = 1e5 + 50 ;
const double eps = 1e-10;
const int max_index = 26;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;

inline int read(){
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    int x = 0;
    while (isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

int ch[maxn * 20][max_index];
int f[maxn * 20], last[maxn * 20], val[maxn * 20];
map<string, int> mp;
int T, n, Hash[10005];

int idx(char c) { return c - 'a'; }

class AC_Automation {
private:
    int sz;
public :
    AC_Automation() { sz = 1; CLR(ch[0]); }
    ~AC_Automation() {}

    void Insert(char *s, int v) {
        int u = 0;
        for (int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            if (!ch[u][c]) {
                CLR(ch[sz]);
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
        mp[string(s)] = v;
    }

    void get_fail(){
        f[0] = 0;
        queue<int> q;
        for (int i = 0; i < max_index; i++) {
            int u = ch[0][i];
            if (!u) continue ;
            q.push(u);
            f[u] = 0;
            last[u] = 0;
        }
        while (q.size()) {
            int r = q.front();q.pop();
            for (int i = 0; i < max_index; i++) {
                int u = ch[r][i];
                if (!u) { continue;}
                q.push(u);
                int v = f[r];
                while (v && !ch[v][i]) v = f[v];
                f[u] = ch[v][i];
                last[u] = val[f[u]] ? f[u] : last[f[u]];
            }
        }
    }

    int Find(char *t){
        int j = 0, res = 0;
        for (int i = 0; t[i]; i++) {
            int c = idx(t[i]);
//            while (j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            if (val[j]) print(j);
            else if (last[j]) print(last[j]);
        }
        return res;
    }

    void print(int j) {
        if (!j) return ;
        Hash[val[j]] = 1;
        print(last[j]);
    }

};

char s[maxn], p[maxn];
string test[maxn];
int dp[maxn], ans[maxn];

bool flag;

bool dfs(int cur, int id) {
    if (!id && cur) return 0;
    if (!id || flag) return 1;
//    if (dp[id]) return 0;
//    cout << cur << "\n";
    int ID = idx(s[id]);

    int nxt = ch[cur][ID];
    if (nxt == 0 && id > 1) return 0;

//    cout << nxt << "**\n";

    if (val[nxt]) {
        ans[id] = val[nxt];
//        cout << "test" << test[val[nxt]] << "\n";
        if (dfs(0, id - 1)) return flag = 1;
        ans[id] = 0;
    }

    if (dfs(nxt, id - 1)) return flag = 1;
    return 0;

}

int main () {
#ifdef LOCAL
	freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
//      freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);
#endif
    int n = read();
    scanf("%s", s + 1);
    AC_Automation Ac;
    int m = read();
    flag = 0;
    for (int i = 1; i <= m; i++) {
        scanf("%s", p);
//        if (n == 10000) printf("%s\n", p);
        test[i] = string(p);
        int len = test[i].size();
        for (int j = 0; p[j]; j++) p[j] = tolower(p[j]);
//        printf("%s\n", p);
        Ac.Insert(p, i);
    }
//    Ac.get_fail();

    dfs(0, n);

    for (int i = 1; i <= n; i++) if (ans[i]) cout << test[ans[i]] << " " ;

	return 0;
}


/***************************************
      zzblack                         **
      2016-02-27                      **
      Orz                             **
****************************************/
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
typedef long long ll ;
typedef pair<int,int> pii ;
const int maxn = 1e5 + 50 ;
const double eps = 1e-10;
const int max_index = 26;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;

inline int read(){
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    int x = 0;
    while (isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

int ch[maxn * 20][max_index];
int f[maxn * 20], last[maxn * 20], val[maxn * 20];
map<string, int> mp;
int T, n, Hash[10005];

int idx(char c) { return c - 'a'; }

class AC_Automation {
private:
    int sz;
public :
    AC_Automation() { sz = 1; CLR(ch[0]); }
    ~AC_Automation() {}

    void Insert(char *s, int v) {
        int u = 0;
        for (int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            if (!ch[u][c]) {
                CLR(ch[sz]);
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
        mp[string(s)] = v;
    }

    void get_fail(){
        f[0] = 0;
        queue<int> q;
        for (int i = 0; i < max_index; i++) {
            int u = ch[0][i];
            if (!u) continue ;
            q.push(u);
            f[u] = 0;
            last[u] = 0;
        }
        while (q.size()) {
            int r = q.front();q.pop();
            for (int i = 0; i < max_index; i++) {
                int u = ch[r][i];
                if (!u) { continue;}
                q.push(u);
                int v = f[r];
                while (v && !ch[v][i]) v = f[v];
                f[u] = ch[v][i];
                last[u] = val[f[u]] ? f[u] : last[f[u]];
            }
        }
    }

    int Find(char *t){
        int j = 0, res = 0;
        for (int i = 0; t[i]; i++) {
            int c = idx(t[i]);
//            while (j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            if (val[j]) print(j);
            else if (last[j]) print(last[j]);
        }
        return res;
    }

    void print(int j) {
        if (!j) return ;
        Hash[val[j]] = 1;
        print(last[j]);
    }

};

char s[maxn], p[maxn];
string test[maxn];
int dp[maxn], ans[maxn];

bool flag;

bool dfs(int cur, int id) {
    if (!id || flag) return 1;
//    if (dp[id]) return 0;
//    cout << cur << "\n";
    int ID = idx(s[id]);

    int nxt = ch[cur][ID];
    if (nxt == 0 && id > 1) return 0;

//    cout << nxt << "**\n";

    if (val[nxt]) {
        ans[id] = val[nxt];
//        cout << "test" << test[val[nxt]] << "\n";
        if (dfs(0, id - 1)) return flag = 1;
        ans[id] = 0;
    }

    if (dfs(nxt, id - 1)) return flag = 1;
    return 0;

}

int main () {
#ifdef LOCAL
	freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
//      freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);
#endif
    int n = read();
    scanf("%s", s + 1);
    AC_Automation Ac;
    int m = read();
    flag = 0;
    for (int i = 1; i <= m; i++) {
        scanf("%s", p);
        test[i] = string(p);
        int len = test[i].size();
        for (int j = 0; p[j]; j++) p[j] = tolower(p[j]);
//        printf("%s\n", p);
        Ac.Insert(p, i);
    }
    Ac.get_fail();

    dfs(0, n);

    for (int i = 1; i <= n; i++) if (ans[i]) cout << test[ans[i]] << " " ;

	return 0;
}


/***************************************
      zzblack                         **
      2016-02-27                      **
      Orz                             **
****************************************/
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
typedef long long ll ;
typedef pair<int,int> pii ;
const int maxn = 1e5 + 50 ;
const double eps = 1e-10;
const int max_index = 26;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;

inline int read(){
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    int x = 0;
    while (isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

int ch[maxn * 20][max_index];
int f[maxn * 20], last[maxn * 20], val[maxn * 20];
map<string, int> mp;
int T, n, Hash[10005];

int idx(char c) { return c - 'a'; }

class AC_Automation {
private:
    int sz;
public :
    AC_Automation() { sz = 1; CLR(ch[0]); }
    ~AC_Automation() {}

    void Insert(char *s, int v) {
        int u = 0;
        for (int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            if (!ch[u][c]) {
                CLR(ch[sz]);
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
        mp[string(s)] = v;
    }

    void get_fail(){
        f[0] = 0;
        queue<int> q;
        for (int i = 0; i < max_index; i++) {
            int u = ch[0][i];
            if (!u) continue ;
            q.push(u);
            f[u] = 0;
            last[u] = 0;
        }
        while (q.size()) {
            int r = q.front();q.pop();
            for (int i = 0; i < max_index; i++) {
                int u = ch[r][i];
                if (!u) { continue;}
                q.push(u);
                int v = f[r];
                while (v && !ch[v][i]) v = f[v];
                f[u] = ch[v][i];
                last[u] = val[f[u]] ? f[u] : last[f[u]];
            }
        }
    }

    int Find(char *t){
        int j = 0, res = 0;
        for (int i = 0; t[i]; i++) {
            int c = idx(t[i]);
//            while (j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            if (val[j]) print(j);
            else if (last[j]) print(last[j]);
        }
        return res;
    }

    void print(int j) {
        if (!j) return ;
        Hash[val[j]] = 1;
        print(last[j]);
    }

};

char s[maxn], p[maxn];
string test[maxn];
int dp[maxn], ans[maxn];

bool flag;

bool dfs(int cur, int id) {
    if (!id || flag) return 1;
//    if (dp[id]) return 0;
//    cout << cur << "\n";
    int ID = idx(s[id]);

    int nxt = ch[cur][ID];
    if (nxt == 0 && id > 1) return 0;

//    cout << nxt << "**\n";

    if (val[nxt]) {
        ans[id] = val[nxt];
//        cout << "test" << test[val[nxt]] << "\n";
        if (dfs(0, id - 1)) return flag = 1;
        ans[id] = 0;
    }

    if (dfs(nxt, id - 1)) return flag = 1;
    return 0;

}

int main () {
#ifdef LOCAL
	freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
//      freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);
#endif
    int n = read();
    scanf("%s", s + 1);
    AC_Automation Ac;
    int m = read();
    flag = 0;
    for (int i = 1; i <= m; i++) {
        scanf("%s", p);
        test[i] = string(p);
        int len = test[i].size();
        for (int j = 0; p[j]; j++) p[j] = tolower(p[j]);
//        printf("%s\n", p);
        Ac.Insert(p, i);
    }
//    Ac.get_fail();

    dfs(0, n);

    for (int i = 1; i <= n; i++) if (ans[i]) cout << test[ans[i]] << " " ;

	return 0;
}


/***************************************
      zzblack                         **
      2016-02-27                      **
      Orz                             **
****************************************/
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
typedef long long ll ;
typedef pair<int,int> pii ;
const int maxn = 1e5 + 50 ;
const double eps = 1e-10;
const int max_index = 26;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;

inline int read(){
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    int x = 0;
    while (isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

int ch[maxn * 20][max_index];
int f[maxn * 20], last[maxn * 20], val[maxn * 20];
map<string, int> mp;
int T, n, Hash[10005];

int idx(char c) { return c - 'a'; }

class AC_Automation {
private:
    int sz;
public :
    AC_Automation() { sz = 1; CLR(ch[0]); }
    ~AC_Automation() {}

    void Insert(char *s, int v) {
        int u = 0;
        for (int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            if (!ch[u][c]) {
                CLR(ch[sz]);
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
        mp[string(s)] = v;
    }

    void get_fail(){
        f[0] = 0;
        queue<int> q;
        for (int i = 0; i < max_index; i++) {
            int u = ch[0][i];
            if (!u) continue ;
            q.push(u);
            f[u] = 0;
            last[u] = 0;
        }
        while (q.size()) {
            int r = q.front();q.pop();
            for (int i = 0; i < max_index; i++) {
                int u = ch[r][i];
                if (!u) { continue;}
                q.push(u);
                int v = f[r];
                while (v && !ch[v][i]) v = f[v];
                f[u] = ch[v][i];
                last[u] = val[f[u]] ? f[u] : last[f[u]];
            }
        }
    }

    int Find(char *t){
        int j = 0, res = 0;
        for (int i = 0; t[i]; i++) {
            int c = idx(t[i]);
//            while (j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            if (val[j]) print(j);
            else if (last[j]) print(last[j]);
        }
        return res;
    }

    void print(int j) {
        if (!j) return ;
        Hash[val[j]] = 1;
        print(last[j]);
    }

};

char s[maxn], p[maxn];
string test[maxn];
int dp[maxn], ans[maxn];

bool flag;

bool dfs(int cur, int id) {
    if (!id || flag) return 1;
//    if (dp[id]) return 0;
//    cout << cur << "\n";
    int ID = idx(s[id]);

    int nxt = ch[cur][ID];
    if (nxt == 0 && id > 1) return 0;

//    cout << nxt << "**\n";

    if (val[nxt]) {
        ans[id] = val[nxt];
//        cout << "test" << test[val[nxt]] << "\n";
        if (dfs(0, id - 1)) return flag = 1;
        ans[id] = 0;
    }

    if (dfs(nxt, id - 1)) return flag = 1;
    return 0;

}

int main () {
#ifdef LOCAL
	freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
//      freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);
#endif
    int n = read();
    scanf("%s", s + 1);
    AC_Automation Ac;
    int m = read();
    if (n == 10000) cout << m << "\n";
    flag = 0;
    for (int i = 1; i <= m; i++) {
        scanf("%s", p);
        test[i] = string(p);
        int len = test[i].size();
        for (int j = 0; p[j]; j++) p[j] = tolower(p[j]);
//        printf("%s\n", p);
        Ac.Insert(p, i);
    }
//    Ac.get_fail();

    dfs(0, n);

    for (int i = 1; i <= n; i++) if (ans[i]) cout << test[ans[i]] << " " ;

	return 0;
}


/***************************************
      zzblack                         **
      2016-02-27                      **
      Orz                             **
****************************************/
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
typedef long long ll ;
typedef pair<int,int> pii ;
const int maxn = 1e5 + 50 ;
const double eps = 1e-10;
const int max_index = 26;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;

inline int read(){
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    int x = 0;
    while (isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

int ch[maxn * 20][max_index];
int f[maxn * 20], last[maxn * 20], val[maxn * 20];
int T, n, Hash[10005];

char s[maxn];
string p[maxn];
int dp[maxn];

bool flag;

int idx(char c) { if (isupper(c)) return c - 'A'; return c - 'a'; }

class AC_Automation {
private:
    int sz;
public :
    AC_Automation() { sz = 1; CLR(ch[0]); }
    ~AC_Automation() {}

    void Insert(string &s, int v) {
        int u = 0;
        for (int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            if (!ch[u][c]) {
                CLR(ch[sz]);
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
    }

    void Find(int pos){
        int u = 0;
        for (; ~pos; pos--) {
            int c = idx(s[pos]);
            u = ch[u][c];
            if (!u) return ;
            if (val[u] && !dp[pos]) dp[pos] = val[u];
        }
    }

    void print(int j) {
        if (!j) return ;
        Hash[val[j]] = 1;
        print(last[j]);
    }

};

int main () {
#ifdef LOCAL
    freopen("C:\\Users\\zzblack\\Desktop\\case.in","r",stdin);
//      freopen("C:\\Users\\zzblack\\Desktop\\case.out","w",stdout);
#endif
    int n = read();
    scanf("%s", s);
    AC_Automation Ac;
    int m = read();
    for (int i = 1; i <= m; i++) {
        cin >> p[i];
        Ac.Insert(p[i], i);
    }

    dp[n] = 1;
    for(int i = n-1; ~i; i--) {
        if (dp[i+1]) Ac.Find(i);
    }

    for (int i = 0; i < n; ) {
        cout << p[dp[i]] << " ";
        i += p[dp[i]].size();
    }
	return 0;
}


/***************************************
      zzblack                         **
      2016-02-27                      **
      Orz                             **
****************************************/
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
typedef long long ll ;
typedef pair<int,int> pii ;
const int maxn = 1e5 + 50 ;
const double eps = 1e-10;
const int max_index = 26;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;

inline int read(){
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    int x = 0;
    while (isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

int ch[maxn * 20][max_index];
int f[maxn * 20], last[maxn * 20], val[maxn * 20];
map<string, int> mp;
int T, n, Hash[10005];

int idx(char c) { return c - 'a'; }

class AC_Automation {
private:
    int sz;
public :
    AC_Automation() { sz = 1; CLR(ch[0]); }
    ~AC_Automation() {}

    void Insert(char *s, int v) {
        int u = 0;
        for (int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            if (!ch[u][c]) {
                CLR(ch[sz]);
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
        mp[string(s)] = v;
    }

    void get_fail(){
        f[0] = 0;
        queue<int> q;
        for (int i = 0; i < max_index; i++) {
            int u = ch[0][i];
            if (!u) continue ;
            q.push(u);
            f[u] = 0;
            last[u] = 0;
        }
        while (q.size()) {
            int r = q.front();q.pop();
            for (int i = 0; i < max_index; i++) {
                int u = ch[r][i];
                if (!u) { continue;}
                q.push(u);
                int v = f[r];
                while (v && !ch[v][i]) v = f[v];
                f[u] = ch[v][i];
                last[u] = val[f[u]] ? f[u] : last[f[u]];
            }
        }
    }

    int Find(char *t){
        int j = 0, res = 0;
        for (int i = 0; t[i]; i++) {
            int c = idx(t[i]);
//            while (j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            if (val[j]) print(j);
            else if (last[j]) print(last[j]);
        }
        return res;
    }

    void print(int j) {
        if (!j) return ;
        Hash[val[j]] = 1;
        print(last[j]);
    }

};

char s[maxn], p[maxn];
string test[maxn];
int dp[maxn], ans[maxn];

bool flag;

bool dfs(int cur, int id) {
    if (!id || flag) return 1;
//    if (dp[id]) return 0;
//    cout << cur << "\n";
    int ID = idx(s[id]);

    int nxt = ch[cur][ID];
    if (nxt == 0 && id > 1) return 0;

//    cout << nxt << "**\n";

    if (val[nxt]) {
        ans[id] = val[nxt];
//        cout << "test" << test[val[nxt]] << "\n";
        if (dfs(0, id - 1)) return flag = 1;
        ans[id] = 0;
    }

    if (dfs(nxt, id - 1)) return flag = 1;
    return 0;

}

int main () {
#ifdef LOCAL
	freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
//      freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);
#endif
    int n = read();
    scanf("%s", s + 1);
    AC_Automation Ac;
    int m = read();
    flag = 0;
    for (int i = 1; i <= m; i++) {
        scanf("%s", p);
        printf("%s\n", p);
        test[i] = string(p);
        int len = test[i].size();
        for (int j = 0; p[j]; j++) p[j] = tolower(p[j]);
//        printf("%s\n", p);
        Ac.Insert(p, i);
    }
//    Ac.get_fail();

    dfs(0, n);

    for (int i = 1; i <= n; i++) if (ans[i]) cout << test[ans[i]] << " " ;

	return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1000000+5;
char s[10005];
char str[100005][1005];
int len[100005];
int trie[N][26],mk[N];
int ans[10005],tot,cnt,m,n;
void add(int x)
{
    int now=0;
    for(int i=len[x]-1; i>=0; --i)
    {
        char tmp=str[x][i];
        if(tmp<'a'||tmp>'z')
            tmp+='a'-'A';
        int p=tmp-'a';
        if(!trie[now][p])
            trie[now][p]=++cnt;
        now=trie[now][p];
    }
    mk[now]=x;
}
void solve(int pos)
{
    if(pos==n)
    {
        for(int i=1; i<tot; ++i)
            printf("%s ",str[ans[i]]);
        printf("%s\n",str[ans[tot]]);
       return;
    }
    int now=0;
    for(int i=pos+1; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=trie[now][p];
        if(!now)break;
        if(mk[now])
        {
            ans[++tot]=mk[now];
            solve(pos+len[mk[now]]);
            --tot;
        }
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
//    for(int i=1; i<=n/2; ++i)
//        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    for(int i=1; i<=m; ++i)
    {
        scanf("%s",str[i]);
        len[i]=strlen(str[i]);
        add(i);
    }
    solve(0);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e4+5;
char s[N];
int n,m,cnt;
char str[100005][1005];
int len[100005];
struct Node
{
    int mark;
    int next[26];
} o[N*100];
int newnode()
{
    ++cnt;
    memset(o[cnt].next,-1,sizeof(o[cnt].next));
    o[cnt].mark=0;
    return cnt;
}
void add(int x)
{
    int now=0;
    for(int i=0; i<len[x]; ++i)
    {
        char tmp=str[x][i];
        if(tmp<'a'||tmp>'z')
            tmp+='a'-'A';
        int p=tmp-'a';
        if(o[now].next[p]==-1)
            o[now].next[p]=newnode();
        now=o[now].next[p];
    }
    o[now].mark=x;
}
int ans[N],tot;

void solve(int pos)
{
    if(pos==n)
    {
        for(int i=tot; i>1; --i)
            printf("%s ",str[ans[i]]);
        printf("%s\n",str[ans[1]]);
        return;
    }
    int now=0;
    for(int i=pos+1; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=o[now].next[p];
        if(now==-1)break;
        if(o[now].mark)
        {
            ans[++tot]=o[now].mark;
            solve(pos+len[o[now].mark]);
            --tot;
        }
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    cnt=-1,newnode();
    for(int i=1; i<=m; ++i)
    {
        scanf("%s",str[i]);
        len[i]=strlen(str[i]);
        add(i);
    }
    solve(0);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e4+5;
char s[N];
int n,m,cnt;
vector<string>str;
string tmp;
struct Node
{
    int mark;
    int next[26];
} o[N*100];
int newnode()
{
    ++cnt;
    memset(o[cnt].next,-1,sizeof(o[cnt].next));
    o[cnt].mark=-1;
    return cnt;
}
void add(int x)
{
    int now=0;
    for(int i=0; i<tmp.size(); ++i)
    {
        int p=tmp[i]-'a';
        if(o[now].next[p]==-1)
            o[now].next[p]=newnode();
        now=o[now].next[p];
    }
    o[now].mark=x;
}

int ans[N],tot;
void solve(int pos)
{
    vector<int>t;
    t.clear();
    int now=0;
    for(int i=pos; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=o[now].next[p];
        if(now==-1)break;
        if(o[now].mark!=-1)
            t.push_back(i),t.push_back(o[now].mark);
    }
    if(t.size()&&t[t.size()-2]==n)
    {
        int id=t[t.size()-1];
        cout<<str[id];
        for(int i=tot; i>=1; --i)
        {
            printf(" ");
            cout<<str[ans[i]];
        }
        printf("\n");
        return;
    }
    for(int i=0; i<t.size(); i+=2)
    {
        ans[++tot]=t[i+1];
        solve(t[i]+1);
        --tot;
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    cnt=-1,newnode();
    while(m--)
    {
        cin>>tmp;
        str.push_back(tmp);
        for(int i=0; i<tmp.size(); ++i)
        {
            if(tmp[i]<'a'||tmp[i]>'z')
            {
                int ad='a'-'A';
                tmp[i]+=ad;
            }
        }
        add(str.size()-1);
    }
    solve(1);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e4+5;
char s[N];
int n,m,cnt;
char str[100005][1005];
int len[100005];
struct Node
{
    int mark;
    int next[26];
} o[N*100];
int newnode()
{
    ++cnt;
    memset(o[cnt].next,-1,sizeof(o[cnt].next));
    o[cnt].mark=0;
    return cnt;
}
void add(int x)
{
    int now=0;
    for(int i=0; i<len[x]; ++i)
    {
        char tmp=str[x][i];
        if(tmp<'a'||tmp>'z')
            tmp+='a'-'A';
        int p=tmp-'a';
        if(o[now].next[p]==-1)
            o[now].next[p]=newnode();
        now=o[now].next[p];
    }
    o[now].mark=x;
}
int ans[N],tot;
vector<int>dp[N];
void solve(int pos)
{
    int l=dp[pos].size();
    if(l&&dp[pos][l-2]==n)
    {
        int id=dp[pos][l-1];
        printf("%s",str[id]);
        for(int i=tot; i>=1; --i)
        {
            printf(" ");
            printf("%s",str[ans[i]]);
        }
        printf("\n");
        return;
    }
    for(int i=0; i<l; i+=2)
    {
        ans[++tot]=dp[pos][i+1];
        solve(dp[pos][i]+1);
        --tot;
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    cnt=-1,newnode();
    for(int i=1; i<=m; ++i)
    {
        scanf("%s",str[i]);
        len[i]=strlen(str[i]);
        add(i);
    }
    for(int i=1; i<=n; ++i)
    {
        int now=0;
        for(int j=i; j<=n; ++j)
        {
            int p=s[j]-'a';
            now=o[now].next[p];
            if(now==-1)break;
            if(o[now].mark)
                dp[i].push_back(j),dp[i].push_back(o[now].mark);
        }

    }
    solve(1);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e4+5;
char s[N];
int n,m,cnt;
char str[100005][N/10];
char tmp[N/10];
struct Node
{
    int mark;
    int next[26];
} o[N*100];
int newnode()
{
    ++cnt;
    memset(o[cnt].next,-1,sizeof(o[cnt].next));
    o[cnt].mark=0;
    return cnt;
}
void add(int x)
{
    int now=0,l=strlen(tmp);
    for(int i=0; i<l; ++i)
    {
        int p=tmp[i]-'a';
        if(o[now].next[p]==-1)
            o[now].next[p]=newnode();
        now=o[now].next[p];
    }
    o[now].mark=x;
}
int ans[N],tot;

void solve(int pos)
{
    vector<int>t;
    t.clear();
    int now=0;
    for(int i=pos; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=o[now].next[p];
        if(now==-1)break;
        if(o[now].mark)
            t.push_back(i),t.push_back(o[now].mark);
    }

    if(t.size()&&t[t.size()-2]==n)
    {
        int id=t[t.size()-1];
        printf("%s",str[id]);
        for(int i=tot; i>=1; --i)
        {
            printf(" ");
            printf("%s",str[ans[i]]);
        }
        printf("\n");
        return;
    }
    for(int i=0; i<t.size(); i+=2)
    {
        ans[++tot]=t[i+1];
        solve(t[i]+1);
        --tot;
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    cnt=-1,newnode();
    for(int i=1;i<=m;++i)
    {
        scanf("%s",str[i]);
        int l=strlen(str[i]);
        for(int j=0; j<l; ++j)
        {
            if(str[i][j]<'a'||str[i][j]>'z')
            {
                int ad='a'-'A';
                tmp[j]=str[i][j]+ad;
            }
            else tmp[j]=str[i][j];
        }
        tmp[l]='\0';
        add(i);
    }
    solve(1);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1000000+5;
char s[10005];
char str[100005][1005];
int len[100005];
int trie[N][26],mk[N];
int ans[10005],tot,cnt,m,n;
void add(int x)
{
    int now=0;
    for(int i=0; i<len[x]; ++i)
    {
        char tmp=str[x][i];
        if(tmp<'a'||tmp>'z')
            tmp+='a'-'A';
        int p=tmp-'a';
        if(!trie[now][p])
            trie[now][p]=++cnt;
        now=trie[now][p];
    }
    mk[now]=x;
}
void solve(int pos)
{
    if(pos==n)
    {
        for(int i=tot; i>1; --i)
            printf("%s ",str[ans[i]]);
        printf("%s\n",str[ans[1]]);
       exit(0);
    }
    int now=0;
    for(int i=pos+1; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=trie[now][p];
        if(!now)break;
        if(mk[now])
        {
            ans[++tot]=mk[now];
            solve(pos+len[mk[now]]);
            --tot;
        }
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    for(int i=1; i<=m; ++i)
    {
        scanf("%s",str[i]);
        len[i]=strlen(str[i]);
        add(i);
    }
    solve(0);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e4+5;
char s[N];
int n,m,cnt;
char str[100005][1005];
char tmp[N/10];
struct Node
{
    int mark;
    int next[26];
} o[N*100];
int newnode()
{
    ++cnt;
    memset(o[cnt].next,-1,sizeof(o[cnt].next));
    o[cnt].mark=0;
    return cnt;
}
void add(int x)
{
    int now=0,l=strlen(tmp);
    for(int i=0; i<l; ++i)
    {
        int p=tmp[i]-'a';
        if(o[now].next[p]==-1)
            o[now].next[p]=newnode();
        now=o[now].next[p];
    }
    o[now].mark=x;
}
int ans[N],tot;

void solve(int pos)
{
    vector<int>t;
    t.clear();
    int now=0;
    for(int i=pos; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=o[now].next[p];
        if(now==-1)break;
        if(o[now].mark)
            t.push_back(i),t.push_back(o[now].mark);
    }

    if(t.size()&&t[t.size()-2]==n)
    {
        int id=t[t.size()-1];
        printf("%s",str[id]);
        for(int i=tot; i>=1; --i)
        {
            printf(" ");
            printf("%s",str[ans[i]]);
        }
        printf("\n");
        return;
    }
    for(int i=0; i<t.size(); i+=2)
    {
        ans[++tot]=t[i+1];
        solve(t[i]+1);
        --tot;
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    cnt=-1,newnode();
    for(int i=1;i<=m;++i)
    {
        scanf("%s",str[i]);
        int l=strlen(str[i]);
        for(int j=0; j<l; ++j)
        {
            if(str[i][j]<'a'||str[i][j]>'z')
            {
                int ad='a'-'A';
                tmp[j]=str[i][j]+ad;
            }
            else tmp[j]=str[i][j];
        }
        tmp[l]='\0';
        add(i);
    }
    solve(1);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e6+5;
char s[N];
char str[100005][1005];
int len[100005];
int trie[N][26],mk[N];
int ans[10005],tot,cnt,m,n;
void add(int x)
{
    int now=0;
    for(int i=0; i<len[x]; ++i)
    {
        char tmp=str[x][i];
        if(tmp<'a'||tmp>'z')
            tmp+='a'-'A';
        int p=tmp-'a';
        if(!trie[now][p])
            trie[now][p]=++cnt;
        now=trie[now][p];
    }
    mk[now]=x;
}
void solve(int pos)
{
    if(pos==n)
    {
        for(int i=tot; i>1; --i)
            printf("%s ",str[ans[i]]);
        printf("%s\n",str[ans[1]]);
        exit(0);
    }
    int now=0;
    for(int i=pos+1; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=trie[now][p];
        if(!now)break;
        if(mk[now])
        {
            ans[++tot]=mk[now];
            solve(pos+len[mk[now]]);
            --tot;
        }
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    for(int i=1; i<=m; ++i)
    {
        scanf("%s",str[i]);
        len[i]=strlen(str[i]);
        add(i);
    }
    solve(0);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1000000+5;
char s[10005];
char str[100005][1005];
int len[100005];
int trie[N][26],mk[N];
int ans[10005],tot,cnt,m,n;
void add(int x)
{
    int now=0;
    for(int i=len[x]-1; i>=0; --i)
    {
        char tmp=str[x][i];
        if(tmp<'a'||tmp>'z')
            tmp+='a'-'A';
        int p=tmp-'a';
        if(!trie[now][p])
            trie[now][p]=++cnt;
        now=trie[now][p];
    }
    mk[now]=x;
}
void solve(int pos)
{
    if(pos==n)
    {
        for(int i=1; i<tot; ++i)
            printf("%s ",str[ans[i]]);
        printf("%s\n",str[ans[tot]]);
       exit(0);
    }
    int now=0;
    for(int i=pos+1; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=trie[now][p];
        if(!now)break;
        if(mk[now])
        {
            ans[++tot]=mk[now];
            solve(pos+len[mk[now]]);
            --tot;
        }
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
//    for(int i=1; i<=n/2; ++i)
//        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    for(int i=1; i<=m; ++i)
    {
        scanf("%s",str[i]);
        len[i]=strlen(str[i]);
        add(i);
    }
    solve(0);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e4+5;
char s[N];
int n,m,cnt;
char str[100005][1005];
int len[100005];
struct Node
{
    int mark;
    int next[26];
} o[N*100];
int newnode()
{
    ++cnt;
    memset(o[cnt].next,-1,sizeof(o[cnt].next));
    o[cnt].mark=0;
    return cnt;
}
void add(int x)
{
    int now=0;
    for(int i=0; i<len[x]; ++i)
    {
        char tmp=str[x][i];
        if(tmp<'a'||tmp>'z')
            tmp+='a'-'A';
        int p=tmp-'a';
        if(o[now].next[p]==-1)
            o[now].next[p]=newnode();
        now=o[now].next[p];
    }
    o[now].mark=x;
}
int ans[N],tot;

void solve(int pos)
{
    if(pos==n)
    {
        for(int i=tot; i>1; --i)
            printf("%s ",str[ans[i]]);
        printf("%s\n",str[ans[1]]);
        exit(0);
    }
    int now=0;
    for(int i=pos+1; i<=n; ++i)
    {
        int p=s[i]-'a';
        now=o[now].next[p];
        if(now==-1)break;
        if(o[now].mark)
        {
            ans[++tot]=o[now].mark;
            solve(pos+len[o[now].mark]);
            --tot;
        }
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    cnt=-1,newnode();
    for(int i=1; i<=m; ++i)
    {
        scanf("%s",str[i]);
        len[i]=strlen(str[i]);
        add(i);
    }
    solve(0);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e4+5;
char s[N];
int n,m,cnt;
char str[100005][1005];
char tmp[N/10];
struct Node
{
    int mark;
    int next[26];
} o[N*100];
int newnode()
{
    ++cnt;
    memset(o[cnt].next,-1,sizeof(o[cnt].next));
    o[cnt].mark=0;
    return cnt;
}
void add(int x)
{
    int now=0,l=strlen(tmp);
    for(int i=0; i<l; ++i)
    {
        int p=tmp[i]-'a';
        if(o[now].next[p]==-1)
            o[now].next[p]=newnode();
        now=o[now].next[p];
    }
    o[now].mark=x;
}
int ans[N],tot;
vector<int>dp[N];
void solve(int pos)
{
    int l=dp[pos].size();
    if(l&&dp[pos][l-2]==n)
    {
        int id=dp[pos][l-1];
        printf("%s",str[id]);
        for(int i=tot; i>=1; --i)
        {
            printf(" ");
            printf("%s",str[ans[i]]);
        }
        printf("\n");
        return;
    }
    for(int i=0; i<l; i+=2)
    {
        ans[++tot]=dp[pos][i+1];
        solve(dp[pos][i]+1);
        --tot;
    }
}
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1; i<=n/2; ++i)
        swap(s[i],s[n-i+1]);
    scanf("%d",&m);
    cnt=-1,newnode();
    for(int i=1; i<=m; ++i)
    {
        scanf("%s",str[i]);
        int l=strlen(str[i]);
        for(int j=0; j<l; ++j)
        {
            if(str[i][j]<'a'||str[i][j]>'z')
            {
                int ad='a'-'A';
                tmp[j]=str[i][j]+ad;
            }
            else tmp[j]=str[i][j];
        }
        tmp[l]='\0';
        add(i);
    }
    for(int i=1; i<=n; ++i)
    {
        int now=0;
        for(int j=i; j<=n; ++j)
        {
            int p=s[j]-'a';
            now=o[now].next[p];
            if(now==-1)break;
            if(o[now].mark)
                dp[i].push_back(j),dp[i].push_back(o[now].mark);
        }

    }
    solve(1);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=4e5+5;
char s[100000][1000];
int main()
{

    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5+10;
int n,m;
int ans[maxn],lst[maxn];
char s[maxn],c[maxn][1005];
int trie[maxn*10][30],vis[maxn];
int cnt;
int getnum(char x){
	return x >= 'a'?x-'a':x-'A';
}
void build(int x,char *a){
	int len = strlen(a),root = 0;
	for (int i = 0;i < len;i++){
		int to = getnum(a[i]);
		if (!trie[root][to]) trie[root][to] = ++cnt;
		root = trie[root][to];
		if (i == len-1) vis[root] = x;
	}
}
void query(int x){
	int root = 0;
	for (int i = x;i >= 0;i--){
		int to = getnum(s[i]);
		if (!trie[root][to]) return;
		root = trie[root][to];
		if (vis[root]&&(ans[i-1]||i==0)){
			lst[x] = i-1;ans[x] = vis[root];return;
		}
	}
}
void print(int x){
  	if(lst[x] != -1) print(lst[x]);
  	printf("%s ", c[ans[x]]);
}
int main(){
	scanf ("%d",&n);
	scanf ("%s",s);
	scanf ("%d",&m);
	for (int i = 1;i <= m;i++){
		scanf ("%s",c[i]);
		build(i,c[i]);
	}
	for (int i = 0;i < n;i++){
		query(i);
	}
	print(n-1);
	return 0;
}


/*
        ####   ####
     ###    ###    ###
   ###    Bravery    ###
  ###  Determination  ###
   ##  Perseverance   ##
    ##   Integrity   ##
     ##  Patience   ##
      ## Kindness  ##
        ##Justice##
         ##     ##
           ## ##
             #
*/
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
typedef unsigned long long ll;
using namespace std;
int n,m,frm[100005],sr[100005];
string str,sub[100005];
bool dp[100005];
map <ll,int> ma[1005];
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	cin>>str;
	reverse(str.begin(),str.end());
	str=' '+str;
	cin>>m;
	for (int i=1;i<=m;i++){
		cin>>sub[i];
		ll hash=0;
		for (int j=0;j<sub[i].size();j++){
			ll nv;
			if (sub[i][j]<='Z') nv=sub[i][j]-'A'+'a'; else nv=sub[i][j];
			hash=hash*817+nv%1000000000000007;
		}
		ma[sub[i].size()][hash]=i;
	}
	dp[0]=true;
	for (int i=0;i<=n;i++){
		ll hash=0;
		if (!dp[i]) continue;
		for (int j=i+1;j<=min(i+1000,n);j++){
			ll nv;
			if (str[j]<='Z') nv=str[j]-'A'+'a'; else nv=str[j];
			hash=hash*817+nv%1000000000000007;
			if (ma[j-i][hash]){
				frm[j]=i;
				sr[j]=ma[j-i][hash];
				dp[j]=true;
			}
		}
	}
	if (!dp[n]){
		cout<<"error";
		return 0;
	}
	vector <int> ve;
	int nv=n;
	while (nv!=0){
		ve.pb(sr[nv]);
		nv=frm[nv];
	}
	for (int i=0;i<ve.size();i++){
		cout<<sub[ve[i]]<<' ';
	}
	return 0;
}


#include <bits/stdc++.h>

#define setIO(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout);

using namespace std;

typedef unsigned long long ull;

const int N = 100000;

const int M = 20000;

const int Hash = 31;

int n, m, len;

char ss[N], str[M];

ull ans[N];

map <ull, string> mp;

int main()
{
	// setIO("char");

	scanf("%d", &n);
	scanf("%s", ss + 1);
	scanf("%d", &m);
	ans[n + 1] = 1;
	for (int i = 1; i <= m; i ++ )
	{
		scanf("%s", str + 1);
		len = strlen(str + 1);
		ull tmp = 1;
		string s;
		for (int j = 1; j <= len; j ++ ) {
			s += str[j];
		}
		for (int j = 1; j <= len; j ++ ) {
			if (str[j] <= 'Z' && str[j] >= 'A') {
				str[j] = str[j] - 'A' + 'a';
			}
		}
		for (int j = len; j >= 1; j -- ) {
			tmp = tmp * Hash + str[j] - 'a' + 1;
		}
		mp[tmp] = s;
	}
	for (int i = n; i >= 1; i -- )
	{
		ull tmp = 1;
		for (int j = 1; j <= 1010; j ++ )
		{
			if (i + j - 1 > n) {
				continue;
			}
			tmp = tmp * Hash + ss[i + j - 1] - 'a' + 1;
			if (mp.find(tmp) != mp.end() && ans[i + j]) {
				ans[i] = tmp;
				break;
			}
		}
	}
	for (int i = 1; i <= n; i += mp[ans[i]].length()) {
		cout << mp[ans[i]] << ' ';
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1111111;
int ch[maxn][26],to[maxn],sa[maxn];
int cnt,rt;
string s[maxn],str;
int vis[maxn];
int newnode(){
	for(int i=0;i<26;i++){
		ch[cnt][i]=-1;
	}
	sa[cnt]=0,to[cnt]=-1;
	return cnt++;
}
void init(int n){
	cnt=0;
	rt=newnode();
	memset(vis,-1,sizeof vis);
}
void insert(int id,string s){
	int u=rt;
	for(int i=0;i<s.length();i++){
		char cc=tolower(s[i]);
		int v=cc-'a';
		if(ch[u][v]==-1){
			ch[u][v]=newnode();
		}
		u=ch[u][v];
		sa[u]++;
	}
	to[u]=id;
}
bool dfs(int pos){
	if(pos==-1)
		return true;
	if(vis[pos]!=-1) return vis[pos];
	int u=rt;
	for(int i=pos;i>=0;i--){
		u=ch[u][str[i]-'a'];
		if(u==-1) break;
		int id=to[u];
		if(id!=-1&&dfs(i-1)){
			if(i==0) cout<<s[id];
			else cout<<" "<<s[id];
			return vis[pos]=true;
		}
	}
	return vis[pos]=false;
}
int main(){
	int n,m;
	cin>>n;
	cin>>str;
	cin>>m;
	init(n);
	for(int i=0;i<m;i++){
		cin>>s[i];
		insert(i,s[i]);
	}
	dfs(n-1);
	printf("\n");
	return 0;
}


/*
        ####   ####
     ###    ###    ###
   ###    Bravery    ###
  ###  Determination  ###
   ##  Perseverance   ##
    ##   Integrity   ##
     ##  Patience   ##
      ## Kindness  ##
        ##Justice##
         ##     ##
           ## ##
             #
*/
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
typedef long long ll;
using namespace std;
int n,m,frm[100005],sr[100005];
string str,sub[100005];
bool dp[100005];
map <ll,int> ma[1005];
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	cin>>str;
	reverse(str.begin(),str.end());
	str=' '+str;
	cin>>m;
	for (int i=1;i<=m;i++){
		cin>>sub[i];
		ll hash=0;
		for (int j=0;j<sub[i].size();j++){
			int nv;
			if (sub[i][j]<'Z') nv=sub[i][j]-'A'+'a'; else nv=sub[i][j];
			hash=hash*817+nv;
		}
		ma[sub[i].size()][hash]=i;
	}
	dp[0]=true;
	for (int i=0;i<=n;i++){
		ll hash=0;
		if (!dp[i]) continue;
		for (int j=i+1;j<=min(i+1000,n);j++){
			int nv;
			if (str[j]<'Z') nv=str[j]-'A'+'a'; else nv=str[j];
			hash=hash*817+nv;
			if (ma[j-i][hash]){
				frm[j]=i;
				sr[j]=ma[j-i][hash];
				dp[j]=true;
			}
		}
	}
	vector <int> ve;
	int nv=n;
	while (nv!=0){
		ve.pb(sr[nv]);
		nv=frm[nv];
	}
	for (int i=0;i<ve.size();i++){
		cout<<sub[ve[i]]<<' ';
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
const int M = 1e4 + 5;
const int p = 1e5 + 7;
struct node {
	ll dot;
	int len;
	bool operator == (const struct node a) const {
		return len == a.len && dot == a.dot;
	}
}hm[M], hs[N];
string s;
string s1[N];
int dp[M];
vector<int> q[M];

int getnum(char c) {
	return (c >= 'a' && c <= 'z') ? c - 'a' : c - 'A';
}

struct node geth(const string str, int len) {
	struct node res;
	//cout << str << endl;
	res.dot = 0, res.len = len;
	for (int i = 0; i < len; i++) {
		res.dot = res.dot * p + getnum(str[i]);
		//cout << res.dot << endl;
	}
	return res;
}

ll qpow(ll a, ll b) {
	ll cnt = 1;
	while (b) {
		if (b & 1) cnt = cnt * a;
		a = a * a;
		b = b >> 1;
	}
	return cnt;
}

struct node cal(node a, node b) {
	node res;
	res.len = a.len - b.len;
	res.dot = a.dot - b.dot*qpow(p, res.len);
	return res;
}
int main() {
	//cout << getnum('i') << endl;
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n;
	cin >> s;
	cin >> m;
	reverse(s.begin(), s.end());
	//cout << s << endl;
	int len = s.size();
	hm[0].dot = 0; hm[0].len = 0;
	for (int i = 1; i <= n; i++) hm[i].dot = hm[i - 1].dot * p + getnum(s[i - 1]), hm[i].len = i;
	for (int i = 1; i <= m; i++) {
		cin >> s1[i];
		hs[i] = geth(s1[i], s1[i].size());
		q[s1[i].size()].push_back(i);
	}
	memset(dp, 0, sizeof(dp));
	dp[0] = 1;
	for (int i = 1; i <= n; i++) {
		bool f = true;
		for (int j = 1; j <= 1000 && j <= n && f; j++) {
			if (!dp[i - j]) continue;
			for (int v = 0; v < q[j].size() && f; v++) {
				if (hs[q[j][v]] == cal(hm[i], hm[i - j])) {

					dp[i] = q[j][v];
					f = false;
				}
			}
		}
	}
	int x = n;
	/*cout << dp[n] << endl;
	return 0;*/
	while (n) {
		cout << s1[dp[n]];
		n -= s1[dp[n]].size();
		if (n) cout << " ";
		else cout << "\n";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e6+10;
int n,m;
int ans[maxn],lst[maxn];
char s[maxn],c[1005];
int trie[maxn][28],vis[maxn];
int cnt;
string str[maxn];
int getnum(char x){
	return x >= 'a'?x-'a':x-'A';
}
void build(int x,char *a){
	int len = strlen(a),root = 0;
	for (int i = 0;i < len;i++){
		int to = getnum(a[i]);
		if (!trie[root][to]) trie[root][to] = ++cnt;
		root = trie[root][to];
		if (i == len-1) vis[root] = x;
	}
}
void query(int x){
	int root = 0;
	for (int i = x;i >= 0;i--){
		int to = getnum(s[i]);
		if (!trie[root][to]) return;
		root = trie[root][to];
		if (vis[root]&&(ans[i-1]||i==0)){
			lst[x] = i-1;ans[x] = vis[root];return;
		}
	}
}
void print(int x){
  	if(lst[x] != -1) print(lst[x]);
  	cout<<str[ans[x]]<<" ";
}
int main(){
	scanf ("%d",&n);
	scanf ("%s",s);
	scanf ("%d",&m);
	for (int i = 1,qwq;i <= m;i++){
		scanf ("%s",c);qwq = strlen(c);
		for (int j = 0;j < qwq;j++) str[i]+=c[j];
		build(i,c);
	}
	for (int i = 0;i < n;i++){
		query(i);
	}
	print(n-1);
	return 0;
}


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<map>
#define inf 0x3f3f3f3f
#define N 10010
#define ll unsigned long long
#define Hi 421
using namespace std;
ll f[N],n,m;
map<ll ,string>mp;
char a[N];
inline int read(){
    int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();
    }while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();
    }return x*f;
}
int main(){
    n=read();
    scanf("%s",a+1);
    m=read();
    for(int i=1;i<=m;i++){
        char ch[1010];scanf("%s",ch+1);
        int len=strlen(ch+1);string tmp="";
        for(int j=1;j<=len;j++)tmp+=ch[j];
        ll tmphash=0;
        for(int j=len;j>0;j--){
            tmphash=tmphash*Hi+tolower(ch[j])-'a'+1;  //Hi为Hash值随便取
        }
        mp[tmphash]=tmp;
    }
    f[n+1]=1;
    for(int i=n;i>=1;i--){
        ll tmp=0;
        for(int j=1;j<=1000&&i+j-1<=n;j++){         //因为子串长度<1000,枚举长度即可
            tmp=tmp*Hi+a[i+j-1]-'a'+1;
            if(mp.count(tmp)&&f[i+j]){
                f[i]=tmp;
                break;
            }
        }
    }
    for(int i=1;i<=n;i+=mp[f[i]].length()){
        cout<<mp[f[i]]<<' ';
    }cout<<endl;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e4 + 5;
const int maxm = 1e5 + 5;
inline ll read()
{
  ll ans = 0;
  char ch = getchar(), las = ' ';
  while(!isdigit(ch)) las = ch, ch = getchar();
  while(isdigit(ch)) ans = ans * 10 + ch - '0', ch = getchar();
  if(las == '-') ans = -ans;
  return ans;
}
inline void write(ll x)
{
  if(x < 0) putchar('-'), x = -x;
  if(x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}

int n, m;
char s[maxn], ss[maxm][1005];

int ch[1005 * 26][26], val[1005 * 26], cnt = 0;
int getnum(char c)
{
  return c >= 'a' ? c - 'a' : c - 'A';
}
void insert(int id, char *s)
{
  int len = strlen(s);
  for(int i = 0, now = 0; i < len; ++i)
    {
      int c = getnum(s[i]);
      if(!ch[now][c]) ch[now][c] = ++cnt;
      now = ch[now][c];
      if(i == len - 1) val[now] = id;
    }
}
int query(int L, int R)
{
  for(int i = L, now = 0; i >= R; --i)
    {
      int c = getnum(s[i]);
      if(!ch[now][c]) return 0;
      now = ch[now][c];
      if(i == R) return val[now];
    }
}

int ans[maxn];

int main()
{
  n = read(); scanf("%s", s);
  m = read();
  for(int i = 1; i <= m; ++i)
    {
      scanf("%s", ss[i]);
      insert(i, ss[i]);
    }
  // printf("HAHAH\n");
  int len = strlen(s), las = 0;
  for(int i = 0; i < len; ++i)
    {
      //printf("#%d %d\n", i, las);
      ans[i] = query(i, las ? las + 1 : las);
      las = ans[i] ? i : las;
    }
  // for(int i = 0; i < len; ++i) printf("%d ", ans[i]); enter;
  for(int i = 0; i < len; ++i) if(ans[i]) printf("%s ", ss[ans[i]]);
  enter;
  return 0;
}
/*
30
ariksihsidlihcdnaehsetahgnisol
10
Kira
hates
is
he
losing
death
childish
L
and
Note
 */


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define mod 10000009
#define b 26
typedef  long long int ll;

ll hsh(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b + s[i] -'a')%mod;
	}

	return h;
}

string solve(vector<string> &dp,string &s,int p,unordered_map<ll,string> &words){
	int n = s.length();

	//string tmp="";
	ll tmp=0;

	for(int i=p; i<n; i++){
		tmp = (tmp*b + s[i]-'a')%mod;

		if(words.find(tmp)!=words.end()){
			if(i==n-1){
				dp[p] = words[tmp];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words[tmp];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(dp,s,i+1,words);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words[tmp];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	string s;
	cin>>s;

	int m;
	cin>>m;

	unordered_map<ll,string> words;

	for(int i=0; i<m; i++){
		string str;
		cin>>str;

		words[hsh(lower(str))] = str;

		//cout<<"*"<<str<<endl;

	}

	vector<string> dp(n,"");

	string rs="";

	for(int i=0; i<n; i++){
		rs+=s[n-i-1];
	}

	string tmp = solve(dp,rs,0,words);

	cout<<tmp<<endl;

	return 0;

}


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
#define N 1045
#define printVector(v) {for(int i=0; i<(int)v.size(); i++) cout<<" "<<v[i]; cout<<endl;}
#define print(s) {cout<<" "<<s<<endl;}
typedef long long ll;

vector<ll> a(N,0);
int n;

int computeLength(unordered_map<ll,int> ma,ll u,ll v){

	ll f=u,s=v,t=0;

	vector<ll> seq(n,0);

	seq[0] = u;
	seq[1] = v;

	for(int i=2; i<n; i++){
		t = f+s;
		f=s;
		s=t;
		seq[i] = t;
	}
	//cout<<"--";
	//printVector(seq);
	int ans=0;

	for(int i=0; i<n; i++){
		//cout<<" "<<ma[seq[i]];
		if(ma[seq[i]]>0){
			ma[seq[i]]--;
			//cout<<" minus "<<ma[seq[i]];
			ans++;
		}
		else{
			break;
		}
	}
	//cout<<endl;
	return ans;
}

int main()
{
    cin>>n;
    unordered_map<ll,int> ma;
    for(int i=0; i<n; i++) {
		ll t;
		cin>>t;
		a[i] = t;
		if(ma.find(t)!=ma.end()){
			ma[t]=0;
		}
		else{
			ma[t]++;
		}
    }

    //for(auto it =ma.begin(); it!=ma.end(); it++){
		//cout<<
	//}

    int m=0;

    for(int i=0; i<n; i++){
		for(int j=0; j<n; j++){
			if(i!=j){
				//cout<<"* i:"<<i<<" j: "<<j<<" a[i]:"<<a[i]<<" a[j]: "<<a[j]<<" len: "<<computeLength(ma,a[i],a[j])<<endl;
				m = max(m,computeLength(ma,a[i],a[j]));
			}
		}
	}

    cout<<m<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	char data='a';
	node* child[26];
	bool leaf = true;

	node (): data('\0') {}
	node (char c): data(c){}
};

node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	node* cur = root;

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

		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	node *nd = new node(s[i]);
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	node *cur = root;
	for(int i=p; i<n; i++){
		if(cur->child[tolower(str[i])-'a']==NULL) return "";
		tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] =tmp;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+tmp;
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+tmp;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define mod1 1000009
#define b1 26
#define mod2 1000007
#define b2 23
typedef  long long int ll;
#define N 10045

map< pair < int , int > , string > words;
vector < string > dp(N,"");
string str;

int hsh1(string s){

	int n= s.length();

	int h =0;

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

		h = (h*b1 + s[i] -'a')%mod1;
	}

	return h;
}

int hsh2(string s){

	int n= s.length();

	int h =0;

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

		h = (h*b2 + s[i] -'a')%mod2;
	}

	return h;
}

string solve(int p){
	int n = str.length();

	//string tmp="";
	int tmp1=0,tmp2=0;

	for(int i=p; i<n; i++){
		tmp1 = (tmp1*b1 + str[i]-'a')%mod1;
		tmp2 = (tmp2*b2 + str[i]-'a')%mod2;

		if(words.find(make_pair(tmp1,tmp2))!=words.end()){
			if(i==n-1){
				dp[p] = words[make_pair(tmp1,tmp2)];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words[make_pair(tmp1,tmp2)];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words[make_pair(tmp1,tmp2)];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		words[make_pair(hsh1(lower(str1)),hsh2(lower(str1)))] = str1;
		//cout<<"*"<<str<<endl;

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;

}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define mod 1000009
#define b 26
typedef  int  ll;

ll hsh(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b + s[i] -'a')%mod;
	}

	return h;
}

string solve(vector<string> &dp,string &s,int p,unordered_map<ll,string> &words){
	int n = s.length();

	//string tmp="";
	ll tmp=0;

	for(int i=p; i<n; i++){
		tmp = (tmp*b + s[i]-'a')%mod;

		if(words.find(tmp)!=words.end()){
			if(i==n-1){
				dp[p] = words[tmp];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words[tmp];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(dp,s,i+1,words);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words[tmp];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	string s;
	cin>>s;

	int m;
	cin>>m;

	unordered_map<ll,string> words;

	for(int i=0; i<m; i++){
		string str;
		cin>>str;

		words[hsh(lower(str))] = str;

		//cout<<"*"<<str<<endl;

	}

	vector<string> dp(n,"");

	string rs="";

	for(int i=0; i<n; i++){
		rs+=s[n-i-1];
	}

	string tmp = solve(dp,rs,0,words);

	cout<<tmp<<endl;

	return 0;

}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	char data;
	vector<node*> child;
	bool leaf;

	node (): data('\0'),child(26,NULL),leaf(true) {//memset(child, NULL, sizeof child);
					}
	node (char c): data(c),child(26,NULL),leaf(true){//memset(child, NULL, sizeof child);
		}
};

struct node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	struct node* cur = root;

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

		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	struct node *nd = new node(s[i]);
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	struct node *cur = root;
	for(int i=p; i<n; i++){
		if(cur->child[tolower(str[i])-'a']==NULL) return "";
		tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] =tmp;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+tmp;
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+tmp;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	char data;
	vector<node*> child;
	bool leaf;
	bool isword;
	node (): data('\0'),child(26,NULL),leaf(true),isword(false) {//memset(child, NULL, sizeof child);
					}
	node (char c): data(c),child(26,NULL),leaf(true),isword(false){//memset(child, NULL, sizeof child);
		}
};

struct node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	struct node* cur = root;

	for(int i=0; i<n; i++){
		if(cur==NULL) return;
		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	struct node *nd = new node(s[i]);
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}

	cur->isword=true;
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	struct node *cur = root;
	for(int i=p; i<n; i++){
		if(cur->child[tolower(str[i])-'a']==NULL) return "";
		tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->leaf&&cur->isword){
			if(i==n-1){
				dp[p] =tmp;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+tmp;
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+tmp;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	char data;
	vector<node*> child;
	bool leaf;

	node (): data('\0'),child(26,NULL),leaf(true) {//memset(child, NULL, sizeof child);
					}
	node (char c): data(c),child(26,NULL),leaf(true){//memset(child, NULL, sizeof child);
		}
};

struct node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	struct node* cur = root;

	for(int i=0; i<n; i++){
		if(cur==NULL) return;
		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	struct node *nd = new node(s[i]);
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	struct node *cur = root;
	for(int i=p; i<n; i++){
		if(cur->child[tolower(str[i])-'a']==NULL) return "";
		tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] =tmp;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+tmp;
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+tmp;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define mod1 10000009
#define b1 26
#define mod2 10000007
#define b2 23
typedef  long long int ll;
#define N 10045

map< pair < ll , ll > ,string> words;
vector < string > dp(N,"");
string str;

ll hsh1(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b1 + s[i] -'a')%mod1;
	}

	return h;
}

ll hsh2(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b2 + s[i] -'a')%mod2;
	}

	return h;
}

string solve(int p){
	int n = str.length();

	//string tmp="";
	ll tmp1=0,tmp2=0;

	for(int i=p; i<n; i++){
		tmp1 = (tmp1*b1 + str[i]-'a')%mod1;
		tmp2 = (tmp2*b2 + str[i]-'a')%mod2;

		if(words.find(make_pair(tmp1,tmp2))!=words.end()){
			if(i==n-1){
				dp[p] = words[make_pair(tmp1,tmp2)];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words[make_pair(tmp1,tmp2)];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words[make_pair(tmp1,tmp2)];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		words[make_pair(hsh1(lower(str1)),hsh2(lower(str1)))] = str1;
		//cout<<"*"<<str<<endl;

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;

}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define mod1 10000009
#define b1 26
#define mod2 10000007
#define b2 23
typedef  long long int ll;

ll hsh1(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b1 + s[i] -'a')%mod1;
	}

	return h;
}

ll hsh2(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b2 + s[i] -'a')%mod2;
	}

	return h;
}

string solve(vector<string> &dp,string &s,int p,unordered_map<ll,string> &words1,unordered_map<ll,string> &words2){
	int n = s.length();

	//string tmp="";
	ll tmp1=0,tmp2=0;

	for(int i=p; i<n; i++){
		tmp1 = (tmp1*b1 + s[i]-'a')%mod1;
		tmp2 = (tmp2*b2 + s[i]-'a')%mod2;

		if(words1.find(tmp1)!=words1.end()&&words2.find(tmp2)!=words1.end()&&words1[tmp1]==words2[tmp2]){
			if(i==n-1){
				dp[p] = words1[tmp1];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words1[tmp1];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(dp,s,i+1,words1,words2);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words1[tmp1];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	string s;
	cin>>s;

	int m;
	cin>>m;

	unordered_map<ll,string> words1;
	unordered_map<ll,string> words2;

	for(int i=0; i<m; i++){
		string str;
		cin>>str;

		words1[hsh1(lower(str))] = str;
		words2[hsh2(lower(str))] = str;
		//cout<<"*"<<str<<endl;

	}

	vector<string> dp(n,"");

	string rs="";

	for(int i=0; i<n; i++){
		rs+=s[n-i-1];
	}

	string tmp = solve(dp,rs,0,words1,words2);

	cout<<tmp<<endl;

	return 0;

}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	char data='a';
	node* child[26];
	bool leaf = true;

	node (): data('\0') {}
	node (char c): data(c){}
};

node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	node* cur = root;

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

		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	node *nd = new node(s[i]);
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	node *cur = root;
	for(int i=p; i<n; i++){
		tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] =tmp;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+tmp;
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+tmp;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	char data;
	vector<node*> child;
	bool leaf;
	bool isword;
	string word;
	node (): data('\0'),child(26,NULL),leaf(true),isword(false),word("") {//memset(child, NULL, sizeof child);
					}
	node (char c): data(c),child(26,NULL),leaf(true),isword(false),word(""){//memset(child, NULL, sizeof child);
		}
};

struct node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	struct node* cur = root;

	for(int i=0; i<n; i++){
		if(cur==NULL) return;
		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	struct node *nd = new node(s[i]);
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}

	cur->isword=true;
	cur->word = s;
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	struct node *cur = root;
	for(int i=p; i<n; i++){
		if(cur->child[tolower(str[i])-'a']==NULL) return "";
		tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->leaf&&cur->isword){
			if(i==n-1){
				dp[p] =cur->word;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+cur->word;
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+cur->word;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define mod1 10000009
#define b1 26
#define mod2 10000007
#define b2 23
typedef  long long int ll;

ll hsh1(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b1 + s[i] -'a')%mod1;
	}

	return h;
}

ll hsh2(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b2 + s[i] -'a')%mod2;
	}

	return h;
}

string solve(vector<string> &dp,string &s,int p,map<ll,string> &words1,map<ll,string> &words2){
	int n = s.length();

	//string tmp="";
	ll tmp1=0,tmp2=0;

	for(int i=p; i<n; i++){
		tmp1 = (tmp1*b1 + s[i]-'a')%mod1;
		tmp2 = (tmp2*b2 + s[i]-'a')%mod2;

		if(words1.find(tmp1)!=words1.end()&&words2.find(tmp2)!=words1.end()&&words1[tmp1]==words2[tmp2]){
			if(i==n-1){
				dp[p] = words1[tmp1];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words1[tmp1];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(dp,s,i+1,words1,words2);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words1[tmp1];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	string s;
	cin>>s;

	int m;
	cin>>m;

	map<ll,string> words1;
	map<ll,string> words2;

	for(int i=0; i<m; i++){
		string str;
		cin>>str;

		words1[hsh1(lower(str))] = str;
		words2[hsh2(lower(str))] = str;
		//cout<<"*"<<str<<endl;

	}

	vector<string> dp(n,"");

	string rs="";

	for(int i=0; i<n; i++){
		rs+=s[n-i-1];
	}

	string tmp = solve(dp,rs,0,words1,words2);

	cout<<tmp<<endl;

	return 0;

}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

string solve(vector<string> &dp,string &s,int p,unordered_map<string,string> &words){
	int n = s.length();

	string tmp="";

	for(int i=p; i<n; i++){
		tmp+=s[i];

		if(words.find(tmp)!=words.end()){
			if(i==n-1){
				dp[p] = words[tmp];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words[tmp];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(dp,s,i+1,words);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words[tmp];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	string s;
	cin>>s;

	int m;
	cin>>m;

	unordered_map<string,string> words;

	for(int i=0; i<m; i++){
		string str;
		cin>>str;

		words[lower(str)] = str;

		//cout<<"*"<<str<<endl;

	}

	vector<string> dp(n,"");

	string rs="";

	for(int i=0; i<n; i++){
		rs+=s[n-i-1];
	}

	string tmp = solve(dp,rs,0,words);

	cout<<tmp<<endl;

	return 0;

}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	vector<node*> child;
	bool isword;
	string word;
	node (): child(26,NULL),isword(false),word("") {}
};

struct node *root = new node();

void add(string s){

	int n=s.length();

	node* cur = root;

	for(int i=0; i<n; i++){
		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	struct node *nd = new node();
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur = nd;
		}
	}
	cur->isword=true;
	cur->word = s;
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	struct node *cur = root;
	for(int i=p; i<n; i++){
		if(cur->child[tolower(str[i])-'a']==NULL) return "";
		//tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->isword){
			if(i==n-1){
				dp[p] =cur->word;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+cur->word;
				return dp[p];
			}
			else if(dp[i+1]=="1"){
				continue;
			}
			else{

				string t = "";
				t = solve(i+1);

				if(t=="") {
					dp[i+1] = "1";
					continue;
				}
				else{
					dp[p] = t+" "+cur->word;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define mod1 10000009
#define b1 26
#define mod2 10000007
#define b2 23
typedef  long long int ll;

unordered_map<ll,string> words1,words2;
vector < string > dp;
string str;

ll hsh1(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b1 + s[i] -'a')%mod1;
	}

	return h;
}

ll hsh2(string s){

	int n= s.length();

	ll h =0;

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

		h = (h*b2 + s[i] -'a')%mod2;
	}

	return h;
}

string solve(int p){
	int n = str.length();

	//string tmp="";
	ll tmp1=0,tmp2=0;

	for(int i=p; i<n; i++){
		tmp1 = (tmp1*b1 + str[i]-'a')%mod1;
		tmp2 = (tmp2*b2 + str[i]-'a')%mod2;

		if(words1.find(tmp1)!=words1.end()&&words2.find(tmp2)!=words1.end()&&words1[tmp1]==words2[tmp2]){
			if(i==n-1){
				dp[p] = words1[tmp1];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words1[tmp1];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words1[tmp1];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		words1[hsh1(lower(str1))] = str1;
		words2[hsh2(lower(str1))] = str1;
		//cout<<"*"<<str<<endl;

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;

}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	char data;
	node* child[26];
	bool leaf;

	node (): data('\0'),leaf(true) {}
	node (char c): data(c),leaf(true){}
};

struct node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	struct node* cur = root;

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

		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	struct node *nd = new node(s[i]);
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	struct node *cur = root;
	for(int i=p; i<n; i++){
		if(cur->child[tolower(str[i])-'a']==NULL) return "";
		tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] =tmp;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+tmp;
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+tmp;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define N 10045

map<string,string> words;
vector < string > dp(N,"");
string str;

struct node{
	char data='a';
	bool upper=false;
	node* child[26];
	bool leaf = true;

	node (): data('\0'),upper(false) {}
	node (char c): data(c),upper(false) {}
	node (char c,bool up): data(c), upper(up) {}
};

node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	node* cur = root;

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

		if(cur->child[s[i]-'a']!=NULL) 	cur = cur->child[s[i]-'a'];
		else{	node *nd = new node(s[i]);
			    cur->child[s[i]-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	node *cur = root;
	for(int i=p; i<n; i++){
		tmp+= cur->child[str[i]-'a']->data;
		cur = cur->child[str[i]-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] = words[tmp];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words[tmp];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words[tmp];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(lower(str1));
		words[lower(str1)] = str1;
		//cout<<"*"<<str<<endl;

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define N 10045
vector < string > dp(N,"");
string str;

struct node{
	char data='a';
	node* child[26];
	bool leaf = true;

	node (): data('\0') {}
	node (char c): data(c){}
};

struct node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	struct node* cur = root;

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

		if(cur->child[tolower(s[i])-'a']!=NULL) 	cur = cur->child[tolower(s[i])-'a'];
		else{	struct node *nd = new node(s[i]);
			    cur->child[tolower(s[i])-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	struct node *cur = root;
	for(int i=p; i<n; i++){
		if(cur->child[tolower(str[i])-'a']==NULL) return "";
		tmp+= cur->child[tolower(str[i])-'a']->data;
		cur = cur->child[tolower(str[i])-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] =tmp;
				return dp[p];
			}
			else if(dp[i+1]!=""){
				dp[p] = dp[i+1]+" "+tmp;
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+tmp;
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(str1);

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define N 10045

map<string,string> words;
vector < string > dp(N,"");
string str;

struct node{
	char data='a';
	node* child[26];
	bool leaf = true;

	node (): data('\0') {}
	node (char c): data(c){}
};

node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	node* cur = root;

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

		if(cur->child[s[i]-'a']!=NULL) 	cur = cur->child[s[i]-'a'];
		else{	node *nd = new node(s[i]);
			    cur->child[s[i]-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	node *cur = root;
	for(int i=p; i<n; i++){
		tmp+= cur->child[str[i]-'a']->data;
		cur = cur->child[str[i]-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] = words[tmp];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words[tmp];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words[tmp];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(lower(str1));
		words[lower(str1)] = str1;
		//cout<<"*"<<str<<endl;

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define mod1 1000009
#define b1 26
#define mod2 1000007
#define b2 23
typedef  long long int ll;
#define N 10045

map<string,string> words;
vector < string > dp(N,"");
string str;

struct node{
	char data='a';
	bool upper=false;
	node* child[26];
	bool leaf = true;

	node (): data('\0'),upper(false) {}
	node (char c): data(c),upper(false) {}
	node (char c,bool up): data(c), upper(up) {}
};

node *root = new node();

void add(string s){

	int n=s.length();

	root->leaf = false;

	node* cur = root;

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

		if(cur->child[s[i]-'a']!=NULL) 	cur = cur->child[s[i]-'a'];
		else{	node *nd = new node(s[i]);
			    cur->child[s[i]-'a'] = nd;
			    cur->leaf =false;
			    cur = nd;
		}
	}
}

string solve(int p){
	int n = str.length();

	string tmp="";
	//int tmp1=0,tmp2=0;
	node *cur = root;
	for(int i=p; i<n; i++){
		tmp+= cur->child[str[i]-'a']->data;
		cur = cur->child[str[i]-'a'];

		if(cur->leaf){
			if(i==n-1){
				dp[p] = words[tmp];
				return dp[p];
			}
			else if(dp[i+1]!=""){
				//dp[p] = tmp+" "+dp[i+1];
				dp[p] = dp[i+1]+" "+words[tmp];
				return dp[p];
			}
			else{

				string t = "";
				t = solve(i+1);
				if(t=="") continue;
				else{
					dp[p] = t+" "+words[tmp];
					return dp[p];
				}

			}
		}
	}

	return "";
}

string lower(string s){

	int n= s.length();

	for(int i=0; i<n; i++){
		s[i] = tolower(s[i]);
	}

	return s;
}

int main(){

	int n;
	cin>>n;

	cin>>str;

	int m;
	cin>>m;

	for(int i=0; i<m; i++){
		string str1;
		cin>>str1;

		add(lower(str1));
		words[lower(str1)] = str1;
		//cout<<"*"<<str<<endl;

	}

	string rs="";

	for(int i=0; i<n; i++){
		rs+=str[n-i-1];
	}

	str = rs;

	string tmp = solve(0);

	cout<<tmp<<endl;

	return 0;

}