#include #include int N1, N2; char words1[20][41]; char words2[20][41]; #define MAX (1 + 2 * 20 * 40) int adj[MAX][MAX], nadj[MAX]; int tag[MAX]; int id(int s, int p, int l) { if (l == 0) return 0; return 1 + s * 20 * 40 + p * 40 + l; } int min(int x, int y) { return (x < y) ? x : y; } void edge(int p, int q) { adj[p][nadj[p]++] = q; } void build_graph() { int p, q, l, m; memset(nadj, 0, sizeof(nadj)); for (p = 0; p < N1; p++) { edge(0, id(0, p, strlen(words1[p]))); } for (p = 0; p < N2; p++) { edge(0, id(1, p, strlen(words2[p]))); } for (p = 0; p < N1; p++) { for (l = 1; l <= strlen(words1[p]); l++) { for (q = 0; q < N2; q++) { m = min(l, strlen(words2[q])); if (strncmp(words1[p] + (strlen(words1[p]) - l), words2[q], m) == 0) { if (strlen(words2[q]) >= l) { edge(id(0, p, l), id(1, q, strlen(words2[q]) - m)); } else { edge(id(0, p, l), id(0, p, l - m)); } } } } } for (p = 0; p < N2; p++) { for (l = 1; l <= strlen(words2[p]); l++) { for (q = 0; q < N1; q++) { m = min(l, strlen(words1[q])); if (strncmp(words2[p] + (strlen(words2[p]) - l), words1[q], m) == 0) { if (strlen(words1[q]) >= l) { edge(id(1, p, l), id(0, q, strlen(words1[q]) - m)); } else { edge(id(1, p, l), id(1, p, l - m)); } } } } } } void init_dfs() { memset(tag, 0, sizeof(tag)); } int dfs(int p) { int k, q; if (tag[p]) return (p == 0); tag[p] = 1; for (k = 0; k < nadj[p]; k++) { q = adj[p][k]; if (dfs(q)) return 1; } return 0; } int main() { int i; while (scanf(" %d %d", &N1, &N2) != EOF) { for (i = 0; i < N1; i++) { scanf(" %s", &words1[i][0]); } for (i = 0; i < N2; i++) { scanf(" %s", &words2[i][0]); } build_graph(); init_dfs(); puts(dfs(0) ? "S" : "N"); } return 0; }