#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge
using cat = long long;
#ifdef DONLINE_JUDGE
// palindromic tree is better than splay tree!
#define lld I64d
#endif
struct seg {
int l, r, id;
bool operator<(const seg & S) const {
if(l != S.l) return l < S.l;
return r < S.r;
}
};
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
cout << fixed << setprecision(10);
int L, N;
cin >> L >> N;
vector<seg> A(N);
int max_dif = 0, max_dif_id = -1;
for(int i = 0; i < N; i++) {
cin >> A[i].l >> A[i].r;
A[i].l--, A[i].r--;
A[i].id = i;
int dif = (A[i].r >= A[i].l) ? (A[i].r-A[i].l+1) : (A[i].r+1+L-A[i].l);
if(dif > max_dif) {
max_dif = dif;
max_dif_id = i;
}
}
sort(begin(A), end(A));
for(int i = 0; i < N; i++) if(max_dif_id == A[i].id) {
max_dif_id = i;
break;
}
set< pair<int, int> > open;
for(int i = 0; i < N; i++) if(A[i].l == 0 || A[i].r < A[i].l)
open.insert({A[i].r+1, i});
int a = 0;
while(a < N && A[a].l == 0) a++;
vector< set<int> > dif_col(N);
int curx = 0;
while(true) {
if((int)open.size() <= 1) {
cout << "impossible\n";
return 0;
}
if(open.size() == 2) {
dif_col[begin(open)->ss].insert(open.rbegin()->ss);
dif_col[open.rbegin()->ss].insert(begin(open)->ss);
}
int x = L;
auto it = open.upper_bound({curx, N+1});
if(it != end(open)) x = it->ff;
if(a < N) x = min(x, A[a].l);
if(x == L) break;
while(it != end(open) && it->ff == x) {
auto jt = it;
it++;
open.erase(jt);
}
while(a < N && A[a].l == x) {
open.insert({A[a].r+1, a});
a++;
}
curx = x;
}
map<int, vector<int> > starts;
for(int i = 0; i < N; i++) starts[A[i].l].push_back(i);
int cur = max_dif_id;
set<int> bl;
queue< pair<int, int> > q;
q.push({cur, 1});
vector<bool> vis(N, false);
vis[cur] = true;
while(!q.empty()) {
ALL_THE(dif_col[q.front().ff], it) if(!vis[*it]) {
if(q.front().ss == 1) bl.insert(*it);
vis[*it] = true;
q.push({*it, 1-q.front().ss});
}
q.pop();
}
ALL_THE(bl, it) ALL_THE(dif_col[*it], jt) if(bl.find(*jt) != bl.end()) {
cout << "impossible\n";
return 0;
}
vector<bool> ans(N, 0);
ans[cur] = 1;
int l = A[cur].l, r = (A[cur].r+1)%L;
int cov = A[cur].r+1-A[cur].l;
if(cov <= 0) cov += L;
while(cov < L) {
ALL_THE(dif_col[cur], it) bl.insert(*it);
bl.insert(cur);
int r_nxt = -1, id_nxt = -1;
for(int i = l; ; i = (i+1)%L) {
if(starts.empty()) break;
auto it = starts.lower_bound(i);
if(it == end(starts)) it = begin(starts);
int cp = it->ff, rp = r;
if(cp < l) cp += L;
if(rp < l) rp += L;
if(cp > rp) break;
i = it->ff;
ALL_THE(it->ss, jt) {
if(bl.find(*jt) != end(bl)) continue;
// ignore segments that don't extend cover(1)
if(A[cur].r >= A[cur].l) {
if(A[*jt].r <= A[cur].r && A[*jt].l >= A[cur].l && A[*jt].l <= A[*jt].r) continue;
}
else {
if(A[*jt].r <= A[cur].r && A[*jt].l >= A[cur].l) continue;
if(A[*jt].r <= A[cur].r && A[*jt].l <= A[*jt].r) continue;
if(A[*jt].l >= A[cur].l && A[*jt].l <= A[*jt].r) continue;
}
int x = A[*jt].r+1;
if(x <= l) x += L;
if(x > r_nxt) {
r_nxt = x;
id_nxt = *jt;
}
}
starts.erase(it);
}
assert(id_nxt != -1);
int r_old = r;
if(r_old < l) r_old += L;
assert(r_nxt != r_old);
cov += (r_nxt-r_old+10*L)%L;
l = r;
r = (A[id_nxt].r+1)%L;
ans[id_nxt] = 1;
cur = id_nxt;
}
vector<int> ans_orig(N);
for(int i = 0; i < N; i++) ans_orig[A[i].id] = ans[i];
for(int i = 0; i < N; i++) cout << (int) ans_orig[i];
cout << "\n";
return 0;
}
// look at my code
// my code is amazing