#include <bits/stdc++.h>
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
#define all(x) x.begin(), x.end()
#define ll long long
#define pii pair<int,int>
#define V vector
#define pb push_back
#define FASTIO ios_base::sync_with_stdio(false); cin.tie(nullptr);
const int N = 3e5 + 5;
int par[N], sz_[N];
int bg[N], sm[N];
V<int> adj[N], radj[N];
int indeg[N];
int comp[N];
int findp(int x) {
if (par[x] == x) return x;
return par[x] = findp(par[x]);
}
void unite(int a, int b) {
a = findp(a);
b = findp(b);
if (a == b) return;
if (sz_[a] < sz_[b]) swap(a, b);
par[b] = a;
sz_[a] += sz_[b];
}
int main() {
FASTIO
int n, m, q;
cin >> n >> m >> q;
for (int i = 1; i <= m; i++) {
par[i] = i;
sz_[i] = 1;
}
V<tuple<int,int,char>> edges;
for (int i = 1; i <= q; i++) {
int a, b;
char c;
cin >> a >> b >> c;
if (c == '=')
unite(a, b);
else
edges.pb({a, b, c});
}
int id = 0;
map<int,int> mp;
for (int i = 1; i <= m; i++) {
int p = findp(i);
if (!mp.count(p))
mp[p] = ++id;
comp[i] = mp[p];
}
for (auto [a, b, c] : edges) {
int u = comp[a];
int v = comp[b];
if (u == v) continue;
if (c == '>') {
adj[u].pb(v);
radj[v].pb(u);
indeg[v]++;
}
else {
adj[v].pb(u);
radj[u].pb(v);
indeg[u]++;
}
}
queue<int> qu;
for (int i = 1; i <= id; i++)
if (!indeg[i])
qu.push(i);
V<int> topo;
while (!qu.empty()) {
int u = qu.front(); qu.pop();
topo.pb(u);
for (auto v : adj[u]) {
indeg[v]--;
if (!indeg[v])
qu.push(v);
}
}
if ((int)topo.size() != id) {
for (int i = 1; i <= m; i++)
cout << "?\n";
return 0;
}
for (auto u : topo)
for (auto v : adj[u])
bg[v] = max(bg[v], bg[u] + 1);
reverse(all(topo));
for (auto u : topo)
for (auto v : radj[u])
sm[v] = max(sm[v], sm[u] + 1);
for (int i = 1; i <= m; i++) {
int c = comp[i];
if (bg[c] + sm[c] == n - 1)
cout << 'K' << sm[c] + 1 << "\n";
else
cout << "?\n";
}
}