#include <bits/stdc++.h>
using namespace std;
vector<pair<int, vector<int>>> g, gr;
vector<char> used;
vector<int> order;
set<pair<int, int>> edg_c;
int comp_num = 0;
void dfs1(int v) {
  used[v] = true;
  for (size_t i = 0; i < g[v].second.size(); ++i)
    if (!used[g[v].second[i]]) dfs1(g[v].second[i]);
  order.push_back(v);
}
void dfs2(int v) {
  used[v] = true;
  g[v].first = comp_num;
  for (auto& i : gr[v].second)
    if (!used[i]) {
      dfs2(i);
    }
}
void add_edge(int a, int b) {
  g[a ^ 1].second.emplace_back(b);
  g[b ^ 1].second.emplace_back(a);
  gr[b].second.emplace_back(a ^ 1);
  gr[a].second.emplace_back(b ^ 1);
}
int main() {
  int n, roads;
  cin >> n >> roads;
  g.resize(2 * (roads));
  gr.resize(2 * (roads));
  vector<pair<int, int>> _buffer;
  for (auto i = 0; i < roads; ++i) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    _buffer.emplace_back(make_pair(min(a, b), max(a, b)));
  }
  for (int k = 0; k < roads; ++k) {
    for (int i = k + 1; i < roads; ++i) {
      if ((_buffer[k].first < _buffer[i].first &&
           _buffer[i].first < _buffer[k].second &&
           _buffer[k].second < _buffer[i].second) ||
          (_buffer[i].first < _buffer[k].first &&
           _buffer[k].first < _buffer[i].second &&
           _buffer[i].second < _buffer[k].second)) {
        add_edge(2 * i, 2 * k);
        add_edge((2 * i) ^ 1, (2 * k) ^ 1);
      }
    }
  }
  used.assign(2 * roads, false);
  for (int i = 0; i < 2 * roads; ++i)
    if (!used[i]) dfs1(i);
  used.assign(2 * roads, false);
  for (int i = 0; i < 2 * roads; ++i) {
    int v = order[2 * roads - 1 - i];
    if (!used[v]) {
      dfs2(v);
      comp_num++;
    }
  }
  for (int i = 0; i < roads; ++i) {
    if (g[i].first == g[i ^ 1].first) {
      cout << "Impossible " << endl;
      return 0;
    }
  }
  for (int i = 0; i < roads; ++i) {
    string ans = g[2 * i].first > g[(2 * i) ^ 1].first ? "i" : "o";
    cout << ans;
  }
  return 0;
}
