using namespace std;
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <queue>
#include <set>
#include <cmath>
#include <vector>

//By chyx111
typedef long long ll;
#define Rep(i,n) for(int n_ = (n), i = 0; i< n_; ++i)
#define SZ(a) ((int)(a).size())
template<typename S, typename T> ostream& operator<<(ostream& os, pair<S,T> p){ return os << "(" << p.first << "," << p.second << ")"; };

int const N = 1024, M = 2 * N;
struct Edge{
    int to, w;
    Edge(int to, int w):to(to), w(w){}
    Edge(){}
};
ll dist[N][N];
ll taxi_dist[N];
vector<Edge> G[N];

struct Taxi{
    int max_dist, cost;
    void scan(){
        scanf("%d%d", &max_dist, &cost);
    }
};
Taxi taxi[N];
int main() {
    int n, m;
    int s, t;
    while( scanf("%d%d", &n, &m) == 2 ){
        scanf("%d%d", &s, &t); s--; t--;
        Rep(i, n) G[i].clear();
        Rep(i, m){
            int a, b, w;
            scanf("%d%d%d", &a, &b, &w); a--; b--;
            G[a].push_back(Edge(b, w));
            G[b].push_back(Edge(a, w));
        }
        Rep(i,n)taxi[i].scan();
        Rep(src, n){
            priority_queue<pair<ll, int>, vector< pair<ll, int> >, greater< pair<ll, int> > > Q;
            memset(dist[src], 0x3f, (sizeof dist[src]));
            dist[src][src] = 0;
            Q.push(make_pair(0LL,src));
            while( !Q.empty() ){
                pair<ll, int> top = Q.top(); Q.pop();
                int cur = top.second;
                Rep(i, SZ(G[cur])){
                    int nxt = G[cur][i].to;
                    ll better = dist[src][cur] + G[cur][i].w;
                    if( better < dist[src][nxt] ){
                        dist[src][nxt] = better;
                        Q.push(make_pair(dist[src][nxt], nxt));
                    }
                }
            }
        }

        priority_queue<pair<ll, int>, vector< pair<ll, int> >, greater< pair<ll, int> > > Q;
        memset(taxi_dist, 0x3f, (sizeof taxi_dist));
        taxi_dist[s] = 0;
        Q.push(make_pair(0LL,s));
        while( !Q.empty() ){
            pair<ll, int> top = Q.top(); Q.pop();
            int cur = top.second;
            Rep(nxt, n){
                if( dist[cur][nxt] <= taxi[cur].max_dist ){
                    ll better = taxi_dist[cur] + taxi[cur].cost;
                    if( better < taxi_dist[nxt] ){
                        taxi_dist[nxt] = better;
                        Q.push(make_pair(taxi_dist[nxt], nxt));
                    }
                }
            }
        }
        ll oo = 0x3f3f3f3f3f3f3f3fLL;
        if( taxi_dist[t] == oo ) taxi_dist[t] = -1;
        cout<<taxi_dist[t]<<endl;
    }
    return 0;
}


#include <queue>
#include <cstdio>
#include <vector>
#include <utility>
#include <iostream>

using namespace std;

const int MAXN = 1024;
const long long INF = 1000000007LL * 1000000007LL;

vector<pair<int, int> > e[MAXN], ee[MAXN];
long long mind[MAXN];

void sp(int n, int s) {
	priority_queue<pair<int, int> > pq;

	for (int i = 0; i < n; ++i) {
		mind[i] = INF;
	}
	mind[s] = 0;
	pq.push(make_pair(-mind[s], s));
	while (!pq.empty()) {
		s = pq.top().second;
		if (pq.top().first != -mind[s]) {
			pq.pop();
			continue;
		}
		pq.pop();
		for (auto ei: e[s]) {
			if (mind[ei.first] > mind[s] + ei.second) {
				mind[ei.first] = mind[s] + ei.second;
				pq.push(make_pair(-mind[ei.first], ei.first));
			}
		}
	}
}

int main() {
	int n, m, s, t, a, b, c;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	--s;
	--t;
	for (int i = 0; i < m; ++i) {
		scanf("%d%d%d", &a, &b, &c);
		--a;
		--b;
		e[a].push_back(make_pair(b, c));
		e[b].push_back(make_pair(a, c));
	}

	for (int i = 0; i < n; ++i) {
		scanf("%d%d", &a, &b);
		sp(n, i);
		for (int j = 0; j < n; ++j) {
			if (mind[j] <= a) {
				ee[i].push_back(make_pair(j, b));
			}
		}
	}

	for (int i = 0; i < n; ++i) {
		e[i].swap(ee[i]);
	}
	sp(n, s);
	cout << mind[t] << endl;

	return 0;
}


#include <queue>
#include <cstdio>
#include <vector>
#include <utility>
#include <iostream>

using namespace std;

const int MAXN = 1024;
const long long INF = 1000000007LL * 1000000007LL;

vector<pair<int, int> > e[MAXN], ee[MAXN];
long long mind[MAXN];

void sp(int n, int s) {
	priority_queue<pair<long long, int> > pq;

	for (int i = 0; i < n; ++i) {
		mind[i] = INF;
	}
	mind[s] = 0;
	pq.push(make_pair(-mind[s], s));
	while (!pq.empty()) {
		s = pq.top().second;
		if (pq.top().first != -mind[s]) {
			pq.pop();
			continue;
		}
		pq.pop();
		for (auto ei: e[s]) {
			if (mind[ei.first] > mind[s] + ei.second) {
				mind[ei.first] = mind[s] + ei.second;
				pq.push(make_pair(-mind[ei.first], ei.first));
			}
		}
	}
}

int main() {
	int n, m, s, t, a, b, c;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	--s;
	--t;
	for (int i = 0; i < m; ++i) {
		scanf("%d%d%d", &a, &b, &c);
		--a;
		--b;
		e[a].push_back(make_pair(b, c));
		e[b].push_back(make_pair(a, c));
	}

	for (int i = 0; i < n; ++i) {
		scanf("%d%d", &a, &b);
		sp(n, i);
		for (int j = 0; j < n; ++j) {
			if (mind[j] <= a) {
				ee[i].push_back(make_pair(j, b));
			}
		}
	}

	for (int i = 0; i < n; ++i) {
		e[i].swap(ee[i]);
	}
	sp(n, s);
	cout << (mind[t] < INF ? mind[t] : -1LL) << endl;

	return 0;
}


#include <queue>
#include <cstdio>
#include <vector>
#include <utility>
#include <iostream>

using namespace std;

const int MAXN = 1024;
const long long INF = 1000000007LL * 1000000007LL;

vector<pair<int, int> > e[MAXN], ee[MAXN];
long long mind[MAXN];

void sp(int n, int s) {
	priority_queue<pair<int, int> > pq;

	for (int i = 0; i < n; ++i) {
		mind[i] = INF;
	}
	mind[s] = 0;
	pq.push(make_pair(-mind[s], s));
	while (!pq.empty()) {
		s = pq.top().second;
		if (pq.top().first != -mind[s]) {
			pq.pop();
			continue;
		}
		pq.pop();
		for (auto ei: e[s]) {
			if (mind[ei.first] > mind[s] + ei.second) {
				mind[ei.first] = mind[s] + ei.second;
				pq.push(make_pair(-mind[ei.first], ei.first));
			}
		}
	}
}

