#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:268435456")
using namespace std;
template <typename T>
T sqr(const T &x) {
  return x * x;
}
template <typename T>
T my_abs(const T &x) {
  return x < 0 ? -x : x;
}
const int INF = (int)1e9;
const long long LINF = (long long)6e18;
const long long INF64 = LINF;
const long long INFLL = LINF;
const long double EPS = 1e-15;
const long double PI = 3.1415926535897932384626433832795;
const long double ME = 1e-5;
const long long MOD = (int)1e9 + 7;
const long long MOD2 = (int)1e9 + 21;
const int SQN = 320;
const int LOGN = 17;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
const int N = (int)1e3 + 10;
vector<int> g[N];
vector<int> rg[N];
bool used[N];
int comp[N];
vector<int> topsort;
int ans[N];
void add_disjunction(bool na, int a, bool nb, int b) {
  int v = (2 * a) ^ (int)na;
  int nv = v ^ 1;
  int u = (2 * b) ^ (int)nb;
  int nu = u ^ 1;
  g[nv].push_back(u);
  rg[u].push_back(nv);
  g[nu].push_back(v);
  rg[v].push_back(nu);
}
void add_disjunction(bool na, int a) {
  int v = (2 * a) ^ (int)na;
  int nv = v ^ 1;
  g[nv].push_back(v);
  rg[v].push_back(nv);
}
void dfs1(int v) {
  used[v] = true;
  for (int i = 0; i < int(int(g[v].size())); ++i) {
    int u = g[v][i];
    if (!used[u]) {
      dfs1(u);
    }
  }
  topsort.push_back(v);
}
void dfs2(int v, int cc) {
  comp[v] = cc;
  for (int i = 0; i < int(int(rg[v].size())); ++i) {
    int u = rg[v][i];
    if (comp[u] == -1) {
      dfs2(u, cc);
    }
  }
}
bool two_sat(int n) {
  memset(used, false, 2 * n * sizeof(used[0]));
  memset(comp, -1, 2 * n * sizeof(comp[0]));
  for (int v = 0; v < int(2 * n); ++v) {
    if (!used[v]) {
      dfs1(v);
    }
  }
  int cc = 0;
  for (int i = int(2 * n) - 1; i >= 0; --i) {
    int v = topsort[i];
    if (comp[v] == -1) {
      dfs2(v, cc++);
    }
  }
  for (int i = 0; i < int(n); ++i) {
    if (comp[2 * i] == comp[2 * i + 1]) {
      return false;
    }
    ans[i] = comp[2 * i] > comp[2 * i + 1];
  }
  return true;
}
bool intersect(int l1, int r1, int l2, int r2) {
  if (l1 > r1) {
    swap(l1, r1);
  }
  if (l2 > r2) {
    swap(l2, r2);
  }
  int cnt1 = (l1 < l2 && l2 < r1) + (l1 < r2 && r2 < r1);
  int cnt2 = (l2 < l1 && l1 < r2) + (l2 < r1 && r1 < r2);
  return cnt1 == 1 && cnt2 == 1;
}
void solve() {
  int n, m;
  cin >> n >> m;
  vector<pair<int, int> > r(m);
  for (int i = 0; i < int(m); ++i) {
    cin >> r[i].first >> r[i].second;
    r[i].first--, r[i].second--;
  }
  for (int i = 0; i < int(m); ++i) {
    for (int j = 0; j < int(m); ++j) {
      if (intersect(r[i].first, r[i].second, r[j].first, r[j].second)) {
        add_disjunction(0, i, 0, j);
        add_disjunction(1, i, 1, j);
      }
    }
  }
  if (two_sat(m)) {
    for (int i = 0; i < int(m); ++i) {
      cout << (ans[i] ? 'i' : 'o');
    }
    cout << endl;
  } else {
    cout << "Impossible" << endl;
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  srand((unsigned int)time(NULL));
  cout << setprecision(15) << fixed;
  solve();
  return 0;
}

### Prompt

Your challenge is to write a cpp solution to the following problem:

It is well known that Berland has n cities, which form the Silver ring — cities i and i + 1 (1 ≤ i < n) are connected by a road, as well as the cities n and 1. The goverment have decided to build m new roads. The list of the roads to build was prepared. Each road will connect two cities. Each road should be a curve which lies inside or outside the ring. New roads will have no common points with the ring (except the endpoints of the road).

Now the designers of the constructing plan wonder if it is possible to build the roads in such a way that no two roads intersect (note that the roads may intersect at their endpoints). If it is possible to do, which roads should be inside the ring, and which should be outside?

Input

The first line contains two integers n and m (4 ≤ n ≤ 100, 1 ≤ m ≤ 100). Each of the following m lines contains two integers ai and bi (1 ≤ ai, bi ≤ n, ai ≠ bi). No two cities will be connected by more than one road in the list. The list will not contain the roads which exist in the Silver ring.

Output

If it is impossible to build the roads in such a way that no two roads intersect, output Impossible. Otherwise print m characters. i-th character should be i, if the road should be inside the ring, and o if the road should be outside the ring. If there are several solutions, output any of them.

Examples

Input

4 2
1 3
2 4


Output

io


Input

6 3
1 3
3 5
5 1


Output

ooo

### Response

```cpp
#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:268435456")
using namespace std;
template <typename T>
T sqr(const T &x) {
  return x * x;
}
template <typename T>
T my_abs(const T &x) {
  return x < 0 ? -x : x;
}
const int INF = (int)1e9;
const long long LINF = (long long)6e18;
const long long INF64 = LINF;
const long long INFLL = LINF;
const long double EPS = 1e-15;
const long double PI = 3.1415926535897932384626433832795;
const long double ME = 1e-5;
const long long MOD = (int)1e9 + 7;
const long long MOD2 = (int)1e9 + 21;
const int SQN = 320;
const int LOGN = 17;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
const int N = (int)1e3 + 10;
vector<int> g[N];
vector<int> rg[N];
bool used[N];
int comp[N];
vector<int> topsort;
int ans[N];
void add_disjunction(bool na, int a, bool nb, int b) {
  int v = (2 * a) ^ (int)na;
  int nv = v ^ 1;
  int u = (2 * b) ^ (int)nb;
  int nu = u ^ 1;
  g[nv].push_back(u);
  rg[u].push_back(nv);
  g[nu].push_back(v);
  rg[v].push_back(nu);
}
void add_disjunction(bool na, int a) {
  int v = (2 * a) ^ (int)na;
  int nv = v ^ 1;
  g[nv].push_back(v);
  rg[v].push_back(nv);
}
void dfs1(int v) {
  used[v] = true;
  for (int i = 0; i < int(int(g[v].size())); ++i) {
    int u = g[v][i];
    if (!used[u]) {
      dfs1(u);
    }
  }
  topsort.push_back(v);
}
void dfs2(int v, int cc) {
  comp[v] = cc;
  for (int i = 0; i < int(int(rg[v].size())); ++i) {
    int u = rg[v][i];
    if (comp[u] == -1) {
      dfs2(u, cc);
    }
  }
}
bool two_sat(int n) {
  memset(used, false, 2 * n * sizeof(used[0]));
  memset(comp, -1, 2 * n * sizeof(comp[0]));
  for (int v = 0; v < int(2 * n); ++v) {
    if (!used[v]) {
      dfs1(v);
    }
  }
  int cc = 0;
  for (int i = int(2 * n) - 1; i >= 0; --i) {
    int v = topsort[i];
    if (comp[v] == -1) {
      dfs2(v, cc++);
    }
  }
  for (int i = 0; i < int(n); ++i) {
    if (comp[2 * i] == comp[2 * i + 1]) {
      return false;
    }
    ans[i] = comp[2 * i] > comp[2 * i + 1];
  }
  return true;
}
bool intersect(int l1, int r1, int l2, int r2) {
  if (l1 > r1) {
    swap(l1, r1);
  }
  if (l2 > r2) {
    swap(l2, r2);
  }
  int cnt1 = (l1 < l2 && l2 < r1) + (l1 < r2 && r2 < r1);
  int cnt2 = (l2 < l1 && l1 < r2) + (l2 < r1 && r1 < r2);
  return cnt1 == 1 && cnt2 == 1;
}
void solve() {
  int n, m;
  cin >> n >> m;
  vector<pair<int, int> > r(m);
  for (int i = 0; i < int(m); ++i) {
    cin >> r[i].first >> r[i].second;
    r[i].first--, r[i].second--;
  }
  for (int i = 0; i < int(m); ++i) {
    for (int j = 0; j < int(m); ++j) {
      if (intersect(r[i].first, r[i].second, r[j].first, r[j].second)) {
        add_disjunction(0, i, 0, j);
        add_disjunction(1, i, 1, j);
      }
    }
  }
  if (two_sat(m)) {
    for (int i = 0; i < int(m); ++i) {
      cout << (ans[i] ? 'i' : 'o');
    }
    cout << endl;
  } else {
    cout << "Impossible" << endl;
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  srand((unsigned int)time(NULL));
  cout << setprecision(15) << fixed;
  solve();
  return 0;
}

```