#include <cctype>
#include <iostream>
#include <set>
#include <string>
#include <vector>

struct regla {
   char no_terminal;
   std::string reemplazo;
};

std::set<int> intenta(const std::string& producir, int i, char no_terminal, int profundidad, const std::vector<regla>& reglas) {
   if (profundidad > 26 * producir.size( )) {      // el 26* por si hubiera reglas del tipo S -> A; A -> B; B -> C; etc
      return { };
   }

   std::set<int> res;
   for (regla r : reglas) {
      if (no_terminal == r.no_terminal) {
         std::set<int> pos_actuales = { i };
         for (char c : r.reemplazo) {
            std::set<int> pos_siguientes;
            if (std::islower(c)) {
               for (int p : pos_actuales) {
                  if (producir[p] == c) {
                     pos_siguientes.insert(p + 1);
                  }
               }
            } else if (std::isupper(c)) {
               for (int p : pos_actuales) {
                  for (int ps : intenta(producir, p, c, profundidad + 1, reglas)) {
                     pos_siguientes.insert(ps);
                  }
               }
            }
            pos_actuales = pos_siguientes;
         }
         for (int p : pos_actuales) {
            res.insert(p);
         }
      }
   }

   return res;
}

bool intenta(const std::string& producir, const std::vector<regla>& reglas) {
   std::set<int> res = intenta(producir, 0, 'S', 0, reglas);
   return res.contains(producir.size( ));
}

int main( ) {
   int n;
   std::cin >> n;

   std::vector<regla> reglas(n);
   for (int i = 0; i < n; ++i) {
      std::string flecha;
      std::cin >> reglas[i].no_terminal >> flecha >> reglas[i].reemplazo;     // no permitiremos reemplazos vacíos (si los permitimos, acotar la profundidad de la recursión es aún más problemático)
   }

   std::string producir;
   std::cin >> producir;
   std::cout << intenta(producir, reglas);
}

/* Ejemplo de entrada:
4
S -> SaT
S -> c
T -> b
T -> Ta
cabaab
*/
