#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define R cin>>
#define ll long long
#define ln cout<<endl
#define in(a) insert(a)
#define pb(a) push_back(a)
#define pd(a) printf("%.10f\n",a)
#define mem(a) memset(a,0,sizeof(a))
#define all(c) (c).begin(),(c).end()
#define iter(c) __typeof((c).begin())
#define rrep(i,n) for(ll i=(ll)(n)-1;i>=0;i--)
#define REP(i,m,n) for(ll i=(ll)(m);i<(ll)(n);i++)
#define rep(i,n) REP(i,0,n)
#define tr(it,c) for(iter(c) it=(c).begin();it!=(c).end();it++)
ll check(ll n,ll m,ll x,ll y){return x>=0&&x<n&&y>=0&&y<m;}void pr(){ln;}
template<class A,class...B>void pr(const A &a,const B&...b){cout<<a<<(sizeof...(b)?" ":"");pr(b...);}
template<class A>void PR(A a,ll n){rep(i,n)cout<<(i?" ":"")<<a[i];ln;}
const ll MAX=1e9+7,MAXL=1LL<<61,dx[8]={-1,0,1,0,-1,-1,1,1},dy[8]={0,1,0,-1,-1,1,1,-1};
typedef pair<ll,ll> P;

vector<string> C(vector<string> s) {
  ll n=s.size();
  rep(i,n)REP(j,i+1,n) swap(s[i][j],s[j][i]);
  return s;
}

ll n,m;
string s[1000];

ll calc(vector<string> t) {
  ll cnt=0;
  rep(k,m) {
    ll f=0;
    rep(l,2) {
      rep(i,n) {
        rep(j,n) {
          if(t[i].substr(0,s[k].size())==s[k]) f=1;
          rotate(t[i].begin(),t[i].begin()+1,t[i].end());
        }
      }
      t=C(t);
    }
    cnt+=f;
  }
  return cnt;
}

vector<string> ans;
ll MM;

void solve(vector<string> t) {
  ll d=calc(t);
  if(MM<d) {
    MM=d;
    ans=t;
  }
  rep(k,5) {
    random_shuffle(all(t));
    rep(i,n) rotate(t[i].begin(),t[i].begin()+rand()%n,t[i].end());
    ll d=calc(t);
    if(MM<d) {
      MM=d;
      ans=t;
    }
  }
}

void Main() {
  srand((unsigned)time(NULL));
  cin >> n >> m;
  rep(i,m) R s[i];
  vector<string> v[15];
  rep(i,m) v[s[i].size()].pb(s[i]);
  rep(e,35) {
    vector<string> t(n);
    rrep(i,15) {
      random_shuffle(all(v[i]));
      rep(j,v[i].size()) {
        ll M=MAX,x=0;
        string rr;
        rep(k,n) {
          rep(l,t[k].size()+1) {
            string r1=t[k].substr(l);
            if(r1.size()<=v[i][j].size()) {
              string r2=v[i][j].substr(0,r1.size());
              if(r1==r2) {
                ll d=t[k].size()+v[i][j].size()-r1.size();
                if(d<=n&&M>d) {
                  M=d;
                  x=k;
                  rr=t[k]+v[i][j].substr(r1.size());
                }
              }
            }
            if(l+v[i][j].size()<=t[k].size()) {
              r1=t[k].substr(l,v[i][j].size());
              if(r1==v[i][j]) {
                M=0;
                x=k;
                rr=t[k];
              }
            }
          }
        }
        if(rand()%(i+3)==0) M=MAX;
        if(M!=MAX) t[x]=rr;
      }
    }
    rep(i,n) {
      while(t[i].size()<n) {
        //t[i]+='.';
        t[i]+=(char)(rand()%8+'A');
      }
    }
    solve(t);
  }
  rep(i,n) pr(ans[i]);
}

int main(){Main();return 0;}