int main() {
	int n, m, s, t, a, b, c;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	--s;
	--t;
	for (int i = 0; i < m; ++i) {
		scanf("%d%d%d", &a, &b, &c);
		--a;
		--b;
		e[a].push_back(make_pair(b, c));
		e[b].push_back(make_pair(a, c));
	}

	for (int i = 0; i < n; ++i) {
		scanf("%d%d", &a, &b);
		sp(n, i);
		for (int j = 0; j < n; ++j) {
			if (mind[j] <= a) {
				ee[i].push_back(make_pair(j, b));
			}
		}
	}

	for (int i = 0; i < n; ++i) {
		e[i].swap(ee[i]);
	}
	sp(n, s);
	cout << (mind[t] < INF ? mind[t] : -1LL) << endl;

	return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<map>
#include<list>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>

#define mod 1000000007
#define sd(x) scanf("%d",&x)
#define pd(x) printf("%d",x)
#define ll long long
#define no_nodes 10002
using namespace std;
ll power(ll b,ll exp,ll m) {ll ans=1; b%=m; while(exp){if(exp&1) ans=(ans*b)%m; exp>>=1; b=(b*b)%m; } return ans; }
const int intmax=1000000009;

vector< vector<pair<int,int> > > adj(no_nodes);              //graph
vector< vector<pair<int,int> > >adj2(no_nodes);
vector<pair<int,int > > rec(no_nodes);
vector<int> hash_(no_nodes);
vector<ll> d(no_nodes,intmax);

int n,m;

int cost,root;
void dfs(int node,int dist)
{

    if(dist<0) return;
    if(dist>=0&&node!=root&&hash_[node]==-1)
    {
        adj2[root].push_back({node,cost});
    }
    hash_[node]=dist;
    //cout<<node<<" "<<dist<<" "<<cost<<endl;

    for(auto i:adj[node])
    {

        int u=i.first;
        int cost1=i.second;
        if(hash_[u]>dist-cost1) continue;
        int cost=i.second;
        dfs(u,dist-cost1);
    }
}

void dijkastra(int node,int fnode)
{

    set<pair<ll,int> > q;
    q.insert({0,node});
    d[node]=0;
    while(!q.empty())
    {
        auto i=q.begin();
        int v=i->second;
        if(v==fnode) break;
        q.erase(i);
        for(auto i:adj2[v])
        {
            int u=i.first;
            int cost=i.second;
            if(d[u]>d[v]+cost)
            {
                if(d[u]!=intmax) q.erase(q.find({d[u],u}));
                d[u]=d[v]+cost;
                q.insert({d[u],u});
            }
        }

    }
    q.clear();

}

int main()
{
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   int test,t1,t2,t3,t4,t5;
   test=1;

   while(test--)
   {
        sd(n);
        sd(m);
        sd(t1);
        sd(t2);
        while(m--)
        {

            sd(t3);
            sd(t4);
            sd(t5);
            adj[t3].push_back({t4,t5});
            adj[t4].push_back({t3,t5});
        }
        for(int i=1;i<=n;i++)
        {
            sd(t3);
            sd(t4);
            rec[i]={t3,t4};
        }
        for(int i=1;i<=n;i++)
        {
            root=i;
            cost=rec[i].second;
            for(int j=1;j<=n;j++) hash_[j]=-1;
            dfs(i,rec[i].first);
            //cout<<endl;
        }

        /*for(int i=1;i<=n;i++)
        {
            cout<<i<<"++";
            for(auto v:adj2[i]) cout<<v.first<<"=>"<<v.second<<" ";
            cout<<endl;
        }
        */
        //cout<<t2;

        dijkastra(t1,t2);
        if(d[t2]==intmax) cout<<"-1"<<endl;
        else cout<<d[t2]<<endl;

   }
   return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<map>
#include<list>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>

#define mod 1000000007
#define sd(x) scanf("%d",&x)
#define pd(x) printf("%d",x)
#define ll long long
#define no_nodes 10002
using namespace std;
ll power(ll b,ll exp,ll m) {ll ans=1; b%=m; while(exp){if(exp&1) ans=(ans*b)%m; exp>>=1; b=(b*b)%m; } return ans; }
const int intmax=1000000009;

vector< vector<pair<int,int> > > adj(no_nodes);              //graph
vector< vector<pair<int,int> > >adj2(no_nodes);
vector<pair<int,int > > rec(no_nodes);
vector<int> hash_(no_nodes);
vector<ll> d(no_nodes,intmax);

int n,m;

int cost,root;
void dfs(int node,int dist)
{

    if(dist<0) return;
    if(dist>=0&&node!=root&&hash_[node]==-1)
    {
        adj2[root].push_back({node,cost});
    }
    hash_[node]=dist;
    //cout<<node<<" "<<dist<<" "<<cost<<endl;

    for(auto i:adj[node])
    {

        int u=i.first;
        int cost1=i.second;
        if(hash_[u]>dist-cost1) continue;
        int cost=i.second;
        dfs(u,dist-cost1);
    }
}

void dijkastra(int node,int fnode)
{

    set<pair<ll,int> > q;
    q.insert({0,node});
    d[node]=0;
    while(!q.empty())
    {
        auto i=q.begin();
        int v=i->second;
        if(v==fnode) break;
        q.erase(i);
        for(auto i:adj2[v])
        {
            int u=i.first;
            int cost=i.second;
            if(d[u]>d[v]+cost)
            {
                if(d[u]!=intmax) q.erase(q.find({d[u],u}));
                d[u]=d[v]+cost;
                q.insert({d[u],u});
            }
        }

    }
    q.clear();

}

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int test,t1,t2,t3,t4,t5;
   test=1;

   while(test--)
   {
        sd(n);
        sd(m);
        sd(t1);
        sd(t2);
        while(m--)
        {

            sd(t3);
            sd(t4);
            sd(t5);
            adj[t3].push_back({t4,t5});
            adj[t4].push_back({t3,t5});
        }
        for(int i=1;i<=n;i++)
        {
            sd(t3);
            sd(t4);
            rec[i]={t3,t4};
        }
        for(int i=1;i<=n;i++)
        {
            root=i;
            cost=rec[i].second;
            for(int j=1;j<=n;j++) hash_[j]=-1;
            dfs(i,rec[i].first);
            //cout<<endl;
        }

        /*for(int i=1;i<=n;i++)
        {
            cout<<i<<"++";
            for(auto v:adj2[i]) cout<<v.first<<"=>"<<v.second<<" ";
            cout<<endl;
        }
        */
        //cout<<t2;

        dijkastra(t1,t2);
        if(d[t2]==intmax) cout<<"-1"<<endl;
        else cout<<d[t2]<<endl;

   }
   return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<map>
#include<list>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>

#define mod 1000000007
#define sd(x) scanf("%d",&x)
#define pd(x) printf("%d",x)
#define ll long long
#define no_nodes 10002
using namespace std;
ll power(ll b,ll exp,ll m) {ll ans=1; b%=m; while(exp){if(exp&1) ans=(ans*b)%m; exp>>=1; b=(b*b)%m; } return ans; }
const int intmax=1000000009;

vector< vector<pair<int,int> > > adj(no_nodes);              //graph
vector< vector<pair<int,int> > >adj2(no_nodes);
vector<pair<int,int > > rec(no_nodes);
vector<int> hash_(no_nodes);
vector<ll> d(no_nodes,intmax);

int n,m;

int cost,root;
void dfs(int node,int dist)
{

    if(dist<0) return;
    hash_[node]=dist;
    //cout<<node<<" "<<dist<<" "<<cost<<endl;
    if(dist>=0&&node!=root)
    {
        adj2[root].push_back({node,cost});
    }
    for(auto i:adj[node])
    {

        int u=i.first;
        int cost1=i.second;
        if(hash_[u]>dist-cost1) continue;
        int cost=i.second;
        dfs(u,dist-cost1);
    }
}

void dijkastra(int node,int fnode)
{

    set<pair<ll,int> > q;
    q.insert({0,node});
    d[node]=0;
    while(!q.empty())
    {
        auto i=q.begin();
        int v=i->second;
        if(v==fnode) break;
        q.erase(i);
        for(auto i:adj2[v])
        {
            int u=i.first;
            int cost=i.second;
            if(d[u]>d[v]+cost)
            {
                if(d[u]!=intmax) q.erase(q.find({d[u],u}));
                d[u]=d[v]+cost;
                q.insert({d[u],u});
            }
        }

    }
    q.clear();

}

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int test,t1,t2,t3,t4,t5;
   test=1;

   while(test--)
   {
        sd(n);
        sd(m);
        sd(t1);
        sd(t2);
        while(m--)
        {

            sd(t3);
            sd(t4);
            sd(t5);
            adj[t3].push_back({t4,t5});
            adj[t4].push_back({t3,t5});
        }
        for(int i=1;i<=n;i++)
        {
            sd(t3);
            sd(t4);
            rec[i]={t3,t4};
        }
        for(int i=1;i<=n;i++)
        {
            root=i;
            cost=rec[i].second;
            for(int j=1;j<=n;j++) hash_[j]=-1;
            dfs(i,rec[i].first);
            //cout<<endl;
        }

        /*for(int i=1;i<=n;i++)
        {
            cout<<i<<"++";
            for(auto v:adj2[i]) cout<<v.first<<"=>"<<v.second<<" ";
            cout<<endl;
        }
        */
        //cout<<t2;

        dijkastra(t1,t2);
        if(d[t2]==intmax) cout<<"-1"<<endl;
        else cout<<d[t2]<<endl;

   }
   return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<map>
#include<list>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>

#define mod 1000000007
#define sd(x) scanf("%d",&x)
#define pd(x) printf("%d",x)
#define ll long long
#define no_nodes 10002
using namespace std;
ll power(ll b,ll exp,ll m) {ll ans=1; b%=m; while(exp){if(exp&1) ans=(ans*b)%m; exp>>=1; b=(b*b)%m; } return ans; }
const ll intmax=100000000000015;

vector< vector<pair<int,int> > > adj(no_nodes);              //graph
vector< vector<pair<int,int> > >adj2(no_nodes);
vector<pair<int,int > > rec(no_nodes);
vector<int> hash_(no_nodes);
vector<ll> d(no_nodes,intmax);

int n,m;

int cost,root;
void dfs(int node,int dist)
{

    if(dist<0) return;
    if(dist>=0&&node!=root&&hash_[node]==-1)
    {
        adj2[root].push_back({node,cost});
    }
    hash_[node]=dist;
    //cout<<node<<" "<<dist<<" "<<cost<<endl;

    for(auto i:adj[node])
    {

        int u=i.first;
        int cost1=i.second;
        if(hash_[u]>dist-cost1) continue;
        int cost=i.second;
        dfs(u,dist-cost1);
    }
}

void dijkastra(int node,int fnode)
{

    set<pair<ll,int> > q;
    q.insert({0,node});
    d[node]=0;
    while(!q.empty())
    {
        auto i=q.begin();
        int v=i->second;
        if(v==fnode) break;
        q.erase(i);
        for(auto i:adj2[v])
        {
            int u=i.first;
            int cost=i.second;
            if(d[u]>d[v]+cost)
            {
                if(d[u]!=intmax) q.erase(q.find({d[u],u}));
                d[u]=d[v]+cost;
                q.insert({d[u],u});
            }
        }

    }
    q.clear();

}

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int test,t1,t2,t3,t4,t5;
   test=1;

   while(test--)
   {
        sd(n);
        sd(m);
        sd(t1);
        sd(t2);
        while(m--)
        {

            sd(t3);
            sd(t4);
            sd(t5);
            adj[t3].push_back({t4,t5});
            adj[t4].push_back({t3,t5});
        }
        for(int i=1;i<=n;i++)
        {
            sd(t3);
            sd(t4);
            rec[i]={t3,t4};
        }
        for(int i=1;i<=n;i++)
        {
            root=i;
            cost=rec[i].second;
            for(int j=1;j<=n;j++) hash_[j]=-1;
            dfs(i,rec[i].first);
            //cout<<endl;
        }

        /*for(int i=1;i<=n;i++)
        {
            cout<<i<<"++";
            for(auto v:adj2[i]) cout<<v.first<<"=>"<<v.second<<" ";
            cout<<endl;
        }
        */
        //cout<<t2;

        dijkastra(t1,t2);
        if(d[t2]==intmax) cout<<"-1"<<endl;
        else cout<<d[t2]<<endl;

   }
   return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<map>
#include<list>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>

#define mod 1000000007
#define sd(x) scanf("%d",&x)
#define sl(x) scanf("%lld",&x)
#define pd(x) printf("%d",x)
#define ll long long
#define no_nodes 10002
using namespace std;
ll power(ll b,ll exp,ll m) {ll ans=1; b%=m; while(exp){if(exp&1) ans=(ans*b)%m; exp>>=1; b=(b*b)%m; } return ans; }
const int intmax=1000000009;

vector< vector<pair<int,int> > > adj(no_nodes);              //graph
vector< vector<pair<int,int> > >adj2(no_nodes);
vector<pair<int,int > > rec(no_nodes);
vector<int> hash_(no_nodes);
vector<ll> d(no_nodes,intmax);

int n,m;

int cost,root;
void dfs(int node,int dist)
{

    if(dist<0) return;
    hash_[node]=dist;
    //cout<<node<<" "<<dist<<" "<<cost<<endl;
    if(dist>=0&&node!=root)
    {
        adj2[root].push_back({node,cost});
    }
    for(auto i:adj[node])
    {

        int u=i.first;
        int cost1=i.second;
        if(hash_[u]>dist-cost1) continue;
        int cost=i.second;
        dfs(u,dist-cost1);
    }
}

void dijkastra(int node,int fnode)
{

    set<pair<ll,int> > q;
    q.insert({0,node});
    d[node]=0;
    while(!q.empty())
    {
        auto i=q.begin();
        int v=i->second;
        if(v==fnode) break;
        q.erase(i);
        for(auto i:adj2[v])
        {
            int u=i.first;
            int cost=i.second;
            if(d[u]>d[v]+cost)
            {
                if(d[u]!=intmax) q.erase(q.find({d[u],u}));
                d[u]=d[v]+cost;
                q.insert({d[u],u});
            }
        }

    }
    q.clear();

}

int main()
{
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   int test,t1,t2,t3,t4,t5;
   test=1;

   while(test--)
   {
        sd(n);
        sd(m);
        sd(t1);
        sd(t2);
        while(m--)
        {

            sd(t3);
            sd(t4);
            sd(t5);
            adj[t3].push_back({t4,t5});
            adj[t4].push_back({t3,t5});
        }
        for(int i=1;i<=n;i++)
        {
            sd(t3);
            sd(t4);
            rec[i]={t3,t4};
        }
        for(int i=1;i<=n;i++)
        {
            root=i;
            cost=rec[i].second;
            for(int j=1;j<=n;j++) hash_[j]=-1;
            dfs(i,rec[i].first);
            //cout<<endl;
        }

        /*for(int i=1;i<=n;i++)
        {
            cout<<i<<"++";
            for(auto v:adj2[i]) cout<<v.first<<"=>"<<v.second<<" ";
            cout<<endl;
        }
        */
        //cout<<t2;

        dijkastra(t1,t2);
        if(d[t2]==intmax) cout<<"-1"<<endl;
        else cout<<d[t2]<<endl;

   }
   return 0;
}


//ITNOG
#include<bits/stdc++.h>

using namespace std;
#define int long long
const int maxN = 1000 + 10;
const int mod = 1000*1000*1000 + 7;
int dis[maxN][maxN];
vector< pair<int, int> > a[maxN];
vector< pair<int, int> > ad[maxN];
int n, m;
int di[maxN];

void dij1()
{

    for(int i = 0; i < n; i ++)
    {
	  set< pair<int, int> > s;
	  fill(dis[i], dis[i] + n, 1000 * mod);
	  dis[i][i] = 0;
	  for(int j = 0; j < n; j ++) s.insert(make_pair(dis[i][j], j));

	  while(s.size())
	  {
		auto x = *s.begin(); s.erase(x);
		int v = x.second;
		for(auto u : a[v])
		{
		    if(dis[i][u.first] > x.first + u.second)
		    {
			  s.erase(make_pair(dis[i][u.first], u.first));
			  dis[i][u.first] = x.first + u.second;
			  s.insert(make_pair(dis[i][u.first], u.first));
		    }
		}
	  }
    }
}

main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    int st, e; cin >> st >> e; st --; e --;
    for(int i = 0; i < m; i ++)
    {
	  int v, u, w; cin >> v >> u >> w; v --; u --;
	  a[v].push_back(make_pair(u, w));
	  a[u].push_back(make_pair(v, w));
    }

    dij1();

    for(int i = 0; i < n; i ++)
    {
	  int t, c; cin >> t >> c;
	  for(int j = 0; j < n; j ++)
		if(dis[i][j] <= t)
		    ad[i].push_back(make_pair(j, c));
    }

    fill(di, di + n, 1000*mod);

    di[st] = 0;
    set < pair<int , int> > s;
    for(int i = 0; i < n; i ++)
	  s.insert(make_pair(di[i], i));

    while(s.size())
    {
	  auto x = *s.begin(); s.erase(x);
	  int v = x.second;
	  for(auto u : ad[v])
	  {
		if(di[u.first] > x.first + u.second)
		{
		    s.erase(make_pair(di[u.first], u.first));
		    di[u.first] = x.first + u.second;
		    s.insert(make_pair(di[u.first], u.first));
		}
	  }
    }

    if(di[e] == 1000*mod) cout << -1 << endl;
    else cout << di[e] << endl;
    return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <set>

#define InTheNameOfGod ios_base::sync_with_stdio(0);cin.tie(0);
#define rep(x,y) for (int x = 0; x < y; x++)
#define ff first
#define m0(x) memset(x,0,sizeof x)
#define ss second
#define mp make_pair
#define N 1007
#define inf 1e18

using namespace std;
typedef long long ll;

int n,m,fir,sec;
vector<pair<ll,ll> > v[N], a[N];
ll t[N], c[N], dis[N][N], val[N];

void dij(int x, ll *d)
{
    set<pair<ll,ll> > s;
    rep(i,n)
        d[i] = ((i == x)?0:inf);
    s.insert(mp(0,x));
    while (!s.empty())
    {
        pair<ll,ll> o = *s.begin();
        s.erase(s.begin());
        rep(i,a[o.ss].size())
        {
            ll vali = a[o.ss][i].ss;
            ll p = a[o.ss][i].ff;
            if (d[p] > d[o.ss] + vali)
            {
                if(d[p] != inf)
                    s.erase(s.find(mp(d[p], p)));
                d[p] = d[o.ss] + vali;
                s.insert(mp(d[p],p));
            }
        }
    }
}

void SoLvE(ll *d)
{
    ll x = fir;
    set<pair<ll,ll> > s;
    rep(i,n)
        d[i] = ((i == x)?0:inf);
    s.insert(mp(0,x));
    while (!s.empty())
    {
        pair<ll,ll> o = *s.begin();
        s.erase(s.begin());
        rep(i,v[o.ss].size())
        {
            ll vali = v[o.ss][i].ss;
            ll p = v[o.ss][i].ff;
            if (d[p] > d[o.ss] + vali)
            {
                if(d[p] != inf)
                    s.erase(s.find(mp(d[p], p)));
                d[p] = d[o.ss] + vali;
                s.insert(mp(d[p],p));
            }
        }
    }
    if(d[sec] == inf)
        cout << -1;
    else
        cout << d[sec];
}

int main()
{
    InTheNameOfGod

    cin >> n >> m >> fir >> sec;
    fir--,sec--;
    rep(i,m)
    {
        int x,y,z; cin >> x >> y >> z;
        x--, y--;
        a[x].push_back(mp(y,z));
        a[y].push_back(mp(x,z));
    }
    rep(i,n) cin >> t[i] >> c[i];
    rep(i,n)
    {
        dij(i,dis[i]);
        rep(j,n)
            if (dis[i][j] <= t[i])
                v[i].push_back(mp(j,c[i]));
    }
    //rep(i,n) { rep(j,n) cout << dis[i][j] << ' '; cout << endl;}
    SoLvE(val);
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <set>

#define InTheNameOfGod ios_base::sync_with_stdio(0);cin.tie(0);
#define rep(x,y) for (int x = 0; x < y; x++)
#define ff first
#define m0(x) memset(x,0,sizeof x)
#define ss second
#define mp make_pair
#define N 1007
#define inf 1e18

using namespace std;
typedef long long ll;

int n,m,fir,sec;
vector<pair<ll,ll> > v[N], a[N];
ll t[N], c[N], dis[N][N], val[N];

void dij(int x, ll *d)
{
    set<pair<ll,ll> > s;
    rep(i,n)
        d[i] = ((i == x)?0:inf);
    s.insert(mp(0,x));
    while (!s.empty())
    {
        pair<ll,ll> o = *s.begin();
        s.erase(s.begin());
        rep(i,a[o.ss].size())
        {
            ll vali = a[o.ss][i].ss;
            ll p = a[o.ss][i].ff;
            if (d[p] > d[o.ss] + vali)
            {
                if(d[p] != inf)
                    s.erase(s.find(mp(d[p], p)));
                d[p] = d[o.ss] + vali;
                s.insert(mp(d[p],p));
            }
        }
    }
}

ll SoLvE(ll *d)
{
    ll x = fir;
    set<pair<ll,ll> > s;
    rep(i,n)
        d[i] = ((i == x)?0:inf);
    s.insert(mp(0,x));
    while (!s.empty())
    {
        pair<ll,ll> o = *s.begin();
        s.erase(s.begin());
        rep(i,v[o.ss].size())
        {
            ll vali = v[o.ss][i].ss;
            ll p = v[o.ss][i].ff;
            if (d[p] > d[o.ss] + vali)
            {
                if(d[p] != inf)
                    s.erase(s.find(mp(d[p], p)));
                d[p] = d[o.ss] + vali;
                s.insert(mp(d[p],p));
            }
        }
    }
    return d[sec];
}

int main()
{
    InTheNameOfGod

    cin >> n >> m >> fir >> sec;
    fir--,sec--;
    rep(i,m)
    {
        int x,y,z; cin >> x >> y >> z;
        x--, y--;
        a[x].push_back(mp(y,z));
        a[y].push_back(mp(x,z));
    }
    rep(i,n) cin >> t[i] >> c[i];
    rep(i,n)
    {
        dij(i,dis[i]);
        rep(j,n)
            if (dis[i][j] <= t[i])
                v[i].push_back(mp(j,c[i]));
    }
    //rep(i,n) { rep(j,n) cout << dis[i][j] << ' '; cout << endl;}
    cout << SoLvE(val);
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <tuple>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cctype>
using namespace std;
typedef long long LL;

typedef int vert;
typedef LL  dist;
typedef pair<vert, dist> edge;
typedef vector<edge> edges;
typedef vector<edges> graph;
typedef LL  cost;

void dijkstra(graph& g, vert s, graph& gg, LL tMax, LL theCost)
{
	priority_queue<pair<LL,vert>, vector<pair<LL,vert>>, greater<pair<LL,vert>>> Q;
	vector<bool> vis(g.size());
	Q.push( make_pair(0,s) );
	while( !Q.empty() )
	{
		vert v = Q.top().second;
		LL c = Q.top().first;
		Q.pop();
		if( vis[v] )
			continue;
		vis[v] = true;

		if( tMax < c )
			return;
		if( v != s )
			gg[s].emplace_back(v,theCost);

		for(auto e : g[v])
			if( !vis[e.first] )
				Q.push( make_pair(e.second+c, e.first) );
	}
}

LL dijkstra(graph& g, vert s, vert e)
{
	priority_queue<pair<LL,vert>, vector<pair<LL,vert>>, greater<pair<LL,vert>>> Q;
	vector<bool> vis(g.size());
	Q.push( make_pair(0,s) );
	while( !Q.empty() )
	{
		vert v = Q.top().second;
		LL c = Q.top().first;
		Q.pop();
		if( vis[v] )
			continue;
		vis[v] = true;

		if( v == e )
			return c;

		for(auto e : g[v])
			if( !vis[e.first] )
				Q.push( make_pair(e.second+c, e.first) );
	}
	return -1;
}

int main()
{
	int nV, nE;
	while( cin >> nV >> nE )
	{
		vert vs, ve;
		cin >> vs >> ve;
		--vs, --ve;

		graph g(nV);
		for(int i=0; i<nE; ++i)
		{
			vert u, v;
			LL w;
			cin >> u >> v >> w;
			--u, --v;
			g[u].emplace_back(v,w);
			g[v].emplace_back(u,w);
		}

		graph gg(nV);
		for(int i=0; i<nV; ++i)
		{
			LL t, c;
			cin >> t >> c;
			dijkstra(g, i, gg, t, c);
		}

		cout << dijkstra(gg, vs, ve) << endl;
	}
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <tuple>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cctype>
using namespace std;
typedef long long LL;

template<typename T>
class IdGen
{
	map<T, int> v2id_;
	vector<T>   id2v_;
public:
	int v2id(const T& v) {
		if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); }
		return v2id_[v];
	}
	const T& id2v(int i) const { return id2v_[i]; }
	int size() const { return id2v_.size(); }
};

template<typename Vert, typename Cost>
class Dijkstra
{
	IdGen<Vert> idgen;

	typedef pair<Cost,int> Edge;
	typedef vector<Edge>   Edges;
	typedef vector<Edges>  Graph;
	Graph G;

public:
	void addEdge( Vert s_, Vert t_, Cost c )
	{
		int s = idgen.v2id(s_), t = idgen.v2id(t_);
		if( max(s,t) >= G.size() ) G.resize(max(s,t)+1);
		G[s].push_back(Edge(c, t));
	}

	Cost calc( Vert s_, Vert t_ )
	{
		int s = idgen.v2id(s_), t = idgen.v2id(t_);
		if( max(s,t) >= G.size() ) G.resize(max(s,t)+1);

		priority_queue< Edge, vector<Edge>, greater<Edge> > Q;
		Q.push( Edge(0,s) );
		vector<bool> visited(G.size());
		while( !Q.empty() )
		{
			int  v = Q.top().second;
			Cost c = Q.top().first;
			Q.pop();
			if( visited[v] )
				continue;
			visited[v] = true;

			if( v == t )
				return c;

			for(int i=0; i<G[v].size(); ++i)
				if( !visited[G[v][i].second] )
					Q.push( make_pair(G[v][i].first+c, G[v][i].second) );
		}
		return -1;
	}
};

typedef int vert;
typedef LL cost;
typedef pair<vert,cost> edge;
typedef vector<edge> edges;
typedef vector<edges> graph;

void dijkstra(graph& g, vert s, Dijkstra<int,LL>& gg, LL tMax, LL theCost)
{
	priority_queue<pair<LL,vert>, vector<pair<LL,vert>>, greater<pair<LL,vert>>> Q;
	vector<bool> vis(g.size());
	Q.push( make_pair(0,s) );
	while( !Q.empty() )
	{
		vert v = Q.top().second;
		LL c = Q.top().first;
		Q.pop();
		if( vis[v] )
			continue;
		vis[v] = true;

		if( tMax < c )
			return;
		if( v != s )
			gg.addEdge(s, v, theCost);

		for(auto e : g[v])
			if( !vis[e.first] )
				Q.push( make_pair(e.second+c, e.first) );
	}
}

int main()
{
	int nV, nE;
	while( cin >> nV >> nE )
	{
		int vs, ve;
		cin >> vs >> ve;

		graph g(nV+1);
		for(int i=0; i<nE; ++i)
		{
			int u, v;
			LL w;
			cin >> u >> v >> w;
			g[u].emplace_back(v,w);
			g[v].emplace_back(u,w);
		}

		Dijkstra<int,LL> dij;
		for(int i=1; i<=nV; ++i)
		{
			LL t, c;
			cin >> t >> c;
			dijkstra(g, i, dij, t, c);
		}

		cout << dij.calc(vs, ve) << endl;
	}
}


	//		- -- --- ---- -----be name khoda----- ---- --- -- -		\\

#include <bits/stdc++.h>

using namespace std;

const int N = 2002;
const long long INF = 1e17;

vector <pair<int, int>> g[N], h[N];
int n, m, c[N], t[N];
long long d[N];

struct cmp{
	bool operator()(int l, int r) { return (d[l] != d[r] ? d[l] < d[r] : l < r); }
};
set <int, cmp> s;

void dj(int st, bool chi)
{
	fill(d, d + n, INF);
	d[st] = 0;
	for(int i = 0; i < n; i++)
		s.insert(i);
	while(s.size())
	{
		int v = *s.begin();
		s.erase(s.begin());
		vector <pair<int, int>> &neis = (chi ? g[v] : h[v]);
		for(auto e : neis)
		{
			int u = e.first;
			int w = e.second;
			if(d[v] + w < d[u])
			{
				s.erase(u);
				d[u] = d[v] + w;
				s.insert(u);
			}
		}
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;
	int s, e;
	cin >> s >> e;
	s--;
	e--;
	while(m--)
	{
		int l, r, w;
		cin >> l >> r >> w;
		l--;
		r--;
		g[l].push_back(make_pair(r, w));
		g[r].push_back(make_pair(l, w));
	}
	for(int i = 0; i < n; i++)
		cin >> t[i] >> c[i];

	for(int i = 0; i < n; i++)
	{
		dj(i, 1);
		for(int j = 0; j < n; j++)
			if(i != j)
				if(d[j] <= t[i])
					h[i].push_back(make_pair(j, c[i]));
	}
	dj(s, 0);
	if(d[e] == INF)
		cout << "-1\n";
	else
		cout << d[e] << endl;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
#include <bitset>
//#include <map>
#include <set>
#include <stdlib.h>
#include <algorithm>
#define MAX 1000000000
using namespace std;

struct node
{
    long long x,len;
    friend bool operator <(node n1,node n2)
    {
        return n2.len<n1.len;
    }
};
long long n;
vector <node> map[1001];
long long t[1001];
long long c[1001];
bool mark[1001];
long long d[1001];
vector <node> go[1001];

void dfs(long long x,long long dist,long long up)
{
    mark[x]=true;
    long long i;
    for(i=0;i<map[x].size();i++)
    {
        if(mark[map[x][i].x])
            continue;
        if(dist+map[x][i].len>up)
            continue;
        dfs(map[x][i].x,dist+map[x][i].len,up);
    }
}

int main()
{
    node ss,tt;
    long long x,y,len,m,i,j,k;
    long long S,T;
    while(cin>>n>>m)
    {
        cin>>S>>T;
        for(i=1;i<=n;i++)
        {
            go[i].clear();
            map[i].clear();
        }
        while(m--)
        {
            cin>>x>>y>>len;
            ss.len=len;
            ss.x=x;
            map[y].push_back(ss);
            ss.x=y;
            map[x].push_back(ss);
        }

        for(i=1;i<=n;i++)
        {
            cin>>t[i]>>c[i];
        }
        for(i=1;i<=n;i++)
        {
            memset(mark,0,sizeof(mark));
            dfs(i,0,t[i]);
            for(j=1;j<=n;j++)
            {
                if(i==j)
                    continue;
                if(mark[j])
                {
                    ss.x=j;
                    ss.len=c[i];
                    go[i].push_back(ss);
                }
            }
        }
        /*
        for(i=1;i<=n;i++)
        {
            cout<<i<<" : ";
            for(j=0;j<go[i].size();j++)
                cout<<go[i][j].x<<" "<<go[i][j].len<<"  ";
            cout<<endl;
        }*/

        memset(d,-1,sizeof(d));
        d[S]=0;
        ss.x=S;
        ss.len=0;
        priority_queue <node> q;
        q.push(ss);

        while(!q.empty())
        {
            ss=q.top();
            q.pop();
            for(i=0;i<go[ss.x].size();i++)
            {
                tt.x=go[ss.x][i].x;
                tt.len=go[ss.x][i].len+ss.len;
                if(d[tt.x]==-1||tt.len<d[tt.x])
                {
                    d[tt.x]=tt.len;
                    q.push(tt);
                }
            }

        }
        cout<<d[T]<<endl;

    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
#include <bitset>
//#include <map>
#include <set>
#include <stdlib.h>
#include <algorithm>
#define MAX 1000000000
using namespace std;

struct node
{
    long long x,len;
    friend bool operator <(node n1,node n2)
    {
        return n2.len<n1.len;
    }
};
long long n;
vector <node> map[1001];
long long t[1001];
long long c[1001];
bool mark[1001];
long long d[1001];
long long D[1001][1001];
vector <node> go[1001];

int main()
{
    node ss,tt;
    long long x,y,len,m,i,j,k;
    long long S,T;
    while(cin>>n>>m)
    {
        cin>>S>>T;
        for(i=1;i<=n;i++)
        {
            go[i].clear();
            map[i].clear();
        }
        while(m--)
        {
            cin>>x>>y>>len;
            ss.len=len;
            ss.x=x;
            map[y].push_back(ss);
            ss.x=y;
            map[x].push_back(ss);
        }

        for(i=1;i<=n;i++)
        {
            cin>>t[i]>>c[i];
        }
        memset(D,-1,sizeof(D));
        for(i=1;i<=n;i++)
        {
            D[i][i]=0;
            ss.x=i;
            ss.len=0;
            priority_queue <node> q;
            q.push(ss);
            while(!q.empty())
            {
                ss=q.top();
                q.pop();
                //cout<<ss.x<<" "<<ss.len<<endl;
                for(j=0;j<map[ss.x].size();j++)
                {
                    tt.x=map[ss.x][j].x;
                    tt.len=ss.len+map[ss.x][j].len;
                    //cout<<tt.x<<" "<<tt.len<<" "<<D[i][tt.x]<<endl;
                    if(D[i][tt.x]==-1||tt.len<D[i][tt.x])
                    {
                        D[i][tt.x]=tt.len;
                        q.push(tt);
                    }
                }

            }

            for(j=1;j<=n;j++)
            {
                if(i==j)
                    continue;
                if(D[i][j]>=0&&D[i][j]<=t[i])
                {
                    ss.x=j;
                    ss.len=c[i];
                    go[i].push_back(ss);

                }
            }

        }
        /*
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
                cout<<D[i][j]<<" ";
            cout<<endl;
        }
        for(i=1;i<=n;i++)
        {
            cout<<i<<" : ";
            for(j=0;j<go[i].size();j++)
                cout<<go[i][j].x<<" "<<go[i][j].len<<"  ";
            cout<<endl;
        }*/

        memset(d,-1,sizeof(d));
        d[S]=0;
        ss.x=S;
        ss.len=0;
        priority_queue <node> q;
        q.push(ss);

        while(!q.empty())
        {
            ss=q.top();
            q.pop();
            for(i=0;i<go[ss.x].size();i++)
            {
                tt.x=go[ss.x][i].x;
                tt.len=go[ss.x][i].len+ss.len;
                if(d[tt.x]==-1||tt.len<d[tt.x])
                {
                    d[tt.x]=tt.len;
                    q.push(tt);
                }
            }

        }
        cout<<d[T]<<endl;

    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    char let = 'a';
    string ans(n+1,'$');
    int mx2 = -1;
    int letUsed=-1;
    while(i <= n) {
        int j = i;
        int cnt1 = 0;
        while(j <= n) {
            if(seen[perm1[j]] == 1) --cnt1;
            if(seen[perm2[j]] == 1) --cnt1;
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) ++cnt1;
            if(seen[perm2[j]] == 1) ++cnt1;
            ++j;
            if(cnt1 == 0) break;
        }
        for(int k = i; k < j; ++k) ans[perm1[k]] = let;
        letUsed=let-'a';
        if(let != 'z') ++let;
        i = j;
    }
    if(letUsed+1 >= k) {
        cout << "YES\n";
        for(int i = 1; i <= n; ++i) {
            cout << ans[i];
        }
        cout << endl;
    } else {
        cout << "NO\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    char let = 'a';
    string ans(n,'$');
    int mx2 = -1;
    while(i <= n) {
        int j = i;
        int cnt1 = 0;
        while(j <= n) {
            if(seen[perm1[j]] == 1) --cnt1;
            if(seen[perm2[j]] == 1) --cnt1;
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) ++cnt1;
            if(seen[perm2[j]] == 1) ++cnt1;
            if(seen[perm1[j]] == 2) mx2 = max(mx2, perm1[j]);
            if(seen[perm2[j]] == 2) mx2 = max(mx2, perm2[j]);
            ++j;
            if(cnt1 == 0) break;
        }
        for(int k = i; k < j; ++k) ans[perm1[k]] = let;
        if(let != 'z') ++let;
        i = j;
    }
    if(let-'a' >= k-1) {
        cout << "YES\n";
        for(int i = 1; i <= n; ++i) {
            cout << ans[i];
        }
        cout << endl;
    } else {
        cout << "NO\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    char let = 'a';
    string ans(n+1,'$');
    int mx2 = -1;
    while(i <= n) {
        int j = i;
        int cnt1 = 0;
        while(j <= n) {
            if(seen[perm1[j]] == 1) --cnt1;
            if(seen[perm2[j]] == 1) --cnt1;
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) ++cnt1;
            if(seen[perm2[j]] == 1) ++cnt1;
            ++j;
            if(cnt1 == 0) break;
        }
        for(int k = i; k < j; ++k) ans[perm1[k]] = let;
        if(let != 'z') ++let;
        i = j;
    }
    if(let-'a' >= k) {
        cout << "YES\n";
        for(int i = 1; i <= n; ++i) {
            cout << ans[i];
        }
        cout << endl;
    } else {
        cout << "NO\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    char let = 'a';
    string ans(n+1,'$');
    int mx2 = -1;
    while(i <= n) {
        int j = i;
        int cnt1 = 0;
        while(j <= n) {
            if(seen[perm1[j]] == 1) --cnt1;
            if(seen[perm2[j]] == 1) --cnt1;
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) ++cnt1;
            if(seen[perm2[j]] == 1) ++cnt1;
            ++j;
            if(cnt1 == 0) break;
        }
        for(int k = i; k < j; ++k) ans[perm1[k]] = let;
        if(let != 'z') ++let;
        i = j;
    }
    if(let-'a'+1 >= k) {
        cout << "YES\n";
        for(int i = 1; i <= n; ++i) {
            cout << ans[i];
        }
        cout << endl;
    } else {
        cout << "NO\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    char let = 'a';
    string ans(n,'$');
    int mx2 = -1;
    while(i <= n) {
        int j = i;
        int cnt1 = 0;
        while(j <= n) {
            if(seen[perm1[j]] == 1) --cnt1;
            if(seen[perm2[j]] == 1) --cnt1;
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) ++cnt1;
            if(seen[perm2[j]] == 1) ++cnt1;
            if(seen[perm1[j]] == 2) mx2 = max(mx2, perm1[j]);
            if(seen[perm2[j]] == 2) mx2 = max(mx2, perm2[j]);
            ++j;
            if(cnt1 == 0) break;
        }
        for(int k = i; k < j; ++k) ans[k] = let;
        if(let != 'z') ++let;
        i = j;
    }
    if(ans.back()-'a' >= k-1) {
        cout << "YES\n";
        for(int i = 1; i <= n; ++i) {
            cout << ans[i];
        }
        cout << endl;
    } else {
        cout << "NO\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    char let = 'a';
    string ans(n,'$');
    int mx2 = -1;
    while(i <= n) {
        int j = i;
        int cnt1 = 0;
        while(j <= n) {
            if(seen[perm1[j]] == 1) --cnt1;
            if(seen[perm2[j]] == 1) --cnt1;
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) ++cnt1;
            if(seen[perm2[j]] == 1) ++cnt1;

            if(seen[perm1[j]] == 2) mx2 = max(mx2, perm1[j]);
            if(seen[perm2[j]] == 2) mx2 = max(mx2, perm2[j]);

            ++j;
            if(cnt1 == 0 && j-1 == mx2) break;
        }
        for(int k = i; k < j; ++k) ans[k] = let;
        if(let != 'z') ++let;
        i = j;
    }
    if(ans.back()-'a' >= k-1) {
        cout << "YES\n";
        for(int i = 1; i <= n; ++i) {
            cout << ans[i];
        }
        cout << endl;
    } else {
        cout << "NO\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    char let = 'a';
    string ans(n,'$');
    while(i <= n) {
        //cout << "here, i: " << i << endl;
        int j = i;
        int cnt1 = 0;
        while(j <= n) {
            if(seen[perm1[j]] == 1) {
                --cnt1;
            }
            if(seen[perm2[j]] == 1) {
                --cnt1;
            }
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) {
                ++cnt1;
            }
            if(seen[perm2[j]] == 1) {
                ++cnt1;
            }
            ++j;
            if(cnt1 == 0) break;
        }
        for(int k = i; k < j; ++k) ans[k] = let;
        if(let != 'z') ++let;
        i = j;
    }
    if(ans.back()-'a' >= k-1) {
        cout << "YES\n";
        for(int i = 1; i <= n; ++i) {
            cout << ans[i];
        }
        cout << endl;
    } else {
        cout << "NO\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;

struct range {
    int i,j,mn,mx;
};

bool cmp(const range &i, const range &j) {
    return i.mn < j.mn;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    vector<range> ranges;
    while(i <= n) {
        int j = i;
        int cnt1 = 0;
        int mx2 = -1;
        int mn2 = n+2;
        while(j <= n) {
            if(seen[perm1[j]] == 1) --cnt1;
            if(seen[perm2[j]] == 1) --cnt1;
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) ++cnt1;
            if(seen[perm2[j]] == 1) ++cnt1;

            if(seen[perm1[j]] == 2) {
                mx2 = max(mx2, perm1[j]);
                mn2 = min(mn2, perm1[j]);
            }
            if(seen[perm2[j]] == 2) {
                mx2 = max(mx2, perm2[j]);
                mn2 = min(mn2, perm2[j]);
            }

            ++j;
            if(cnt1 == 0 && mx2-mn2+1 == j-i) break;
        }
        ranges.push_back({i,j,mn2,mx2});
        i = j;
    }
    if((int)ranges.size() < k) {
        cout << "NO\n";
        return 0;
    }
    sort(ranges.begin(), ranges.end(), cmp);
    char let = 'a';
    string ans(n,'$');
    for(auto &r : ranges) {
        //cout << "range: " << r.i << ' ' << r.j << ' ' << r.mn << ' ' << r.mx << endl;
        for(int i = r.i; i < r.j; ++i) {
            ans[i-1] = let;
        }
        if(let != 'z') ++let;
    }
    cout << "YES\n";
    cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    vector<int> perm1(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm1[i];
    }
    vector<int> perm2(n+1);
    for(int i = 1; i <= n; ++i) {
        cin >> perm2[i];
    }
    vector<int> seen(n+1,0);
    int i = 1;
    char let = 'a';
    string ans(n,'$');
    int mx2 = -1;
    while(i <= n) {
        int j = i;
        int cnt1 = 0;
        while(j <= n) {
            if(seen[perm1[j]] == 1) --cnt1;
            if(seen[perm2[j]] == 1) --cnt1;
            ++seen[perm1[j]];
            ++seen[perm2[j]];
            if(seen[perm1[j]] == 1) ++cnt1;
            if(seen[perm2[j]] == 1) ++cnt1;

            if(seen[perm1[j]] == 2) mx2 = max(mx2, perm1[j]);
            if(seen[perm2[j]] == 2) mx2 = max(mx2, perm2[j]);

            ++j;
            if(cnt1 == 0) break;
        }
        for(int k = i; k < j; ++k) ans[k] = let;
        if(let != 'z') ++let;
        i = j;
    }
    if(ans.back()-'a' >= k-1) {
        cout << "YES\n";
        for(int i = 1; i <= n; ++i) {
            cout << ans[i];
        }
        cout << endl;
    } else {
        cout << "NO\n";
    }
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  char ch = 'a';
  int j = 0;
  FOR(i, 0, n) {
    if (done[p[i]]) continue;
    res[p[i]] = ch;
    done[p[i]] = true;
    while (j < n and q[j] != p[i]) {
      //cerr << q[j] << " " << p[i] << "\n";
      res[q[j]] = ch;
      done[q[j]] = true;
      j++;
    }
    if (i == j) ch = min((char)(ch + 1), 'z');
    j++;
  }
  if (ch - 'a' + 1 < k) {
    //if (n == 200000 and k == 1) printf("ch = %c\n", ch);
    printf("NO\n");
  } else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  char ch = 'a';
  int j = 0;
  FOR(i, 0, n) {
    if (done[p[i]]) continue;
    res[p[i]] = ch;
    done[p[i]] = true;
    while (j < n and q[j] != p[i]) {
      //cerr << q[j] << " " << p[i] << "\n";
      res[q[j]] = ch;
      done[q[j]] = true;
      j++;
    }
    j++;
    ch++;
  }
  if (ch - 'a' + 1 < k) printf("NO\n");
  else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  char ch = 'a';
  int j = 0;
  FOR(i, 0, n) {
    if (done[p[i]]) continue;
    res[p[i]] = ch;
    done[p[i]] = true;
    while (j < n and q[j] != p[i]) {
      //cerr << q[j] << " " << p[i] << "\n";
      res[q[j]] = ch;
      done[q[j]] = true;
      j++;
    }
    if (i == j) ch++;
    j++;
  }
  if (ch - 'a' + 1 < k) {
    if (n == 200000) printf("ch = %c\n", ch);
    printf("NO\n");
  } else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  set<int> sP, sQ;
  int R;
  char ch = 'a';
  FOR(L, 0, n) {
    R = L;
    do {
      if (p[R] != q[R]) {
        if (sQ.count(p[R])) sQ.erase(p[R]);
        else sP.insert(p[R]);
        if (sP.count(q[R])) sP.erase(q[R]);
        else sQ.insert(q[R]);
      }
      R++;
    } while (sP.size());
    FOR(i, L, R) res[i] = ch;
    ch = min((char)(ch + 1), 'z');
    L = R - 1;
  }
  if (ch - 'a' + 1 < k) printf("NO\n");
  else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  set<int> sP, sQ;
  int R;
  char ch = 'a';
  FOR(L, 0, n) {
    R = L;
    do {
      if (p[R] != q[R]) {
        if (sQ.count(p[R])) sQ.erase(p[R]);
        else sP.insert(p[R]);
        if (sP.count(q[R])) sP.erase(q[R]);
        else sQ.insert(q[R]);
      }
      R++;
    } while (sP.size());
    FOR(i, L, R) res[p[i]] = ch;
    ch = min((char)(ch + 1), 'z');
    L = R - 1;
  }
  if (ch - 'a' + 1 < k) printf("NO\n");
  else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  set<int> sP, sQ;
  int R;
  char ch = 'a';
  int cnt = 0;
  FOR(L, 0, n) {
    R = L;
    do {
      if (p[R] != q[R]) {
        if (sQ.count(p[R])) sQ.erase(p[R]);
        else sP.insert(p[R]);
        if (sP.count(q[R])) sP.erase(q[R]);
        else sQ.insert(q[R]);
      }
      R++;
    } while (sP.size());
    FOR(i, L, R) res[p[i]] = ch;
    ch = min((char)(ch + 1), 'z');
    cnt++;
    L = R - 1;
  }
  if (cnt < k) printf("NO\n");
  else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  char ch = 'a';
  int j = 0;
  FOR(i, 0, n) {
    if (done[p[i]]) continue;
    res[p[i]] = ch;
    done[p[i]] = true;
    while (j < n and q[j] != p[i]) {
      //cerr << q[j] << " " << p[i] << "\n";
      res[q[j]] = ch;
      done[q[j]] = true;
      j++;
    }
    if (i == j) ch++;
    j++;
  }
  if (ch - 'a' + 1 < k) {
    if (n == 200000 and k == 1) printf("ch = %c\n", ch);
    printf("NO\n");
  } else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  char ch = 'a';
  int j = 0;
  FOR(i, 0, n) {
    if (done[p[i]]) continue;
    res[p[i]] = ch;
    done[p[i]] = true;
    while (j < n and q[j] != p[i]) {
      //cerr << q[j] << " " << p[i] << "\n";
      res[q[j]] = ch;
      done[q[j]] = true;
      j++;
    }
    if (i == j) ch++;
    j++;
  }
  if (ch - 'a' + 1 < k) printf("NO\n");
  else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  char ch = 'a';
  int j = 0;
  FOR(i, 0, n) {
    if (done[p[i]]) continue;
    res[p[i]] = ch;
    done[p[i]] = true;
    while (j < n and q[j] != p[i]) {
      //cerr << q[j] << " " << p[i] << "\n";
      res[q[j]] = ch;
      done[q[j]] = true;
      j++;
    }
    if (i == j) ch++;
    j++;
  }
  if (ch - 'a' + 1 < k) {
    printf("ch = %c\n", ch);
    printf("NO\n");
  } else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  set<int> sP, sQ;
  int R;
  char ch = 'a';
  FOR(L, 0, n) {
    R = L;
    do {
      if (p[R] != q[R]) {
        if (sQ.count(p[R])) sQ.erase(p[R]);
        else sP.insert(p[R]);
        if (sP.count(q[R])) sP.erase(q[R]);
        else sQ.insert(q[R]);
      }
      R++;
    } while (sP.size());
    FOR(i, L, R) res[i] = ch;
    ch++;
    L = R - 1;
  }
  if (ch - 'a' + 1 < k) printf("NO\n");
  else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


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

#define double long double
#define vec vector
#define pb push_back
#define unset unordered_set
#define ii pair<int, int>
#define X first
#define Y second
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define bitcount(n) __builtin_popcountll(n)
template <typename T,typename U>
std::pair<T,U> operator+(const std::pair<T,U> & l,const std::pair<T,U> & r) {
  return {l.first+r.first,l.second+r.second};
}
const long long ZERO = 0LL;
const long long INF64 = 1e18;
const int INF32 = 1e9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0L);
const double EPS = static_cast<double>(1e-9);
typedef long long ll;

int norm(int a) {
  return ((a % MOD) + MOD) % MOD;
}

int mul(int a, int b) {
  return int(a * 1LL * b % MOD);
}

int binPow(int a, int k) {
  int ans = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
  }
  return ans;
}

// If I need to find (x / a) % MOD, I need to use this function:
//    (x / a) % MOD = (x * inv(a)) % MOD
int inv(int a) {
  int b = binPow(a, MOD - 2);
  assert(mul(a, b) == 1);
  return b;
}

// Init variables here
const int N = 2e5 + 7;
int n, k, p[N], q[N];

void init() {
  //freopen("??.in", "r", stdin);
  //freopen("??.out", "w", stdout);
  scanf("%d %d", &n, &k);
  FOR(i, 0, n) {scanf("%d", &p[i]); p[i]--;}
  FOR(i, 0, n) {scanf("%d", &q[i]); q[i]--;}
}

char res[N];
bool done[N];

void solve() {
  char ch = 'a', end = 'a' + k - 1;
  int j = 0;
  FOR(i, 0, n) {
    if (done[p[i]]) continue;
    res[p[i]] = ch;
    done[p[i]] = true;
    while (j < n and q[j] != p[i]) {
      //cerr << q[j] << " " << p[i] << "\n";
      res[q[j]] = ch;
      done[q[j]] = true;
      j++;
    }
    if (i == j) ch = min((char)(ch + 1), end);
    j++;
  }
  if (ch - 'a' + 1 < k) {
    //if (n == 200000 and k == 1) printf("ch = %c\n", ch);
    printf("NO\n");
  } else {
    printf("YES\n");
    FOR(i, 0, n) printf("%c", res[i]);
    printf("\n");
  }
  // read the question correctly (is y a vowel?)
  // look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
}

int main() {
  //ios_base::sync_with_stdio(false); cin.tie();
  //auto beginProgram = chrono::steady_clock::now();
  //int t; scanf("%d", &t); while (t--)
  {
    init();
    solve();
  }
  //auto endProgram = chrono::steady_clock::now();

  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F(i,n) for(int i=0;i<n;i++)
#define F1(x,i,n) for(int i=x;i<n;i++)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define a(n) vector<ll> a(n)
#define mem(x,val) memset(x,val,sizeof(x))
#define mod 1000000007
#define in(a,n) F(i,n) cin>>a[i]
#define out(a,n); F(i,n) cout<<a[i]<<" "; cout<<endl;
#define f first
#define s second
vector<ll> par;
ll find(ll node){
	return par[node] = (par[node]==node)?node:find(par[node]);
}

int main()
{
 	cin.tie(NULL);
    ios_base::sync_with_stdio(false);
 	ll n,k; cin>>n>>k;
 	vector<ll> p(n),q(n);
 	par.resize(n+1);
 	in(p,n); in(q,n);
 	F(i,n) par[i+1] = i+1;
 	F(i,n){
 		ll x = find(p[i]);
 		ll y = find(q[i]);
 		if(x!=y){
 		    if(x>y) swap(x,y);
 			par[x] = y;
 		}
 	}
 	ll h[n]; F(i,n) h[p[i]] = i;
 	ll last = p[0];
 	ll idx = 0;
 	ll g = 0;
 	ll ans[n];
 	while(idx<n){
 		ll idx1 = h[find(p[idx])];
 		while(idx<idx1 && idx<n){
 			ans[idx] = g;
 			idx++;
 			idx1 = max(idx1,h[find(p[idx])]);
 		}
 		ans[idx] = g;
 		g++;
 		idx++;
 	}
 	if(g+1<k) return cout<<"NO",0;
 	cout<<"YES\n";
 	F(i,n) cout<<(char)(min(ans[i],25LL)+'a');
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F(i,n) for(int i=0;i<n;i++)
#define F1(x,i,n) for(int i=x;i<n;i++)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define a(n) vector<ll> a(n)
#define mem(x,val) memset(x,val,sizeof(x))
#define mod 1000000007
#define in(a,n) F(i,n) cin>>a[i]
#define out(a,n); F(i,n) cout<<a[i]<<" "; cout<<endl;
#define f first
#define s second
vector<ll> par;
ll find(ll node){
	return par[node] = (par[node]==node)?node:find(par[node]);
}

int main()
{
 	cin.tie(NULL);
    ios_base::sync_with_stdio(false);
 	ll n,k; cin>>n>>k;
 	vector<ll> p(n),q(n);
 	par.resize(n+1);
 	in(p,n); in(q,n);
 	F(i,n) par[i+1] = i+1;
 	F(i,n){
 		ll x = find(p[i]);
 		ll y = find(q[i]);
 		if(x!=y){
 		    if(x<y) swap(x,y);
 			par[x] = y;
 		}
 	}
 	// F(i,n) cout<<find(p[i])<<" \n"[i==n-1];
 	ll pl[n]; F(i,n) pl[i] = find(p[i]);
 	ll pk[n+1]; mem(pk,-1); for(ll i=n-1;i>=0;i--) if(pk[pl[i]]==-1) pk[pl[i]] = i;

 	ll idx = 0;
 	ll g = 0;
 	ll ans[n]; F(i,n) ans[i] = INT_MAX;
 	while(idx<n){
 		ll idx1 = pk[pl[idx]];
 		while(idx<idx1){
 			ans[p[idx]-1] = g;
 			idx++;
 			idx1 = max(idx1,pk[pl[idx]]);
 		}
 		ans[p[idx]-1] = g++; idx++;
 	}
 	if(g+1<k) return cout<<"NO",0;
 	cout<<"YES\n";
 	F(i,n) cout<<(char)(min(ans[i],25LL)+'a');
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F(i,n) for(int i=0;i<n;i++)
#define F1(x,i,n) for(int i=x;i<n;i++)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define a(n) vector<ll> a(n)
#define mem(x,val) memset(x,val,sizeof(x))
#define mod 1000000007
#define in(a,n) F(i,n) cin>>a[i]
#define out(a,n); F(i,n) cout<<a[i]<<" "; cout<<endl;
#define f first
#define s second
vector<ll> par;
ll find(ll node){
	return par[node] = (par[node]==node)?node:find(par[node]);
}

int main()
{
 	cin.tie(NULL);
    ios_base::sync_with_stdio(false);
 	ll n,k; cin>>n>>k;
 	vector<ll> p(n),q(n);
 	par.resize(n+1);
 	in(p,n); in(q,n);
 	F(i,n) par[i+1] = i+1;
 	F(i,n){
 		ll x = find(p[i]);
 		ll y = find(q[i]);
 		if(x!=y){
 		    if(x<y) swap(x,y);
 			par[x] = y;
 		}
 	}
 	F(i,n) if(find(p[i])>26) return cout<<"NO",0;
 	string ans = "";
 	F(i,n){
 		ans+=(char)(find(p[i]) + 'a' - 1);
 	}
 	string t = ans;
 	set<char> s(t.begin(), t.end());
 	sort(t.begin(), t.end());
 	if(t!=ans || s.size()<k){
 		cout<<"NO";
 	}
 	else{
	 	cout<<"YES\n";
	 	cout<<ans;
	 }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F(i,n) for(int i=0;i<n;i++)
#define F1(x,i,n) for(int i=x;i<n;i++)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define a(n) vector<ll> a(n)
#define mem(x,val) memset(x,val,sizeof(x))
#define mod 1000000007
#define in(a,n) F(i,n) cin>>a[i]
#define out(a,n); F(i,n) cout<<a[i]<<" "; cout<<endl;
#define f first
#define s second
vector<ll> par;
ll find(ll node){
	return par[node] = (par[node]==node)?node:find(par[node]);
}

int main()
{
 	cin.tie(NULL);
    ios_base::sync_with_stdio(false);
 	ll n,k; cin>>n>>k;
 	vector<ll> p(n),q(n);
 	par.resize(n+1);
 	in(p,n); in(q,n);
 	F(i,n) par[i+1] = i+1;
 	F(i,n){
 		ll x = find(p[i]);
 		ll y = find(q[i]);
 		if(x!=y){
 		    if(x>y) swap(x,y);
 			par[x] = y;
 		}
 	}
 	ll h[n+1]; F(i,n) h[p[i]] = i;
 	ll last = p[0];
 	ll idx = 0;
 	ll g = 0;
 	ll ans[n];
 	while(idx<n){
 		ll idx1 = h[find(p[idx])];
 		while(idx<idx1 && idx<n){
 			ans[idx] = g;
 			idx++;
 			idx1 = max(idx1,h[find(p[idx])]);
 		}
 		ans[idx] = g;
 		g++;
 		idx++;
 	}
 	if(g+1<k) return cout<<"NO",0;
 	cout<<"YES\n";
 	F(i,n) cout<<(char)(min(ans[i],25LL)+'a');
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F(i,n) for(int i=0;i<n;i++)
#define F1(x,i,n) for(int i=x;i<n;i++)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define a(n) vector<ll> a(n)
#define mem(x,val) memset(x,val,sizeof(x))
#define mod 1000000007
#define in(a,n) F(i,n) cin>>a[i]
#define out(a,n); F(i,n) cout<<a[i]<<" "; cout<<endl;
#define f first
#define s second
vector<ll> par;
ll find(ll node){
	return par[node] = (par[node]==node)?node:find(par[node]);
}

int main()
{
 	cin.tie(NULL);
    ios_base::sync_with_stdio(false);
 	ll n,k; cin>>n>>k;
 	vector<ll> p(n),q(n);
 	par.resize(n+1);
 	in(p,n); in(q,n);
 	F(i,n) par[i+1] = i+1;
 	F(i,n){
 		ll x = find(p[i]);
 		ll y = find(q[i]);
 		if(x!=y){
 		    if(x>y) swap(x,y);
 			par[x] = y;
 		}
 	}
 	ll h[n+1]; F(i,n) h[p[i]] = i;
 	ll last = p[0], idx = 0, g = 0, ans[n];
 	while(idx<n){
 		ll idx1 = h[find(p[idx])];
 		while(idx<idx1 && idx<n){
 			ans[p[idx]-1] = g;
 			idx++;
 			idx1 = max(idx1,h[find(p[idx])]);
 		}
 		ans[p[idx]-1] = g;
 		g++;
 		idx++;
 	}
 	if(g+1<k) return cout<<"NO",0;
 	cout<<"YES\n";
 	F(i,n) cout<<(char)(min(ans[i],25LL)+'a');
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F(i,n) for(int i=0;i<n;i++)
#define F1(x,i,n) for(int i=x;i<n;i++)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define a(n) vector<ll> a(n)
#define mem(x,val) memset(x,val,sizeof(x))
#define mod 1000000007
#define in(a,n) F(i,n) cin>>a[i]
#define out(a,n); F(i,n) cout<<a[i]<<" "; cout<<endl;
#define f first
#define s second
vector<ll> par;
ll find(ll node){
	return par[node] = (par[node]==node)?node:find(par[node]);
}

int main()
{
 	cin.tie(NULL);
    ios_base::sync_with_stdio(false);
 	ll n,k; cin>>n>>k;
 	vector<ll> p(n),q(n);
 	par.resize(n+1);
 	in(p,n); in(q,n);
 	F(i,n) par[i+1] = i+1;
 	F(i,n){
 		ll x = find(p[i]);
 		ll y = find(q[i]);
 		if(x!=y){
 		    if(x<y) swap(x,y);
 			par[x] = y;
 		}
 	}
 	// F(i,n) cout<<find(p[i])<<" \n"[i==n-1];
 	ll pl[n]; F(i,n) pl[i] = find(p[i]);
 	ll pk[n+1]; mem(pk,-1); for(ll i=n-1;i>=0;i--) if(pk[pl[i]]==-1) pk[pl[i]] = i;
 	ll idx = 0;
 	ll g = 0;
 	ll ans[n]; F(i,n) ans[i] = INT_MAX;
 	while(idx<n){
 		ll idx1 = pk[pl[idx]];
 		while(idx<idx1){
 			ans[p[idx]-1] = g;
 			idx++;
 			idx1 = max(idx1,pk[pl[idx]]);
 		}
 		ans[p[idx]-1] = g++; idx++;
 	}
 	if(g+1<k) return cout<<"NO",0;
 	string o="";
 	F(i,n) o+=(char)(min(ans[i],25LL)+'a');
 	string s="",t=""; F(i,n) s+=ans[p[i]-1],t+=ans[q[i]-1];
 	string temp = s;
 	sort(s.begin(), s.end());
 	if(temp!=s || s!=t) return cout<<"NO",0;
 	cout<<"YES\n";
 	cout<<o;

}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F(i,n) for(int i=0;i<n;i++)
#define F1(x,i,n) for(int i=x;i<n;i++)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define a(n) vector<ll> a(n)
#define mem(x,val) memset(x,val,sizeof(x))
#define mod 1000000007
#define in(a,n) F(i,n) cin>>a[i]
#define out(a,n); F(i,n) cout<<a[i]<<" "; cout<<endl;
#define f first
#define s second
vector<ll> par;
ll find(ll node){
	return par[node] = (par[node]==node)?node:find(par[node]);
}

int main()
{
 	cin.tie(NULL);
    ios_base::sync_with_stdio(false);
 	ll n,k; cin>>n>>k;
 	vector<ll> p(n),q(n);
 	par.resize(n+1);
 	in(p,n); in(q,n);
 	F(i,n) par[i+1] = i+1;
 	F(i,n){
 		ll x = find(p[i]);
 		ll y = find(q[i]);
 		if(x!=y){
 		    if(x<y) swap(x,y);
 			par[x] = y;
 		}
 	}
 	// F(i,n) cout<<find(p[i])<<" \n"[i==n-1];
 	ll pl[n]; F(i,n) pl[i] = find(p[i]);
 	ll pk[n+1]; mem(pk,-1); for(ll i=n-1;i>=0;i--) if(pk[pl[i]]==-1) pk[pl[i]] = i;

 	ll idx = 0;
 	ll g = 0;
 	ll ans[n]; F(i,n) ans[i] = INT_MAX;
 	while(idx<n){
 		ll idx1 = pk[pl[idx]];
 		while(idx<idx1){
 			ans[p[idx]-1] = g;
 			idx++;
 			idx1 = max(idx1,pk[pl[idx]]);
 		}
 		ans[p[idx]-1] = g++; idx++;
 	}
 	if(g<k) return cout<<"NO",0;
 	cout<<"YES\n";
 	F(i,n) cout<<(char)(min(ans[i],25LL)+'a');
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F(i,n) for(int i=0;i<n;i++)
#define F1(x,i,n) for(int i=x;i<n;i++)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define a(n) vector<ll> a(n)
#define mem(x,val) memset(x,val,sizeof(x))
#define mod 1000000007
#define in(a,n) F(i,n) cin>>a[i]
#define out(a,n); F(i,n) cout<<a[i]<<" "; cout<<endl;
#define f first
#define s second
vector<ll> par;
ll find(ll node){
	return par[node] = (par[node]==node)?node:find(par[node]);
}

int main()
{
 	cin.tie(NULL);
    ios_base::sync_with_stdio(false);
 	ll n,k; cin>>n>>k;
 	vector<ll> p(n),q(n);
 	par.resize(n+1);
 	in(p,n); in(q,n);
 	F(i,n) par[i+1] = i+1;
 	F(i,n){
 		ll x = find(p[i]);
 		ll y = find(q[i]);
 		if(x!=y){
 		    if(x>y) swap(x,y);
 			par[x] = y;
 		}
 	}
 	ll h[n+1]; F(i,n) h[p[i]] = i;
 	ll last = p[0], idx = 0, g = 0, ans[n];
 	while(idx<n){
 		ll idx1 = h[find(p[idx])];
 		while(idx<idx1 && idx<n){
 			ans[idx] = g;
 			idx++;
 			idx1 = max(idx1,h[find(p[idx])]);
 		}
 		ans[p[idx]-1] = g;
 		g++;
 		idx++;
 	}
 	if(g+1<k) return cout<<"NO",0;
 	cout<<"YES\n";
 	F(i,n) cout<<(char)(min(ans[i],25LL)+'a');
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <cmath>
#include <iomanip>
#include <unordered_map>
#include <chrono>
#include <queue>
#include <random>
#include <immintrin.h>
#include <unordered_set>

int32_t* dsu_parents;
int32_t* dsu_right;

int32_t find_parent(int32_t vertex) {
    if(dsu_parents[vertex] == vertex)
	return vertex;
    return dsu_parents[vertex] = find_parent(dsu_parents[vertex]);
}

bool join(int32_t v1, int32_t v2) {
    int32_t root1 = find_parent(v1);
    int32_t root2 = find_parent(v2);
    if(root1 == root2)
	return false;
    dsu_parents[root1] = root2;
    dsu_right[root2] = std::max(dsu_right[root1], dsu_right[root2]);
    return true;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int32_t n, k;
    std::cin >> n >> k;

    int32_t* arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr1[i];
	arr1[i]--;
    }

    int32_t* arr2 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr2[i];
	arr2[i]--;
    }

    int32_t* r_arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++)
	r_arr1[arr1[i]] = i;

    dsu_parents = new int32_t[n];
    dsu_right = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	dsu_parents[i] = i;
	dsu_right[i] = i;
    }

    int32_t* next = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	next[i] = i + 1;
    }

    int32_t left = n;
    for(int32_t i = 0 ; i < n - 1; i++) {
	if(r_arr1[arr2[i]] < r_arr1[arr2[i + 1]])
	    continue;
	int32_t cur = r_arr1[arr2[i + 1]];
	while(cur != dsu_right[find_parent(r_arr1[arr2[i]])] + 1) {
	    if(join(cur, r_arr1[arr2[i + 1]]))
		left--;
	    cur = dsu_right[find_parent(cur)] + 1;
	}
	if(join(r_arr1[arr2[i]], r_arr1[arr2[i + 1]]))
	    left--;
    }

    if(k > left) {
	std::cout << "NO";
	return 0;
    }
    std::cout << "YES" << "\n";
    std::string answer(n, ' ');

    std::map<int32_t, char> per_component;
    char new_char = 'a';
    for(int32_t i = 0 ;  i < n  ; i++) {
	if (per_component.find(find_parent(i)) == per_component.end()) {
	    per_component[find_parent(i)] = new_char;
	    if(new_char != 'a' + k - 1)
		new_char++;
	}
	answer[i] = per_component[find_parent(i)];
    }
    std::cout << answer;
    return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <cmath>
#include <iomanip>
#include <unordered_map>
#include <chrono>
#include <queue>
#include <random>
#include <immintrin.h>
#include <unordered_set>

int32_t* dsu_parents;
int32_t* dsu_right;

int32_t find_parent(int32_t vertex) {
    if(dsu_parents[vertex] == vertex)
	return vertex;
    return dsu_parents[vertex] = find_parent(dsu_parents[vertex]);
}

bool join(int32_t v1, int32_t v2) {
    int32_t root1 = find_parent(v1);
    int32_t root2 = find_parent(v2);
    if(root1 == root2)
	return false;
    dsu_parents[root1] = root2;
    dsu_right[root2] = std::max(dsu_right[root1], dsu_right[root2]);
    return true;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int32_t n, k;
    std::cin >> n >> k;

    int32_t* arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr1[i];
	arr1[i]--;
    }

    int32_t* arr2 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr2[i];
	arr2[i]--;
    }

    int32_t* r_arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++)
	r_arr1[arr1[i]] = i;

    dsu_parents = new int32_t[n];
    dsu_right = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	dsu_parents[i] = i;
	dsu_right[i] = i;
    }

    int32_t* next = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	next[i] = i + 1;
    }

    int32_t left = n;
    for(int32_t i = 0 ; i < n - 1; i++) {
	if(r_arr1[arr2[i]] < r_arr1[arr2[i + 1]])
	    continue;
	int32_t cur = r_arr1[arr2[i + 1]];
	while(cur != r_arr1[arr2[i]]) {
	    if(join(cur, r_arr1[arr2[i + 1]]))
		left--;
	    cur = dsu_right[find_parent(cur)] + 1;
	}
	if(join(r_arr1[arr2[i]], r_arr1[arr2[i + 1]]))
	    left--;
    }

    if(k > left) {
	std::cout << "NO";
	return 0;
    }
    std::cout << "YES" << "\n";
    std::string answer(n, ' ');

    std::map<int32_t, char> per_component;
    char new_char = 'a';
    for(int32_t i = 0 ;  i < n  ; i++) {
	if (per_component.find(find_parent(i)) == per_component.end()) {
	    per_component[find_parent(i)] = new_char;
	    if(new_char != 'a' + k - 1)
		new_char++;
	}
	answer[i] = per_component[find_parent(i)];
    }
    std::cout << answer;
    return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <cmath>
#include <iomanip>
#include <unordered_map>
#include <chrono>
#include <queue>
#include <random>
#include <immintrin.h>
#include <unordered_set>

int32_t* dsu_parents;
int32_t* dsu_right;

int32_t find_parent(int32_t vertex) {
    if(dsu_parents[vertex] == vertex)
	return vertex;
    return dsu_parents[vertex] = find_parent(dsu_parents[vertex]);
}

bool join(int32_t v1, int32_t v2) {
    int32_t root1 = find_parent(v1);
    int32_t root2 = find_parent(v2);
    if(root1 == root2)
	return false;
    dsu_parents[root1] = root2;
    dsu_right[root2] = std::max(dsu_right[root1], dsu_right[root2]);
    return true;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int32_t n, k;
    std::cin >> n >> k;

    int32_t* arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr1[i];
	arr1[i]--;
    }

    int32_t* arr2 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr2[i];
	arr2[i]--;
    }

    int32_t* r_arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++)
	r_arr1[arr1[i]] = i;

    dsu_parents = new int32_t[n];
    dsu_right = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	dsu_parents[i] = i;
	dsu_right[i] = i;
    }

    int32_t* next = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	next[i] = i + 1;
    }

    int32_t left = n;
    for(int32_t i = 0 ; i < n - 1; i++) {
	if(r_arr1[arr2[i]] < r_arr1[arr2[i + 1]])
	    continue;
	int32_t cur = r_arr1[arr2[i + 1]];
	while(cur != dsu_right[find_parent(r_arr1[arr2[i]])] + 1) {
	    if(join(cur, r_arr1[arr2[i + 1]]))
		left--;
	    cur = dsu_right[find_parent(cur)] + 1;
	}
	if(join(r_arr1[arr2[i]], r_arr1[arr2[i + 1]]))
	    left--;
    }

    if(k > left) {
	std::cout << "NO";
	return 0;
    }
    std::cout << "YES" << "\n";
    std::string answer(n, ' ');

    std::map<int32_t, char> per_component;
    char new_char = 'a';
    for(int32_t i = 0 ;  i < n; i++) {
	if (per_component.find(find_parent(i)) == per_component.end()) {
	    per_component[find_parent(i)] = new_char;
	    if(new_char != 'a' + k - 1)
		new_char++;
	}
    }
    for(int32_t i = 0 ; i < n ;i++)
	answer[arr1[i]] = per_component[find_parent(i)];
    std::cout << answer;
    return 0;
}

OD


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <cmath>
#include <iomanip>
#include <unordered_map>
#include <chrono>
#include <queue>
#include <random>
#include <immintrin.h>
#include <unordered_set>

int32_t* dsu_parents;

int32_t find_parent(int32_t vertex) {
    if(dsu_parents[vertex] == vertex)
	return vertex;
    return dsu_parents[vertex] = find_parent(dsu_parents[vertex]);
}

void join(int32_t v1, int32_t v2) {
    int32_t root1 = find_parent(v1);
    int32_t root2 = find_parent(v2);
    if(root1 == root2)
	return;
    dsu_parents[root1] = root2;
}

int main() {
    int32_t n, k;
    std::cin >> n >> k;

    int32_t* arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr1[i];
	arr1[i]--;
    }

    int32_t* arr2 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr2[i];
	arr2[i]--;
    }

    int32_t* r_arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++)
	r_arr1[arr1[i]] = i;

    dsu_parents = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++)
	dsu_parents[i] = i;

    int32_t* next = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	next[i] = i + 1;
    }

    for(int32_t i = 0 ; i < n - 1; i++) {
	if(r_arr1[arr2[i]] < r_arr1[arr2[i + 1]])
	    continue;
	int32_t cur = arr2[i + 1];
	while(cur != arr2[i]) {
	    join(r_arr1[cur], r_arr1[arr2[i]]);
	    cur = arr1[next[r_arr1[arr1[cur]]]];
	}
	next[r_arr1[arr2[i + 1]]] = r_arr1[arr2[i]];
    }

    if(k > n) {
	std::cout << "NO";
	return 0;
    }
    std::cout << "YES" << "\n";
    std::string answer(n, ' ');

    std::map<int32_t, char> per_component;
    char new_char = 'a';
    for(int32_t i = 0 ;  i < n  ; i++) {
	if (per_component.find(dsu_parents[i]) == per_component.end()) {
	    per_component[dsu_parents[i]] = new_char;
	    if(new_char != 'a' + k - 1)
		new_char++;
	}
	answer[i] = per_component[dsu_parents[i]];
    }
    std::cout << answer;
    return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <cmath>
