#include <bits/stdc++.h>

using namespace std;

struct edge {
  int to;
  string cost;
  edge(int to = -1, string cost = ""):to(to), cost(cost){}
};

using Graph = vector<vector<edge>>;

int n, a, s, g;
Graph graph;

struct State {
  int now;
  string str;
  State(int now = -1, string str = ""):now(now), str(str){}
  bool operator < (const State& st) const {
    return str > st.str;
  }
};

string mincost[44][444];
string dijkstra() {
  fill(mincost[0], mincost[44], "~");
  priority_queue<State> que;
  que.emplace(s, "");
  mincost[s][0] = "";
  while(!que.empty()) {
    State st = que.top(); que.pop();
    if(mincost[st.now][st.str.size()] < st.str) continue;
    for(edge& e : graph[st.now]) {
      string ns = st.str + e.cost;
      if(ns.size() >= 444) continue;
      if(mincost[e.to][ns.size()] > ns) {
	que.emplace(e.to, ns);
	mincost[e.to][ns.size()] = ns;
      }
    }
  }
  string res = "~";
  for(int i = 0; i < 444; i++) {
    if(res > mincost[g][i]) {
      res = mincost[g][i];
      if(i > 400) return "NO";
    }
  }
  return res == "~" ? "NO" : res;
}

int main() {
  while(cin >> n >> a >> s >> g, n || a || s || g) {
    graph.clear();
    graph.resize(n);
    for(int i = 0; i < a; i++) {
      int x, y;
      string lab;
      cin >> x >> y >> lab;
      graph[x].emplace_back(y, lab);
    }
    cout << dijkstra() << endl;
  }
  return 0;
}