#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
#define maxN 100007
int n, m, k;
int sz[maxN];
int par[maxN];
string op[maxN];
vector<int>groupPar;
int groupLeadChar[maxN] = {0};
vector<int>adj[maxN];
vector<int>realAdj[maxN];
int dp[maxN] = {0};
void make_set(int u)
{
sz[u] = 1;
par[u] = u;
}
int find_set(int u)
{
if(par[u] == u) return u;
int p = find_set(par[u]);
par[u] = p;
return p;
}
void union_set(int u, int v)
{
if(u == v)
return;
if(sz[u] < sz[v])
swap(u, v);
sz[u] += sz[v];
par[v] = u;
}
void readData()
{
cin >> n >> k >> m;
for(int i = 1; i <= m; i++)
cin >> op[i];
}
void dsu()
{
for(int i = 1; i <= m; i++)
{
int equalPos = -1;
for(int j = 0; j < op[i].size(); j++)
if(op[i][j] == '=')
equalPos = j;
if(equalPos == -1) continue;
int group1 = 0, group2 = 0;
for(int j = 0; j < equalPos; j++)
group1 = group1*10+op[i][j]-'0';
for(int j = equalPos+1; j < op[i].size(); j++)
group2 = group2*10+op[i][j]-'0';
union_set(group1, group2);
}
}
int dfs(int u)
{
if (dp[u] > 0) return dp[u];
int res = 1;
for (int v : adj[u])
res = max(res, 1 + dfs(v));
return dp[u] = res;
}
void dfsAns(int u, int h)
{
groupLeadChar[u] = h;
for(int v: realAdj[u])
dfsAns(v, h+1);
}
void solve()
{
for(int i = 1; i <= n; i++)
{
int par = find_set(i);
groupPar.push_back(par);
}
sort(groupPar.begin(), groupPar.end());
auto it = unique(groupPar.begin(), groupPar.end());
groupPar.erase(it, groupPar.end());
for(int i = 1; i <= m; i++)
{
int opPos = -1;
for(int j = 0; j < op[i].size(); j++)
if(op[i][j] == '>' || op[i][j] == '<')
opPos = j;
if(opPos == -1)
continue;
int group1 = 0, group2 = 0;
for(int j = 0; j < opPos; j++)
group1 = group1*10+op[i][j]-'0';
for(int j = opPos+1; j < op[i].size(); j++)
group2 = group2*10+op[i][j]-'0';
group1 = find_set(group1);
group2 = find_set(group2);
if(op[i][opPos] == '<')
adj[group1].push_back(group2);
else adj[group2].push_back(group1);
}
for(int i = 0; i < groupPar.size(); i++)
{
adj[0].push_back(groupPar[i]);
adj[groupPar[i]].push_back(n+1);
}
//for(int i = 0; i < groupPar.size(); i++)
// cout << groupPar[i] << " ";
dfs(0);
/*for(int i = 0; i <= n; i++)
{
cout << i << "-> ";
for(int j = 0; j < adj[i].size(); j++)
cout << adj[i][j] << " ";
cout << "\n";
}*/
if(dp[0] - 2 < k)
{
for(int i = 1; i <= n; i++)
cout << "?";
return;
}
queue<int>q;
q.push(0);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int v : adj[u])
{
if(dp[v] + 1 == dp[u])
{
realAdj[u].push_back(v);
q.push(v);
}
}
}
/*for(int i = 0; i <= n; i++)
{
cout << i << "-> ";
for(int j = 0; j < realAdj[i].size(); j++)
cout << realAdj[i][j] << " ";
cout << "\n";
}*/
string ans = " ";
for(int i = 1; i <= n; i++)
ans += '?';
dfsAns(0, 0);
for(int i = 1; i <= n; i++)
{
int par = find_set(i);
if(1 <= groupLeadChar[par] && groupLeadChar[par] <= k)
ans[i] = ('a'+groupLeadChar[par]-1);
}
for(int i = 1; i <= n; i++)
cout << ans[i];
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
readData();
for(int i = 0; i <= n+1; i++)
make_set(i);
dsu();
solve();
return 0;
}