#include <iomanip>
#include <unordered_map>
#include <chrono>
#include <queue>
#include <random>
#include <immintrin.h>
#include <unordered_set>

int32_t* dsu_parents;
int32_t* dsu_right;

int32_t find_parent(int32_t vertex) {
    if(dsu_parents[vertex] == vertex)
	return vertex;
    return dsu_parents[vertex] = find_parent(dsu_parents[vertex]);
}

bool join(int32_t v1, int32_t v2) {
    int32_t root1 = find_parent(v1);
    int32_t root2 = find_parent(v2);
    if(root1 == root2)
	return false;
    dsu_parents[root1] = root2;
    dsu_right[root2] = std::max(dsu_right[root1], dsu_right[root2]);
    return true;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int32_t n, k;
    std::cin >> n >> k;

    int32_t* arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr1[i];
	arr1[i]--;
    }

    int32_t* arr2 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ;i++) {
	std::cin >> arr2[i];
	arr2[i]--;
    }

    int32_t* r_arr1 = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++)
	r_arr1[arr1[i]] = i;

    dsu_parents = new int32_t[n];
    dsu_right = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	dsu_parents[i] = i;
	dsu_right[i] = i;
    }

    int32_t* next = new int32_t[n];
    for(int32_t i = 0 ; i  < n ; i++) {
	next[i] = i + 1;
    }

    int32_t left = n;
    for(int32_t i = 0 ; i < n - 1; i++) {
	if(r_arr1[arr2[i]] < r_arr1[arr2[i + 1]])
	    continue;
	int32_t cur = r_arr1[arr2[i + 1]];
	while(cur != dsu_right[find_parent(r_arr1[arr2[i]])] + 1) {
	    if(join(cur, r_arr1[arr2[i + 1]]))
		left--;
	    cur = dsu_right[find_parent(cur)] + 1;
	}
	if(join(r_arr1[arr2[i]], r_arr1[arr2[i + 1]]))
	    left--;
    }

    if(k > left) {
	std::cout << "NO";
	return 0;
    }
    std::cout << "YES" << "\n";
    std::string answer(n, ' ');

    std::map<int32_t, char> per_component;
    char new_char = 'a';
    for(int32_t i = 0 ;  i < n; i++) {
	if (per_component.find(find_parent(i)) == per_component.end()) {
	    per_component[find_parent(i)] = new_char;
	    if(new_char != 'a' + k - 1)
		new_char++;
	}
    }
    for(int32_t i = 0 ; i < n ;i++)
	answer[arr1[i]] = per_component[find_parent(i)];
    std::cout << answer;
    return 0;
}