#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
 
struct edge{
    int v;
    string cost;
    edge(int v_, string cost_){
        v = v_; cost = cost_;
    }
};
bool operator<(const edge& a, const edge& b){
    return a.cost > b.cost;
}
const int MAX_V = 40;
const int MAX_E = 400;
// dp[v][l] := テゥツ?づァツつケ v, テヲツ鳴?・ツュツ療・ツ按療」ツ?ョテゥツ閉キテ」ツ??l テ」ツ?ョテ」ツ?ィテ」ツ?催」ツ?ョテヲツ慊?・ツシツキテ」ツ?ョテ・ツ堕ェテヲツ鳴?
string dp[MAX_V][500];
vector<edge> G[MAX_V];
int n, a, s, g;
 
void add_edge(int u, int v, string cost){
    G[u].push_back( edge(v, cost) );
}
 
void dfs(int v, vector<bool>& visited){
    visited[v] = true;
    for(int i=0 ; i < G[v].size() ; i++ ){
        int to = G[v][i].v;
        if( !visited[to] ){
            dfs(to, visited);
        }
    }
}
 
bool is_exist(){
    vector<bool> visited(n, false);
    dfs(s, visited);
    if( !visited[g] ) return false;
     
    return true;
}
 
string solve(){
    for(int i=0 ; i < MAX_V ; i++ ){
        fill(dp[i], dp[i] + 500, "~");
    }
    int N = 6 * (n - 1); 
    dp[s][0] = "";
    priority_queue<edge> q;
    q.push( edge(s, "") );
     
    string res = "~";
    while( !q.empty() ){
        int v = q.top().v;
        string cost = q.top().cost;
        int l = cost.size();
        q.pop();
         
        if( v == g ){
            res = min(res, cost);
            break;
        }
         
        for(int i=0 ; i < G[v].size() ; i++ ){
            int to = G[v][i].v;
            string add_cost = G[v][i].cost;
            string next_cost = cost + add_cost;
            int l_ = next_cost.size();
            if( 500 <= next_cost.size() ){
                continue;
            }
            if( next_cost < dp[to][l_] ){
                dp[to][l_] = next_cost;
                q.push( edge(to, dp[to][l_]) );
            }
        }
    }
    for(int i=N ; i < 500 ; i++ ){
        if( dp[g][i].size() == i ) return "~";
    }
    return res;
}
 
int main(){
    while( cin >> n >> a >> s >> g, n ){
        for(int i=0 ; i < MAX_V ; i++ ) G[i].clear();    
         
        for(int i=0 ; i < a ; i++ ){
            int x, y;
            string lab;
            cin >> x >> y >> lab;
            add_edge(x, y, lab);
        }
        if( !is_exist() ){
            cout << "NO" << endl;
        }else{
            string ans = solve();
            if( ans == "~" ) ans = "NO";
            cout << ans << endl;
        }
    }
}