Problem: Background

The kindergarten attached to the University of Aizu is a kindergarten where children who love programming gather. Yu, one of the kindergarten children, loves lowercase letters as much as programming. Yu-kun decided to write a scoring program for a new play that uses paper, circles, lines, and lowercase letters.

Problem

Initially, V circles and E lines are drawn on the paper. The circles are numbered from 0 in ascending order, with one lowercase letter or nothing in each circle. Each line connects two different circles. A circle cannot be connected by more than 26 lines.

The play procedure is as follows.

1. Select one circle with nothing written on it. If such a circle does not exist, this process ends.
2. Write one lowercase letter in the circle. However, if the circle is already connected to a circle with lowercase letters by a line, the same lowercase letters as the lowercase letters cannot be written.
3. Return to 1.



After writing lowercase letters in all the circles according to the above procedure, arrange the lowercase letters in the circles in ascending order of the circle numbers to make a character string. I want to minimize the character strings that can be created in this way in lexicographical order. There are two strings s and t of the same length, and s is smaller than t in lexicographical order in the following cases. si represents the i-th lowercase letter of the string s and ti represents the i-th lowercase letter of the string t. For the smallest i where si differs from ti, si is less than ti.

Since the initial state of the paper is given, output the smallest character string that can be created according to the above procedure in lexicographical order.

Constraints

The input satisfies the following conditions.

* 1 ≤ V ≤ 100,000
* 0 ≤ E ≤ 200,000
* ai is either lowercase or'?' (0 ≤ i ≤ V-1)
* 0 ≤ si, ti ≤ V-1 (si <ti, 0 ≤ i ≤ E-1)
* One circle cannot be connected by more than 26 lines

Input


V E
a0 a1 ... a (V-1)
s0 t0
s1 t1
...
s (E-1) t (E-1)


The number of circles V and the number of lines E are given on the first line, separated by blanks.

The initial state of the circle is given on the second line, separated by blanks.

If ai is a lowercase letter, the lowercase letter is written in the i-th circle, and if it is'?', It means that nothing is written in the i-th circle.

The line information is given as si ti on the following E line, which means that the si and ti circles are connected by a line.

Output

Output the smallest character string in the dictionary order on one line among the character strings that can be created according to the procedure in the question sentence.

Examples

Input

3 3
c ? ?
0 1
0 2
1 2


Output

cab


Input

3 2
c ? ?
0 1
0 2


Output

caa


Input

7 6
? a ? ? z a ?
0 1
0 2
3 4
4 5
4 6
5 6


Output

baaazab


Input

5 0
? ? ? ? ?


Output

aaaaa

Solution (in CPP):

Solution:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>
#include <iomanip>
#include <fstream>
#include <bitset>

using namespace std;

#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
template <typename T> void print_container(ostream& os, const T& c) { const char* _s = " "; if (!c.empty()) { __typeof__(c.begin()) last = --c.end(); foreach (it, c) { os << *it; if (it != last) os << _s; } } }
template <typename T> ostream& operator<<(ostream& os, const vector<T>& c) { print_container(os, c); return os; }
template <typename T> ostream& operator<<(ostream& os, const set<T>& c) { print_container(os, c); return os; }
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& c) { print_container(os, c); return os; }
template <typename T> ostream& operator<<(ostream& os, const deque<T>& c) { print_container(os, c); return os; }
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& c) { print_container(os, c); return os; }
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) { os << "(" << p.first << ", " << p.second << ")"; return os; }

template <typename T> void print(T a, int n, const string& split = " ") { for (int i = 0; i < n; i++) { cout << a[i]; if (i + 1 != n) cout << split; } cout << endl; }
template <typename T> void print2d(T a, int w, int h, int width = -1, int br = 0) { for (int i = 0; i < h; ++i) { for (int j = 0; j < w; ++j) { if (width != -1) cout.width(width); cout << a[i][j] << ' '; } cout << endl; } while (br--) cout << endl; }
template <typename T> void input(T& a, int n) { for (int i = 0; i < n; ++i) cin >> a[i]; }
#define dump(v) (cerr << #v << ": " << v << endl)

#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define erep(i, n) for (int i = 0; i <= (int)(n); ++i)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define clr(a, x) memset(a, x, sizeof(a))
#define sz(a) ((int)(a).size())
#define mp(a, b) make_pair(a, b)
#define ten(n) ((long long)(1e##n))

template <typename T, typename U> void upmin(T& a, const U& b) { a = min<T>(a, b); }
template <typename T, typename U> void upmax(T& a, const U& b) { a = max<T>(a, b); }
template <typename T> void uniq(T& a) { sort(a.begin(), a.end()); a.erase(unique(a.begin(), a.end()), a.end()); }
template <class T> string to_s(const T& a) { ostringstream os; os << a; return os.str(); }
template <class T> T to_T(const string& s) { istringstream is(s); T res; is >> res; return res; }
void fast_io() { cin.tie(0); ios::sync_with_stdio(false); }
bool in_rect(int x, int y, int w, int h) { return 0 <= x && x < w && 0 <= y && y < h; }

typedef long long ll;
typedef pair<int, int> pint;

const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };


int main()
{
    fast_io();

    int n, m;
    cin >> n >> m;
    string maru(n, '@');
    rep(i, n)
        cin >> maru[i];
    vector<vector<int>> g(n);
    rep(i, m)
    {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }

    rep(i, n)
    {
        if (maru[i] != '?')
            continue;

        bool ng[26] = {};
        for (int j : g[i])
            if (maru[j] != '?')
                ng[maru[j] - 'a'] = true;

        rep(k, 26)
        {
            if (!ng[k])
            {
                maru[i] = 'a' + k;
                break;
            }
        }
    }
    cout << maru << endl;
}