#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1 << 19;
const int MAXC = 1 << 18;
struct edge {
  int v;
  int id;
  bool rev;
  edge(int a, int b, bool c) : v(a), id(b), rev(c) {}
};
vector<edge> g[MAXN];
int color[MAXN];
bool vis[MAXN];
bool path[MAXN];
int edgePos[MAXN];
int diff[MAXN];
void addEdge(int x, int y, int id) {
  g[x].push_back(edge(y, id, false));
  g[y].push_back(edge(x, id, true));
}
void markEdge(const edge& e, bool reversed = false) {
  color[e.id] = ((e.rev != reversed) ? -1 : 1);
}
int colorCycleDfs(int u) {
  int backTarget = -1;
  path[u] = true;
  for (int& i = edgePos[u]; i < g[u].size(); ++i) {
    const edge& e = g[u][i];
    if (!vis[e.id]) {
      vis[e.id] = true;
      if (path[e.v]) {
        markEdge(e);
        backTarget = e.v;
        break;
      }
      int back = colorCycleDfs(e.v);
      if (back >= 0) {
        markEdge(e);
        if (back != u) {
          backTarget = back;
          break;
        }
      }
    }
  }
  path[u] = false;
  return backTarget;
}
void treeDfs(int u) {
  if (vis[u]) return;
  vis[u] = true;
  for (int i = 0; i < g[u].size(); ++i) {
    const edge& e = g[u][i];
    if (!vis[e.v] && color[e.id] == 0) {
      if (diff[u] > 0) {
        diff[u]--;
        diff[e.v]++;
        markEdge(e, true);
      } else {
        diff[u]++;
        diff[e.v]--;
        markEdge(e);
      }
      treeDfs(e.v);
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  set<int> vs;
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    y += MAXC;
    vs.insert(x);
    vs.insert(y);
    addEdge(x, y, i);
  }
  for (int s : vs) colorCycleDfs(s);
  memset(vis, 0, sizeof(vis));
  for (int s : vs) {
    if (!vis[s]) treeDfs(s);
  }
  for (int i = 0; i < n; ++i)
    cout << (color[i] == 1 ? 'r' : (color[i] == -1 ? 'b' : '?'));
  cout << endl;
}
