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

struct data {
  int p;
  string s;
};

bool operator<(const data &l, const data &r) {
  if(l.s != r.s) return l.s > r.s;
  return l.p < r.p;
}

int n, a, s, g;
string dummy;
vector<vector<string>> dist;
vector<data> edge[50];
priority_queue<data> pq;

string solve();

int main() {
  dummy += 'z' + 1;
  while(1) {
    cin >> n >> a >> s >> g;
    if(n + a + s + g == 0) break;
    for(int i = 0; i < a; ++i) {
      int x, y;
      string st;
      cin >> x >> y >> st;
      edge[x].push_back({y, st});
    }
    dist.assign(n, vector<string>(500, dummy));
    cout << solve() << endl;
    for(int i = 0; i < n; ++i)
      edge[i].erase(edge[i].begin(), edge[i].end());
  }
  return 0;
}

string solve() {
  pq.push({s, ""});
  dist[s][0] = "";
  while(pq.size() > 0) {
    data now = pq.top();
    pq.pop();
    if(dist[now.p][now.s.size()] < now.s) continue;
    for(int i = 0; i < edge[now.p].size(); ++i) {
      data nextp = now;
      nextp.p = edge[now.p][i].p;
      nextp.s += edge[now.p][i].s;
      if(nextp.s.size() >= 500) continue;
      if(dist[nextp.p][nextp.s.size()] > nextp.s) {
        dist[nextp.p][nextp.s.size()] = nextp.s;
        pq.push(nextp);
      }
    }
  }
  string ans = dummy;
  for(int i = 0; i < 500; ++i) ans = min(ans, dist[g][i]);
  if(ans == dummy || ans.size() > 240) return "NO";
  return ans;
}
