///In the name of God! :)
///mano peg darim code mizanim vase hellinet horrrray!
///khodesh cherto pert ziad mg

#include <iostream>
#include <vector>
#define pb push_back

using namespace std;

const int md = 1e9, maxn = 110;
int n, m, arr[maxn];
vector <int> fib;

void make_fib (){
    int cur1 = 1, cur2 = 1;
    fib.pb (1);
    for (int i = 0; i < maxn; i++){
        fib.pb (cur2 % md);
        cur2 = (cur1 + cur2) % md;
        cur1 = fib[fib.size() - 1];
    }
}

int find_ans (int l, int r){
    int st = 0; long long ans = 0;
    for (int i = l; i <= r; i++){
        ans = (ans + (1ll * arr[i] * fib[st]) % md) % md;
        st++;
    }
    return ans;
}

int main()
{
   make_fib ();
   cin>>n>>m;
   for (int i = 0; i < n; i++)
        cin>>arr[i];
   for (int i = 0; i < m; i++){
        int t;  cin>>t;
        if (t == 1){
            int x, v;   cin>>x>>v;
            arr[x - 1] = v;
        }
        if (t == 2){
            int l, r;   cin>>l>>r;  l--;    r--;
            cout<<find_ans (l, r)<<'\n';
        }
        if (t == 3){
            int l, r, d;    cin>>l>>r>>d;   l--, r--;
            for (int j = l; j <= r; j++)
                arr[j] += d;
        }
   }
   return 0;
}


#include<bits/stdc++.h>

#define LL long long
#define Dl double
#define Pb push_back
#define Po pop_back
#define Mp make_pair
#define Ub upper_bound
#define Lb lower_bound
#define In insert
#define All(x) x.begin(), x.end()
#define mem(a, b) memset(a, b, sizeof(a))
#define fast ios_base::sync_with_stdio(0);cin.tie(0)

using namespace std;

typedef vector<LL> Vl;
typedef vector<Vl> VVl;
typedef pair<LL, LL> Pll;
typedef vector<Pll> Vpl;
typedef queue<LL> Ql;
typedef stack<LL> Sl;
#define X first
#define Y second
#define mx2 110
#define mx3 1010
#define mx4 10010
#define mx5 100010
#define mx6 1000010

LL n, m;
LL a[mx2];
LL f[mx2];
LL mod = 1e9;

