#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];
int dp[maxN] = {0};
vector<int>topo;
int cnt[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);
}
}
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);
cnt[group2]++;
}
else
{
adj[group2].push_back(group1);
cnt[group1]++;
}
}
queue<int>q;
for(int i = 1; i <= n; i++)
if(cnt[i] == 0)
q.push(i);
while(!q.empty())
{
int cur = q.front();
q.pop();
topo.push_back(cur);
for(int v: adj[cur])
{
if(cnt[v] == 1)
q.push(v);
cnt[v]--;
}
}
for(int u : topo)
for(int v : adj[u])
dp[v] = max(dp[v], dp[u]+1);
string ans;
for(int i = 0; i <= n; i++)
ans[i] = '|';
for(int i = topo.size()-1; i >= 0; i--)
{
int u = topo[i];
char temp = '~';
for(int v : adj[u])
temp = min(temp, ans[find_set(v)]);
if(temp == '~')
{
if(dp[u] == k-1)
ans[u] = char('a' + k - 1);
}
else
{
if (char(dp[u] + 1 + 'a') == temp)
ans[u] = char(dp[u] + 'a');
}
}
for(int i = 1; i <= n; i++)
{
int grp = find_set(i);
if(ans[grp] == '|')
cout << '?';
else cout << ans[grp];
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
readData();
for(int i = 1; i <= n; i++)
make_set(i);
dsu();
solve();
return 0;
}