#include <iostream>
#include <iomanip>
#include <string>
#include <stack>
#include <vector>
#include <complex>
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <utility>
#include <functional>
#include <iterator>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <regex>
#include <limits>
#include <time.h>
#include <cstdint>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <limits.h>
using namespace std;
using pii  = pair<int,int>;
using ll=long long;
using ld=long double;
#define pb push_back
#define mp make_pair
#define sc second
#define fr first
#define stpr setprecision
#define cYES cout<<"YES"<<endl
#define cNO cout<<"NO"<<endl
#define cYes cout<<"Yes"<<endl
#define cNo cout<<"No"<<endl
#define rep(i,n) for(ll i=0;i<(n);++i)
#define Rep(i,a,b) for(ll i=(a);i<(b);++i)
#define rrep(i,n) for(ll i=n-1;i>=0;i--)
#define rRep(i,a,b) for(ll i=a;i>=b;i--)
#define crep(i) for(char i='a';i<='z';++i)
#define psortsecond(A,N) sort(A,A+N,[](const pii &a, const pii &b){return a.second<b.second;});
#define ALL(x) (x).begin(),(x).end()
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define endl '\n'
int ctoi(const char c){
  if('0' <= c && c <= '9') return (c-'0');
  return -1;
}
ll gcd(ll a,ll b){return (b == 0 ? a : gcd(b, a%b));}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
constexpr ll MOD=1000000007;
constexpr ll INF=1000000011;
constexpr ll MOD2=998244353;
constexpr ll LINF = 1001002003004005006ll;
constexpr ld EPS=10e-8;
template <class T, class U> inline bool chmax(T& lhs, const U& rhs) { if (lhs < rhs) { lhs = rhs; return 1; } return 0; }
template <class T, class U> inline bool chmin(T& lhs, const U& rhs) { if (lhs > rhs) { lhs = rhs; return 1; } return 0; }
template<typename T> istream& operator>>(istream& is,vector<T>& v){for(auto&& x:v)is >> x;return is;}
template<typename T,typename U> istream& operator>>(istream& is, pair<T,U>& p){ is >> p.first; is >> p.second; return is;}
template<typename T,typename U> ostream& operator>>(ostream& os, const pair<T,U>& p){ os << p.first << ' ' << p.second; return os;}
template<class T> ostream& operator<<(ostream& os, vector<T>& v){
  for(auto i=begin(v); i != end(v); ++i){
    if(i !=begin(v)) os << ' ';
    os << *i;
  }
  return os;
}

class DisjointSet{
  public:
    vector<int> rank,p,sz;

    DisjointSet(){}

    //初期化
    DisjointSet(int size){
      rank.resize(size,0);
      p.resize(size,0);
      sz.resize(size,1);
      rep(i,size){
        makeSet(i);
      }
    }        
    void makeSet(int x){
      p[x]=x;
      rank[x]=0;
    }

    bool same(int x,int y){
      return findSet(x)==findSet(y);
    }

    void unite(int x,int y){
      if(!same(x,y)) link(findSet(x),findSet(y));
    }

    int size(int key){
      return sz[findSet(key)];
    }

    void link(int x,int y){
      if(rank[x]>rank[y]){
        p[y]=x;
        sz[x]+=sz[y];
      }
      else{
        p[x]=y;
        sz[y]+=sz[x];
        if(rank[x]==rank[y]){
            rank[y]++;
        }
      }
    }

    int findSet(int x){ // 根を返す
      if(x!=p[x]){
        p[x]=findSet(p[x]);
      }
      return  p[x];
    }
};

map<ll,ll> S,T;

int main(){
  ll N,M;
  cin >> N >> M;
  DisjointSet X;
  X=DisjointSet(N+1);  // N頂点(0-indexed)を用意
  vector<ll> A(N),B(N);
  rep(i,N){
    cin >> A[i];
  }
  rep(i,N){
    cin >> B[i];
  }
  rep(i,M){
    ll a,b;cin>>a>>b;a--;b--;
    X.unite(a,b);
  }
  rep(i,N){
    S[X.findSet(i)]+=A[i];
    T[X.findSet(i)]+=B[i];
  }
  for(auto P : S){
    if(S[P.fr]!=T[P.fr]){
      cNo;
      return 0;
    }
  }
  cYes;
}