void fib()
{
    f[0] = f[1] = 1;

    for(LL i = 2; i <= n; i++)
        f[i] = ((f[i - 1] % mod) + (f[i - 2] % mod)) % mod;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    cin >> n >> m;

    fib();

    for(LL i = 1; i <= n; i++)
        cin >> a[i];

    while(m--){

        LL t;
        cin >> t;

        t--;
        if(t){
            LL l, r;
            cin >> l >> r;

            LL ans = 0;
            for(LL i = l, j = 0; i <= r; i++, j++)
                ans = (ans + ((f[j] % mod) * (a[i] % mod)) % mod) % mod;

            cout << ans % mod << '\n';
        }
        else{
            LL x, b;
            cin >> x >> b;
            a[x] = b;
        }
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int maxn = 100 + 7;
const int mod = 1000 * 1000 * 1000;

int n, m;
int a[maxn], f[maxn];

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;
	f[0] = f[1] = 1;
	for (int i = 2; i <= n; ++i)
		f[i] = (f[i - 1] + f[i - 2]) % mod;
	for (int i = 0; i < n; ++i)
		cin >> a[i];
	while (m --)
	{
		int t;
		cin >> t;
		if (t == 1)
		{
			int x, v;
			cin >> x >> v;
			x --;
			a[x] = v;
		}
		else
		{
			int l, r;
			cin >> l >> r;
			l --;
			int ans = 0;
			for (int i = l; i < r; ++i)
				ans = (ans + 1LL * f[i - l] * a[i] % mod) % mod;
			cout << ans << "\n";
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=200010;
typedef long long ll;
const int mod=1e9;
ll a[N],f[N];int n,m;
void fib()
{
	f[0]=1;f[1]=1;
	for(int i=2;i<=n;i++) f[i]=(f[i-1]+f[i-2])%mod;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	fib();
	for(int i=1;i<=m;i++)
	{
		int oo;scanf("%d",&oo);
		if(oo==1)
		{
			int t;ll x;scanf("%d%lld",&t,&x);
			a[t]=x;
		}else if(oo==2)
		{
			int l,r;scanf("%d%d",&l,&r); ll ans=0;
			for(int i=l;i<=r;i++)
			{
				(ans+=(f[i-l]*a[i])%mod)%=mod;
			}
			printf("%lld\n",ans);
		}else
		{
			int l,r;ll x;scanf("%d%d%lld",&l,&r,&x);
			for(int i=l;i<=r;i++) a[i]+=x;
	    }
	}
 }
//hellobig_tq


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int nmax = 2 * 100000 + 10;
const ll mod = 1000000000;

ll ar[nmax], f[nmax];

int main()
{
    ios_base::sync_with_stdio ( 0 );
    cin.tie ( 0 );

    int n, m;
    cin >> n >> m;

    f[0] = f[1] = 1ll;
    for ( int i = 2; i <= n; ++i )
        f[i] = ( f[i - 1]%mod + f[i - 2]%mod ) % mod;

    for ( int i = 1; i <= n; ++i )
        cin >> ar[i];

    while ( m-- )
    {
        int t,  l, r;
        cin >> t >> l >> r;
        if ( t == 1 )
        {
            ar[l] =(ll) r;
        }
        else
        {
            ll sum = 0;
            for ( int i = 0; i <= r - l; ++i )
                sum = (sum%mod + ( f[i]%mod * ar[l + i]%mod ) % mod)%mod;
            cout << sum << "\n";
        }
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int nmax = 2 * 100000 + 10;
const int mod = 1000000000;

int ar[nmax], f[nmax];

int main()
{
    ios_base::sync_with_stdio ( 0 );
    cin.tie ( 0 );

    int n, m;
    cin >> n >> m;

    f[0] = f[1] = 1;
    for ( int i = 2; i <= n; ++i )
        f[i] = ( f[i - 1]%mod + f[i - 2]%mod ) % mod;

    for ( int i = 1; i <= n; ++i )
        cin >> ar[i];

    while ( m-- )
    {
        int t,  l, r;
        cin >> t >> l >> r;
        if ( t == 1 )
        {
            ar[l] = r;
        }
        else
        {
            int sum = 0;
            for ( int i = 0; i <= r - l; ++i )
                sum = (sum%mod + ( f[i]%mod * ar[l + i]%mod ) % mod)%mod;
            cout << sum << "\n";
        }
    }

    return 0;
}


//
//  main.cpp
//  Kolcevaya2
//
//  Created by Tim Reizin on 3/7/20.
//  Copyright © 2020 Tim Reizin. All rights reserved.
//

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

vector<int> adjG[210];
vector<pair<int, int>> newRoads;
bool used[210];
vector<int> vertex;
pair<int, int> componentu[210];

void dfs1(int start)
{
    used[start] = true;
    for (auto i : adjG[start]) if (!used[i]) dfs1(i);
    vertex.push_back(start);
}

void dfs2(int start, int counter)
{
    used[start] = true;
    for (auto i : adjG[start]) if (!used[i]) dfs2(i, counter);
    if (start >= 103) componentu[start - 103].second = counter;
    else componentu[start].first = counter;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    newRoads.resize(m + 1);
    for (int i = 1; i <= m; ++i)
    {
        cin >> newRoads[i].first >> newRoads[i].second;
        if (newRoads[i].first > newRoads[i].second) swap(newRoads[i].first, newRoads[i].second);
    }
    for (int i = 1; i <= m; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
            auto a = newRoads[i], b = newRoads[j];
            if (a != b)
            {
                if ((a.first < b.first && b.first < a.second) || (a.first < b.second && b.second < a.second) || (b.first < a.first && a.first < b.second) || (b.first < a.second && a.second < b.second))
                {
                    adjG[i + 103].push_back(j);
                    adjG[j + 103].push_back(i);
                    adjG[j].push_back(i + 103);
                    adjG[i].push_back(j + 103);
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i) if (!used[i]) dfs1(i);
    for (int i = 104; i <= n + 103; ++i) if (!used[i]) dfs1(i);
    reverse(vertex.begin(), vertex.end());
    for (int i = 1; i <= n; ++i) used[i] = false;
    for (int i = 104; i <= n + 103; ++i) used[i] = false;
    int counter = 0;
    for (auto i : vertex)
    {
        if (!used[i])
        {
            dfs2(i, counter);
            ++counter;
        }
    }
    bool can = true;
    string answer = "";
    for (int i = 1; i <= m; ++i)
    {
        if (componentu[i].first == componentu[i].second)
        {
            can = false;
            break;
        }
        if (componentu[i].first > componentu[i].second) answer += 'i';
        else answer += 'o';
    }
    if (!can) cout << "Impossible";
    else cout << answer;
    return 0;
}


//
//  main.cpp
//  Kolcevaya2
//
//  Created by Tim Reizin on 3/7/20.
//  Copyright © 2020 Tim Reizin. All rights reserved.
//

#include <iostream>
#include <vector>
#include <string>

using namespace std;

vector<int> adjG[210];
vector<pair<int, int>> newRoads;
bool used[210];
vector<int> vertex;
pair<int, int> componentu[210];

void dfs1(int start)
{
    used[start] = true;
    for (auto i : adjG[start]) if (!used[i]) dfs1(i);
    vertex.push_back(start);
}

void dfs2(int start, int counter)
{
    used[start] = true;
    for (auto i : adjG[start]) if (!used[i]) dfs2(i, counter);
    if (start >= 103) componentu[start - 103].second = counter;
    else componentu[start].first = counter;
}

int main()
{
    int n, m;
    cin >> n >> m;
    newRoads.resize(m);
    for (int i = 1; i <= m; ++i)
    {
        cin >> newRoads[i].first >> newRoads[i].second;
        if (newRoads[i].first > newRoads[i].second) swap(newRoads[i].first, newRoads[i].second);
    }
    for (int i = 1; i <= m; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
            auto a = newRoads[i], b = newRoads[j];
            if (a != b)
            {
                if ((a.first < b.first && b.first < a.second) || (a.first < b.second && b.second < a.second) || (b.first < a.first && a.first < b.second) || (b.first < a.second && a.second < b.second))
                {
                    adjG[i + 103].push_back(j);
                    adjG[j + 103].push_back(i);
                    adjG[j].push_back(i + 103);
                    adjG[i].push_back(j + 103);
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i) if (!used[i]) dfs1(i);
    for (int i = 104; i <= n + 103; ++i) if (!used[i]) dfs1(i);
    reverse(vertex.begin(), vertex.end());
    for (int i = 1; i <= n; ++i) used[i] = false;
    for (int i = 104; i <= n + 103; ++i) used[i] = false;
    int counter = 0;
    for (auto i : vertex)
    {
        if (!used[i])
        {
            dfs2(i, counter);
            ++counter;
        }
    }
    bool can = true;
    string answer = "";
    for (int i = 1; i <= m; ++i)
    {
        if (componentu[i].first == componentu[i].second)
        {
            can = false;
            break;
        }
        if (componentu[i].first > componentu[i].second) answer += 'i';
        else answer += 'o';
    }
    if (!can) cout << "Impossible";
    else cout << answer;
    return 0;
}


//
//  main.cpp
//  Kolcevaya2
//
//  Created by Tim Reizin on 3/7/20.
//  Copyright © 2020 Tim Reizin. All rights reserved.
//

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

vector<int> adjG[210];
vector<pair<int, int>> newRoads;
bool used[210];
vector<int> vertex;
pair<int, int> componentu[210];

void dfs1(int start)
{
    used[start] = true;
    for (auto i : adjG[start]) if (!used[i]) dfs1(i);
    vertex.push_back(start);
}

void dfs2(int start, int counter)
{
    used[start] = true;
    for (auto i : adjG[start]) if (!used[i]) dfs2(i, counter);
    if (start >= 103) componentu[start - 103].second = counter;
    else componentu[start].first = counter;
}

bool isIntersect(pair<int, int> a, pair<int, int> b)
{
    if ((a.first <= b.first && b.second <= a.second) || (b.first <= a.first && a.second <= b.second)) return false;
    if (a.second <= b.first || b.second <= a.first) return false;
    return true;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    newRoads.resize(m + 1);
    for (int i = 1; i <= m; ++i)
    {
        cin >> newRoads[i].first >> newRoads[i].second;
        if (newRoads[i].first > newRoads[i].second) swap(newRoads[i].first, newRoads[i].second);
    }
    for (int i = 1; i <= m; ++i)
    {
        for (int j = i + 1; j <= m; ++j)
        {
            auto a = newRoads[i], b = newRoads[j];
            if (i != j)
            {
                if (isIntersect(a, b))
                {
                    adjG[i + 103].push_back(j);
                    adjG[j + 103].push_back(i);
                    adjG[j].push_back(i + 103);
                    adjG[i].push_back(j + 103);
                }
            }
        }
    }
    for (int i = 1; i <= m; ++i) if (!used[i]) dfs1(i);
    for (int i = 104; i <= m + 103; ++i) if (!used[i]) dfs1(i);
    reverse(vertex.begin(), vertex.end());
    for (int i = 1; i <= m; ++i) used[i] = false;
    for (int i = 104; i <= m + 103; ++i) used[i] = false;
    int counter = 1;
    for (auto i : vertex)
    {
        if (!used[i])
        {
            dfs2(i, counter);
            ++counter;
        }
    }
    bool can = true;
    string answer = "";
    for (int i = 1; i <= m; ++i)
    {
        if (componentu[i].first == componentu[i].second)
        {
            can = false;
            break;
        }
        if (componentu[i].first > componentu[i].second) answer += 'i';
        else answer += 'o';
    }
    if (!can) cout << "Impossible";
    else cout << answer;
    return 0;
}


//
//  main.cpp
//  Kolcevaya2
//
//  Created by Tim Reizin on 3/7/20.
//  Copyright © 2020 Tim Reizin. All rights reserved.
//

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

vector<int> adjG[210];
vector<pair<int, int>> newRoads;
bool used[210];
vector<int> vertex;
pair<int, int> componentu[210];

void dfs1(int start)
{
    used[start] = true;
    for (auto i : adjG[start]) if (!used[i]) dfs1(i);
    vertex.push_back(start);
}

void dfs2(int start, int counter)
{
    used[start] = true;
    for (auto i : adjG[start]) if (!used[i]) dfs2(i, counter);
    if (start >= 103) componentu[start - 103].second = counter;
    else componentu[start].first = counter;
}

int main()
{
    int n, m;
    cin >> n >> m;
    newRoads.resize(m);
    for (int i = 1; i <= m; ++i)
    {
        cin >> newRoads[i].first >> newRoads[i].second;
        if (newRoads[i].first > newRoads[i].second) swap(newRoads[i].first, newRoads[i].second);
    }
    for (int i = 1; i <= m; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
            auto a = newRoads[i], b = newRoads[j];
            if (a != b)
            {
                if ((a.first < b.first && b.first < a.second) || (a.first < b.second && b.second < a.second) || (b.first < a.first && a.first < b.second) || (b.first < a.second && a.second < b.second))
                {
                    adjG[i + 103].push_back(j);
                    adjG[j + 103].push_back(i);
                    adjG[j].push_back(i + 103);
                    adjG[i].push_back(j + 103);
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i) if (!used[i]) dfs1(i);
    for (int i = 104; i <= n + 103; ++i) if (!used[i]) dfs1(i);
    reverse(vertex.begin(), vertex.end());
    for (int i = 1; i <= n; ++i) used[i] = false;
    for (int i = 104; i <= n + 103; ++i) used[i] = false;
    int counter = 0;
    for (auto i : vertex)
    {
        if (!used[i])
        {
            dfs2(i, counter);
            ++counter;
        }
    }
    bool can = true;
    string answer = "";
    for (int i = 1; i <= m; ++i)
    {
        if (componentu[i].first == componentu[i].second)
        {
            can = false;
            break;
        }
        if (componentu[i].first > componentu[i].second) answer += 'i';
        else answer += 'o';
    }
    if (!can) cout << "Impossible";
    else cout << answer;
    return 0;
}


#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>
#ifndef _2SAT_HPP
#define _2SAT_HPP
#ifndef KOSARAJU_HPP
#define KOSARAJU_HPP
#ifndef GLOBAL_HPP
#define GLOBAL_HPP
#define for_n(i,n) for (int i=0;i<n;i++)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int oo = 1000*1000*1000;
inline int readInt ()
{
    int v;
    cin >> v;
    return v;
}
#endif // GLOBAL_HPP
#ifndef GRAPHE_HPP
#define GRAPHE_HPP
// Propriétés du graphe (TODO: ne pas utiliser de int, car on peut échanger propriétés et nbNoeuds dans le constructeur)
const int GRAPHE_ORIENTE = 1<<0;
const int GRAPHE_NON_ORIENTE = 0;
const int GRAPHE_PONDERE = 1<<1;
const int GRAPHE_NON_PONDERE = 0;
class Graphe
{
public:
    Graphe (const int proprietes, const int nbNoeuds=0) :
        m_proprietes (proprietes),
        m_nbArcs (0)
    {
        m_noeuds.resize(nbNoeuds);
    }
    void lire (const bool doitDecrementer=false)
    {
        int nbNoeuds, nbArcs;
        cin >> nbNoeuds >> nbArcs;
        m_noeuds.resize(nbNoeuds);
        for (int i=0; i<nbArcs; i++) {
            int noeud1, noeud2;
            int ponderation = 1;
            cin >> noeud1 >> noeud2;
            if (m_proprietes & GRAPHE_PONDERE) cin >> ponderation;
            if (doitDecrementer) noeud1--, noeud2--;
            if (m_proprietes & GRAPHE_ORIENTE) {
                ajouterArc(noeud1, noeud2, ponderation);
            }
            else {
                ajouterArrete(noeud1, noeud2, ponderation);
            }
        }
    }
    // Lecture
    inline int nbNoeuds () const
    {
        return m_noeuds.size();
    }
    inline int nbVoisins (const int noeud) const
    {
        return m_noeuds[noeud].size();
    }
    inline int voisin (const int noeud, const int voisin) const
    {
        return m_noeuds[noeud][voisin].first;
    }
    inline int ponderation (const int noeud, const int voisin) const
    {
        return m_ponderations[ m_noeuds[noeud][voisin].second ];
    }
    inline const vector<pair<int,int>>& arcs (const int noeud) const
    {
        return m_noeuds[noeud];
    }
    // Modification
    inline void ajouterArc (const int noeud1, const int noeud2, const int ponderation=1)
    {
        m_noeuds[noeud1].push_back(make_pair(noeud2, m_nbArcs++));
        m_ponderations.push_back(ponderation);
    }
    inline void ajouterArrete (const int noeud1, const int noeud2, const int ponderation=1)
    {
        m_noeuds[noeud1].push_back(make_pair(noeud2, m_nbArcs));
        m_noeuds[noeud2].push_back(make_pair(noeud1, m_nbArcs++));
        m_ponderations.push_back(ponderation);
    }
private:
    int m_proprietes;
    int m_nbArcs;
    vector<vector<pair<int, int>>> m_noeuds; // [noeud][voisin] --> {idVoisin, idArc}
    vector<int> m_ponderations;
};
#endif // GRAPHE_HPP
#ifndef INVERSERARCS_HPP
#define INVERSERARCS_HPP
Graphe inverserArcs (const Graphe &graphe)
{
    Graphe nouveauGraphe (GRAPHE_ORIENTE, graphe.nbNoeuds());
    for (int noeud=0; noeud<graphe.nbNoeuds(); noeud++) {
        for (int iVoisin=0; iVoisin<graphe.nbVoisins(noeud); iVoisin++) {
            nouveauGraphe.ajouterArc(graphe.voisin(noeud, iVoisin), noeud);
        }
    }
    return nouveauGraphe;
}
#endif // INVERSERARCS_HPP
// Calcule les composantes fortement connexes d'un graphe orienté
class Kosaraju
{
public:
    Kosaraju (const Graphe &graphe) :
        m_nbCFCs (0)
    {
        m_CFCs.resize(graphe.nbNoeuds());
        m_estVu.resize(graphe.nbNoeuds(), false);
        for (int i=0; i<graphe.nbNoeuds(); i++) calculerOrdreParcours(graphe, i);
        fill(m_estVu.begin(), m_estVu.end(), false);
        const Graphe grapheInverse = inverserArcs(graphe);
        for (int i=m_aVisiter.size()-1; i>=0; i--) {
            const int noeud = m_aVisiter[i];
            if (!m_estVu[noeud]) {
                ajouterDansCFC(grapheInverse, noeud, m_nbCFCs);
                m_nbCFCs++;
            }
        }
    }
    int nbCFCs () const
    {
        return m_nbCFCs;
    }
    int CFC (const int noeud) const
    {
        return m_CFCs[noeud];
    }
private:
    void calculerOrdreParcours (const Graphe &g, const int noeud)
    {
        if (m_estVu[noeud]) return;
        m_estVu[noeud] = true;
        for (int i=0; i<g.nbVoisins(noeud); i++) {
            calculerOrdreParcours(g, g.voisin(noeud, i));
        }
        m_aVisiter.push_back(noeud);
    }
    void ajouterDansCFC (const Graphe &g, const int noeud, const int idCFC)
    {
        if (m_estVu[noeud]) return;
        m_estVu[noeud] = true;
        m_CFCs[noeud] = idCFC;
        for (int i=0; i<g.nbVoisins(noeud); i++) {
            ajouterDansCFC(g, g.voisin(noeud, i), idCFC);
        }
    }
    vector<int> m_aVisiter;
    vector<bool> m_estVu;
    int m_nbCFCs;
    vector<int> m_CFCs;
};
#endif // KOSARAJU_HPP
class Resoudre2SAT
{
public:
    Resoudre2SAT (const int nbVariables) :
        m_nbVariables (nbVariables),
        m_grapheContraintes (GRAPHE_ORIENTE, 2*nbVariables)
    {}
    inline int non (const int x) const
    {
        if (x < m_nbVariables) return x + m_nbVariables;
        return x - m_nbVariables;
    }
    void ajouterContrainte (const int a, const int b) // a v b
    {
        if (a%m_nbVariables != b%m_nbVariables) {
            m_grapheContraintes.ajouterArc(non(a), b);
            m_grapheContraintes.ajouterArc(non(b), a);
        }
        else if (a == b) {
            m_grapheContraintes.ajouterArc(non(a), a);
        }
    }
    // Renvoie s'il existe une solution, et calcule une affectation possible
    bool resoudre ()
    {
        Kosaraju kosaraju (m_grapheContraintes); // Calcul des CFC
        m_affectations.clear();
        for (int i=0; i<m_nbVariables; i++) {
            if (kosaraju.CFC(i) == kosaraju.CFC(non(i))) {
                m_affectations.clear();
                return false;
            }
            m_affectations.push_back(kosaraju.CFC(i) > kosaraju.CFC(non(i)));
        }
        return true;
    }
    bool estVrai (const int x) const
    {
        return m_affectations[x];
    }
private:
    int m_nbVariables;
    // Représentation d'une variable par un noeud x
    //  - si x < nbVariables : représente x
    //  - si x >= nbVariables : représente non x
    Graphe m_grapheContraintes;
    vector<bool> m_affectations;
};
#endif // _2SAT_HPP
using namespace std;
const int NB_MAX_ARRETES = 100;
int nbNoeuds, nbArretes;
pair<int, int> arretes[NB_MAX_ARRETES];
bool getEstDansIntervalle (const int debut, const int fin, const int pos)
{
    if (debut < fin) {
        return debut < pos && pos < fin;
    }
    else {
        return pos > debut || pos < fin;
    }
}
int main ()
{
    scanf("%d %d", &nbNoeuds, &nbArretes);
    for (int i=0; i<nbArretes; i++) {
        int a, b;
        scanf("%d %d", &a, &b);
        a--, b--;
        arretes[i] = make_pair(a, b);
    }
    Resoudre2SAT solver (nbArretes);
    for (int iArrete1=0; iArrete1<nbArretes; iArrete1++) {
        const int a1 = arretes[iArrete1].first;
        const int b1 = arretes[iArrete1].second;
        for (int iArrete2=iArrete1+1; iArrete2<nbArretes; iArrete2++) {
            const int a2 = arretes[iArrete2].first;
            const int b2 = arretes[iArrete2].second;
            if (getEstDansIntervalle(a1, b1, a2) != getEstDansIntervalle(a1, b1, b2)
             && a1 != a2 && a1 != b2 && b1 != a2 && b1 != b2) {
                solver.ajouterContrainte(iArrete1, iArrete2);
                solver.ajouterContrainte(solver.non(iArrete1), solver.non(iArrete2));
            }
        }
    }
    if (!solver.resoudre()) {
        printf("Impossible\n");
    }
    else {
        for (int i=0; i<nbArretes; i++) {
            if (solver.estVrai(i)) {
                printf("i");
            }
            else {
                printf("o");
            }
        }
        printf("\n");
    }
}


#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>

using namespace std;

const int NB_MAX_ARRETES = 100;

/*
 * 2-SAT
 */

const int NB_MAX_VARIABLES = 100;
int nbVariables; // à initialiser

int affectationsNoeuds[2*NB_MAX_VARIABLES];
vector<int> implicationsNoeuds[2*NB_MAX_VARIABLES];

inline int non (const int x) { return (x + nbVariables) % (2*nbVariables); }

// Représentation d'une contrainte sur une variable
//  - si x < nbVariables : représente x
//  - si x >= nbVariables : représente non x
void ajouterContrainte (const int a, const int b) // a v b
{
    if (a%nbVariables != b%nbVariables) {
        implicationsNoeuds[non(a)].push_back(b);
        implicationsNoeuds[non(b)].push_back(a);
    }
}

bool affecter (const int noeud, const int valeur)
{
    if (affectationsNoeuds[noeud] == valeur) return true;
    if (affectationsNoeuds[noeud] != -1) return false;

    affectationsNoeuds[noeud] = valeur;

    if (valeur) {
        for (const int voisin : implicationsNoeuds[noeud]) {
            if (!affecter(voisin, true) || !affecter(non(voisin), false)) return false;
        }
    }

    return true;
}

bool resoudre_2SAT ()
{
    fill(affectationsNoeuds, affectationsNoeuds+2*nbVariables, -1);

    for (int x=0; x<nbVariables; x++) {
        if (affectationsNoeuds[x] == -1) {
            if (!affecter(x, true) || !affecter(non(x), false)) {
                return false;
            }
        }
    }

    return true;
}

int nbNoeuds, nbArretes;
pair<int, int> arretes[NB_MAX_ARRETES];

bool getEstDansIntervalle (const int debut, const int fin, const int pos)
{
    if (debut < fin) {
        return debut < pos && pos < fin;
    }
    else {
        return pos > debut || pos < fin;
    }
}

int main ()
{
    scanf("%d %d", &nbNoeuds, &nbArretes);
    nbVariables = nbArretes;

    for (int i=0; i<nbArretes; i++) {
        int a, b;
        scanf("%d %d", &a, &b);
        a--, b--;

        arretes[i] = make_pair(a, b);
    }

    for (int iArrete1=0; iArrete1<nbArretes; iArrete1++) {
        const int a1 = arretes[iArrete1].first;
        const int b1 = arretes[iArrete1].second;

        for (int iArrete2=iArrete1+1; iArrete2<nbArretes; iArrete2++) {
            const int a2 = arretes[iArrete2].first;
            const int b2 = arretes[iArrete2].second;

            if (getEstDansIntervalle(a1, b1, a2) != getEstDansIntervalle(a1, b1, b2)
             && a1 != a2 && a1 != b2 && b1 != a2 && b1 != b2) {
                ajouterContrainte(iArrete1, iArrete2);
                ajouterContrainte(non(iArrete1), non(iArrete2));
            }

        }
    }

    if (!resoudre_2SAT()) {
        printf("Impossible\n");
    }
    else {
        for (int i=0; i<nbArretes; i++) {
            if (affectationsNoeuds[i]) {
                printf("i");
            }
            else {
                printf("o");
            }
        }
        printf("\n");
    }
}


#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>

using namespace std;

const int NB_MAX_ARRETES = 100;

/*
 * 2-SAT
 */

const int NB_MAX_VARIABLES = 100;
int nbVariables; // à initialiser

int affectationsNoeuds[2*NB_MAX_VARIABLES];
vector<int> implicationsNoeuds[2*NB_MAX_VARIABLES];

inline int non (const int x) { return (x + nbVariables) % (2*nbVariables); }

// Représentation d'une contrainte sur une variable
//  - si x < nbVariables : représente x
//  - si x >= nbVariables : représente non x
void ajouterContrainte (const int a, const int b) // a v b
{
    implicationsNoeuds[non(a)].push_back(b);
    implicationsNoeuds[non(b)].push_back(a);
}

bool affecter (const int noeud, const int valeur)
{
    if (affectationsNoeuds[noeud] == valeur) return true;
    if (affectationsNoeuds[noeud] != -1) return false;

    affectationsNoeuds[noeud] = valeur;

    if (valeur) {
        for (const int voisin : implicationsNoeuds[noeud]) {
            if (!affecter(voisin, true) || !affecter(non(voisin), false)) return false;
        }
    }

    return true;
}

bool resoudre_2SAT ()
{
    fill(affectationsNoeuds, affectationsNoeuds+2*nbVariables, -1);

    for (int x=0; x<nbVariables; x++) {
        if (affectationsNoeuds[x] == -1) {
            if (!affecter(x, true) || !affecter(non(x), false)) {
                return false;
            }
        }
    }

    return true;
}

int nbNoeuds, nbArretes;
pair<int, int> arretes[NB_MAX_ARRETES];

int main ()
{
    scanf("%d %d", &nbNoeuds, &nbArretes);
    nbVariables = nbArretes;

    for (int i=0; i<nbArretes; i++) {
        int a, b;
        scanf("%d %d", &a, &b);
        a--, b--;

        if (b < a) {
            b += nbNoeuds;
        }

        arretes[i] = make_pair(a, b);
    }

    for (int iArrete1=0; iArrete1<nbArretes; iArrete1++) {
        const int a1 = arretes[iArrete1].first;
        const int b1 = arretes[iArrete1].second;

        for (int iArrete2=iArrete1+1; iArrete2<nbArretes; iArrete2++) {
            const int a2 = arretes[iArrete2].first;
            const int b2 = arretes[iArrete2].second;

            if ((a1 < a2 && b1 > a2)  ||  (a1 < b2 && a2 > b2)) {
                ajouterContrainte(iArrete1, iArrete2);
                ajouterContrainte(non(iArrete1), non(iArrete2));
            }

        }
    }

    if (!resoudre_2SAT()) {
        printf("Impossible\n");
    }
    else {
        for (int i=0; i<nbArretes; i++) {
            if (affectationsNoeuds[i]) {
                printf("i");
            }
            else {
                printf("o");
            }
        }
        printf("\n");
    }
}


#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>

using namespace std;

const int NB_MAX_ARRETES = 100;

/*
 * 2-SAT
 */

const int NB_MAX_VARIABLES = 100;
int nbVariables; // à initialiser

int affectationsNoeuds[2*NB_MAX_VARIABLES];
vector<int> implicationsNoeuds[2*NB_MAX_VARIABLES];

inline int non (const int x) { return (x + nbVariables) % (2*nbVariables); }

// Représentation d'une contrainte sur une variable
//  - si x < nbVariables : représente x
//  - si x >= nbVariables : représente non x
void ajouterContrainte (const int a, const int b) // a v b
{
    implicationsNoeuds[non(a)].push_back(b);
    implicationsNoeuds[non(b)].push_back(a);
}

bool affecter (const int noeud, const int valeur)
{
    if (affectationsNoeuds[noeud] == valeur) return true;
    if (affectationsNoeuds[noeud] != -1) return false;

    affectationsNoeuds[noeud] = valeur;

    if (valeur) {
        for (const int voisin : implicationsNoeuds[noeud]) {
            if (!affecter(voisin, true) || !affecter(non(voisin), false)) return false;
        }
    }

    return true;
}

bool resoudre_2SAT ()
{
    fill(affectationsNoeuds, affectationsNoeuds+2*nbVariables, -1);

    for (int x=0; x<nbVariables; x++) {
        if (affectationsNoeuds[x] == -1) {
            if (!affecter(x, true) || !affecter(non(x), false)) {
                return false;
            }
        }
    }

    return true;
}

int nbNoeuds, nbArretes;
pair<int, int> arretes[NB_MAX_ARRETES];

bool getEstDansIntervalle (const int debut, const int fin, const int pos)
{
    if (debut < fin) {
        return debut < pos && pos < fin;
    }
    else {
        return pos > debut || pos < fin;
    }
}

int main ()
{
    scanf("%d %d", &nbNoeuds, &nbArretes);
    nbVariables = nbArretes;

    for (int i=0; i<nbArretes; i++) {
        int a, b;
        scanf("%d %d", &a, &b);
        a--, b--;

        arretes[i] = make_pair(a, b);
    }

    for (int iArrete1=0; iArrete1<nbArretes; iArrete1++) {
        const int a1 = arretes[iArrete1].first;
        const int b1 = arretes[iArrete1].second;

        for (int iArrete2=iArrete1+1; iArrete2<nbArretes; iArrete2++) {
            const int a2 = arretes[iArrete2].first;
            const int b2 = arretes[iArrete2].second;

            if (getEstDansIntervalle(a1, b1, a2) != getEstDansIntervalle(a1, b1, b2)
             && a1 != a2 && a1 != b2 && b1 != a2 && b1 != b2) {
                ajouterContrainte(iArrete1, iArrete2);
                ajouterContrainte(non(iArrete1), non(iArrete2));

                cerr << iArrete1+1 << " " << iArrete2+1 << endl;
            }

        }
    }

    if (!resoudre_2SAT()) {
        printf("Impossible\n");
    }
    else {
        for (int i=0; i<nbArretes; i++) {
            if (affectationsNoeuds[i]) {
                printf("i");
            }
            else {
                printf("o");
            }
        }
        printf("\n");
    }
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;
using namespace std;
typedef long long int ll;
// template <typename T>
// using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
//     tree_order_statistics_node_update>;
// #define ll int
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define pii pair<ll,ll>

const ll N = 1e4;
const ll p = 31;
// const ll inf= 1e14;
const ll mod = 1e9+7;
std::vector<ll> g[N],gt[N];
bool used[N];
vector<ll> order;
ll comp[N];
ll n,m;
vector<bool> assignment;

void dfs1(ll v) {
    used[v] = true;
    // cout<<v<<" : ";
    // for(auto u:g[v]){
    //  cout<<u<<" ";
    // }
    // cout<<'\n';
    for (auto u : g[v]) {
        if (!used[u])
            dfs1(u);
    }
    order.push_back(v);
}

void dfs2(ll v, ll cl) {
    comp[v] = cl;
    for (auto u : gt[v]) {
        if (comp[u] == -1)
            dfs2(u, cl);
    }
}

bool solve_2SAT() {
     m = m*2;
     fill(used,used+n+2,0);
    for (int i = 0; i < m; ++i) {
        if (!used[i])
            dfs1(i);
    }
    fill(comp,comp+m+9,-1);
    for (int i = 0, j = 0; i < m; ++i) {
        int v = order[m - i - 1];
        if (comp[v] == -1)
            dfs2(v, j++);
    }

    assignment.assign(m / 2, false);
    for (int i = 0; i < m; i += 2) {
        if (comp[i] == comp[i + 1])
            return false;
        assignment[i / 2] = comp[i] > comp[i + 1];
    }
    return true;
}
bool intersect(pii a,pii b){

     if((b.x<a.x||a.y<b.x)&&(a.x<b.y||b.y<a.y)){
          return true;
     }
     if((b.y<a.x||a.y<b.y)&&(a.x<b.x&&b.x<a.y)){
          return true;
     }
     return false;
}
void solve(){
     cin>>n>>m;
     pii ex[m];
     for(int i = 0;i<m;i++){
          cin>>ex[i].first>>ex[i].second;
          if(ex[i].first>ex[i].second){
               swap(ex[i].first,ex[i].second);
          }
          ex[i].second--;ex[i].first--;
     }
     for(int i = 0;i<m;i++){
          for(int j = 0;j<m;j++){
               if(intersect(ex[i],ex[j])){
                    g[2*i].pb(2*j+1);
                    gt[2*j+1].pb(2*i);
               }
          }
     }
     if(solve_2SAT()){
          for(auto i:assignment){
               if(i){
                    cout<<"i";
               }
               else{
                    cout<<"o";
               }
          }
     }
     else{
          cout<<"Impossible";
     }

}
int main() {
     ios::sync_with_stdio(false);
     cin.tie(0);
     cout.tie(0);
     #ifndef ONLINE_JUDGE
     freopen("input.txt", "r", stdin);
     freopen("output.txt", "w", stdout);

     #endif

     ll t = 1;
     // cin>>t;
     while(t--){
          solve();

     }
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;
using namespace std;
typedef long long int ll;
// template <typename T>
// using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
//     tree_order_statistics_node_update>;
// #define ll int
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define pii pair<ll,ll>

const ll N = 1e4;
const ll p = 31;
// const ll inf= 1e14;
const ll mod = 1e9+7;
std::vector<ll> g[N],gt[N];
bool used[N];
vector<ll> order;
ll comp[N];
ll n,m;
vector<bool> assignment;

void dfs1(ll v) {
    used[v] = true;
    // cout<<v<<" : ";
    // for(auto u:g[v]){
    //  cout<<u<<" ";
    // }
    // cout<<'\n';
    for (auto u : g[v]) {
        if (!used[u])
            dfs1(u);
    }
    order.push_back(v);
}

void dfs2(ll v, ll cl) {
    comp[v] = cl;
    for (auto u : gt[v]) {
        if (comp[u] == -1)
            dfs2(u, cl);
    }
}

bool solve_2SAT() {
     m = m*2;
     fill(used,used+m+2,0);
     // for(int i = 0;i<m;i++){
     //      cout<<i<<": ";
     //      for(auto v:g[i]){
     //           cout<<v<<" ";
     //      }
     //      cout<<'\n';
     // }
     for (int i = 0; i < m; ++i) {
          if (!used[i])
          dfs1(i);
     }
     fill(comp,comp+m+9,-1);
     for (int i = 0, j = 0; i < m; ++i) {
        int v = order[m - i - 1];
        if (comp[v] == -1)
            dfs2(v, j++);

     }
     // for(int i = 0;i<m;i++){
     //      cout<<comp[i]<<" ";
     // }
     // cout<<'\n';
     assignment.assign(m / 2, false);
     for (int i = 0; i < m; i += 2) {
        if (comp[i] == comp[i + 1])
            return false;
        assignment[i / 2] = comp[i] > comp[i + 1];
     }
     return true;
}
bool intersect(pii a,pii b){
     return (a.x>b.x && a.y>b.y && a.x<b.y);
}
void solve(){
     cin>>n>>m;
     pii ex[m];
     for(int i = 0;i<m;i++){
          cin>>ex[i].first>>ex[i].second;
          if(ex[i].x>ex[i].y){
               swap(ex[i].x,ex[i].y);
          }
          // ex[i].second--;ex[i].first--;
     }
     for(int i = 0;i<m;i++){
          for(int j = 0;j<m;j++){
               if(intersect(ex[i],ex[j]) && i!=j){

                    g[2*i].pb(2*j+1);
                    g[2*j].pb(2*i+1);
                    g[2*i+1].pb(2*j);
                    g[2*j+1].pb(2*i);
                    gt[2*i].pb(2*j+1);
                    gt[2*j].pb(2*i+1);
                    gt[2*j+1].pb(2*i);
                    gt[2*i+1].pb(2*j);
               }
          }
     }
     if(solve_2SAT()){
          for(auto i:assignment){
               if(i){
                    cout<<"i";
               }
               else{
                    cout<<"o";
               }
          }
     }
     else{
          cout<<"Impossible";
     }

}
int main() {
     ios::sync_with_stdio(false);
     cin.tie(0);
     cout.tie(0);
     #ifndef ONLINE_JUDGE
     freopen("input.txt", "r", stdin);
     freopen("output.txt", "w", stdout);

     #endif

     ll t = 1;
     // cin>>t;
     while(t--){
          solve();

     }
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;
using namespace std;
typedef long long int ll;
// template <typename T>
// using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
//     tree_order_statistics_node_update>;
// #define ll int
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define pii pair<ll,ll>

const ll N = 1e4;
const ll p = 31;
// const ll inf= 1e14;
const ll mod = 1e9+7;
std::vector<ll> g[N],gt[N];
bool used[N];
vector<ll> order;
ll comp[N];
ll n,m;
vector<bool> assignment;

void dfs1(ll v) {
    used[v] = true;
    // cout<<v<<" : ";
    // for(auto u:g[v]){
    //  cout<<u<<" ";
    // }
    // cout<<'\n';
    for (auto u : g[v]) {
        if (!used[u])
            dfs1(u);
    }
    order.push_back(v);
}

void dfs2(ll v, ll cl) {
    comp[v] = cl;
    for (auto u : gt[v]) {
        if (comp[u] == -1)
            dfs2(u, cl);
    }
}

bool solve_2SAT() {
     m = m*2;
     fill(used,used+m+2,0);
     // for(int i = 0;i<m;i++){
     //      cout<<i<<": ";
     //      for(auto v:g[i]){
     //           cout<<v<<" ";
     //      }
     //      cout<<'\n';
     // }
     for (int i = 0; i < m; ++i) {
          if (!used[i])
          dfs1(i);
     }
     fill(comp,comp+m+9,-1);
     for (int i = 0, j = 0; i < m; ++i) {
        int v = order[m - i - 1];
        if (comp[v] == -1)
            dfs2(v, j++);

     }
     // for(int i = 0;i<m;i++){
     //      cout<<comp[i]<<" ";
     // }
     // cout<<'\n';
     assignment.assign(m / 2, false);
     for (int i = 0; i < m; i += 2) {
        if (comp[i] == comp[i + 1])
            return false;
        assignment[i / 2] = comp[i] > comp[i + 1];
     }
     return true;
}
bool intersect(pii a,pii b){
     return (a.x>b.x && a.y>b.y && a.x<b.y);
}
void solve(){
     cin>>n>>m;
     pii ex[m];
     for(int i = 0;i<m;i++){
          cin>>ex[i].first>>ex[i].second;
          if(ex[i].x>ex[i].y){
               swap(ex[i].x,ex[i].y);
          }
          // ex[i].second--;ex[i].first--;
     }
     for(int i = 0;i<m;i++){
          for(int j = 0;j<i;j++){
               if(intersect(ex[i],ex[j])){
                    g[2*i].pb(2*j+1);
                    g[2*j].pb(2*i+1);
                    g[2*i+1].pb(2*j);
                    g[2*j+1].pb(2*i);
                    gt[2*i].pb(2*j+1);
                    gt[2*j].pb(2*i+1);
                    gt[2*j+1].pb(2*i);
                    gt[2*i+1].pb(2*j);
               }
          }
     }
     if(solve_2SAT()){
          for(auto i:assignment){
               if(i){
                    cout<<"i";
               }
               else{
                    cout<<"o";
               }
          }
     }
     else{
          cout<<"Impossible";
     }

}
int main() {
     ios::sync_with_stdio(false);
     cin.tie(0);
     cout.tie(0);
     #ifndef ONLINE_JUDGE
     freopen("input.txt", "r", stdin);
     freopen("output.txt", "w", stdout);

     #endif

     ll t = 1;
     // cin>>t;
     while(t--){
          solve();

     }
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;
using namespace std;
typedef long long int ll;
// template <typename T>
// using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
//     tree_order_statistics_node_update>;
// #define ll int
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define pii pair<ll,ll>

const ll N = 1e4;
const ll p = 31;
// const ll inf= 1e14;
const ll mod = 1e9+7;
std::vector<ll> g[N],gt[N];
bool used[N];
vector<ll> order;
ll comp[N];
ll n,m;
vector<bool> assignment;

void dfs1(ll v) {
    used[v] = true;
    // cout<<v<<" : ";
    // for(auto u:g[v]){
    //  cout<<u<<" ";
    // }
    // cout<<'\n';
    for (auto u : g[v]) {
        if (!used[u])
            dfs1(u);
    }
    order.push_back(v);
}

void dfs2(ll v, ll cl) {
    comp[v] = cl;
    for (auto u : gt[v]) {
        if (comp[u] == -1)
            dfs2(u, cl);
    }
}

bool solve_2SAT() {
     m = m*2;
     fill(used,used+m+2,0);
     // for(int i = 0;i<m;i++){
     //      cout<<i<<": ";
     //      for(auto v:g[i]){
     //           cout<<v<<" ";
     //      }
     //      cout<<'\n';
     // }
     for (int i = 0; i < m; ++i) {
          if (!used[i])
          dfs1(i);
     }
     fill(comp,comp+m+9,-1);
     for (int i = 0, j = 0; i < m; ++i) {
        int v = order[m - i - 1];
        if (comp[v] == -1)
            dfs2(v, j++);

     }
     // for(int i = 0;i<m;i++){
     //      cout<<comp[i]<<" ";
     // }
     // cout<<'\n';
     assignment.assign(m / 2, false);
     for (int i = 0; i < m; i += 2) {
        if (comp[i] == comp[i + 1])
            return false;
        assignment[i / 2] = comp[i] > comp[i + 1];
     }
     return true;
}
bool intersect(pii a,pii b){
     if(a.x>a.y){
          swap(a.x,a.y);
     }
     if((b.x<a.x||a.y<b.x)&&(a.x<b.y||b.y<a.y)){
          return true;
     }
     if((b.y<a.x||a.y<b.y)&&(a.x<b.x&&b.x<a.y)){
          return true;
     }
     return false;
}
void solve(){
     cin>>n>>m;
     pii ex[m];
     for(int i = 0;i<m;i++){
          cin>>ex[i].first>>ex[i].second;

          ex[i].second--;ex[i].first--;
     }
     for(int i = 0;i<m;i++){
          for(int j = 0;j<i;j++){
               if(intersect(ex[i],ex[j])){
                    g[2*i].pb(2*j+1);
                    g[2*j].pb(2*i+1);
                    g[2*i+1].pb(2*j);
                    g[2*j+1].pb(2*i);
                    gt[2*i].pb(2*j+1);
                    gt[2*j].pb(2*i+1);
                    gt[2*j+1].pb(2*i);
                    gt[2*i+1].pb(2*j);
               }
          }
     }
     if(solve_2SAT()){
          for(auto i:assignment){
               if(i){
                    cout<<"i";
               }
               else{
                    cout<<"o";
               }
          }
     }
     else{
          cout<<"Impossible";
     }

}
int main() {
     ios::sync_with_stdio(false);
     cin.tie(0);
     cout.tie(0);
     #ifndef ONLINE_JUDGE
     freopen("input.txt", "r", stdin);
     freopen("output.txt", "w", stdout);

     #endif

     ll t = 1;
     // cin>>t;
     while(t--){
          solve();

     }
}


#include <bits/stdc++.h>

#define int         long long
#define uint        unsigned int
#define ld          long double
#define showoff     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb          push_back
#define pii         pair<int,int>
#define FOR(i,a,b)  for(int i=a;i<b;++i)
#define RFOR(i,a,b) for(int i=a;i>b;--i)
#define f           first
#define se          second
#define maxn        200005
#define all(v)      v.begin(),v.end()
#define sz(x)       (int)x.size()
#define mod         1000000007
#define pqueue      priority_queue<pii>
#define pdqueue     priority_queue< int,vector<int> ,greater< int >>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int power(int a,int n)
{
    a %= mod;
    if(n == 1)return a;
    if(n == 0)return 1;
    if(n%2)return (a*(power((a*a)%mod,n/2)%mod))%mod;
    return power((a*a)%mod,n/2)%mod;
}

const int inf = (int) 1e18;

int inverse(int x){
    return power(x,mod-2)%mod;//little fermat....
}
int n,m,col[105];

void solve(){
    memset(col,-1,sizeof col);
    cin >> n >> m;
    vector<pii>v(m+5);
    FOR(i,1,m+1){
        int a,b;
        cin >> a >> b;
        if(a > b)swap(a,b);
        v[i] = {a,b};
    }
    FOR(i,1,m+1)if(col[i] == -1){
        col[i] = 0;
        bool can = 1;
        FOR(j,1,m+1){
            bool fo = 0;
            if(v[j].f > v[i].f && v[j].f < v[i].se && v[j].se > v[i].se)fo = 1;
            else if(v[j].f < v[i].f && v[j].se > v[i].f && v[j].se < v[i].se)fo = 1;
            if(fo && col[j] != -1 && col[j] == col[i])can = 0;
        }
        if(!can)col[i] = 1;
    }
    FOR(i,1,m+1)if(col[i])cout << "i";
    else cout << "o";
}

signed main()
{
    showoff;
    int T = 1;
    //cin >> T;
    FOR(t,1,T+1){
        solve();
    }
    return 0;
}
//*->for large size of matrix take int not long long if possible......
//*->always take maximum as inf for safer side ...


#include <bits/stdc++.h>

#define int         long long
#define uint        unsigned int
#define ld          long double
#define showoff     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb          push_back
#define pii         pair<int,int>
#define FOR(i,a,b)  for(int i=a;i<b;++i)
#define RFOR(i,a,b) for(int i=a;i>b;--i)
#define f           first
#define se          second
#define maxn        200005
#define all(v)      v.begin(),v.end()
#define sz(x)       (int)x.size()
#define mod         1000000007
#define pqueue      priority_queue<pii>
#define pdqueue     priority_queue< int,vector<int> ,greater< int >>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int power(int a,int n)
{
    a %= mod;
    if(n == 1)return a;
    if(n == 0)return 1;
    if(n%2)return (a*(power((a*a)%mod,n/2)%mod))%mod;
    return power((a*a)%mod,n/2)%mod;
}

const int inf = (int) 1e18;

int inverse(int x){
    return power(x,mod-2)%mod;//little fermat....
}
int n,m,col[105];

void solve(){
    memset(col,-1,sizeof col);
    cin >> n >> m;
    vector<pii>v(m+5);
    FOR(i,1,m+1){
        int a,b;
        cin >> a >> b;
        if(a > b)swap(a,b);
        v[i] = {a,b};
    }
    FOR(i,1,m+1)if(col[i] == -1){
        col[i] = 0;
        bool can = 1;
        FOR(j,1,m+1){
            bool fo = 0;
            if(v[j].f > v[i].f && v[j].f < v[i].se && v[j].se > v[i].se)fo = 1;
            else if(v[j].f < v[i].f && v[j].se > v[i].f && v[j].se < v[i].se)fo = 1;
            if(fo && col[j] != -1 && col[j] == col[i])can = 0;
        }
        if(!can){
            can = 1;
            col[i] = 1;
            FOR(j,1,m+1){
                bool fo = 0;
                if(v[j].f > v[i].f && v[j].f < v[i].se && v[j].se > v[i].se)fo = 1;
                else if(v[j].f < v[i].f && v[j].se > v[i].f && v[j].se < v[i].se)fo = 1;
                if(fo && col[j] != -1 && col[j] == col[i])can = 0;
            }
            if(!can){cout << "Impossible\n";return ;}
        }
    }
    FOR(i,1,m+1)if(col[i])cout << "i";
    else cout << "o";
}

signed main()
{
    showoff;
    int T = 1;
    //cin >> T;
    FOR(t,1,T+1){
        solve();
    }
    return 0;
}
//*->for large size of matrix take int not long long if possible......
//*->always take maximum as inf for safer side ...


#include <bits/stdc++.h>

#define int         long long
#define uint        unsigned int
#define ld          long double
#define showoff     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb          push_back
#define pii         pair<int,int>
#define FOR(i,a,b)  for(int i=a;i<b;++i)
#define RFOR(i,a,b) for(int i=a;i>b;--i)
#define f           first
#define se          second
#define maxn        200005
#define all(v)      v.begin(),v.end()
#define sz(x)       (int)x.size()
#define mod         1000000007
#define pqueue      priority_queue<pii>
#define pdqueue     priority_queue< int,vector<int> ,greater< int >>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int power(int a,int n)
{
    a %= mod;
    if(n == 1)return a;
    if(n == 0)return 1;
    if(n%2)return (a*(power((a*a)%mod,n/2)%mod))%mod;
    return power((a*a)%mod,n/2)%mod;
}

const int inf = (int) 1e18;

int inverse(int x){
    return power(x,mod-2)%mod;//little fermat....
}
int n,m,col[105],can = 1;
vector<int>adj[105];

void dfs(int x){
    for(auto &y:adj[x]){
        if(col[y] == -1)col[y] = (1^col[x]),dfs(y);
        else if(col[y] == col[x]){can = 0;return ;}
    }
}

void solve(){
    cin >> n >> m;
    vector<pii>v(m+5);
    FOR(i,1,m+1){
        int a,b;
        cin >> a >> b;
        if(a > b)swap(a,b);
        v[i] = {a,b};
    }
    FOR(i,1,m+1){
        bool can = 1;
        FOR(j,1,m+1){
            bool fo = 0;
            if(v[j].f > v[i].f && v[j].f < v[i].se && v[j].se > v[i].se)fo = 1;
            else if(v[j].f < v[i].f && v[j].se > v[i].f && v[j].se < v[i].se)fo = 1;
            if(fo)adj[i].pb(j),adj[j].pb(i);
        }
    }
    memset(col,-1,sizeof col);
    FOR(i,1,m+1)if(col[i] == -1){
        col[i] = 1;
        dfs(i);
    }
    if(!can)cout << "Impossible\n";
    else FOR(i,1,m+1)if(col[i])cout << "i";
    else cout << "o";
}

signed main()
{
    showoff;
    int T = 1;
    //cin >> T;
    FOR(t,1,T+1){
        solve();
    }
    return 0;
}
//*->for large size of matrix take int not long long if possible......
//*->always take maximum as inf for safer side ...


#include <bits/stdc++.h>

#define int         long long
#define uint        unsigned int
#define ld          long double
#define showoff     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb          push_back
#define pii         pair<int,int>
#define FOR(i,a,b)  for(int i=a;i<b;++i)
#define RFOR(i,a,b) for(int i=a;i>b;--i)
#define f           first
#define se          second
#define maxn        200005
#define all(v)      v.begin(),v.end()
#define sz(x)       (int)x.size()
#define mod         1000000007
#define pqueue      priority_queue<pii>
#define pdqueue     priority_queue< int,vector<int> ,greater< int >>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int power(int a,int n)
{
    a %= mod;
    if(n == 1)return a;
    if(n == 0)return 1;
    if(n%2)return (a*(power((a*a)%mod,n/2)%mod))%mod;
    return power((a*a)%mod,n/2)%mod;
}

const int inf = (int) 1e18;

int inverse(int x){
    return power(x,mod-2)%mod;//little fermat....
}
int n,m,col[105],can = 1;
vector<int>adj[105];

void dfs(int x){
    for(auto &y:adj[x]){
        if(col[y] == -1)col[y] = (1^col[x]),dfs(y);
        else if(col[y] == col[x]){can = 0;return ;}
    }
}

void solve(){
    cin >> n >> m;
    vector<pii>v(m+5);
    FOR(i,1,m+1){
        int a,b;
        cin >> a >> b;
        if(a > b)swap(a,b);
        v[i] = {a,b};
    }
    FOR(i,1,m+1){
        bool can = 1;
        FOR(j,1,m+1){
            bool fo = 0;
            if(v[j].f > v[i].f && v[j].f < v[i].se && v[j].se > v[i].se)fo = 1;
            else if(v[j].f < v[i].f && v[j].se > v[i].f && v[j].se < v[i].se)fo = 1;
            if(fo)adj[i].pb(j),adj[j].pb(i);
        }
    }
    memset(col,-1,sizeof col);
    col[1] = 1;
    dfs(1);
    if(!can)cout << "Impossible\n";
    else FOR(i,1,m+1)if(col[i])cout << "i";
    else cout << "o";
}

signed main()
{
    showoff;
    int T = 1;
    //cin >> T;
    FOR(t,1,T+1){
        solve();
    }
    return 0;
}
//*->for large size of matrix take int not long long if possible......
//*->always take maximum as inf for safer side ...


#include<bits/stdc++.h>
#define pb push_back
#define F first
#define S second
using namespace std;
const int M=100;
int i,j,n,m,a,b,aa,bb,height[M];
bool is_bigraph=1,mark[M];
pair<int,int>edge[M];
vector<int>adj[M];
void dfs(int a)
{
	mark[a]=1;
	for(j=0;j<adj[a].size();++j)
	{
		int b=adj[a][j];
		if(!mark[b])
			height[b]=height[a]+1,dfs(b);
		else if(mark[b])
			if(abs(height[a]-height[b])%2==0)
				is_bigraph=0;
	}
}
int main()
{
	cin>>n>>m;
	for(i=0;i<m;++i)
	{
		cin>>a>>b;
		edge[i]={min(a,b),max(a,b)};
	}
	for(i=0;i<m;++i)
	{
		a=edge[i].F;
		b=edge[i].S;
		for(j=i+1;j<m;++j)
		{
			aa=edge[j].F;
			bb=edge[j].S;
			if(a<aa&&aa<b&&b<bb)
			{
				adj[i].pb(j);
				adj[j].pb(i);
			}
		}
	}
	for(i=0;i<m;++i)
		if(!mark[i])
			dfs(i);
	if(!is_bigraph)
		return cout<<"Impossible\n",0;
	for(i=0;i<m;++i)
	{
		if(height[i]%2)
			cout<<'i';
		else
			cout<<'o';
	}
	cout<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define F first
#define S second
using namespace std;
const int M=100;
int i,j,n,m,a,b,aa,bb,height[M];
bool mark[M];
pair<int,int>edge[M];
vector<int>adj[M];
void dfs(int a)
{
	mark[a]=1;
	for(j=0;j<adj[a].size();++j)
	{
		int b=adj[a][j];
		if(!mark[b])
			height[b]=height[a]+1,dfs(b);
		else if(abs(height[a]-height[b])%2==0)
		{
			cout<<"Impossible\n";
			exit(0);
		}
	}
}
int main()
{
	cin>>n>>m;
	for(i=0;i<m;++i)
	{
		cin>>a>>b;
		edge[i]={min(a,b),max(a,b)};
	}
	for(i=0;i<m;++i)
	{
		a=edge[i].F;
		b=edge[i].S;
		for(j=0;j<m;++j)
		{
			aa=edge[j].F;
			bb=edge[j].S;
			if(a<aa&&aa<b&&b<bb)
			{
				adj[i].pb(j);
				adj[j].pb(i);
				//cout <<" moshkel " << i << ' ' << j << endl;
			}
		}
	}
	for(i=0;i<m;++i)
		if(!mark[i])
			dfs(i);
	for(i=0;i<m;++i)
	{
		if(height[i]%2)
			cout<<'i';
		else
			cout<<'o';
	}
	cout<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define F first
#define S second
using namespace std;
const int M=100;
int i,j,n,m,a,b,aa,bb,height[M];
bool is_bigraph=1,mark[M];
pair<int,int>edge[M];
vector<int>adj[M];
void dfs(int a)
{
	mark[a]=1;
	for(j=0;j<adj[a].size();++j)
	{
		int b=adj[a][j];
		if(!mark[b])
			height[b]=height[a]+1,dfs(b);
		if(mark[b])
			if(abs(height[a]-height[b])%2==0)
				is_bigraph=0;
	}
}
int main()
{
	cin>>n>>m;
	for(i=0;i<m;++i)
	{
		cin>>a>>b;
		edge[i]={min(a,b),max(a,b)};
	}
	for(i=0;i<m;++i)
	{
		a=edge[i].F;
		b=edge[i].S;
		for(j=0;j<m;++j)
		{
			aa=edge[j].F;
			bb=edge[j].S;
			if(a<aa&&aa<b&&b<bb)
			{
				adj[i].pb(j);
				adj[j].pb(i);
			}
		}
	}
	for(i=0;i<m;++i)
		if(!mark[i])
			dfs(i);
	if(!is_bigraph)
		return cout<<"Impossible\n",0;
	for(i=0;i<m;++i)
	{
		if(height[i]%2)
			cout<<'i';
		else
			cout<<'o';
	}
	cout<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define F first
#define S second
using namespace std;
const int M=100;
int i,j,n,m,a,b,aa,bb,height[M];
bool mark[M];
pair<int,int>edge[M];
vector<int>adj[M];
void dfs(int v)
{
	mark[v]=1;
	for(int i=0;i<adj[v].size();++i)
	{
		int u=adj[v][i];
		if(!mark[u])
			height[u]=1-height[v],dfs(u);
		else if(height[v]==height[u])
		{
			cout<<"Impossible\n";
			exit(0);
		}
	}
}
int main()
{
	cin>>n>>m;
	for(i=0;i<m;++i)
	{
		cin>>a>>b;
		edge[i]={min(a,b),max(a,b)};
	}
	for(i=0;i<m;++i)
	{
		a=edge[i].F;
		b=edge[i].S;
		for(j=0;j<m;++j)
		{
			aa=edge[j].F;
			bb=edge[j].S;
			if(a<aa&&aa<b&&b<bb)
			{
				adj[i].pb(j);
				adj[j].pb(i);
			}
		}
	}
	for(i=0;i<m;++i)
		if(!mark[i])
			dfs(i);
	for(i=0;i<m;++i)
	{
		if(height[i]==0)
			cout<<'i';
		else
			cout<<'o';
	}
	cout<<'\n';
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;

const int maxn = 2000 * 2 + 10;

//maxn > 2*(quantidade de variáveis booleanas)
//No main, para negar a variavel de numero x, basta adicionar ~x
vector<int> adj[maxn];
int idx[maxn], low[maxn], z, comp[maxn], ncomp;
stack<int> st;

int dfs(int u){
	//Se visitado, retorna idx[u] caso o nó ainda não esteja em um SCC
	if(~idx[u])
		return idx[u] ? idx[u] : z;

	low[u] = idx[u] = z++;
	st.push(u);
	for(int v : adj[u]){
		//Atualiza o low[u] com os idx dos nós daquele SCC
		low[u] = min(low[u], dfs(v));
	}

	//Popando a pilha até termos a "raiz" do SCC, onde low[u] == idx[u]
	if(low[u] == idx[u]){
		while(st.top() != u){
			int v = st.top();
			idx[v] = 0;
			low[v] = low[u];
			comp[v] = ncomp;
			st.pop();
		}
		idx[st.top()] = 0;
		st.pop();
		comp[u] = ncomp++;
	}

	//Retorna o menor valor alcançado por aquele nó, para atualizar a raiz do SCC
	return low[u];
}

bool solveSat(int n){
	memset(idx, -1, sizeof idx);
	z = 1;
	ncomp = 0;
	for(int i =0; i < 2*n; i++)
		dfs(i);
	for(int i = 0; i < 2*n; i++)
		if(comp[i] == comp[i^1])
			return false;
	return true;
}

//Mapeia os numeros para seus devidos lugares no grafo
int trad(int v) { return v < 0 ? (~v)*2^1 : v*2; }
void add(int a, int b) { adj[trad(a)].push_back(trad(b)); }
void addOr(int a, int b) { add(~a, b); add(~b, a); }
void addImp(int a, int b) { addOr(~a, b); }
void addEqual(int a, int b) { addOr(a, ~b); addOr(~a, b); }
void addDiff(int a, int b) { addEqual(a, ~b); }
// value[i] = comp[trad(i)] < comp[trad(~i)];

int32_t main(){
	cin.tie(0);
	ios::sync_with_stdio(0);

	int n, m;
	cin >> n >> m;
	vector<ii> a(m);
	for(int i = 0; i < m; i++){
		cin >> a[i].first >> a[i].second;
		if(a[i].first > a[i].second)
			swap(a[i].first, a[i].second);
	}

	for(int i = 0; i < m; i++)
		for(int j = 0; j < m; j++)
			if(a[j].first > a[i].first && a[j].second > a[i].second && a[j].first < a[i].second)
				addDiff(i, j);

	string ans = "";
	if(solveSat(m)){
		for(int i = 0; i < m; i++){
			if(comp[trad(i)] < comp[trad(~i)])
				ans += "o";
			else
				ans += "i";
		}
	}
	else
		ans = "Impossible";

	cout << ans << endl;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;

const int maxn = 2000 * 2 + 10;

//maxn > 2*(quantidade de variáveis booleanas)
//No main, para negar a variavel de numero x, basta adicionar ~x
vector<int> adj[maxn];
int idx[maxn], low[maxn], z, comp[maxn], ncomp;
stack<int> st;

int dfs(int u){
	//Se visitado, retorna idx[u] caso o nó ainda não esteja em um SCC
	if(~idx[u])
		return idx[u] ? idx[u] : z;

	low[u] = idx[u] = z++;
	st.push(u);
	for(int v : adj[u]){
		//Atualiza o low[u] com os idx dos nós daquele SCC
		low[u] = min(low[u], dfs(v));
	}

	//Popando a pilha até termos a "raiz" do SCC, onde low[u] == idx[u]
	if(low[u] == idx[u]){
		while(st.top() != u){
			int v = st.top();
			idx[v] = 0;
			low[v] = low[u];
			comp[v] = ncomp;
			st.pop();
		}
		idx[st.top()] = 0;
		st.pop();
		comp[u] = ncomp++;
	}

	//Retorna o menor valor alcançado por aquele nó, para atualizar a raiz do SCC
	return low[u];
}

bool solveSat(int n){
	memset(idx, -1, sizeof idx);
	z = 1;
	ncomp = 0;
	for(int i =0; i < 2*n; i++)
		dfs(i);
	for(int i = 0; i < 2*n; i++)
		if(comp[i] == comp[i^1])
			return false;
	return true;
}

//Mapeia os numeros para seus devidos lugares no grafo
int trad(int v) { return v < 0 ? (~v)*2^1 : v*2; }
void add(int a, int b) { adj[trad(a)].push_back(trad(b)); }
void addOr(int a, int b) { add(~a, b); add(~b, a); }
void addImp(int a, int b) { addOr(~a, b); }
void addEqual(int a, int b) { addOr(a, ~b); addOr(~a, b); }
void addDiff(int a, int b) { addEqual(a, ~b); }
// value[i] = comp[trad(i)] < comp[trad(~i)];

int32_t main(){
	cin.tie(0);
	ios::sync_with_stdio(0);

	int n, m;
	cin >> n >> m;
	vector<ii> a(m);
	for(int i = 0; i < m; i++){
		cin >> a[i].first >> a[i].second;
		if(a[i].first > a[i].second)
			swap(a[i].first, a[i].second);
	}

	for(int i = 0; i < m; i++)
		for(int j = 0; j < m; j++)
			if(a[j].first > a[i].first && a[j].second > a[i].second)
				addDiff(i, j);

	string ans = "";
	if(solveSat(m)){
		for(int i = 0; i < m; i++){
			if(comp[trad(i)] < comp[trad(~i)])
				ans += "o";
			else
				ans += "i";
		}
	}
	else
		ans = "Impossible";

	cout << ans << endl;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;

const int maxn = 2000 * 2 + 10;

//maxn > 2*(quantidade de variáveis booleanas)
//No main, para negar a variavel de numero x, basta adicionar ~x
vector<int> adj[maxn];
int idx[maxn], low[maxn], z, comp[maxn], ncomp;
stack<int> st;

int dfs(int u){
	//Se visitado, retorna idx[u] caso o nó ainda não esteja em um SCC
	if(~idx[u])
		return idx[u] ? idx[u] : z;

	low[u] = idx[u] = z++;
	st.push(u);
	for(int v : adj[u]){
		//Atualiza o low[u] com os idx dos nós daquele SCC
		low[u] = min(low[u], dfs(v));
	}

	//Popando a pilha até termos a "raiz" do SCC, onde low[u] == idx[u]
	if(low[u] == idx[u]){
		while(st.top() != u){
			int v = st.top();
			idx[v] = 0;
			low[v] = low[u];
			comp[v] = ncomp;
			st.pop();
		}
		idx[st.top()] = 0;
		st.pop();
		comp[u] = ncomp++;
	}

	//Retorna o menor valor alcançado por aquele nó, para atualizar a raiz do SCC
	return low[u];
}

bool solveSat(int n){
	memset(idx, -1, sizeof idx);
	z = 1;
	ncomp = 0;
	for(int i =0; i < 2*n; i++)
		dfs(i);
	for(int i = 0; i < 2*n; i++)
		if(comp[i] == comp[i^1])
			return false;
	return true;
}

//Mapeia os numeros para seus devidos lugares no grafo
int trad(int v) { return v < 0 ? (~v)*2^1 : v*2; }
void add(int a, int b) { adj[trad(a)].push_back(trad(b)); }
void addOr(int a, int b) { add(~a, b); add(~b, a); }
void addImp(int a, int b) { addOr(~a, b); }
void addEqual(int a, int b) { addOr(a, ~b); addOr(~a, b); }
void addDiff(int a, int b) { addEqual(a, ~b); }
// value[i] = comp[trad(i)] < comp[trad(~i)];

int32_t main(){
	cin.tie(0);
	ios::sync_with_stdio(0);

	int n, m;
	cin >> n >> m;
	vector<ii> a(m);
	for(int i = 0; i < m; i++){
		cin >> a[i].first >> a[i].second;
		if(a[i].first > a[i].second)
			swap(a[i].first, a[i].second);
	}

	sort(a.begin(), a.end());
	for(int i = 0; i < m; i++)
		for(int j = i+1; j < m; j++)
			if(a[j].first > a[i].first && a[j].second > a[i].second)
				addDiff(i, j);

	string ans = "";
	if(solveSat(m)){
		for(int i = 0; i < m; i++){
			if(comp[trad(i)] < comp[trad(~i)])
				ans += "o";
			else
				ans += "i";
		}
	}
	else
		ans = "Impossible";

	cout << ans << endl;
}


#include <bits/stdc++.h>

using namespace std;

#define Speed ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define mod 1000000007
#define fr first
#define sc second
#define pb push_back
#define PI acos(-1.0)
#define print(num,ans) cout<<setprecision(num)<<fixed<<ans

pair<pair<int,int>,int> p[200];

int main()
{
    Speed;
    int n,m,i;
    cin>>n>>m;
    for(i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        if(x > y)swap(x , y);
        p[i].fr.fr = x;
        p[i].fr.sc = y;
    }
    for(i=0;i<m;i++)
    {
        bool in = 0 , ou = 0;
        for(int j=0;j<i;j++)
        {
            if(p[i].fr.fr > p[j].fr.fr && p[i].fr.fr < p[j].fr.sc && (p[i].fr.sc < p[j].fr.fr || p[i].fr.sc > p[j].fr.sc))
            {
                if(p[j].sc == 1)in = 1;
                else ou = 1;
            }
            else if(p[i].fr.sc > p[j].fr.fr && p[i].fr.sc < p[j].fr.sc && (p[i].fr.fr < p[j].fr.fr || p[i].fr.fr > p[j].fr.sc))
            {
                if(p[j].sc == 1)in = 1;
                else ou = 1;
            }
        }
        if(!in)p[i].sc = 1;
        else if(!ou)p[i].sc = 2;
        else return cout<<"Impossible"<<endl , 0;
    }
    for(i=0;i<m;i++)if(p[i].sc == 1)cout<<'i';else cout<<'o';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define Speed ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define mod 1000000007
#define fr first
#define sc second
#define pb push_back
#define PI acos(-1.0)
#define print(num,ans) cout<<setprecision(num)<<fixed<<ans

pair<pair<int,int>,int> p[200];

struct Tow_SAT{
    int n;
    vector < vector<int> > g, gt;
    vector<bool> used;
    vector<int> order, comp;
    void dfs1 (int v) {
        used[v] = true;
        for (size_t i=0; i<g[v].size(); ++i) {
            int to = g[v][i];
            if (!used[to])
                dfs1 (to);
        }
        order.push_back (v);
    }
    void dfs2 (int v, int cl) {
        comp[v] = cl;
        for (size_t i=0; i<gt[v].size(); ++i) {
            int to = gt[v][i];
            if (comp[to] == -1)
                dfs2 (to, cl);
        }
    }
    bool Satisfiable(vector < int > &sol){
        sol.resize(n/2);
        sol.clear();
        for(int i = 0 ; i < n ; i++)
            if (!used[i])
                dfs1 (i);
        for (int i=0, j=0; i<n; ++i) {
            int v = order[n-i-1];
            if (comp[v] == -1) dfs2 (v, j++);
        }
        for(int i = 0 ; i < n ; i++)
            if (comp[i] == comp[i^1])
                return 0;
        for(int i = 0 ; i < n ; i+=2){
            int ans = comp[i] > comp[i^1] ? i : i^1;
            sol.push_back(ans%2);
        }
        return 1;
    }
    void init(int N){
        n = N * 2;
        used.clear(); order.clear(); comp.clear();
        g.resize(n);
        gt.resize(n);
        used.assign (n, false);
        comp.assign (n, -1);
    }
    void imply(int a , int na ,int b , int nb){
        // na :: 0 variable is false , 1 variable is true
        // pass variables 1 indexed
        a--;b--;
        a*=2 , b*=2;
        a += na , b +=nb;
        g[a].push_back(b);
        gt[b].push_back(a);
        g[b^1].push_back(a^1);
        gt[a^1].push_back(b^1);
    }
}sat;

vector<int> res;

int main()
{
    Speed;
    int n,m,i;
    cin>>n>>m;
    sat.init(m);
    for(i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        if(x > y)swap(x , y);
        p[i].fr.fr = x;
        p[i].fr.sc = y;
    }
    for(i=1;i<=m;i++)
    {
        for(int j=1;j<i;j++)
        {
            if((p[i].fr.fr > p[j].fr.fr && p[i].fr.fr < p[j].fr.sc && (p[i].fr.sc < p[j].fr.fr || p[i].fr.sc > p[j].fr.sc))|| (p[i].fr.sc > p[j].fr.fr && p[i].fr.sc < p[j].fr.sc && (p[i].fr.fr < p[j].fr.fr || p[i].fr.fr > p[j].fr.sc)))
            {
                sat.imply(i , 0 , j , 1);
                sat.imply(i , 1 , j , 0);
            }
        }
    }
    bool b = sat.Satisfiable(res);
    if(!b)return cout<<"Impossible" , 0;
    for(i=0;i<res.size();i++)if(res[i])cout<<'i';else cout<<'o';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define Speed ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define mod 1000000007
#define fr first
#define sc second
#define pb push_back
#define PI acos(-1.0)
#define print(num,ans) cout<<setprecision(num)<<fixed<<ans

pair<pair<int,int>,int> p[200];
vector<int> v[200];
int res[200] , vis[200];
ll ans = 0;

void dfs(int x)
{
    vis[x] = true;
    for(auto u:v[x])
    {
        if(vis[u] && res[u] == res[x])ans = -1;
        if(vis[u])continue;
        if(res[x] == 1)res[u] = 2;
        else res[u] = 1;
        dfs(u);
    }
}

int main()
{
    Speed;
    int n,m,i;
    cin>>n>>m;
    for(i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        if(x > y)swap(x , y);
        p[i].fr.fr = x;
        p[i].fr.sc = y;
    }
    for(i=0;i<m;i++)
    {
        for(int j=0;j<i;j++)
        {
            if((p[i].fr.fr > p[j].fr.fr && p[i].fr.fr < p[j].fr.sc && (p[i].fr.sc < p[j].fr.fr || p[i].fr.sc > p[j].fr.sc))|| (p[i].fr.sc > p[j].fr.fr && p[i].fr.sc < p[j].fr.sc && (p[i].fr.fr < p[j].fr.fr || p[i].fr.fr > p[j].fr.sc)))
            {
                v[i].pb(j);
                v[j].pb(i);
            }
        }
    }
    for(i=0;i<m;i++)
    {
        if(!vis[i]){
            res[i] = 1;
            dfs(i);
        }
        if(ans == -1)return cout<<"Impossible" , 0;
    }

    for(i=0;i<m;i++)if(res[i] == 1)cout<<'i';else cout<<'o';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define Speed ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define mod 1000000007
#define fr first
#define sc second
#define pb push_back
#define PI acos(-1.0)
#define print(num,ans) cout<<setprecision(num)<<fixed<<ans

pair<pair<int,int>,int> p[200];

int main()
{
    Speed;
    int n,m,i;
    cin>>n>>m;
    for(i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        if(x > y)swap(x , y);
        p[i].fr.fr = x;
        p[i].fr.sc = y;
    }
    for(i=0;i<m;i++)
    {
        bool in = 0 , ou = 0;
        for(int j=0;j<i;j++)
        {
            if(p[i].fr.fr > p[j].fr.fr && p[i].fr.fr < p[j].fr.sc && (p[i].fr.sc < p[j].fr.fr || p[i].fr.sc > p[j].fr.sc))
            {
                if(p[j].sc == 1)in = 1;
                else ou = 1;
            }
            else if(p[i].fr.sc > p[j].fr.fr && p[i].fr.sc < p[j].fr.sc && (p[i].fr.sc < p[j].fr.fr || p[i].fr.sc > p[j].fr.sc))
            {
                if(p[j].sc == 1)in = 1;
                else ou = 1;
            }
        }
        if(!in)p[i].sc = 1;
        else if(!ou)p[i].sc = 2;
        else return cout<<"Impossible"<<endl , 0;
    }
    for(i=0;i<m;i++)if(p[i].sc == 1)cout<<'i';else cout<<'o';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define Speed ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define mod 1000000007
#define fr first
#define sc second
#define pb push_back
#define PI acos(-1.0)
#define print(num,ans) cout<<setprecision(num)<<fixed<<ans

pair<pair<int,int>,int> p[200];

struct Tow_SAT{
    int n;
    vector < vector<int> > g, gt;
    vector<bool> used;
    vector<int> order, comp;
    void dfs1 (int v) {
        used[v] = true;
        for (size_t i=0; i<g[v].size(); ++i) {
            int to = g[v][i];
            if (!used[to])
                dfs1 (to);
        }
        order.push_back (v);
    }
    void dfs2 (int v, int cl) {
        comp[v] = cl;
        for (size_t i=0; i<gt[v].size(); ++i) {
            int to = gt[v][i];
            if (comp[to] == -1)
                dfs2 (to, cl);
        }
    }
    bool Satisfiable(vector < int > &sol){
        sol.resize(n/2);
        sol.clear();
        for(int i = 0 ; i < n ; i++)
            if (!used[i])
                dfs1 (i);
        for (int i=0, j=0; i<n; ++i) {
            int v = order[n-i-1];
            if (comp[v] == -1) dfs2 (v, j++);
        }
        for(int i = 0 ; i < n ; i++)
            if (comp[i] == comp[i^1])
                return 0;
        for(int i = 0 ; i < n ; i+=2){
            int ans = comp[i] > comp[i^1] ? i : i^1;
            sol.push_back(ans%2);
        }
        return 1;
    }
    void init(int N){
        n = N * 2;
        used.clear(); order.clear(); comp.clear();
        g.resize(n);
        gt.resize(n);
        used.assign (n, false);
        comp.assign (n, -1);
    }
    void imply(int a , int na ,int b , int nb){
        // na :: 0 variable is false , 1 variable is true
        // pass variables 1 indexed
        a*=2 , b*=2;
        a += na , b +=nb;
        g[a].push_back(b);
        gt[b].push_back(a);
        g[b^1].push_back(a^1);
        gt[a^1].push_back(b^1);
    }
}sat;

vector<int> res;

int main()
{
    Speed;
    int n,m,i;
    cin>>n>>m;
    sat.init(m);
    for(i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        if(x > y)swap(x , y);
        p[i].fr.fr = x;
        p[i].fr.sc = y;
    }
    for(i=0;i<m;i++)
    {
        for(int j=0;j<i;j++)
        {
            if((p[i].fr.fr > p[j].fr.fr && p[i].fr.fr < p[j].fr.sc && (p[i].fr.sc < p[j].fr.fr || p[i].fr.sc > p[j].fr.sc))|| (p[i].fr.sc > p[j].fr.fr && p[i].fr.sc < p[j].fr.sc && (p[i].fr.fr < p[j].fr.fr || p[i].fr.fr > p[j].fr.sc)))
            {
                sat.imply(i , 0 , j , 1);
                sat.imply(i , 1 , j , 0);
            }
        }
    }
    bool b = sat.Satisfiable(res);
    if(!b)return cout<<"Impossible" , 0;
    for(auto i:res)if(res[i])cout<<'i';else cout<<'o';
    return 0;
}


#include <stdio.h>
#include <vector>
#include <memory.h>

using namespace std;

const int N = (int)107;

int n, m;
vector < int > gr[N];
vector < pair < int, int > > vec;
vector < int > order;
int used[N], comp[N];
int col = 1;

void dfs1(int v) {
	used[v] = 1;
	for (int to : gr[v]) {
		if (used[to]) continue;
		dfs1(to);
	}
	order.push_back(v);
}

void dfs(int v) {
	comp[v] = col;
	for (int to : gr[v]) {
		if (!comp[to]) {
			dfs(to);
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
		int u, v;
		scanf("%d %d", &u, &v);
		if (u > v) swap(u, v);
		vec.push_back({u, v});
	}
	for (int i = 0; i < (int)vec.size(); i++) {
		for (int j = i + 1; j < (int)vec.size(); j++) {
			if ((vec[j].first < vec[i].first && vec[j].second < vec[i].second && vec[i].first < vec[j].second) ||
				(vec[i].first < vec[j].first && vec[i].second < vec[j].second && vec[j].first < vec[i].second)) {
				//printf("%d %d\n", i, j);
				gr[i].push_back(j + m);
				gr[j].push_back(i + m);
				gr[j + m].push_back(i);
				gr[i + m].push_back(j);
			}
		}
	}
	for (int i = 0; i < m; i++) {
		if (!used[i]) {
			dfs1(i);
		}
	}
	memset(used, 0, sizeof used);
	for (int i = 0; i < m; i++) {
		int v = order[m - i - 1];
		if (!used[v]) {
			dfs(v);
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] == comp[i + m]) {
			puts("Impossible");
			return 0;
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] > comp[i + m]) {
			putchar('i');
		} else {
			putchar('o');
		}
	}
}


#include <stdio.h>
#include <vector>
#include <memory.h>

using namespace std;

const int N = (int)207;

int n, m;
vector < int > gr[N];
vector < pair < int, int > > vec;
vector < int > order;
int used[N], comp[N];
int col = 1;

void dfs1(int v) {
	used[v] = 1;
	for (int to : gr[v]) {
		if (used[to]) continue;
		dfs1(to);
	}
	order.push_back(v);
}

void dfs(int v) {
	comp[v] = col;
	for (int to : gr[v]) {
		if (!comp[to]) {
			dfs(to);
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
		int u, v;
		scanf("%d %d", &u, &v);
		if (u > v) swap(u, v);
		vec.push_back({u, v});
	}
	for (int i = 0; i < (int)vec.size(); i++) {
		for (int j = i + 1; j < (int)vec.size(); j++) {
			if ((vec[j].first < vec[i].first && vec[j].second < vec[i].second && vec[i].first < vec[j].second) ||
				(vec[i].first < vec[j].first && vec[i].second < vec[j].second && vec[j].first < vec[i].second)) {
				gr[i].push_back(j + m);
				gr[j].push_back(i + m);
				gr[j + m].push_back(i);
				gr[i + m].push_back(j);
			}
		}
	}
	for (int i = 0; i < m + m; i++) {
		if (!used[i]) {
			dfs1(i);
		}
	}
	for (int i = 0; i < m + m; i++) {
		int v = order[m + m - i - 1];
		if (!comp[v]) {
			dfs(v);
			col++;
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] == comp[i + m]) {
			puts("Impossible");
			return 0;
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] > comp[i + m]) {
			putchar('i');
		} else {
			putchar('o');
		}
	}
}


#include <stdio.h>
#include <vector>
#include <memory.h>

using namespace std;

const int N = (int)107;

int n, m;
vector < int > gr[N];
vector < pair < int, int > > vec;
vector < int > order;
int used[N], comp[N];
int col = 1;

void dfs1(int v) {
	used[v] = 1;
	for (int to : gr[v]) {
		if (used[to]) continue;
		dfs1(to);
	}
	order.push_back(v);
}

void dfs(int v) {
	comp[v] = col;
	used[v] = 1;
	for (int to : gr[v]) {
		if (!comp[to]) {
			dfs(to);
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
		int u, v;
		scanf("%d %d", &u, &v);
		if (u > v) swap(u, v);
		vec.push_back({u, v});
	}
	for (int i = 0; i < (int)vec.size(); i++) {
		for (int j = i + 1; j < (int)vec.size(); j++) {
			if ((vec[j].first < vec[i].first && vec[j].second < vec[i].second && vec[i].first < vec[j].second) ||
				(vec[i].first < vec[j].first && vec[i].second < vec[j].second && vec[j].first < vec[i].second)) {
				gr[i].push_back(j + m);
				gr[j].push_back(i + m);
				gr[j + m].push_back(i);
				gr[i + m].push_back(j);
			}
		}
	}
	for (int i = 0; i < m; i++) {
		if (!used[i]) {
			dfs1(i);
		}
	}
	memset(used, 0, sizeof used);
	for (int i = 0; i < m; i++) {
		int v = order[m - i - 1];
		if (!used[v]) {
			dfs(v);
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] == comp[i + m]) {
			puts("Impossible");
			return 0;
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] > comp[i + m]) {
			putchar('i');
		} else {
			putchar('o');
		}
	}
}


#include <stdio.h>
#include <vector>
#include <memory.h>

using namespace std;

const int N = (int)107;

int n, m;
vector < int > gr[N];
vector < pair < int, int > > vec;
vector < int > order;
int used[N], comp[N];
int col = 1;

void dfs1(int v) {
	used[v] = 1;
	for (int to : gr[v]) {
		if (used[to]) continue;
		dfs1(to);
	}
	order.push_back(v);
}

void dfs(int v) {
	comp[v] = col;
	for (int to : gr[v]) {
		if (!comp[to]) {
			dfs(to);
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
		int u, v;
		scanf("%d %d", &u, &v);
		if (u > v) swap(u, v);
		vec.push_back({u, v});
	}
	for (int i = 0; i < (int)vec.size(); i++) {
		for (int j = i + 1; j < (int)vec.size(); j++) {
			if ((vec[j].first < vec[i].first && vec[j].second < vec[i].second && vec[i].first < vec[j].second) ||
				(vec[i].first < vec[j].first && vec[i].second < vec[j].second && vec[j].first < vec[i].second)) {
				//printf("%d %d\n", i, j);
				gr[i].push_back(j + m);
				gr[j].push_back(i + m);
				gr[j + m].push_back(i);
				gr[i + m].push_back(j);
			} else {
				gr[i].push_back(j);
				gr[j].push_back(i);
				gr[j + m].push_back(i + m);
				gr[i + m].push_back(j + m);
			}
		}
	}
	for (int i = 0; i < m; i++) {
		if (!used[i]) {
			dfs1(i);
		}
	}
	memset(used, 0, sizeof used);
	for (int i = 0; i < m; i++) {
		int v = order[m - i - 1];
		if (!used[v]) {
			dfs(v);
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] == comp[i + m]) {
			puts("Impossible");
			return 0;
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] > comp[i + m]) {
			putchar('i');
		} else {
			putchar('o');
		}
	}
}


#include <stdio.h>
#include <vector>
#include <memory.h>

using namespace std;

const int N = (int)107;

int n, m;
vector < int > gr[N];
vector < pair < int, int > > vec;
vector < int > order;
int used[N], comp[N];
int col = 1;

void dfs1(int v) {
	used[v] = 1;
	for (int to : gr[v]) {
		if (used[to]) continue;
		dfs1(to);
	}
	order.push_back(v);
}

void dfs(int v) {
	comp[v] = col;
	used[v] = 1;
	for (int to : gr[v]) {
		if (!comp[to]) {
			dfs(to);
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
		int u, v;
		scanf("%d %d", &u, &v);
		if (u > v) swap(u, v);
		vec.push_back({u, v});
	}
	for (int i = 0; i < (int)vec.size(); i++) {
		for (int j = i + 1; j < (int)vec.size(); j++) {
			if ((vec[j].first < vec[i].first && vec[j].second < vec[i].second && vec[i].first < vec[j].second) ||
				(vec[i].first < vec[j].first && vec[i].second < vec[j].second && vec[j].first < vec[i].second)) {
				gr[i].push_back(j + m);
				gr[j].push_back(i + m);
				gr[j + m].push_back(i);
				gr[i + m].push_back(j);
			}
		}
	}
	for (int i = 0; i < m; i++) {
		if (!used[i]) {
			dfs1(i);
		}
	}
	memset(used, 0, sizeof used);
	for (int i = 0; i < m; i++) {
		int v = order[m - i - 1];
		if (!used[v]) {
			dfs(v);
			col++;
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] == comp[i + m]) {
			puts("Impossible");
			return 0;
		}
	}
	for (int i = 0; i < m; i++) {
		if (comp[i] > comp[i + m]) {
			putchar('i');
		} else {
			putchar('o');
		}
	}
}


//In the name of Allah :)
#include <bits/stdc++.h>
using namespace std;
string to_string(char c) { return string(1,c); }
string to_string(bool b) { return b ? "true" : "false"; }
string to_string(const char* s) { return (string)s; }
string to_string(string s) { return s; }
template<class A> string to_string(complex<A> c) {
	stringstream ss; ss << c; return ss.str(); }
string to_string(vector<bool> v) {
	string res = "{"; for(int i = 0; i < (int)v.size(); i++) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> string to_string(bitset<SZ> b) {
	string res = ""; for(size_t i = 0; i < SZ; i++) res += char('0'+b[i]);
	return res; }
template<class A, class B> string to_string(pair<A,B> p);
template<class T> string to_string(T v) { // containers with begin(), end()
	bool fst = 1; string res = "{";
	for (const auto& x: v) {
		if (!fst) res += ", ";
		fst = 0; res += to_string(x);
	}
	res += "}"; return res;
}
template<class A, class B> string to_string(pair<A,B> p) {
	return "("+to_string(p.first)+", "+to_string(p.second)+")"; }
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
	cerr << to_string(h); if (sizeof...(t)) cerr << ", ";
	DBG(t...); }
#ifdef DEBUG// compile with -DLOCAL
#define wis(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "] : [", DBG(__VA_ARGS__)
#else
#define wis(...) 0
#endif
typedef long long ll;
#define all(x) (x).begin(), (x).end()
const int MOD = 1e9 + 7, INF = 1e9 + 5;
const ll LONG_INF = 1e18 + 10;
inline ll powmod(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a%MOD)if(b&1)res=res*a%MOD;return res;}
inline ll power(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a)if(b&1)res=res*a;return res;}

const int MAXN = 2000 + 10;
vector<int> adj[MAXN];
int g[MAXN][MAXN];

struct edge {
	int u, v;
	bool I, O;
	void read(int i){
		cin >> u >> v;
		u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
		g[v][u] = i;
		g[u][v] = i;
		I = O = 1;
	}
} edges[MAXN];

int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m;
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		edges[i].read(i);
	}
	string ans(m, '*');
	queue<int> bfs;
	set<int> have;
	for(int i = 0; i < m; i++){
		have.insert(i);
	}
	while(have.size()){
		bfs.push(*have.begin());
		have.erase(have.begin());
		while(bfs.size()){
			int i = bfs.front();
			wis(i);
			bfs.pop();
			if(edges[i].I){
				assert(ans[i] == '*');
				ans[i] = 'i';
				set<int> nums;
				for(int j = edges[i].u + 1; j != edges[i].v; j = (j + 1) % n){
					nums.insert(j);
				}
				for(int q : nums){
					for(int j : adj[q]){
						if(nums.count(j) || j == edges[i].v || j == edges[i].u){
							continue;
						}
						int tmp = g[q][j];
						if(have.count(tmp)){
							have.erase(tmp);
							bfs.push(tmp);
							assert(edges[tmp].O && edges[tmp].I);
							edges[tmp].I = 0;
						}
					}
				}
				continue;
			}

			if(edges[i].O){
				assert(ans[i] == '*');
				ans[i] = 'o';
				set<int> nums;
				for(int j = edges[i].u + 1; j != edges[i].v; j = (j + 1) % n){
					nums.insert(j);
				}
				for(int q : nums){
					for(int j : adj[q]){
						if(nums.count(j) || j == edges[i].v || j == edges[i].u){
							continue;
						}
						int tmp = g[q][j];
						if(have.count(tmp)){
							have.erase(tmp);
							bfs.push(tmp);
							assert(edges[tmp].O && edges[tmp].I);
							edges[tmp].O = 0;
						}
					}
				}
				continue;
			}
			cout << "Impossible\n";
			return 0;
		}
	}
	cout << ans << '\n';
}


//In the name of Allah :)
#include <bits/stdc++.h>
using namespace std;
string to_string(char c) { return string(1,c); }
string to_string(bool b) { return b ? "true" : "false"; }
string to_string(const char* s) { return (string)s; }
string to_string(string s) { return s; }
template<class A> string to_string(complex<A> c) {
	stringstream ss; ss << c; return ss.str(); }
string to_string(vector<bool> v) {
	string res = "{"; for(int i = 0; i < (int)v.size(); i++) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> string to_string(bitset<SZ> b) {
	string res = ""; for(size_t i = 0; i < SZ; i++) res += char('0'+b[i]);
	return res; }
template<class A, class B> string to_string(pair<A,B> p);
template<class T> string to_string(T v) { // containers with begin(), end()
	bool fst = 1; string res = "{";
	for (const auto& x: v) {
		if (!fst) res += ", ";
		fst = 0; res += to_string(x);
	}
	res += "}"; return res;
}
template<class A, class B> string to_string(pair<A,B> p) {
	return "("+to_string(p.first)+", "+to_string(p.second)+")"; }
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
	cerr << to_string(h); if (sizeof...(t)) cerr << ", ";
	DBG(t...); }
#ifdef LOCAL // compile with -DLOCAL
#define wis(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "] : [", DBG(__VA_ARGS__)
#else
#define wis(...) 0
#endif
typedef long long ll;
#define all(x) (x).begin(), (x).end()
const int MOD = 1e9 + 7, INF = 1e9 + 5;
const ll LONG_INF = 1e18 + 10;
inline ll powmod(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a%MOD)if(b&1)res=res*a%MOD;return res;}
inline ll power(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a)if(b&1)res=res*a;return res;}

const int MAXN = 2000 + 10;
vector<int> adj[MAXN];
int g[MAXN][MAXN];

struct edge {
	int u, v;
	bool I, O;
	void read(int i){
		cin >> u >> v;
		u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
		g[v][u] = i;
		g[u][v] = i;
		I = O = 1;
	}
} edges[MAXN];

int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m;
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		edges[i].read(i);
	}
	string ans(m, ' ');
	queue<int> bfs;
	set<int> have;
	for(int i = 0; i < m; i++){
		have.insert(i);
	}
	while(have.size()){
		bfs.push(*have.begin());
		wis(1111);
		have.erase(have.begin());
		while(bfs.size()){
			int i = bfs.front();
			wis(i);
			bfs.pop();
			if(edges[i].I){
				ans[i] = 'i';
				set<int> nums; for(int j = edges[i].u + 1; j != edges[i].v; j = (j + 1) % n){
					nums.insert(j);
				}
				wis(i, nums);
				for(int q : nums){
					for(int j : adj[q]){
						if(nums.count(j) || j == edges[i].v || j == edges[i].u){
							continue;
						}
						int tmp = g[q][j];
						if(have.count(tmp)){
							have.erase(tmp);
							bfs.push(tmp);
						}
						edges[tmp].I = 0;
					}
				}
				continue;
			}
			if(!edges[i].O){
				cout << "Impossible\n";
				return 0;
			}
			if(edges[i].O){
				ans[i] = 'o';
				set<int> nums;
				for(int j = edges[i].u + 1; j < edges[i].v; j = (j + 1) % n){
					nums.insert(j);
				}
				for(int q : nums){
					for(int j : adj[q]){
						if(nums.count(j) || j == edges[i].v || j == edges[i].u){
							continue;
						}
						int tmp = g[q][j];
						if(have.count(tmp)){
							have.erase(tmp);
							bfs.push(tmp);
						}
						edges[tmp].O = 0;
					}
				}
				continue;
			}
		}
	}
	cout << ans << '\n';
}


//In the name of Allah :)
#include <bits/stdc++.h>
using namespace std;
string to_string(char c) { return string(1,c); }
string to_string(bool b) { return b ? "true" : "false"; }
string to_string(const char* s) { return (string)s; }
string to_string(string s) { return s; }
template<class A> string to_string(complex<A> c) {
	stringstream ss; ss << c; return ss.str(); }
string to_string(vector<bool> v) {
	string res = "{"; for(int i = 0; i < (int)v.size(); i++) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> string to_string(bitset<SZ> b) {
	string res = ""; for(size_t i = 0; i < SZ; i++) res += char('0'+b[i]);
	return res; }
template<class A, class B> string to_string(pair<A,B> p);
template<class T> string to_string(T v) { // containers with begin(), end()
	bool fst = 1; string res = "{";
	for (const auto& x: v) {
		if (!fst) res += ", ";
		fst = 0; res += to_string(x);
	}
	res += "}"; return res;
}
template<class A, class B> string to_string(pair<A,B> p) {
	return "("+to_string(p.first)+", "+to_string(p.second)+")"; }
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
	cerr << to_string(h); if (sizeof...(t)) cerr << ", ";
	DBG(t...); }
#ifdef DEBUG// compile with -DLOCAL
#define wis(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "] : [", DBG(__VA_ARGS__)
#else
#define wis(...) 0
#endif
typedef long long ll;
#define all(x) (x).begin(), (x).end()
const int MOD = 1e9 + 7, INF = 1e9 + 5;
const ll LONG_INF = 1e18 + 10;
inline ll powmod(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a%MOD)if(b&1)res=res*a%MOD;return res;}
inline ll power(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a)if(b&1)res=res*a;return res;}

const int MAXN = 2000 + 10;
vector<int> adj[MAXN];
int g[MAXN][MAXN];

struct edge {
	int u, v;
	bool I, O;
	void read(int i){
		cin >> u >> v;
		u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
		g[v][u] = i;
		g[u][v] = i;
		I = O = 1;
	}
} edges[MAXN];

int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m;
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		edges[i].read(i);
	}
	string ans(m, '*');
	queue<int> bfs;
	set<int> have;
	for(int i = 0; i < m; i++){
		have.insert(i);
	}
	while(have.size()){
		bfs.push(*have.begin());
		have.erase(have.begin());
		while(bfs.size()){
			int i = bfs.front();
			bfs.pop();
			if(edges[i].I){
				assert(ans[i] == '*');
				ans[i] = 'i';
				set<int> nums;
				for(int j = edges[i].u + 1; j != edges[i].v; j = (j + 1) % n){
					nums.insert(j);
				}
				for(int q : nums){
					for(int j : adj[q]){
						if(nums.count(j) || j == edges[i].v || j == edges[i].u){
							continue;
						}
						int tmp = g[q][j];
						if(have.count(tmp)){
							have.erase(tmp);
							bfs.push(tmp);
						}
						edges[tmp].I = 0;
					}
				}
				continue;
			}

			if(edges[i].O){
				assert(ans[i] == '*');
				ans[i] = 'o';
				set<int> nums;
				for(int j = edges[i].u + 1; j != edges[i].v; j = (j + 1) % n){
					nums.insert(j);
				}
				for(int q : nums){
					for(int j : adj[q]){
						if(nums.count(j) || j == edges[i].v || j == edges[i].u){
							continue;
						}
						int tmp = g[q][j];
						if(have.count(tmp)){
							have.erase(tmp);
							bfs.push(tmp);
						}
						edges[tmp].O = 0;
					}
				}
				continue;
			}
			cout << "Impossible\n";
			return 0;
		}
	}
	cout << ans << '\n';
}


//In the name of Allah :)
#include <bits/stdc++.h>
using namespace std;
string to_string(char c) { return string(1,c); }
string to_string(bool b) { return b ? "true" : "false"; }
string to_string(const char* s) { return (string)s; }
string to_string(string s) { return s; }
template<class A> string to_string(complex<A> c) {
	stringstream ss; ss << c; return ss.str(); }
string to_string(vector<bool> v) {
	string res = "{"; for(int i = 0; i < (int)v.size(); i++) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> string to_string(bitset<SZ> b) {
	string res = ""; for(size_t i = 0; i < SZ; i++) res += char('0'+b[i]);
	return res; }
template<class A, class B> string to_string(pair<A,B> p);
template<class T> string to_string(T v) { // containers with begin(), end()
	bool fst = 1; string res = "{";
	for (const auto& x: v) {
		if (!fst) res += ", ";
		fst = 0; res += to_string(x);
	}
	res += "}"; return res;
}
template<class A, class B> string to_string(pair<A,B> p) {
	return "("+to_string(p.first)+", "+to_string(p.second)+")"; }
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
	cerr << to_string(h); if (sizeof...(t)) cerr << ", ";
	DBG(t...); }
#ifdef LOCAL // compile with -DLOCAL
#define wis(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "] : [", DBG(__VA_ARGS__)
#else
#define wis(...) 0
#endif
typedef long long ll;
#define all(x) (x).begin(), (x).end()
const int MOD = 1e9 + 7, INF = 1e9 + 5;
const ll LONG_INF = 1e18 + 10;
inline ll powmod(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a%MOD)if(b&1)res=res*a%MOD;return res;}
inline ll power(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a)if(b&1)res=res*a;return res;}

const int MAXN = 2000 + 10;
vector<int> adj[MAXN];
bitset<MAXN> mark, color;
bool ok = 1;

void dfs(int v, bool c){
	if(mark[v]){
		if(color[v] != c){
			ok = 0;
		}
		return;
	}
	mark[v] = 1;
	color[v] = c;
	for(int i : adj[v]){
		dfs(i, c ^ 1);
	}
}

int main(){
    int n, m;
	scanf("%d%d", &n, &m);
	vector<pair<int, int>> a(m);
	for(int i = 0; i < m; i++){
		scanf("%d%d", &a[i].first, &a[i].second);
		a[i].first--, a[i].second--;
		if(a[i].first > a[i].second){
			swap(a[i].first, a[i].second);
		}
		for(int j = 0; j < i; j++){
			if((a[j].first > a[i].first && a[j].first < a[i].second && a[j].second > a[i].second) ||
			   (a[j].second > a[i].first && a[j].second < a[i].second && a[j].first < a[i].first)){
				adj[i].push_back(j);
				adj[j].push_back(i);
			}
		}
	}
	for(int i = 0; i < n; i++){
		if(!mark[i]){
			dfs(i, 0);
		}
	}
	if(!ok){
		printf("Impossible\n");
		return 0;
	}
	for(int i = 0; i < m; i++){
		printf("%c", color[i] ? 'i' : 'o');
	}
	puts("");

}


//In the name of Allah :)
#include <bits/stdc++.h>
using namespace std;
string to_string(char c) { return string(1,c); }
string to_string(bool b) { return b ? "true" : "false"; }
string to_string(const char* s) { return (string)s; }
string to_string(string s) { return s; }
template<class A> string to_string(complex<A> c) {
	stringstream ss; ss << c; return ss.str(); }
string to_string(vector<bool> v) {
	string res = "{"; for(int i = 0; i < (int)v.size(); i++) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> string to_string(bitset<SZ> b) {
	string res = ""; for(size_t i = 0; i < SZ; i++) res += char('0'+b[i]);
	return res; }
template<class A, class B> string to_string(pair<A,B> p);
template<class T> string to_string(T v) { // containers with begin(), end()
	bool fst = 1; string res = "{";
	for (const auto& x: v) {
		if (!fst) res += ", ";
		fst = 0; res += to_string(x);
	}
	res += "}"; return res;
}
template<class A, class B> string to_string(pair<A,B> p) {
	return "("+to_string(p.first)+", "+to_string(p.second)+")"; }
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
	cerr << to_string(h); if (sizeof...(t)) cerr << ", ";
	DBG(t...); }
#ifdef LOCAL // compile with -DLOCAL
#define wis(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "] : [", DBG(__VA_ARGS__)
#else
#define wis(...) 0
#endif
typedef long long ll;
#define all(x) (x).begin(), (x).end()
const int MOD = 1e9 + 7, INF = 1e9 + 5;
const ll LONG_INF = 1e18 + 10;
inline ll powmod(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a%MOD)if(b&1)res=res*a%MOD;return res;}
inline ll power(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a)if(b&1)res=res*a;return res;}

const int MAXN = 2000 + 10;
vector<int> adj[MAXN];
bitset<MAXN> mark, color;
bool ok = 1;

void dfs(int v, bool c){
	if(mark[v]){
		if(color[v] != c){
			ok = 0;
		}
		return;
	}
	mark[v] = 1;
	color[v] = c;
	for(int i : adj[v]){
		dfs(i, c ^ 1);
	}
}

int main(){
    int n, m;
	scanf("%d%d", &n, &m);
	vector<pair<int, int>> a(m);
	for(int i = 0; i < m; i++){
		scanf("%d%d", &a[i].first, &a[i].second);
		a[i].first--, a[i].second--;
		if(a[i].first > a[i].second){
			swap(a[i].first, a[i].second);
		}
		for(int j = 0; j < i; j++){
			if((a[j].first > a[i].first && a[j].first < a[i].second && a[j].second > a[i].second) ||
			   (a[j].second > a[i].first && a[j].second < a[i].second && a[j].first < a[i].first)){
				adj[i].push_back(j);
				adj[j].push_back(i);
			}
		}
	}
	for(int i = 0; i < n; i++){
		if(!mark[i]){
			dfs(i, 0);
		}
	}
	if(!ok){
		cout << "Impossible" << '\n';
		return 0;
	}
	for(int i = 0; i < m; i++){
		cout << (color[i] ? "i" : "o");
	}
	cout << '\n';

}


//In the name of Allah :)
#include <bits/stdc++.h>
using namespace std;
string to_string(char c) { return string(1,c); }
string to_string(bool b) { return b ? "true" : "false"; }
string to_string(const char* s) { return (string)s; }
string to_string(string s) { return s; }
template<class A> string to_string(complex<A> c) {
	stringstream ss; ss << c; return ss.str(); }
string to_string(vector<bool> v) {
	string res = "{"; for(int i = 0; i < (int)v.size(); i++) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> string to_string(bitset<SZ> b) {
	string res = ""; for(size_t i = 0; i < SZ; i++) res += char('0'+b[i]);
	return res; }
template<class A, class B> string to_string(pair<A,B> p);
template<class T> string to_string(T v) { // containers with begin(), end()
	bool fst = 1; string res = "{";
	for (const auto& x: v) {
		if (!fst) res += ", ";
		fst = 0; res += to_string(x);
	}
	res += "}"; return res;
}
template<class A, class B> string to_string(pair<A,B> p) {
	return "("+to_string(p.first)+", "+to_string(p.second)+")"; }
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
	cerr << to_string(h); if (sizeof...(t)) cerr << ", ";
	DBG(t...); }
#ifdef DEBUG// compile with -DLOCAL
#define wis(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "] : [", DBG(__VA_ARGS__)
#else
#define wis(...) 0
#endif
typedef long long ll;
#define all(x) (x).begin(), (x).end()
const int MOD = 1e9 + 7, INF = 1e9 + 5;
const ll LONG_INF = 1e18 + 10;
inline ll powmod(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a%MOD)if(b&1)res=res*a%MOD;return res;}
inline ll power(ll a, ll b){ll res=1;for(;b;b>>=1,a=a*a)if(b&1)res=res*a;return res;}

const int MAXN = 2000 + 10;
vector<int> adj[MAXN];
int g[MAXN][MAXN];

struct edge {
	int u, v;
	bool I, O;
	void read(int i){
		cin >> u >> v;
		u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
		g[v][u] = i;
		g[u][v] = i;
		I = O = 1;
	}
} edges[MAXN];

int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m;
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		edges[i].read(i);
	}
	string ans(m, ' ');
	queue<int> bfs;
	set<int> have;
	for(int i = 0; i < m; i++){
		have.insert(i);
	}
	while(have.size()){
		bfs.push(*have.begin());
		have.erase(have.begin());
		while(bfs.size()){
			int i = bfs.front();
			bfs.pop();
			if(edges[i].I){
				ans[i] = 'i';
				set<int> nums; for(int j = edges[i].u + 1; j != edges[i].v; j = (j + 1) % n){
					nums.insert(j);
				}
				for(int q : nums){
					for(int j : adj[q]){
						if(nums.count(j) || j == edges[i].v || j == edges[i].u){
							continue;
						}
						int tmp = g[q][j];
						if(have.count(tmp)){
							have.erase(tmp);
							bfs.push(tmp);
						}
						edges[tmp].I = 0;
					}
				}
				continue;
			}
			if(!edges[i].O){
				cout << "Impossible\n";
				return 0;
			}
			if(edges[i].O){
				ans[i] = 'o';
				set<int> nums;
				for(int j = edges[i].u + 1; j != edges[i].v; j = (j + 1) % n){
					nums.insert(j);
				}
				for(int q : nums){
					for(int j : adj[q]){
						if(nums.count(j) || j == edges[i].v || j == edges[i].u){
							continue;
						}
						int tmp = g[q][j];
						if(have.count(tmp)){
							have.erase(tmp);
							bfs.push(tmp);
						}
						edges[tmp].O = 0;
					}
				}
				continue;
			}
		}
	}
	cout << ans << '\n';
}