#include <bits/stdc++.h>
#define debug if (0)

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

const int N = 2e5+7;

struct Node {
    set<int> vtx;
    vector<int> adj;
    int sz;
    int rs;

    bool operator < (const Node & ot) const {
        auto it = vtx.rbegin();
        auto jt = ot.vtx.rbegin();

        while (it != vtx.rend() && jt != ot.vtx.rend()) {
            if (*it != *jt)
                return *it < *jt;
            ++it; ++jt;
        }
        return (it == vtx.rend());
    }
};

pii ed[N];
int n, m;
set<pii> avail;
map<pii, int> idx;
int ns;
Node nd[N];

int inner (pii x)
{ return x.second - x.first; }
int outer (pii x)
{ return n - x.second + x.first; }

int getsz (int u, int p) {
    nd[u].sz = 1;
    for (int v : nd[u].adj) {
        if (v == p || nd[v].sz == -1) continue;
        nd[u].sz += getsz(v, u);
    }
    return nd[u].sz;
}

void centroid (int u, int d) {
    int siz = getsz(u,u);

    int w = u;
    do {
        u = w;
        for (int v : nd[u].adj) {
            if (nd[v].sz == -1 || nd[v].sz >= nd[u].sz || nd[v].sz + nd[v].sz < siz)
                continue;
            w = v;
            break;
        }
    } while (u != w);

    nd[u].rs = d;
    nd[u].sz = -1;

    for (int v : nd[u].adj)
        if (nd[v].sz != -1)
            centroid(v, d+1);
}

void putin (pii aux, int x) {
    nd[x].vtx.insert(aux.first);
    nd[x].vtx.insert(aux.second);

    if ((aux.first + 1)%n != aux.second) {
        assert(idx.find(aux) != idx.end());
        nd[x].adj.pb(idx[aux]);
        nd[idx[aux]].adj.pb(x);
    }
}

void go (int l, int r, int x) {
    auto it = avail.lower_bound(pii(l,l));
    while (it != avail.end() && it->first < r) {
        putin(*it, x);
        auto jt = next(it);
        avail.erase(it);
        it = jt;
    }
}

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

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

    sort(ed, ed+m, [] (pii a, pii b) {
        return min(inner(a),outer(a)) < min(inner(b),outer(b));
    });

    pii extr(n-1,0);
    for (int i = 0; i < n-1; i++)
        avail.insert(pii(i,i+1));

    for (int i = 0; i < m; i++) {
        pii cur = ed[i];
        idx[cur] = i;
        if (inner(cur) <= outer(cur)) {
            go(cur.first, cur.second, i);
            avail.insert(cur);
        } else {
            go(cur.second, n-1, i);
            putin(extr,i);
            go(0, cur.first, i);
            extr = cur;
        }
    }

    go(0,n-1,m);
    putin(extr,m);

    centroid(0,0);

    sort(nd, nd+m+1);
    for (int i = 0; i <= m; i++) {
        cout << nd[i].rs + 1 << " ";
    }
    cout << endl;
}


#include <bits/stdc++.h>
#define debug if (0)

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

const int N = 2e5+7;

int ed[N][2], p[N];
int n, m;

struct Node {
    set<int> vtx;
    vector<int> adj;
    int sz;
    int rs;

    bool operator < (const Node & ot) const {
        auto it = vtx.rbegin();
        auto jt = ot.vtx.rbegin();

        while (it != vtx.rend() && jt != ot.vtx.rend()) {
            if (*it != *jt)
                return *it < *jt;
            ++it; ++jt;
        }
        return (it == vtx.rend());
    }
} nd[N];
int ns;

map<pii, vector<int> > mp;
int cn[N];
set<int> avail;

int inner (int i)
{ return ed[i][1] - ed[i][0]; }
int outer (int i)
{ return n - ed[i][1] + ed[i][0]; }

int getsz (int u, int p) {
    nd[u].sz = 1;
    for (int v : nd[u].adj) {
        if (v == p || nd[v].sz == -1) continue;
        nd[u].sz += getsz(v, u);
    }
    return nd[u].sz;
}

void centroid (int u, int d) {
    int siz = getsz(u,u);

    int w = u;
    do {
        u = w;
        for (int v : nd[u].adj) {
            if (nd[v].sz == -1 || nd[v].sz >= nd[u].sz || nd[v].sz + nd[v].sz < siz)
                continue;
            w = v;
            break;
        }
    } while (u != w);

    nd[u].rs = d;
    nd[u].sz = -1;

    for (int v : nd[u].adj)
        if (nd[v].sz != -1)
            centroid(v, d+1);
}

void go (int l, int r, int x) {
    auto it = avail.upper_bound(l);
    while (it != avail.end() && *it <= r) {
        nd[x].vtx.insert(*it-1);
        nd[x].vtx.insert(*it);
        auto jt = next(it);
        avail.erase(it);
        it = jt;
    }
}

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

    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        cn[a]++; cn[b]++;

        if (a > b) swap(a,b);
        ed[i][0] = a;
        ed[i][1] = b;
        p[i] = i;
    }

    for (int i = 1; i <= n; i++)
        avail.insert(i);

    sort(p, p+m, [] (int i, int j) {
        return min(inner(i),outer(i)) < min(inner(j),outer(j));
    });

    for (int _i = 0; _i < m; _i++) {
        ns++;
        int i = p[_i];

        nd[ns].vtx.insert(ed[i][0]);
        nd[ns].vtx.insert(ed[i][1]);

        if (inner(i) <= outer(i)) {
            go(ed[i][0], ed[i][1], ns);
        } else {
            go(ed[i][1], n, ns);
            go(1, ed[i][0], ns);

            if (avail.find(1) != avail.end()) {
                avail.erase(1);
                nd[ns].vtx.insert(1);
                nd[ns].vtx.insert(n);
            }
        }

        //assert(nd[ns].vtx.size() >= 3);
        int x = *prev(nd[ns].vtx.end());
        for (int y : nd[ns].vtx) {
            if ((x+1)%n != y%n) {
                pii aux(x,y);
                if (aux.first > aux.second)
                    swap(aux.first, aux.second);
                mp[aux].pb(ns);
            }
            cn[y]--;
            x = y;
        }
    }

    for (int i = 1; i <= n; i++) {
        cn[i]++; // standart region

        assert(cn[i] == 0 || cn[i] == 1);
        if (cn[i] == 1) {
            nd[0].vtx.insert(i);
        }
    }

    for (int x : avail) {
        assert(cn[x] == 1);
        if (x == 1)
            assert(cn[n] == 1);
        else
            assert(cn[x-1] == 1);
    }

    //assert(nd[0].vtx.size() >= 3);
    int x = *prev(nd[0].vtx.end());
    for (int y : nd[0].vtx) {
        if ((x+1)%n != y%n) {
            pii aux(x,y);
            if (aux.first > aux.second)
                swap(aux.first, aux.second);
            mp[aux].pb(0);
        }
        x = y;
    }

    for (pair<const pii, vector<int> > & el : mp) {
        debug cout << "edge " << el.first.first << " " << el.first.second << " :";
        assert(el.second.size() == 2);
        nd[el.second[0]].adj.pb(el.second[1]);
        nd[el.second[1]].adj.pb(el.second[0]);
        debug cout << endl;
    }

    debug {
        for (int i = 0; i <= ns; i++) {
            cout << "region " << i << " :";
            for (int j : nd[i].vtx)
                cout << " " << j;
            cout << " :";
            for (int j : nd[i].adj)
                cout << " " << j;
            cout << endl;
        }
    }

    centroid(0,0);

    sort(nd, nd+ns+1);
    for (int i = 0; i <= ns; i++) {
        cout << nd[i].rs + 1 << " ";
    }
    cout << endl;
}


#include <bits/stdc++.h>
#define debug if (0)

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

const int N = 2e5+7;

int ed[N][2], p[N];
int n, m;

struct Node {
    set<int> vtx;
    vector<int> adj;
    int sz;
    int rs;

    bool operator < (const Node & ot) const {
        auto it = vtx.rbegin();
        auto jt = ot.vtx.rbegin();

        while (it != vtx.rend() && jt != ot.vtx.rend()) {
            if (*it != *jt)
                return *it < *jt;
            ++it; ++jt;
        }
        return (it == vtx.rend());
    }
} nd[N];
int ns;

map<pii, vector<int> > mp;
int cn[N];
set<int> avail;

int inner (int i)
{ return ed[i][1] - ed[i][0]; }
int outer (int i)
{ return n - ed[i][1] + ed[i][0]; }

int getsz (int u, int p) {
    nd[u].sz = 1;
    for (int v : nd[u].adj) {
        if (v == p || nd[v].sz == -1) continue;
        nd[u].sz += getsz(v, u);
    }
    return nd[u].sz;
}

void centroid (int u, int d) {
    int siz = getsz(u,u);

    int w = u;
    do {
        u = w;
        for (int v : nd[u].adj) {
            if (nd[v].sz == -1 || nd[v].sz >= nd[u].sz || nd[v].sz + nd[v].sz < siz)
                continue;
            w = v;
            break;
        }
    } while (u != w);

    nd[u].rs = d;
    nd[u].sz = -1;

    for (int v : nd[u].adj)
        if (nd[v].sz != -1)
            centroid(v, d+1);
}

void go (int l, int r, int x) {
    auto it = avail.upper_bound(l);
    while (it != avail.end() && *it <= r) {
        nd[x].vtx.insert(*it-1);
        nd[x].vtx.insert(*it);
        auto jt = next(it);
        avail.erase(it);
        it = jt;
    }
}

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

    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        cn[a]++; cn[b]++;

        if (a > b) swap(a,b);
        ed[i][0] = a;
        ed[i][1] = b;
        p[i] = i;
    }

    for (int i = 1; i <= n; i++)
        avail.insert(i);

    sort(p, p+m, [] (int i, int j) {
        return min(inner(i),outer(i)) < min(inner(j),outer(j));
    });

    for (int _i = 0; _i < m; _i++) {
        ns++;
        int i = p[_i];

        nd[ns].vtx.insert(ed[i][0]);
        nd[ns].vtx.insert(ed[i][1]);

        if (inner(i) <= outer(i)) {
            go(ed[i][0], ed[i][1], ns);
        } else {
            go(ed[i][1], n, ns);
            go(1, ed[i][0], ns);

            if (avail.find(1) != avail.end()) {
                avail.erase(1);
                nd[ns].vtx.insert(1);
                nd[ns].vtx.insert(n);
            }
        }

        int x = *prev(nd[ns].vtx.end());
        for (int y : nd[ns].vtx) {
            if (x + 1 != y && (x+1)%n != y) {
                pii aux(x,y);
                if (aux.first > aux.second)
                    swap(aux.first, aux.second);
                mp[aux].pb(ns);
            }
            cn[y]--;
            x = y;
        }
    }

    for (int i = 1; i <= n; i++) {
        cn[i]++; // standart region

        assert(cn[i] == 0 || cn[i] == 1);
        if (cn[i] == 1) {
            nd[0].vtx.insert(i);
        }
    }

    assert(nd[0].vtx.size() >= 3);

    int x = *prev(nd[0].vtx.end());
    for (int y : nd[0].vtx) {
        if (x + 1 != y && (x+1)%n != y) {
            pii aux(x,y);
            if (aux.first > aux.second)
                swap(aux.first, aux.second);
            mp[aux].pb(0);
        }
        x = y;
    }

    for (pair<const pii, vector<int> > & el : mp) {
        debug cout << "edge " << el.first.first << " " << el.first.second << " :";
        for (int i = 0; i < el.second.size(); i++) {
            debug cout << " " <<  el.second[i];
            for (int j = 0; j < i; j++) {
                nd[el.second[i]].adj.pb(el.second[j]);
                nd[el.second[j]].adj.pb(el.second[i]);
            }
        }
        debug cout << endl;
    }

    debug {
        for (int i = 0; i <= ns; i++) {
            cout << "region " << i << " :";
            for (int j : nd[i].vtx)
                cout << " " << j;
            cout << " :";
            for (int j : nd[i].adj)
                cout << " " << j;
            cout << endl;
        }
    }

    centroid(0,0);

    sort(nd, nd+ns+1);
    for (int i = 0; i <= ns; i++) {
        cout << nd[i].rs + 1 << " ";
    }
    cout << endl;
}


#include <bits/stdc++.h>
#define debug if (0)

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

const int N = 2e5+7;

int ed[N][2], p[N];
int n, m;

struct Node {
    set<int> vtx;
    vector<int> adj;
    int sz;
    int rs;

    bool operator < (const Node & ot) const {
        auto it = vtx.rbegin();
        auto jt = ot.vtx.rbegin();

        while (it != vtx.rend() && jt != ot.vtx.rend()) {
            if (*it != *jt)
                return *it < *jt;
            ++it; ++jt;
        }
        return (it == vtx.rend());
    }
} nd[N];
int ns;

map<pii, vector<int> > mp;
int cn[N];
set<int> avail;

int inner (int i)
{ return ed[i][1] - ed[i][0]; }
int outer (int i)
{ return n - ed[i][1] + ed[i][0]; }

int getsz (int u, int p) {
    nd[u].sz = 1;
    for (int v : nd[u].adj) {
        if (v == p || nd[v].sz == -1) continue;
        nd[u].sz += getsz(v, u);
    }
    return nd[u].sz;
}

void centroid (int u, int d) {
    int siz = getsz(u,u);

    int w = u;
    do {
        u = w;
        for (int v : nd[u].adj) {
            if (nd[v].sz == -1 || nd[v].sz >= nd[u].sz || nd[v].sz + nd[v].sz < siz)
                continue;
            w = v;
            break;
        }
    } while (u != w);

    nd[u].rs = d;
    nd[u].sz = -1;

    for (int v : nd[u].adj)
        if (nd[v].sz != -1)
            centroid(v, d+1);
}

void go (int l, int r, int x) {
    auto it = avail.upper_bound(l);
    while (it != avail.end() && *it <= r) {
        nd[x].vtx.insert(*it-1);
        nd[x].vtx.insert(*it);
        auto jt = next(it);
        avail.erase(it);
        it = jt;
    }
}

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

    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        cn[a]++; cn[b]++;

        if (a > b) swap(a,b);
        ed[i][0] = a;
        ed[i][1] = b;
        p[i] = i;
    }

    for (int i = 1; i <= n; i++)
        avail.insert(i);

    sort(p, p+m, [] (int i, int j) {
        return min(inner(i),outer(i)) < min(inner(j),outer(j));
    });

    for (int _i = 0; _i < m; _i++) {
        ns++;
        int i = p[_i];

        nd[ns].vtx.insert(ed[i][0]);
        nd[ns].vtx.insert(ed[i][1]);

        if (inner(i) <= outer(i)) {
            go(ed[i][0], ed[i][1], ns);
        } else {
            go(ed[i][1], n, ns);
            go(1, ed[i][0], ns);

            if (avail.find(1) != avail.end()) {
                avail.erase(1);
                nd[ns].vtx.insert(1);
                nd[ns].vtx.insert(n);
            }
        }

        assert(nd[ns].vtx.size() >= 3);
        int x = *prev(nd[ns].vtx.end());
        for (int y : nd[ns].vtx) {
            if ((x+1)%n != y%n) {
                pii aux(x,y);
                if (aux.first > aux.second)
                    swap(aux.first, aux.second);
                mp[aux].pb(ns);
            }
            cn[y]--;
            x = y;
        }
    }

    for (int i = 1; i <= n; i++) {
        cn[i]++; // standart region

        assert(cn[i] == 0 || cn[i] == 1);
        if (cn[i] == 1) {
            nd[0].vtx.insert(i);
        }
    }

    assert(nd[0].vtx.size() >= 3);
    int x = *prev(nd[0].vtx.end());
    for (int y : nd[0].vtx) {
        if ((x+1)%n != y%n) {
            pii aux(x,y);
            if (aux.first > aux.second)
                swap(aux.first, aux.second);
            mp[aux].pb(0);
        }
        x = y;
    }

    for (pair<const pii, vector<int> > & el : mp) {
        debug cout << "edge " << el.first.first << " " << el.first.second << " :";
        //assert(el.second.size() == 2);
        nd[el.second[0]].adj.pb(el.second[1]);
        nd[el.second[1]].adj.pb(el.second[0]);
        debug cout << endl;
    }

    debug {
        for (int i = 0; i <= ns; i++) {
            cout << "region " << i << " :";
            for (int j : nd[i].vtx)
                cout << " " << j;
            cout << " :";
            for (int j : nd[i].adj)
                cout << " " << j;
            cout << endl;
        }
    }

    centroid(0,0);

    sort(nd, nd+ns+1);
    for (int i = 0; i <= ns; i++) {
        cout << nd[i].rs + 1 << " ";
    }
    cout << endl;
}


#include <bits/stdc++.h>
#define debug if (0)

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

const int N = 2e5+7;

int ed[N][2], p[N];
int n, m;

struct Node {
    set<int> vtx;
    vector<int> adj;
    int sz;
    int rs;

    bool operator < (const Node & ot) const {
        auto it = vtx.rbegin();
        auto jt = ot.vtx.rbegin();

        while (it != vtx.rend() && jt != ot.vtx.rend()) {
            if (*it != *jt)
                return *it < *jt;
            ++it; ++jt;
        }
        return (it == vtx.rend());
    }
} nd[N];
int ns;

map<pii, vector<int> > mp;
int cn[N];
int cl[N];

int inner (int i)
{ return ed[i][1] - ed[i][0]; }
int outer (int i)
{ return n - ed[i][1] - ed[i][0]; }

int getsz (int u, int p) {
    nd[u].sz = 1;
    for (int v : nd[u].adj) {
        if (v == p || nd[v].sz == -1) continue;
        nd[u].sz += getsz(v, u);
    }
    return nd[u].sz;
}

void centroid (int u, int d) {
    int siz = getsz(u,u);

    int w = u;
    do {
        u = w;
        for (int v : nd[u].adj) {
            if (nd[v].sz == -1 || nd[v].sz >= nd[u].sz || nd[v].sz + nd[v].sz < siz)
                continue;
            w = v;
            break;
        }
    } while (u != w);

    nd[u].rs = d;
    nd[u].sz = -1;

    for (int v : nd[u].adj)
        if (nd[v].sz != -1)
            centroid(v, d+1);
}

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

    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        cn[a]++; cn[b]++;

        if (a > b) swap(a,b);
        ed[i][0] = a;
        ed[i][1] = b;
        p[i] = i;
    }

    sort(p, p+m, [] (int i, int j) {
        return min(inner(i),outer(i)) < min(inner(j),outer(j));
    });

    for (int _i = 0; _i < m; _i++) {
        ns++;
        int i = p[_i];

        nd[ns].vtx.insert(ed[i][0]);
        nd[ns].vtx.insert(ed[i][1]);

        if (inner(i) <= outer(i)) {
            for (int j = ed[i][0] + 1; j <= ed[i][1]; j++) {
                if (cl[j]) continue;
                cl[j] = ns;
                nd[ns].vtx.insert(j-1);
                nd[ns].vtx.insert(j);
            }
        } else {
            for (int j = ed[i][1] + 1; j <= n; j++) {
                if (cl[j]) continue;
                cl[j] = ns;
                nd[ns].vtx.insert(j-1);
                nd[ns].vtx.insert(j);
            }
            if (!cl[1]) {
                cl[1] = ns;
                nd[ns].vtx.insert(1);
                nd[ns].vtx.insert(n);
            }
            for (int j = 2; j <= ed[i][0]; j++) {
                if (cl[j]) continue;
                cl[j] = ns;
                nd[ns].vtx.insert(j-1);
                nd[ns].vtx.insert(j);
            }
        }

        int x = *prev(nd[ns].vtx.end());
        for (int y : nd[ns].vtx) {
            if (x + 1 != y && (x+1)%n != y) {
                pii aux(x,y);
                if (aux.first > aux.second)
                    swap(aux.first, aux.second);
                mp[aux].pb(ns);
            }
            cn[y]--;
            x = y;
        }
    }

    for (int i = 1; i <= n; i++) {
        cn[i]++; // standart region

        assert(cn[i] == 0 || cn[i] == 1);
        if (cn[i] == 1) {
            nd[0].vtx.insert(i);
        }
    }

    int x = *prev(nd[0].vtx.end());
    for (int y : nd[0].vtx) {
        if (x + 1 != y && (x+1)%n != y) {
            pii aux(x,y);
            if (aux.first > aux.second)
                swap(aux.first, aux.second);
            mp[aux].pb(0);
        }
        x = y;
    }

    for (pair<const pii, vector<int> > & el : mp) {
        debug cout << "edge " << el.first.first << " " << el.first.second << " :";
        for (int i = 0; i < el.second.size(); i++) {
            debug cout << " " <<  el.second[i];
            for (int j = 0; j < i; j++) {
                nd[el.second[i]].adj.pb(el.second[j]);
                nd[el.second[j]].adj.pb(el.second[i]);
            }
        }
        debug cout << endl;
    }

    debug {
        for (int i = 0; i <= ns; i++) {
            cout << "region " << i << " :";
            for (int j : nd[i].vtx)
                cout << " " << j;
            cout << " :";
            for (int j : nd[i].adj)
                cout << " " << j;
            cout << endl;
        }
    }

    centroid(0,0);

    sort(nd, nd+ns+1);
    for (int i = 0; i <= ns; i++) {
        cout << nd[i].rs + 1 << " ";
    }
    cout << endl;
}


#include <bits/stdc++.h>
#define debug if (0)

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

const int N = 2e5+7;

int ed[N][2], p[N];
int n, m;

struct Node {
    set<int> vtx;
    vector<int> adj;
    int sz;
    int rs;

    bool operator < (const Node & ot) const {
        auto it = vtx.rbegin();
        auto jt = ot.vtx.rbegin();

        while (it != vtx.rend() && jt != ot.vtx.rend()) {
            if (*it != *jt)
                return *it < *jt;
            ++it; ++jt;
        }
        return (it == vtx.rend());
    }
} nd[N];
int ns;

map<pii, vector<int> > mp;
int cn[N];
int cl[N];

int inner (int i)
{ return ed[i][1] - ed[i][0]; }
int outer (int i)
{ return n - ed[i][1] + ed[i][0]; }

int getsz (int u, int p) {
    nd[u].sz = 1;
    for (int v : nd[u].adj) {
        if (v == p || nd[v].sz == -1) continue;
        nd[u].sz += getsz(v, u);
    }
    return nd[u].sz;
}

void centroid (int u, int d) {
    int siz = getsz(u,u);

    int w = u;
    do {
        u = w;
        for (int v : nd[u].adj) {
            if (nd[v].sz == -1 || nd[v].sz >= nd[u].sz || nd[v].sz + nd[v].sz < siz)
                continue;
            w = v;
            break;
        }
    } while (u != w);

    nd[u].rs = d;
    nd[u].sz = -1;

    for (int v : nd[u].adj)
        if (nd[v].sz != -1)
            centroid(v, d+1);
}

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

    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        cn[a]++; cn[b]++;

        if (a > b) swap(a,b);
        ed[i][0] = a;
        ed[i][1] = b;
        p[i] = i;
    }

    sort(p, p+m, [] (int i, int j) {
        return min(inner(i),outer(i)) < min(inner(j),outer(j));
    });

    for (int _i = 0; _i < m; _i++) {
        ns++;
        int i = p[_i];

        nd[ns].vtx.insert(ed[i][0]);
        nd[ns].vtx.insert(ed[i][1]);

        if (inner(i) <= outer(i)) {
            for (int j = ed[i][0] + 1; j <= ed[i][1]; j++) {
                if (cl[j]) continue;
                cl[j] = ns;
                nd[ns].vtx.insert(j-1);
                nd[ns].vtx.insert(j);
            }
        } else {
            for (int j = ed[i][1] + 1; j <= n; j++) {
                if (cl[j]) continue;
                cl[j] = ns;
                nd[ns].vtx.insert(j-1);
                nd[ns].vtx.insert(j);
            }
            if (!cl[1]) {
                cl[1] = ns;
                nd[ns].vtx.insert(1);
                nd[ns].vtx.insert(n);
            }
            for (int j = 2; j <= ed[i][0]; j++) {
                if (cl[j]) continue;
                cl[j] = ns;
                nd[ns].vtx.insert(j-1);
                nd[ns].vtx.insert(j);
            }
        }
        cout << endl;

        int x = *prev(nd[ns].vtx.end());
        for (int y : nd[ns].vtx) {
            if (x + 1 != y && (x+1)%n != y) {
                pii aux(x,y);
                if (aux.first > aux.second)
                    swap(aux.first, aux.second);
                mp[aux].pb(ns);
            }
            cn[y]--;
            x = y;
        }
    }

    for (int i = 1; i <= n; i++) {
        cn[i]++; // standart region

        assert(cn[i] == 0 || cn[i] == 1);
        if (cn[i] == 1) {
            nd[0].vtx.insert(i);
        }
    }

    assert(!nd[0].vtx.empty());

    int x = *prev(nd[0].vtx.end());
    for (int y : nd[0].vtx) {
        if (x + 1 != y && (x+1)%n != y) {
            pii aux(x,y);
            if (aux.first > aux.second)
                swap(aux.first, aux.second);
            mp[aux].pb(0);
        }
        x = y;
    }

    for (pair<const pii, vector<int> > & el : mp) {
        debug cout << "edge " << el.first.first << " " << el.first.second << " :";
        for (int i = 0; i < el.second.size(); i++) {
            debug cout << " " <<  el.second[i];
            for (int j = 0; j < i; j++) {
                nd[el.second[i]].adj.pb(el.second[j]);
                nd[el.second[j]].adj.pb(el.second[i]);
            }
        }
        debug cout << endl;
    }

    debug {
        for (int i = 0; i <= ns; i++) {
            cout << "region " << i << " :";
            for (int j : nd[i].vtx)
                cout << " " << j;
            cout << " :";
            for (int j : nd[i].adj)
                cout << " " << j;
            cout << endl;
        }
    }

    centroid(0,0);

    sort(nd, nd+ns+1);
    for (int i = 0; i <= ns; i++) {
        cout << nd[i].rs + 1 << " ";
    }
    cout << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define FOR(i,a,b) for (auto i = (a); i <= (b); ++i)
#define NFOR(i,a,b) for(auto i = (a); i >= (b); --i)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define mp(i,a) make_pair(i,a)
#define pb(a) push_back(a)
#define bit(x,b) (x&(1LL<<b))

typedef long long int lli;
typedef pair <lli,lli> ii;
typedef pair <lli,ii> iii;
typedef vector <lli> vi;
int n,m;
bool cmp(ii a,ii b)
{
  int c=min(a.S-a.F-1,n-2-(a.S-a.F-1));
  int d=min(b.S-b.F-1,n-2-(b.S-b.F-1));
  return c<d;
}
int vis[100001],vis1[100001],sz[100001];
vi al[100001];
void dfs(int node)
{
  vis1[node]=1;
  sz[node]=1;
  for(int i=0;i<al[node].size();++i)
  {
    if(vis[al[node][i]]+vis1[al[node][i]]==0)
    {
      dfs(al[node][i]);
      sz[node]+=sz[al[node][i]];
    }
  }
}
int tell(int node,int p,int to)
{
  for(int i=0;i<al[node].size();++i)
    if(vis[al[node][i]]==0&&al[node][i]!=p&&sz[al[node][i]]>to/2)
      return(tell(al[node][i],node,to));
    return(node);
}
int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin>>n>>m;
  set<int> s;
  vi v[m+1];
  for(int i=0;i<n;++i)
    s.insert(i+1);
  ii dg[m];
  for(int i=0;i<m;++i)
  {
    int f,s;
    cin>>f>>s;
    if(f>s)
      swap(f,s);
    dg[i]=mp(f,s);
  }
  sort(dg,dg+m,cmp);
  for(int i=0;i<m;++i)
  {
    if(dg[i].S-dg[i].F-1<=n-2-(dg[i].S-dg[i].F-1))
    {
      auto it=s.upper_bound(dg[i].F);
      v[i].pb(dg[i].F);
      while((*it)!=dg[i].S)
      {
        v[i].pb((*it));
        it++;
      }
      v[i].pb(dg[i].S);
      for(int j=0;j<v[i].size();++j)
        s.erase(v[i][j]);
      s.insert(dg[i].S);
      s.insert(dg[i].F);
    }
    else
    {
      while((*s.begin())!=dg[i].F)
      {
        v[i].pb((*s.begin()));
        s.erase(s.begin());
      }
      v[i].pb(dg[i].F);
      v[i].pb(dg[i].S);
      auto it=s.upper_bound(dg[i].S);
      while(it!=s.end())
      {
        v[i].pb((*it));
        it++;
      }
      for(int j=0;j<v[i].size();++j)
        s.erase(v[i][j]);
      s.insert(dg[i].S);
      s.insert(dg[i].F);
    }
    reverse(all(v[i]));
  }
  while(s.size()!=0)
  {
    v[m].pb((*s.begin()));
    s.erase(s.begin());
  }
  reverse(all(v[m]));
  sort(v,v+m+1);
  map<ii,int> ma;
  for(int i=0;i<m+1;++i)
  {
    for(int j=0;j<v[i].size()-1;++j)
    {
      if(v[i][j]==v[i][j+1])
        continue;
      if(ma.find(mp(v[i][j],v[i][j+1]))!=ma.end())
      {
        al[i].pb(ma[mp(v[i][j],v[i][j+1])]);
        al[ma[mp(v[i][j],v[i][j+1])]].pb(i);
      }
      else
        ma[mp(v[i][j],v[i][j+1])]=i;
    }
    int j=v[i].size()-1;
    if(!(v[i][0]==n&&v[i][j]==1))
    {
     if(ma.find(mp(v[i][0],v[i][j]))!=ma.end())
      {
        al[i].pb(ma[mp(v[i][0],v[i][j])]);
        al[ma[mp(v[i][0],v[i][j])]].pb(i);
      }
      else
        ma[mp(v[i][0],v[i][j])]=i;
    }
  }
  int c=0,cur=1;
  int col[m+1];
  while(c!=m+1)
  {
    for(int i=0;i<m+1;++i)
    {
      if(vis[i]+vis1[i]==0)
      {
        dfs(i);
        int cen=tell(i,i,sz[i]);
        vis[cen]=1;
        col[cen]=cur;
        c++;
      }
    }
    memset(vis1,0,sizeof(vis1));
    cur++;
  }
  for(int i=0;i<m+1;++i)
    cout<<col[i]<<' ';
  cout<<endl;
  return 0;
}


#include <stdio.h>
#include <stdlib.h>

#define MAX_N 500000

static int N, K;
static int H[MAX_N][2];
static int L[MAX_N];
static int solution;

inline
void my_assert(int e) {if (!e) abort();}

void read_input()
{
  int i;
  my_assert(2==scanf("%d %d",&N,&K));
  for(i=0; i<N-1; i++)
    my_assert(3==scanf("%d %d %d",&H[i][0],&H[i][1],&L[i]));
  my_assert(1==scanf("%d",&solution));
}
#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define FOR(i,a,b) for (auto i = (a); i <= (b); ++i)
#define NFOR(i,a,b) for(auto i = (a); i >= (b); --i)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define mp(i,a) make_pair(i,a)
#define pb(a) push_back(a)
#define bit(x,b) (x&(1LL<<b))

typedef long long int lli;
typedef pair <lli,lli> ii;
typedef pair <lli,ii> iii;
typedef vector <lli> vi;
int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int arr1[1048575];
  int s=0,d=1,val=20;
  while(val!=0)
  {
    int i=s;
    while(i<1048575)
    {
      arr1[i]=val;
      i+=2*d;
    }
    s=s+d;
    d*=2;
    val--;
  }
  int n,m;
  cin>>n>>m;
  m++;
  vector<pair<iii,int>> v;
  set<int> al[n+1];
  for(int i=0;i<m-1;++i)
  {
    int f,s;
    cin>>f>>s;
    al[f].insert(s);
    al[s].insert(f);
  }
  int l=1,r=1,co=0,fi;
  multiset<int> se;
  se.insert(1);
  while(co!=m)
  {
    fi=-1;
    while(al[l].size()==0)
    {
      l++;
      if(l==n+1)
        l=1;
      if(l==r)
        break;
      se.insert(l);
      if(se.size()==4)
        se.erase(se.begin());
    }
    if(al[l].size()!=0)
    {
      fi=(*al[l].begin());
      al[l].erase(al[l].begin());
      al[fi].erase(l);
    }
    if(fi!=-1&&l==1)
    {
     while(l!=fi)
      {
        l++;
        if(l==n+1)
          l=1;
       se.insert(l);
        if(se.size()==4)
          se.erase(se.begin());
      }
    }
    else if(fi!=-1)
    {
      while(r!=fi)
      {
        r--;
        if(r==0)
          r=n;
        se.insert(r);
        if(se.size()==4)
          se.erase(se.begin());
      }
    }
    iii f=mp(0,mp(0,0));
    int i=0;
    while(se.size()!=0)
    {
      if(i==0)
        f.F=(*(--se.end()));
      else if(i==1)
        f.S.F=(*(--se.end()));
      else
        f.S.S=(*(--se.end()));
      se.erase((--se.end()));
      i++;
    }
    v.pb(mp(f,arr1[co]));
    co++;
    se.insert(l);
    se.insert(r);
  }
  sort(all(v));
  for(int i=0;i<m;++i)
    cout<<v[i].S<<' ';
  cout<<endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define FOR(i,a,b) for (auto i = (a); i <= (b); ++i)
#define NFOR(i,a,b) for(auto i = (a); i >= (b); --i)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define mp(i,a) make_pair(i,a)
#define pb(a) push_back(a)
#define bit(x,b) (x&(1LL<<b))

typedef long long int lli;
typedef pair <lli,lli> ii;
typedef pair <lli,ii> iii;
typedef vector <lli> vi;
int n,m;
bool cmp(ii a,ii b)
{
  int c=min(a.S-a.F-1,n-2-(a.S-a.F-1));
  int d=min(b.S-b.F-1,n-2-(b.S-b.F-1));
  return c<d;
}
int vis[100001],vis1[100001],sz[100001];
vi al[100001];
void dfs(int node)
{
  vis1[node]=1;
  sz[node]=1;
  for(int i=0;i<al[node].size();++i)
  {
    if(vis[al[node][i]]+vis1[al[node][i]]==0)
    {
      dfs(al[node][i]);
      sz[node]+=sz[al[node][i]];
    }
  }
}
int tell(int node,int p,int to)
{
  for(int i=0;i<al[node].size();++i)
    if(vis[al[node][i]]==0&&al[node][i]!=p&&sz[al[node][i]]>to/2)
      return(tell(al[node][i],node,to));
    return(node);
}
int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin>>n>>m;
  set<int> s;
  vi v[m+1];
  for(int i=0;i<n;++i)
    s.insert(i+1);
  ii dg[m];
  for(int i=0;i<m;++i)
  {
    int f,s;
    if(f>s)
      swap(f,s);
    cin>>f>>s;
    dg[i]=mp(f,s);
  }
  sort(dg,dg+m,cmp);
  for(int i=0;i<m;++i)
  {
    if(dg[i].S-dg[i].F-1<=n-2-(dg[i].S-dg[i].F-1))
    {
      auto it=s.upper_bound(dg[i].F);
      v[i].pb(dg[i].F);
      while((*it)!=dg[i].S)
      {
        v[i].pb((*it));
        it++;
      }
      v[i].pb(dg[i].S);
      for(int j=0;j<v[i].size();++j)
        s.erase(v[i][j]);
      s.insert(dg[i].S);
      s.insert(dg[i].F);
    }
    else
    {
      while((*s.begin())!=dg[i].F)
      {
        v[i].pb((*s.begin()));
        s.erase(s.begin());
      }
      v[i].pb(dg[i].F);
      v[i].pb(dg[i].S);
      auto it=s.upper_bound(dg[i].S);
      while(it!=s.end())
      {
        v[i].pb((*it));
        it++;
      }
      for(int j=0;j<v[i].size();++j)
        s.erase(v[i][j]);
      s.insert(dg[i].S);
      s.insert(dg[i].F);
    }
    reverse(all(v[i]));
  }
  while(s.size()!=0)
  {
    v[m].pb((*s.begin()));
    s.erase(s.begin());
  }
  reverse(all(v[m]));
  sort(v,v+m+1);
  map<ii,int> ma;
  for(int i=0;i<m+1;++i)
  {
    for(int j=0;j<v[i].size()-1;++j)
    {
      if(v[i][j]==v[i][j+1])
        continue;
      if(ma.find(mp(v[i][j],v[i][j+1]))!=ma.end())
      {
        al[i].pb(ma[mp(v[i][j],v[i][j+1])]);
        al[ma[mp(v[i][j],v[i][j+1])]].pb(i);
      }
      else
        ma[mp(v[i][j],v[i][j+1])]=i;
    }
    int j=v[i].size()-1;
    if(!(v[i][0]==n&&v[i][j]==1))
    {
     if(ma.find(mp(v[i][0],v[i][j]))!=ma.end())
      {
        al[i].pb(ma[mp(v[i][0],v[i][j])]);
        al[ma[mp(v[i][0],v[i][j])]].pb(i);
      }
      else
        ma[mp(v[i][0],v[i][j])]=i;
    }
  }
  int c=0,cur=1;
  int col[m+1];
  while(c!=m+1)
  {
    for(int i=0;i<m+1;++i)
    {
      if(vis[i]+vis1[i]==0)
      {
        dfs(i);
        int cen=tell(i,i,sz[i]);
        vis[cen]=1;
        col[cen]=cur;
        c++;
      }
    }
    memset(vis1,0,sizeof(vis1));
    cur++;
  }
  for(int i=0;i<m+1;++i)
    cout<<col[i]<<' ';
  cout<<endl;
  return 0;
}


#define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
#include <random>
using namespace std;

#define rep(i, N) for (int i = 0; i < N; i++)
#define pb push_back

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int u, v; ll w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

struct union_find {
	vector<int> v;
	union_find(int n) : v(n, -1) {}
	int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
	void unite(int x, int y) {
		x = find(x); y = find(y);
		if (x == y) return;
		if (-v[x] < -v[y]) swap(x, y);
		v[x] += v[y]; v[y] = x;
	}
	bool root(int x) { return v[x] < 0; }
	bool same(int x, int y) { return find(x) == find(y); }
	int size(int x) { return -v[find(x)]; }
};

vector<int> E[100001];
char C[100001];
int num[100001];
char CN[100001];

int dfs_num(int cur,int pre) {
	int i;
	int ma=-1;

	num[cur]=1;
	rep(i,E[cur].size()) {
		int tar=E[cur][i];
		if(tar==pre) continue;
		if(C[tar]) CN[cur] = max(CN[cur],C[tar]);
		else num[cur]+= dfs_num(tar,cur), CN[cur] = max(CN[cur],CN[tar]);
	}
	return num[cur];
}

pair<int,int> dfs_center(int cur,int pre,int nu) {
	int i;
	pair<int,int> res=make_pair(1<<30,-1);
	int ma=0,c=1;

	rep(i,E[cur].size()) {
		int tar=E[cur][i];
		if(tar==pre || C[tar]) continue;
		res=min(res,dfs_center(tar,cur,nu));

		ma=max(ma,num[tar]);
		c+=num[tar];
	}
	return min(res,make_pair(max(ma,nu-c),cur));
}

int main() {
	int N, M; cin >> N >> M;
	vector<int> a, b;
	rep(i, N) a.pb(i), b.pb((i + 1) % N);
	rep(j, M) {
		int i1, i2; scanf("%d%d", &i1, &i2);
		i1--; i2--;
		a.pb(i1); b.pb(i2);
	}
	M = a.size();
	vector<vector<i_i> > G(N);
	rep(j, M) {
		G[a[j]].pb(i_i(b[j], j));
		G[b[j]].pb(i_i(a[j], j + M));
	}
	union_find uf(M * 2);
	rep(i, N) {
		vector<i_i> v = G[i];
		for (i_i& p: v) if (p.first < i) p.first += N;
		sort(v.begin(), v.end());
		for (int k = 0; k + 1 < v.size(); k++) {
			uf.unite(v[k].second, (v[k + 1].second + M) % (M * 2));
		}
	}
	int L = 0;
	vector<int> index(M * 2);
	rep(j, M * 2) if (uf.root(j) && uf.size(j) > 1) index[j] = L++;
	for (int j = N; j < M; j++) {
		int u = index[uf.find(j)], v = index[uf.find(M + j)];
		E[u].pb(v); E[v].pb(u);
		// cout << u << ' ' << v << endl;
	}
	// cout << L << endl;
	rep(i,L) {
		while(C[i]==0) {
			dfs_num(i,-1);
			pair<int,int> p=dfs_center(i,-1,num[i]);
			C[p.second] = CN[i]+1;
			if(C[p.second]==1) C[p.second]='A';
			if(p.first==0) break;
		}
	}
	vector<vector<int> > vs(L);
	rep(j, M * 2) {
		if (uf.size(j) == 1) continue;
		int u = index[uf.find(j)];
		vs[u].pb(a[j % M]); vs[u].pb(b[j % M]);
	}
	vector<pair<vector<int>, int> > hoge(L);
	rep(u, L) {
		vector<int> unko = vs[u];
		sort(unko.begin(), unko.end());
		unko.erase(unique(unko.begin(), unko.end()), unko.end());
		reverse(unko.begin(), unko.end());
		hoge[u] = make_pair(unko, u);
	}
	sort(hoge.begin(), hoge.end());
	rep(u, L) printf("%d ", C[hoge[u].second] - 'A' + 1);
	cout << endl;
}


#define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
#include <random>
using namespace std;

#define rep(i, N) for (int i = 0; i < N; i++)
#define pb push_back

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int u, v; ll w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

struct union_find {
	vector<int> v;
	union_find(int n) : v(n, -1) {}
	int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
	void unite(int x, int y) {
		x = find(x); y = find(y);
		if (x == y) return;
		if (-v[x] < -v[y]) swap(x, y);
		v[x] += v[y]; v[y] = x;
	}
	bool root(int x) { return v[x] < 0; }
	bool same(int x, int y) { return find(x) == find(y); }
	int size(int x) { return -v[find(x)]; }
};

vector<int> E[100001];
char C[100001];
int num[100001];
char CN[100001];

int dfs_num(int cur,int pre) {
	int i;
	int ma=-1;

	num[cur]=1;
	rep(i,E[cur].size()) {
		int tar=E[cur][i];
		if(tar==pre) continue;
		if(C[tar]) CN[cur] = max(CN[cur],C[tar]);
		else num[cur]+= dfs_num(tar,cur), CN[cur] = max(CN[cur],CN[tar]);
	}
	return num[cur];
}

pair<int,int> dfs_center(int cur,int pre,int nu) {
	int i;
	pair<int,int> res=make_pair(1<<30,-1);
	int ma=0,c=1;

	rep(i,E[cur].size()) {
		int tar=E[cur][i];
		if(tar==pre || C[tar]) continue;
		res=min(res,dfs_center(tar,cur,nu));

		ma=max(ma,num[tar]);
		c+=num[tar];
	}
	return min(res,make_pair(max(ma,nu-c),cur));
}

int main() {
	int N, M; cin >> N >> M;
	vector<int> a, b;
	rep(i, N) a.pb(i), b.pb((i + 1) % N);
	rep(j, M) {
		int i1, i2; scanf("%d%d", &i1, &i2);
		i1--; i2--;
		a.pb(i1); b.pb(i2);
	}
	M = a.size();
	vector<vector<i_i> > G(N);
	rep(j, M) {
		G[a[j]].pb(i_i(b[j], j));
		G[b[j]].pb(i_i(a[j], j + M));
	}
	union_find uf(M * 2);
	rep(i, N) {
		vector<i_i> v = G[i];
		for (i_i& p: v) if (p.first < i) p.first += N;
		sort(v.begin(), v.end());
		for (int k = 0; k + 1 < v.size(); k++) {
			uf.unite(v[k].second, (v[k + 1].second + M) % (M * 2));
		}
	}
	int L = 0;
	vector<int> index(M * 2);
	rep(j, M * 2) if (uf.root(j) && uf.size(j) > 1) index[j] = L++;
	for (int j = N; j < M; j++) {
		int u = index[uf.find(j)], v = index[uf.find(M + j)];
		E[u].pb(v); E[v].pb(u);
		// cout << u << ' ' << v << endl;
	}
	// cout << L << endl;
	rep(i,L) {
		while(C[i]==0) {
			dfs_num(i,-1);
			pair<int,int> p=dfs_center(i,-1,num[i]);
			C[p.second] = CN[i]+1;
			if(C[p.second]==1) C[p.second]='A';
			if(p.first==0) break;
		}
	}
	vector<vector<int> > vs(L);
	rep(j, M * 2) {
		if (j < N) continue;
		int u = index[uf.find(j)];
		vs[u].pb(a[j % M]); vs[u].pb(b[j % M]);
	}
	vector<pair<vector<int>, int> > hoge(L);
	rep(u, L) {
		vector<int> unko = vs[u];
		sort(unko.begin(), unko.end());
		unko.erase(unique(unko.begin(), unko.end()), unko.end());
		reverse(unko.begin(), unko.end());
		hoge[u] = make_pair(unko, u);
	}
	sort(hoge.begin(), hoge.end());
	reverse(hoge.begin(), hoge.end());
	rep(u, L) printf("%d ", C[hoge[u].second] - 'A' + 1);
	cout << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pi;
typedef long long lint;
const int mod = 1e9 + 7;

vector<int> sm[100005], lg[100005];
int n, m, vis[100005];

int getnext(int x, int p){
	if(x < p){
		auto l = lower_bound(lg[x].begin(), lg[x].end(), p);
		if(lg[x].begin() == l){
			if(sm[x].size()) return sm[x].back();
			return lg[x].back();
		}
		l--;
		return *l;
	}
	else{
		auto l = lower_bound(sm[x].begin(), sm[x].end(), p);
		if(l == sm[x].begin()){
			if(lg[x].size()) return lg[x].back();
			if(sm[x].back() > *l) return sm[x].back();
			assert(0);
		}
		l--;
		return *l;
	}
}

int rev[100005];
set<pi> s;

void dfs(int p, int x, vector<int> &v){
	if(s.find(pi(p, x)) != s.end()) return;
	s.insert(pi(p, x));
	v.push_back(x);
	int nxt = getnext(x, p);
	dfs(x, nxt, v);
}

vector<int> gph[100005];
int ans[100005];
int sz[100005], msz[100005];
vector<int> dfn;

void dfs2(int x, int p){
	sz[x] = 1;
	msz[x] = 0;
	dfn.push_back(x);
	for(auto &i : gph[x]){
		if(vis[i]) continue;
		if(i == p) continue;
		dfs2(i, x);
		sz[x] += sz[i];
		msz[x] = max(msz[x], sz[i]);
	}
}

int get_center(int x){
	dfn.clear();
	dfs2(x, -1);
	int cur = 1e9, ret = x;
	for(auto &i : dfn){
		msz[i] = max(msz[i], (int)dfn.size() - sz[i]);
		if(msz[i] < cur){
			ret = i;
			cur = msz[i];
		}
	}
	return ret;
}

void solve(int l){
	memset(vis, 0, sizeof(vis));
	queue<int> que, dep;
	que.push(1);
	dep.push(1);
	while(!que.empty()){
		int x = que.front();
		int d = dep.front();
		que.pop();
		dep.pop();
		x = get_center(x);
		vis[x] = 1;
		ans[x] = d;
		for(auto &i : gph[x]){
			if(!vis[i]){
				que.push(i);
				dep.push(d+1);
			}
		}
	}
	for(int i=1; i<=l; i++) printf("%d ", ans[i]);
}

int main(){
	scanf("%d %d",&n,&m);
	vector<pi> v;
	for(int i=0; i<m; i++){
		int s, e;
		scanf("%d %d",&s,&e);
		if(s > e) swap(s, e);
		v.push_back(pi(s, e));
		v.push_back(pi(e, s));
		sm[e].push_back(s);
		lg[s].push_back(e);
	}
	for(int i=1; i<n; i++){
		v.push_back(pi(i, i+1));
		sm[i+1].push_back(i);
		lg[i].push_back(i+1);
	}
	v.push_back(pi(n, 1));
	sm[n].push_back(1);
	lg[1].push_back(n);
	for(int i=1; i<=n; i++){
		sort(sm[i].begin(), sm[i].end());
		sort(lg[i].begin(), lg[i].end());
	}
	vector<pair<vector<int> , int> > lis;
	map<pi, int> mp;
	vector<pi> edgs;
	for(auto &ii : v){
		if(s.find(ii) == s.end()){
			vector<int> v;
			dfs(ii.first, ii.second, v);
			for(int j=0; j<v.size(); j++){
			//	printf("%d ", v[j]);
				int nxt = v[(j+1)%v.size()];
				int cur = v[j];
				if(cur > nxt) swap(cur, nxt);
				if(mp.find(pi(cur, nxt)) != mp.end()){
					edgs.push_back({mp[pi(cur, nxt)], (int)lis.size()});
				}
				else mp[pi(cur, nxt)] = lis.size();
			}
		//	puts("");
			sort(v.begin(), v.end());
			reverse(v.begin(), v.end());
			lis.push_back({v, (int)lis.size()});
		}
	}
	sort(lis.begin(), lis.end());
	int idx = 0;
	for(auto &i : lis){
		idx++;
		rev[i.second] = idx;
	}
	for(auto &i : edgs){
		i.first = rev[i.first];
		i.second = rev[i.second];
		gph[i.first].push_back(i.second);
		gph[i.second].push_back(i.first);
	}
	solve(idx);
}


#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pi;
typedef long long lint;
const int mod = 1e9 + 7;

vector<int> sm[100005], lg[100005];
int n, m, vis[100005];

int getnext(int x, int p){
	if(x < p){
		auto l = lower_bound(lg[x].begin(), lg[x].end(), p);
		if(lg[x].begin() == l){
			if(sm[x].size()) return sm[x].back();
			return lg[x].back();
		}
		l--;
		return *l;
	}
	else{
		auto l = lower_bound(sm[x].begin(), sm[x].end(), p);
		if(l == sm[x].begin()){
			if(lg[x].size()) return lg[x].back();
			if(sm[x].back() > *l) return sm[x].back();
			assert(0);
		}
		l--;
		return *l;
	}
}

int rev[100005];

void dfs(int p, int x, vector<int> &v){
	if((x - p + n) % n == 1){
		if(vis[x]) return;
		vis[x] = 1;
	}
	v.push_back(x);
	int nxt = getnext(x, p);
	dfs(x, nxt, v);
}

vector<int> gph[100005];
int ans[100005];
int sz[100005], msz[100005];
vector<int> dfn;

void dfs2(int x, int p){
	sz[x] = 1;
	msz[x] = 0;
	dfn.push_back(x);
	for(auto &i : gph[x]){
		if(vis[i]) continue;
		if(i == p) continue;
		dfs2(i, x);
		sz[x] += sz[i];
		msz[x] = max(msz[x], sz[i]);
	}
}

int get_center(int x){
	dfn.clear();
	dfs2(x, -1);
	int cur = 1e9, ret = x;
	for(auto &i : dfn){
		msz[i] = max(msz[i], (int)dfn.size() - sz[i]);
		if(msz[i] < cur){
			ret = i;
			cur = msz[i];
		}
	}
	return ret;
}

void solve(int l){
	memset(vis, 0, sizeof(vis));
	queue<int> que, dep;
	que.push(1);
	dep.push(1);
	while(!que.empty()){
		int x = que.front();
		int d = dep.front();
		que.pop();
		dep.pop();
		x = get_center(x);
		vis[x] = 1;
		ans[x] = d;
		for(auto &i : gph[x]){
			if(!vis[i]){
				que.push(i);
				dep.push(d+1);
			}
		}
	}
	for(int i=1; i<=l; i++) printf("%d ", ans[i]);
}

int main(){
	scanf("%d %d",&n,&m);
	for(int i=0; i<m; i++){
		int s, e;
		scanf("%d %d",&s,&e);
		if(s > e) swap(s, e);
		sm[e].push_back(s);
		lg[s].push_back(e);
	}
	for(int i=1; i<n; i++){
		sm[i+1].push_back(i);
		lg[i].push_back(i+1);
	}
	sm[n].push_back(1);
	lg[1].push_back(n);
	for(int i=1; i<=n; i++){
		sort(sm[i].begin(), sm[i].end());
		sort(lg[i].begin(), lg[i].end());
	}
	vector<pair<vector<int> , int> > lis;
	map<pi, int> mp;
	vector<pi> edgs;
	for(int i=1; i<=n; i++){
		if(!vis[i]){
			vector<int> v;
			int nxt = i-1;
			if(nxt <= 0) nxt = n;
			dfs(nxt, i, v);
			for(int j=0; j<v.size(); j++){
				int nxt = v[(j+1)%v.size()];
				int cur = v[j];
				if(cur > nxt) swap(cur, nxt);
				if(mp.find(pi(cur, nxt)) != mp.end()){
					edgs.push_back({mp[pi(cur, nxt)], (int)lis.size()});
				}
				else mp[pi(cur, nxt)] = lis.size();
			}
			sort(v.begin(), v.end());
			reverse(v.begin(), v.end());
			lis.push_back({v, (int)lis.size()});
		}
	}
	sort(lis.begin(), lis.end());
	reverse(lis.begin(), lis.end());
	int idx = 0;
	for(auto &i : lis){
		idx++;
		rev[i.second] = idx;
	}
	for(auto &i : edgs){
		i.first = rev[i.first];
		i.second = rev[i.second];
		gph[i.first].push_back(i.second);
		gph[i.second].push_back(i.first);
	}
	solve(idx);
}


#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pi;
typedef long long lint;
const int mod = 1e9 + 7;

vector<int> sm[100005], lg[100005];
int n, m, vis[100005];

int getnext(int x, int p){
	if(x < p){
		auto l = lower_bound(lg[x].begin(), lg[x].end(), p);
		if(lg[x].begin() == l){
			if(sm[x].size()) return sm[x].back();
			return lg[x].back();
		}
		l--;
		return *l;
	}
	else{
		auto l = lower_bound(sm[x].begin(), sm[x].end(), p);
		if(l == sm[x].begin()){
			if(lg[x].size()) return lg[x].back();
			if(sm[x].back() > *l) return sm[x].back();
			assert(0);
		}
		l--;
		return *l;
	}
}

int rev[100005];
set<pi> s;

void dfs(int p, int x, vector<int> &v){
	if(s.find(pi(p, x)) != s.end()) return;
	s.insert(pi(p, x));
	v.push_back(x);
	int nxt = getnext(x, p);
	dfs(x, nxt, v);
}

vector<int> gph[100005];
int ans[100005];
int sz[100005], msz[100005];
vector<int> dfn;

void dfs2(int x, int p){
	sz[x] = 1;
	msz[x] = 0;
	dfn.push_back(x);
	for(auto &i : gph[x]){
		if(vis[i]) continue;
		if(i == p) continue;
		dfs2(i, x);
		sz[x] += sz[i];
		msz[x] = max(msz[x], sz[i]);
	}
}

int get_center(int x){
	dfn.clear();
	dfs2(x, -1);
	int cur = 1e9, ret = x;
	for(auto &i : dfn){
		msz[i] = max(msz[i], (int)dfn.size() - sz[i]);
		if(msz[i] < cur){
			ret = i;
			cur = msz[i];
		}
	}
	return ret;
}

void solve(int l){
	memset(vis, 0, sizeof(vis));
	queue<int> que, dep;
	que.push(1);
	dep.push(1);
	while(!que.empty()){
		int x = que.front();
		int d = dep.front();
		que.pop();
		dep.pop();
		x = get_center(x);
		vis[x] = 1;
		ans[x] = d;
		for(auto &i : gph[x]){
			if(!vis[i]){
				que.push(i);
				dep.push(d+1);
			}
		}
	}
	for(int i=1; i<=l; i++) printf("%d ", ans[i]);
}

int main(){
	scanf("%d %d",&n,&m);
	vector<pi> v;
	for(int i=0; i<m; i++){
		int s, e;
		scanf("%d %d",&s,&e);
		if(s > e) swap(s, e);
		v.push_back(pi(s, e));
		v.push_back(pi(e, s));
		sm[e].push_back(s);
		lg[s].push_back(e);
	}
	for(int i=1; i<n; i++){
		v.push_back(pi(i, i+1));
		sm[i+1].push_back(i);
		lg[i].push_back(i+1);
	}
	v.push_back(pi(n, 1));
	sm[n].push_back(1);
	lg[1].push_back(n);
	for(int i=1; i<=n; i++){
		sort(sm[i].begin(), sm[i].end());
		sort(lg[i].begin(), lg[i].end());
	}
	vector<pair<vector<int> , int> > lis;
	map<pi, int> mp;
	vector<pi> edgs;
	for(auto &ii : v){
		if(s.find(ii) == s.end()){
			vector<int> v;
			dfs(ii.first, ii.second, v);
			for(int j=0; j<v.size(); j++){
			//	printf("%d ", v[j]);
				int nxt = v[(j+1)%v.size()];
				int cur = v[j];
				if(cur > nxt) swap(cur, nxt);
				if(mp.find(pi(cur, nxt)) != mp.end()){
					edgs.push_back({mp[pi(cur, nxt)], (int)lis.size()});
				}
				else mp[pi(cur, nxt)] = lis.size();
			}
		//	puts("");
			sort(v.begin(), v.end());
			reverse(v.begin(), v.end());
			lis.push_back({v, (int)lis.size()});
		}
	}
	sort(lis.begin(), lis.end());
	reverse(lis.begin(), lis.end());
	int idx = 0;
	for(auto &i : lis){
		idx++;
		rev[i.second] = idx;
	}
	for(auto &i : edgs){
		i.first = rev[i.first];
		i.second = rev[i.second];
		gph[i.first].push_back(i.second);
		gph[i.second].push_back(i.first);
	}
	solve(idx);
}


#include <bits/stdc++.h>

using namespace std;

const int MaxN = 1e5 + 15;
const int INF = 1e9;

int color[MaxN];
int num[MaxN];
int dp[MaxN];
int h[MaxN];
int N;
pair<int, int> curc;

vector <int> v[MaxN];

bool used[MaxN];

int ans[MaxN];

set<int> s1[MaxN], s2[MaxN];

vector <int> V[MaxN];

int comps;

int G[MaxN];

void dfs(int x,int p = 0)
{
    dp[x] = 0;
    h[x] = 1;
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
        {
            dfs(v[x][i], x);
            h[x] += h[v[x][i]];
            dp[x] = max(dp[x], h[v[x][i]]);
        }
}

void findc(int x, int p = 0)
{
    dp[x] = max(dp[x], N - h[x]);
    curc = min(curc, make_pair(dp[x], x));
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
            findc(v[x][i], x);
}

void solve(int x, int c)
{
    //cout << "ARY " << x << ' ' << used[x] << ' ' << c << '\n';
    curc = make_pair(INF, INF);
    dfs(x);
    N = h[x];
    findc(x);
    x = curc.second;
    ans[num[x]] = c;
    used[x] = true;
    //cout << x << ' ' << used[x] << '\n';
    for(int i = 0; i < v[x].size(); ++i)
        if(!used[v[x][i]])
            solve(v[x][i], c + 1);
}

int n, m;
int a[MaxN], b[MaxN];

vector<int> tree[MaxN * 8];
vector<int> p[MaxN * 8];

void div(int a, int l, int r)
{
    ++comps;
    int N = s1[a].size();
    int k = 0;
    set<int> :: iterator it = s1[a].upper_bound(l);
    vector <int> order;
    for(set<int> :: iterator it1 = it; it1 != s1[a].end() && (*it1) < r; ++it1)
    {
        order.push_back(*it1);
        if(order.size() >= N / 2)
        {
            order.clear();
            for(it = s1[a].begin(); it != s1[a].end() && (*it) < l; ++it)
            {
                order.push_back(*it);
            }
            for(it = s1[a].upper_bound(r); it != s1[a].end(); ++it)
                order.push_back(*it);
            break;
        }
    }
    /**
    cout << "AYE\n";
    for(int i = 0; i < order.size(); ++i)
        cout << order[i] << ' ';
    cout << "EYA\n";
    */
    s2[l].insert(comps);
    s2[r].insert(comps);
    s1[comps].insert(l);
    s1[comps].insert(r);
    for(int i = 0; i < order.size(); ++i)
    {
        s2[order[i]].erase(a);
        s2[order[i]].insert(comps);
        s1[comps].insert(order[i]);
        s1[a].erase(order[i]);
    }
}

bool cmp(int A, int B)
{
    vector <int> *a = (&V[A]);
    vector <int> *b = (&V[B]);
    int aa = (*a).size() - 1;
    int bb = (*b).size() - 1;
    while(aa >= 0 && bb >= 0)
    {
        if((*a)[aa] < (*b)[bb])
            return !true;
        if((*a)[aa] > (*b)[bb])
            return !false;
        --aa;
        --bb;
    }
    if(aa >= 0 && bb < 0)
        return !false;
    else
        return !true;
}

int main()
{
    //srand(time(NULL));
    ios_base :: sync_with_stdio(false);cin.tie(NULL);
    cin >> n >> m;
    for(int i = 1; i <= n; ++i)
    {
        s1[1].insert(i);
        s2[i].insert(1);
    }
    comps = 1;
    for(int i = 1; i <= m; ++i)
    {
        cin >> a[i] >> b[i];
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, a[i], b[i]);
                    break;
                }
        }else
        {
            swap(a[i], b[i]);
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, b[i], a[i]);
                    break;
                }
            swap(a[i], b[i]);
        }
    }
    for(int i = 1; i <= comps; ++i)
    {
        for(set<int> :: iterator it = s1[i].begin(); it != s1[i].end(); ++it)
            V[i].push_back(*it);
        /*
        cout << i << '\n';
        for(int j = 0; j < V[i].size(); ++j)
            cout << V[i][j] << ' ';
        cout << '\n';
        */

    }
    for(int i = 1; i <= comps; ++i)
        G[i] = i;
    sort(G + 1, G + comps + 1, cmp);

    for(int i = 1; i <= comps; ++i)
        num[G[i]] = i;
    for(int i = 1; i <= n; ++i)
    {
        /**
        cout << i << " AA " << '\n';// << '  ' << "EE \n";
        for(set<int> :: iterator it = s2[i].begin(); it != s2[i].end(); ++it)
            cout << (*it) << '\n';
        cout << '\n';
        */
    }
    for(int i = 1; i <= m; ++i)
    {
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
        }else
        {
            swap(a[i], b[i]);
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
            swap(a[i], b[i]);
        }
    }
    solve(1, 1);
//    return 0;
    for(int i = 1; i <= comps; ++i)
        cout << ans[i] << ' ';
    cout << '\n';
}


#include <bits/stdc++.h>

using namespace std;

const int MaxN = 1e5 + 15;
const int INF = 1e9;

int color[MaxN];
int num[MaxN];
int dp[MaxN];
int h[MaxN];
int N;
pair<int, int> curc;

vector <int> v[MaxN];

bool used[MaxN];

int ans[MaxN];

set<int> s1[MaxN], s2[MaxN];

vector <int> V[MaxN];

int comps;

int G[MaxN];

void dfs(int x,int p = 0)
{
    dp[x] = 0;
    h[x] = 1;
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
        {
            dfs(v[x][i], x);
            h[x] += h[v[x][i]];
            dp[x] = max(dp[x], h[v[x][i]]);
        }
}

void findc(int x, int p = 0)
{
    dp[x] = max(dp[x], N - h[x]);
    curc = min(curc, make_pair(dp[x], x));
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
            findc(v[x][i], x);
}

void solve(int x, int c)
{
    //cout << "ARY " << x << ' ' << used[x] << ' ' << c << '\n';
    curc = make_pair(INF, INF);
    dfs(x);
    N = h[x];
    findc(x);
    x = curc.second;
    ans[num[x]] = c;
    used[x] = true;
    //cout << x << ' ' << used[x] << '\n';
    for(int i = 0; i < v[x].size(); ++i)
        if(!used[v[x][i]])
            solve(v[x][i], c + 1);
}

int n, m;
int a[MaxN], b[MaxN];

vector<int> tree[MaxN * 8];
vector<int> p[MaxN * 8];

void div(int a, int l, int r)
{
    ++comps;
    int N = s1[a].size();
    int k = 0;
    set<int> :: iterator it = s1[a].upper_bound(l);
    vector <int> order;
    for(set<int> :: iterator it1 = it; it1 != s1[a].end() && (*it1) < r; ++it1)
    {
        order.push_back(*it1);
        if(order.size() >= N / 2)
        {
            order.clear();
            for(it = s1[a].begin(); it != s1[a].end() && (*it) < l; ++it)
            {
                order.push_back(*it);
            }
            for(it = s1[a].upper_bound(r); it != s1[a].end(); ++it)
                order.push_back(*it);
            break;
        }
    }
    /**
    cout << "AYE\n";
    for(int i = 0; i < order.size(); ++i)
        cout << order[i] << ' ';
    cout << "EYA\n";
    */
    s2[l].insert(comps);
    s2[r].insert(comps);
    s1[comps].insert(l);
    s1[comps].insert(r);
    for(int i = 0; i < order.size(); ++i)
    {
        s2[order[i]].erase(a);
        s2[order[i]].insert(comps);
        s1[comps].insert(order[i]);
        s1[a].erase(order[i]);
    }
}

bool cmp(int A, int B)
{
    vector <int> *a = (&V[A]);
    vector <int> *b = (&V[B]);
    int aa = (*a).size() - 1;
    int bb = (*b).size() - 1;
    while(aa >= 0 && bb >= 0)
    {
        if((*a)[aa] < (*b)[bb])
            return true;
        if((*a)[aa] > (*b)[bb])
            return false;
        --aa;
        --bb;
    }
    if(aa >= 0 && bb < 0)
        return false;
    else
        return true;
}

int main()
{
    //srand(time(NULL));
    ios_base :: sync_with_stdio(false);cin.tie(NULL);
    cin >> n >> m;
    for(int i = 1; i <= n; ++i)
    {
        s1[1].insert(i);
        s2[i].insert(1);
    }
    comps = 1;
    for(int i = 1; i <= m; ++i)
    {
        cin >> a[i] >> b[i];
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, a[i], b[i]);
                    break;
                }
        }else
        {
            swap(a[i], b[i]);
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, b[i], a[i]);
                    break;
                }
            swap(a[i], b[i]);
        }
    }
    for(int i = 1; i <= comps; ++i)
    {
        for(set<int> :: iterator it = s1[i].begin(); it != s1[i].end(); ++it)
            V[i].push_back(*it);
        /*
        cout << i << '\n';
        for(int j = 0; j < V[i].size(); ++j)
            cout << V[i][j] << ' ';
        cout << '\n';
        */

    }
    for(int i = 1; i <= comps; ++i)
        G[i] = i;
    sort(G + 1, G + comps + 1, cmp);

    for(int i = 1; i <= comps; ++i)
        num[G[i]] = i;
    for(int i = 1; i <= n; ++i)
    {
        /**
        cout << i << " AA " << '\n';// << '  ' << "EE \n";
        for(set<int> :: iterator it = s2[i].begin(); it != s2[i].end(); ++it)
            cout << (*it) << '\n';
        cout << '\n';
        */
    }
    for(int i = 1; i <= m; ++i)
    {
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
        }else
        {
            swap(a[i], b[i]);
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
            swap(a[i], b[i]);
        }
    }
    solve(1, 1);
//    return 0;
    for(int i = 1; i <= comps; ++i)
        cout << ans[i] << ' ';
    cout << '\n';
}


#include <bits/stdc++.h>

using namespace std;

const int MaxN = 1e5 + 15;
const int INF = 1e9;

int color[MaxN];
int num[MaxN];
int dp[MaxN];
int h[MaxN];
int N;
pair<int, int> curc;

vector <int> v[MaxN];

bool used[MaxN];

int ans[MaxN];

set<int> s1[MaxN], s2[MaxN];

vector <int> V[MaxN];

int comps;

int G[MaxN];

void dfs(int x,int p = 0)
{
    dp[x] = 0;
    h[x] = 1;
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
        {
            dfs(v[x][i], x);
            h[x] += h[v[x][i]];
            dp[x] = max(dp[x], h[v[x][i]]);
        }
}

void findc(int x, int p = 0)
{
    dp[x] = max(dp[x], N - h[x]);
    curc = min(curc, make_pair(dp[x], x));
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
            findc(v[x][i], x);
}

void solve(int x, int c)
{
    //cout << "ARY " << x << ' ' << used[x] << ' ' << c << '\n';
    curc = make_pair(INF, INF);
    dfs(x);
    N = h[x];
    findc(x);
    x = curc.second;
    ans[num[x]] = c;
    used[x] = true;
    //cout << x << ' ' << used[x] << '\n';
    for(int i = 0; i < v[x].size(); ++i)
        if(!used[v[x][i]])
            solve(v[x][i], c + 1);
}

int n, m;
int a[MaxN], b[MaxN];

vector<int> tree[MaxN * 8];
vector<int> p[MaxN * 8];

void div(int a, int l, int r)
{
    ++comps;
    int N = s1[a].size();
    int k = 0;
    set<int> :: iterator it = s1[a].upper_bound(l);
    vector <int> order;
    for(set<int> :: iterator it1 = it; it1 != s1[a].end() && (*it1) < r; ++it1)
    {
        order.push_back(*it1);
        if(order.size() >= N / 2)
        {
            order.clear();
            for(it = s1[a].begin(); it != s1[a].end() && (*it) < l; ++it)
            {
                order.push_back(*it);
            }
            for(it = s1[a].upper_bound(r); it != s1[a].end(); ++it)
                order.push_back(*it);
            break;
        }
    }
    /**
    cout << "AYE\n";
    for(int i = 0; i < order.size(); ++i)
        cout << order[i] << ' ';
    cout << "EYA\n";
    */
    s2[l].insert(comps);
    s2[r].insert(comps);
    s1[comps].insert(l);
    s1[comps].insert(r);
    for(int i = 0; i < order.size(); ++i)
    {
        s2[order[i]].erase(a);
        s2[order[i]].insert(comps);
        s1[comps].insert(order[i]);
        s1[a].erase(order[i]);
    }
}

bool cmp(int A, int B)
{
    vector <int> *a = (&V[A]);
    vector <int> *b = (&V[B]);
    int aa = (*a).size() - 1;
    int bb = (*b).size() - 1;
    while(aa && bb)
    {
        if((*a)[aa] < (*b)[bb])
            return true;
        if((*a)[aa] > (*b)[bb])
            return false;
    }
    if(aa && !bb)
        return false;
    else
        return true;
}

int main()
{
    //srand(time(NULL));
    ios_base :: sync_with_stdio(false);cin.tie(NULL);
    cin >> n >> m;
    for(int i = 1; i <= n; ++i)
    {
        s1[1].insert(i);
        s2[i].insert(1);
    }
    comps = 1;
    for(int i = 1; i <= m; ++i)
    {
        cin >> a[i] >> b[i];
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, a[i], b[i]);
                    break;
                }
        }else
        {
            swap(a[i], b[i]);
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, b[i], a[i]);
                    break;
                }
            swap(a[i], b[i]);
        }
    }
    for(int i = 1; i <= comps; ++i)
    {
        for(set<int> :: iterator it = s1[i].begin(); it != s1[i].end(); ++it)
            V[i].push_back(*it);
        /*
        cout << i << '\n';
        for(int j = 0; j < V[i].size(); ++j)
            cout << V[i][j] << ' ';
        cout << '\n';
        */

    }
    //return 0;
    for(int i = 1; i <= comps; ++i)
        G[i] = i;
    sort(G + 1, G + comps + 1, cmp);

    for(int i = 1; i <= comps; ++i)
        num[G[i]] = i;
    //return 0;
    for(int i = 1; i <= n; ++i)
    {
        /**
        cout << i << " AA " << '\n';// << '  ' << "EE \n";
        for(set<int> :: iterator it = s2[i].begin(); it != s2[i].end(); ++it)
            cout << (*it) << '\n';
        cout << '\n';
        */
    }
    for(int i = 1; i <= m; ++i)
    {
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
        }else
        {
            swap(a[i], b[i]);
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
            swap(a[i], b[i]);
        }
    }
    //return 0;
    solve(1, 1);
//    return 0;
    for(int i = 1; i <= comps; ++i)
        cout << ans[i] << ' ';
    cout << '\n';
}


#include <bits/stdc++.h>

using namespace std;

const int MaxN = 1e5 + 15;
const int INF = 1e9;

int color[MaxN];
int num[MaxN];
int dp[MaxN];
int h[MaxN];
int N;
pair<int, int> curc;

vector <int> v[MaxN];

bool used[MaxN];

int ans[MaxN];

set<int> s1[MaxN], s2[MaxN];

vector <int> V[MaxN];

int comps;

int G[MaxN];

void dfs(int x,int p = 0)
{
    dp[x] = 0;
    h[x] = 1;
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
        {
            dfs(v[x][i], x);
            h[x] += h[v[x][i]];
            dp[x] = max(dp[x], h[v[x][i]]);
        }
}

void findc(int x, int p = 0)
{
    dp[x] = max(dp[x], N - h[x]);
    curc = min(curc, make_pair(dp[x], x));
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
            findc(v[x][i], x);
}

void solve(int x, int c)
{
    //cout << "ARY " << x << ' ' << used[x] << ' ' << c << '\n';
    curc = make_pair(INF, INF);
    dfs(x);
    N = h[x];
    findc(x);
    x = curc.second;
    ans[num[x]] = c;
    used[x] = true;
    //cout << x << ' ' << used[x] << '\n';
    for(int i = 0; i < v[x].size(); ++i)
        if(!used[v[x][i]])
            solve(v[x][i], c + 1);
}

int n, m;
int a[MaxN], b[MaxN];

vector<int> tree[MaxN * 8];
vector<int> p[MaxN * 8];

void div(int a, int l, int r)
{
    if(l < r)
        swap(l, r);
    ++comps;
    int N = s1[a].size();
    int k = 0;
    set<int> :: iterator it = s1[a].upper_bound(l);
    vector <int> order;
    for(set<int> :: iterator it1 = it; it1 != s1[a].end() && (*it1) < r; ++it1)
    {
        order.push_back(*it1);
        if(order.size() >= N / 2)
        {
            order.clear();
            for(it = s1[a].begin(); it != s1[a].end() && (*it) < l; ++it)
            {
                order.push_back(*it);
            }
            for(it = s1[a].upper_bound(r); it != s1[a].end(); ++it)
                order.push_back(*it);
            break;
        }
    }
    /**
    cout << "AYE\n";
    for(int i = 0; i < order.size(); ++i)
        cout << order[i] << ' ';
    cout << "EYA\n";
    */
    s2[l].insert(comps);
    s2[r].insert(comps);
    s1[comps].insert(l);
    s1[comps].insert(r);
    for(int i = 0; i < order.size(); ++i)
    {
        s2[order[i]].erase(a);
        s2[order[i]].insert(comps);
        s1[comps].insert(order[i]);
        s1[a].erase(order[i]);
    }
}

bool cmp(int A, int B)
{
    vector <int> *a = (&V[A]);
    vector <int> *b = (&V[B]);
    int aa = (*a).size() - 1;
    int bb = (*b).size() - 1;
    while(aa >= 0 && bb >= 0)
    {
        if((*a)[aa] < (*b)[bb])
            return true;
        if((*a)[aa] > (*b)[bb])
            return false;
        --aa;
        --bb;
    }
    if(aa >= 0 && bb < 0)
        return false;
    else
        return true;
}

int main()
{
    //srand(time(NULL));
    ios_base :: sync_with_stdio(false);cin.tie(NULL);
    cin >> n >> m;
    for(int i = 1; i <= n; ++i)
    {
        s1[1].insert(i);
        s2[i].insert(1);
    }
    comps = 1;
    for(int i = 1; i <= m; ++i)
    {
        cin >> a[i] >> b[i];
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, a[i], b[i]);
                    break;
                }
        }else
        {
            swap(a[i], b[i]);
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, b[i], a[i]);
                    break;
                }
            swap(a[i], b[i]);
        }
    }
    for(int i = 1; i <= comps; ++i)
    {
        for(set<int> :: iterator it = s1[i].begin(); it != s1[i].end(); ++it)
            V[i].push_back(*it);
        /*
        cout << i << '\n';
        for(int j = 0; j < V[i].size(); ++j)
            cout << V[i][j] << ' ';
        cout << '\n';
        */

    }
    for(int i = 1; i <= comps; ++i)
        G[i] = i;
    sort(G + 1, G + comps + 1, cmp);

    for(int i = 1; i <= comps; ++i)
        num[G[i]] = i;
    for(int i = 1; i <= n; ++i)
    {
        /**
        cout << i << " AA " << '\n';// << '  ' << "EE \n";
        for(set<int> :: iterator it = s2[i].begin(); it != s2[i].end(); ++it)
            cout << (*it) << '\n';
        cout << '\n';
        */
    }
    for(int i = 1; i <= m; ++i)
    {
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
        }else
        {
            swap(a[i], b[i]);
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
            swap(a[i], b[i]);
        }
    }
    solve(1, 1);
//    return 0;
    for(int i = 1; i <= comps; ++i)
        cout << ans[i] << ' ';
    cout << '\n';
}


#include <bits/stdc++.h>

using namespace std;

const int MaxN = 1e5 + 15;
const int INF = 1e9;

int color[MaxN];
int num[MaxN];
int dp[MaxN];
int h[MaxN];
int N;
pair<int, int> curc;

vector <int> v[MaxN];

bool used[MaxN];

int ans[MaxN];

set<int> s1[MaxN], s2[MaxN];

vector <int> V[MaxN];

int comps;

int G[MaxN];

void dfs(int x,int p = 0)
{
    dp[x] = 0;
    h[x] = 1;
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
        {
            dfs(v[x][i], x);
            h[x] += h[v[x][i]];
            dp[x] = max(dp[x], h[v[x][i]]);
        }
}

void findc(int x, int p = 0)
{
    dp[x] = max(dp[x], N - h[x]);
    curc = min(curc, make_pair(dp[x], x));
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
            findc(v[x][i], x);
}

void solve(int x, int c)
{
    //cout << "ARY " << x << ' ' << used[x] << ' ' << c << '\n';
    curc = make_pair(INF, INF);
    dfs(x);
    N = h[x];
    findc(x);
    x = curc.second;
    ans[num[x]] = c;
    used[x] = true;
    //cout << x << ' ' << used[x] << '\n';
    for(int i = 0; i < v[x].size(); ++i)
        if(!used[v[x][i]])
            solve(v[x][i], c + 1);
}

int n, m;
int a[MaxN], b[MaxN];

vector<int> tree[MaxN * 8];
vector<int> p[MaxN * 8];

void div(int a, int l, int r)
{
    if(l > r)
        swap(l, r);
    ++comps;
    int N = s1[a].size();
    int k = 0;
    set<int> :: iterator it = s1[a].upper_bound(l);
    vector <int> order;
    for(set<int> :: iterator it1 = it; it1 != s1[a].end() && (*it1) < r; ++it1)
    {
        order.push_back(*it1);
        if(order.size() >= N / 2)
        {
            order.clear();
            for(it = s1[a].begin(); it != s1[a].end() && (*it) < l; ++it)
            {
                order.push_back(*it);
            }
            for(it = s1[a].upper_bound(r); it != s1[a].end(); ++it)
                order.push_back(*it);
            break;
        }
    }
    /**
    cout << "AYE\n";
    for(int i = 0; i < order.size(); ++i)
        cout << order[i] << ' ';
    cout << "EYA\n";
    */
    s2[l].insert(comps);
    s2[r].insert(comps);
    s1[comps].insert(l);
    s1[comps].insert(r);
    for(int i = 0; i < order.size(); ++i)
    {
        s2[order[i]].erase(a);
        s2[order[i]].insert(comps);
        s1[comps].insert(order[i]);
        s1[a].erase(order[i]);
    }
}

bool cmp(int A, int B)
{
    vector <int> *a = (&V[A]);
    vector <int> *b = (&V[B]);
    int aa = (*a).size() - 1;
    int bb = (*b).size() - 1;
    while(aa >= 0 && bb >= 0)
    {
        if((*a)[aa] < (*b)[bb])
            return true;
        if((*a)[aa] > (*b)[bb])
            return false;
        --aa;
        --bb;
    }
    if(aa >= 0 && bb < 0)
        return false;
    else
        return true;
}

int main()
{
    //srand(time(NULL));
    ios_base :: sync_with_stdio(false);cin.tie(NULL);
    cin >> n >> m;
    for(int i = 1; i <= n; ++i)
    {
        s1[1].insert(i);
        s2[i].insert(1);
    }
    comps = 1;
    for(int i = 1; i <= m; ++i)
    {
        cin >> a[i] >> b[i];
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, a[i], b[i]);
                    break;
                }
        }else
        {
            swap(a[i], b[i]);
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, b[i], a[i]);
                    break;
                }
            swap(a[i], b[i]);
        }
    }
    for(int i = 1; i <= comps; ++i)
    {
        for(set<int> :: iterator it = s1[i].begin(); it != s1[i].end(); ++it)
            V[i].push_back(*it);
        /*
        cout << i << '\n';
        for(int j = 0; j < V[i].size(); ++j)
            cout << V[i][j] << ' ';
        cout << '\n';
        */

    }
    for(int i = 1; i <= comps; ++i)
        G[i] = i;
    sort(G + 1, G + comps + 1, cmp);

    for(int i = 1; i <= comps; ++i)
        num[G[i]] = i;
    for(int i = 1; i <= n; ++i)
    {
        /**
        cout << i << " AA " << '\n';// << '  ' << "EE \n";
        for(set<int> :: iterator it = s2[i].begin(); it != s2[i].end(); ++it)
            cout << (*it) << '\n';
        cout << '\n';
        */
    }
    for(int i = 1; i <= m; ++i)
    {
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
        }else
        {
            swap(a[i], b[i]);
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
            swap(a[i], b[i]);
        }
    }
    solve(1, 1);
//    return 0;
    for(int i = 1; i <= comps; ++i)
        cout << ans[i] << ' ';
    cout << '\n';
}


#include <bits/stdc++.h>

using namespace std;

const int MaxN = 1e5 + 15;
const int INF = 1e9;

int color[MaxN];
int num[MaxN];
int dp[MaxN];
int h[MaxN];
int N;
pair<int, int> curc;

vector <int> v[MaxN];

bool used[MaxN];

int ans[MaxN];

set<int> s1[MaxN], s2[MaxN];

vector <int> V[MaxN];

int comps;

int G[MaxN];

void dfs(int x,int p = 0)
{
    dp[x] = 0;
    h[x] = 1;
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
        {
            dfs(v[x][i], x);
            h[x] += h[v[x][i]];
            dp[x] = max(dp[x], h[v[x][i]]);
        }
}

void findc(int x, int p = 0)
{
    dp[x] = max(dp[x], N - h[x]);
    curc = min(curc, make_pair(dp[x], x));
    for(int i = 0; i < v[x].size(); ++i)
        if(v[x][i] != p && !used[v[x][i]])
            findc(v[x][i], x);
}

void solve(int x, int c)
{
    //cout << "ARY " << x << ' ' << used[x] << ' ' << c << '\n';
    curc = make_pair(INF, INF);
    dfs(x);
    N = h[x];
    findc(x);
    x = curc.second;
    ans[num[x]] = c;
    used[x] = true;
    //cout << x << ' ' << used[x] << '\n';
    for(int i = 0; i < v[x].size(); ++i)
        if(!used[v[x][i]])
            solve(v[x][i], c + 1);
}

int n, m;
int a[MaxN], b[MaxN];

vector<int> tree[MaxN * 8];
vector<int> p[MaxN * 8];

void div(int a, int l, int r)
{
    ++comps;
    int N = s1[a].size();
    int k = 0;
    set<int> :: iterator it = s1[a].upper_bound(l);
    vector <int> order;
    for(set<int> :: iterator it1 = it; it1 != s1[a].end() && (*it1) < r; ++it1)
    {
        order.push_back(*it1);
        if(order.size() >= N / 2)
        {
            order.clear();
            for(it = s1[a].begin(); it != s1[a].end() && (*it) < l; ++it)
            {
                order.push_back(*it);
            }
            for(it = s1[a].upper_bound(r); it != s1[a].end(); ++it)
                order.push_back(*it);
            break;
        }
    }
    /**
    cout << "AYE\n";
    for(int i = 0; i < order.size(); ++i)
        cout << order[i] << ' ';
    cout << "EYA\n";
    */
    s2[l].insert(comps);
    s2[r].insert(comps);
    s1[comps].insert(l);
    s1[comps].insert(r);
    for(int i = 0; i < order.size(); ++i)
    {
        s2[order[i]].erase(a);
        s2[order[i]].insert(comps);
        s1[comps].insert(order[i]);
        s1[a].erase(order[i]);
    }
}

bool cmp(int A, int B)
{
    vector <int> *a = (&V[A]);
    vector <int> *b = (&V[B]);
    int aa = (*a).size() - 1;
    int bb = (*b).size() - 1;
    while(aa >= 0 && bb >= 0)
    {
        if((*a)[aa] < (*b)[bb])
            return true;
        if((*a)[aa] > (*b)[bb])
            return false;
        --aa;
        --bb;
    }
    if(aa >= 0 && bb < 0)
        return false;
    else
        return true;
}

int main()
{
    //srand(time(NULL));
    ios_base :: sync_with_stdio(false);cin.tie(NULL);
    cin >> n >> m;
    for(int i = 1; i <= n; ++i)
    {
        s1[1].insert(i);
        s2[i].insert(1);
    }
    comps = 1;
    for(int i = 1; i <= m; ++i)
    {
        cin >> a[i] >> b[i];
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, a[i], b[i]);
                    break;
                }
        }else
        {
            swap(a[i], b[i]);
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    div(*it, a[i], b[i]);
                    break;
                }
            swap(a[i], b[i]);
        }
    }
    for(int i = 1; i <= comps; ++i)
    {
        for(set<int> :: iterator it = s1[i].begin(); it != s1[i].end(); ++it)
            V[i].push_back(*it);
        /*
        cout << i << '\n';
        for(int j = 0; j < V[i].size(); ++j)
            cout << V[i][j] << ' ';
        cout << '\n';
        */

    }
    for(int i = 1; i <= comps; ++i)
        G[i] = i;
    sort(G + 1, G + comps + 1, cmp);

    for(int i = 1; i <= comps; ++i)
        num[G[i]] = i;
    for(int i = 1; i <= n; ++i)
    {
        /**
        cout << i << " AA " << '\n';// << '  ' << "EE \n";
        for(set<int> :: iterator it = s2[i].begin(); it != s2[i].end(); ++it)
            cout << (*it) << '\n';
        cout << '\n';
        */
    }
    for(int i = 1; i <= m; ++i)
    {
        if(s2[a[i]].size() <= s2[b[i]].size())
        {
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
        }else
        {
            swap(a[i], b[i]);
            int p1 = 0;
            int p2 = 0;
            for(set<int> :: iterator it = s2[a[i]].begin(); it != s2[a[i]].end(); ++it)
                if(s2[b[i]].count(int(*it)))
                {
                    p2 = (*it);
                    if(p2 > p1)
                        swap(p1, p2);
                }
            v[p1].push_back(p2);
            v[p2].push_back(p1);
            //cout << p1 << ' ' << p2 << '\n';
            swap(a[i], b[i]);
        }
    }
    solve(1, 1);
//    return 0;
    for(int i = 1; i <= comps; ++i)
        cout << ans[i] << ' ';
    cout << '\n';
}


#include <stdio.h>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <unordered_map>
#include <fstream>
#include <random>
#include <cstring>
#include <complex>
#include <bitset>

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()
#define pb push_back

using namespace std;

const int P = 1e9 + 7;

typedef long long ll;
typedef long double ld;
mt19937 rr(random_device{}());

struct Face {
	vector<int> imp;
	int col;
};

bool operator < (const Face &a, const Face &b) {
	for (int i = 0; i < min(sz(a.imp), sz(b.imp)); ++i) {
		if (a.imp[i] != b.imp[i])
			return a.imp[i] < b.imp[i];
	}
	return sz(a.imp) < sz(b.imp);
}

vector<Face> faces;

vector<int> pos;

int g(int x, int y, int n) {
	return min(abs(x - y), n - abs(x - y));
}

void solve(vector<int> ver, vector<int> x, vector<int> y, int col) {
	assert(col < 21);
	// cout << col << endl;
	int n = sz(ver);
	int m = sz(x);
	// for (int i = 0; i < n; ++i)
	// 	cout << ver[i] << " ";
	// cout << endl;

	// for (int i = 0; i < m; ++i)
	// 	cout << x[i] << ' ' << y[i] << endl;

	for (int i = 0; i < n; ++i)
		pos[ver[i]] = i;

	for (int i = 0; i < m; ++i) {
		if (pos[x[i]] > pos[y[i]]) {
			swap(x[i], y[i]);
		}
	}

	int k = 0;
	int cur = g(pos[x[0]], pos[y[0]], n);
	for (int i = 1; i < n; ++i) {
		if (cur < g(pos[x[i]], pos[y[i]], n)) {
			cur = g(pos[x[i]], pos[y[i]], n);
			k = i;
		}
	}

	vector<vector<int>> g(n);
	for (int i = 0; i < m; ++i) {
		g[pos[x[i]]].push_back(pos[y[i]]);
		g[pos[y[i]]].push_back(pos[x[i]]);
	}

	vector<int> d(n);

	int u = pos[x[k]];
	int v = pos[y[k]];
	cur = v;
	Face f;
	f.imp.push_back(v);

	// cout << u << endl << v << endl;

	if (v - u <= n / 2) {
		while (cur != u) {
			int t = -1;
			for (int w : g[cur]) {
				if ((u < w && w < v) || (cur == v && u == w))
					continue;
				if (t == -1 || (u - w + n) % n < (u - t + n) % n)
					t = w;
			}
			assert(t != -1);
			f.imp.push_back(ver[t]);
			cur = t;
			// cout << cur << endl;
		}
	} else {
		while (cur != u) {
			int t = -1;
			for (int w : g[cur]) {
				if (!(u <= w && w <= v) || (cur == v && u == w))
					continue;
				if (t == -1 || (w - u + n) % n < (t - u + n) % n)
					t = w;
			}
			assert(t != -1);
			f.imp.push_back(ver[t]);
			cur = t;
			// cout << cur << endl;
		}
	}
	// cout << endl;

	int s = sz(f.imp);

	for (auto w : f.imp)
		d[w] = 1;
	f.col = col;
	sort(all(f.imp));
	reverse(all(f.imp));
	faces.push_back(f);

	vector<vector<int>> newV(s);
	vector<vector<int>> newX(s);
	vector<vector<int>> newY(s);
	vector<vector<int>> type(n);

	int cnt = 0;
	for (int i = 0; i < n; ++i) {
		newV[cnt % s].push_back(ver[i]);
		type[i].push_back(cnt % s);
		if (d[i]) {
			++cnt;
			newV[cnt % s].push_back(ver[i]);
			type[i].push_back(cnt % s);
		}
	}

	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < sz(type[pos[x[i]]]); ++j) {
			for (int k = 0; k < sz(type[pos[y[i]]]); ++k) {
				int u = type[pos[x[i]]][j];
				int v = type[pos[y[i]]][k];
				if (u == v) {
					newX[u].push_back(x[i]);
					newY[u].push_back(y[i]);
				}
			}
		}
	}

	for (int i = 0; i < s; ++i) {
		if (sz(newV[i]) > 2) {
			solve(newV[i], newX[i], newY[i], col + 1);
		}
	}
}

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

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int n, m;
	cin >> n >> m;
	vector<int> x(m), y(m);
	for (int i = 0; i < m; ++i) {
		cin >> x[i] >> y[i];
		--x[i]; --y[i];
	}

	vector<int> v(n);
	for (int i = 0; i < n; ++i)
		v[i] = i;

	pos.resize(n);

	for (int i = 0; i < n; ++i) {
		x.push_back(i);
		y.push_back((i + 1) % n);
	}

	solve(v, x, y, 1);

	sort(all(faces));

	for (int i = 0; i < sz(faces); ++i) {
		// for (int v : faces[i].imp)
		// 	cout << v << " ";
		// cout << endl;
		// cout << faces[i].col << endl;
		cout << faces[i].col << " ";
	}
	cout << endl;

}


#include <stdio.h>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <unordered_map>
#include <fstream>
#include <random>
#include <cstring>
#include <complex>
#include <bitset>

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()
#define pb push_back

using namespace std;

const int P = 1e9 + 7;

typedef long long ll;
typedef long double ld;
mt19937 rr(random_device{}());

struct Face {
	vector<int> imp;
	int col;
};

bool operator < (const Face &a, const Face &b) {
	for (int i = 0; i < min(sz(a.imp), sz(b.imp)); ++i) {
		if (a.imp[i] != b.imp[i])
			return a.imp[i] < b.imp[i];
	}
	return sz(a.imp) < sz(b.imp);
}

vector<Face> faces;

vector<int> pos;

int g(int x, int y, int n) {
	return min(abs(x - y), n - abs(x - y));
}

void solve(vector<int> ver, vector<int> x, vector<int> y, int col) {
	assert(col < 21);
	// cout << col << endl;
	int n = sz(ver);
	int m = sz(x);
	// for (int i = 0; i < n; ++i)
	// 	cout << ver[i] << " ";
	// cout << endl;

	// for (int i = 0; i < m; ++i)
	// 	cout << x[i] << ' ' << y[i] << endl;

	for (int i = 0; i < n; ++i)
		pos[ver[i]] = i;

	for (int i = 0; i < m; ++i) {
		if (pos[x[i]] > pos[y[i]]) {
			swap(x[i], y[i]);
		}
	}

	int k = 0;
	int cur = g(pos[x[0]], pos[y[0]], n);
	for (int i = 1; i < n; ++i) {
		if (cur < g(pos[x[i]], pos[y[i]], n)) {
			cur = g(pos[x[i]], pos[y[i]], n);
			k = i;
		}
	}

	vector<vector<int>> g(n);
	for (int i = 0; i < m; ++i) {
		g[pos[x[i]]].push_back(pos[y[i]]);
		g[pos[y[i]]].push_back(pos[x[i]]);
	}

	vector<int> d(n);

	int u = pos[x[k]];
	int v = pos[y[k]];
	cur = v;
	Face f;
	f.imp.push_back(v);

	// cout << u << endl << v << endl;

	if (v - u <= n / 2) {
		while (cur != u) {
			int t = -1;
			for (int w : g[cur]) {
				if ((u < w && w < v) || (cur == v && u == w))
					continue;
				if (t == -1 || (u - w + n) % n < (u - t + n) % n)
					t = w;
			}
			f.imp.push_back(t);
			cur = t;
			// cout << cur << endl;
			assert(cur != -1);
		}
	} else {
		while (cur != u) {
			int t = -1;
			for (int w : g[cur]) {
				if (!(u <= w && w <= v) || (cur == v && u == w))
					continue;
				if (t == -1 || (w - u + n) % n < (t - u + n) % n)
					t = w;
			}
			f.imp.push_back(t);
			cur = t;
			// cout << cur << endl;
			assert(cur != -1);
		}
	}
	// cout << endl;

	int s = sz(f.imp);

	for (auto w : f.imp)
		d[w] = 1;
	f.col = col;
	faces.push_back(f);

	vector<vector<int>> newV(s);
	vector<vector<int>> newX(s);
	vector<vector<int>> newY(s);
	vector<vector<int>> type(n);

	int cnt = 0;
	for (int i = 0; i < n; ++i) {
		newV[cnt % s].push_back(ver[i]);
		type[i].push_back(cnt % s);
		if (d[i]) {
			++cnt;
			newV[cnt % s].push_back(ver[i]);
			type[i].push_back(cnt % s);
		}
	}

	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < sz(type[pos[x[i]]]); ++j) {
			for (int k = 0; k < sz(type[pos[y[i]]]); ++k) {
				int u = type[pos[x[i]]][j];
				int v = type[pos[y[i]]][k];
				if (u == v) {
					newX[u].push_back(x[i]);
					newY[u].push_back(y[i]);
				}
			}
		}
	}

	for (int i = 0; i < s; ++i) {
		if (sz(newV[i]) > 2) {
			solve(newV[i], newX[i], newY[i], col + 1);
		}
	}
}

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

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int n, m;
	cin >> n >> m;
	vector<int> x(m), y(m);
	for (int i = 0; i < m; ++i) {
		cin >> x[i] >> y[i];
		--x[i]; --y[i];
	}

	vector<int> v(n);
	for (int i = 0; i < n; ++i)
		v[i] = i;

	pos.resize(n);

	for (int i = 0; i < n; ++i) {
		x.push_back(i);
		y.push_back((i + 1) % n);
	}

	solve(v, x, y, 1);

	sort(all(faces));

	for (int i = 0; i < sz(faces); ++i) {
		cout << faces[i].col << " ";
	}
	cout << endl;

}


#include <stdio.h>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <unordered_map>
#include <fstream>
#include <random>
#include <cstring>
#include <complex>
#include <bitset>

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()
#define pb push_back

using namespace std;

const int P = 1e9 + 7;

typedef long long ll;
typedef long double ld;
mt19937 rr(random_device{}());

struct Face {
	vector<int> imp;
	int col;
};

bool operator < (const Face &a, const Face &b) {
	for (int i = 0; i < min(sz(a.imp), sz(b.imp)); ++i) {
		if (a.imp[i] != b.imp[i])
			return a.imp[i] < b.imp[i];
	}
	return sz(a.imp) < sz(b.imp);
}

vector<Face> faces;

vector<int> pos;

int g(int x, int y, int n) {
	return min(abs(x - y), n - abs(x - y));
}

void solve(vector<int> ver, vector<int> x, vector<int> y, int col) {
	assert(col < 21);
	// cout << col << endl;
	int n = sz(ver);
	int m = sz(x);
	// for (int i = 0; i < n; ++i)
	// 	cout << ver[i] << " ";
	// cout << endl;

	// for (int i = 0; i < m; ++i)
	// 	cout << x[i] << ' ' << y[i] << endl;

	for (int i = 0; i < n; ++i)
		pos[ver[i]] = i;

	for (int i = 0; i < m; ++i) {
		if (pos[x[i]] > pos[y[i]]) {
			swap(x[i], y[i]);
		}
	}

	int k = 0;
	int cur = g(pos[x[0]], pos[y[0]], n);
	for (int i = 1; i < n; ++i) {
		if (cur < g(pos[x[i]], pos[y[i]], n)) {
			cur = g(pos[x[i]], pos[y[i]], n);
			k = i;
		}
	}

	vector<vector<int>> g(n);
	for (int i = 0; i < m; ++i) {
		g[pos[x[i]]].push_back(pos[y[i]]);
		g[pos[y[i]]].push_back(pos[x[i]]);
	}

	vector<int> d(n);

	int u = pos[x[k]];
	int v = pos[y[k]];
	cur = v;
	Face f;
	f.imp.push_back(ver[v]);
	d[u] = 1;
	d[v] = 1;

	// cout << u << endl << v << endl;

	if (v - u <= n / 2) {
		while (cur != u) {
			int t = -1;
			for (int w : g[cur]) {
				if ((u < w && w < v) || (cur == v && u == w))
					continue;
				if (t == -1 || (u - w + n) % n < (u - t + n) % n)
					t = w;
			}
			assert(t != -1);
			d[t] = 1;
			f.imp.push_back(ver[t]);
			cur = t;
			// cout << cur << endl;
		}
	} else {
		while (cur != u) {
			int t = -1;
			for (int w : g[cur]) {
				if (!(u <= w && w <= v) || (cur == v && u == w))
					continue;
				if (t == -1 || (w - u + n) % n < (t - u + n) % n)
					t = w;
			}
			assert(t != -1);
			d[t] = 1;
			f.imp.push_back(ver[t]);
			cur = t;
			// cout << cur << endl;
		}
	}

	int s = sz(f.imp);

	// for (int v : f.imp)
	// 	cout << v << ' ';
	// cout << endl;
	// cout << endl;

	f.col = col;
	sort(all(f.imp));
	reverse(all(f.imp));
	faces.push_back(f);

	vector<vector<int>> newV(s);
	vector<vector<int>> newX(s);
	vector<vector<int>> newY(s);
	vector<vector<int>> type(n);

	int cnt = 0;
	for (int i = 0; i < n; ++i) {
		newV[cnt % s].push_back(ver[i]);
		type[i].push_back(cnt % s);
		if (d[i]) {
			++cnt;
			newV[cnt % s].push_back(ver[i]);
			type[i].push_back(cnt % s);
		}
	}

	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < sz(type[pos[x[i]]]); ++j) {
			for (int k = 0; k < sz(type[pos[y[i]]]); ++k) {
				int u = type[pos[x[i]]][j];
				int v = type[pos[y[i]]][k];
				if (u == v) {
					newX[u].push_back(x[i]);
					newY[u].push_back(y[i]);
				}
			}
		}
	}

	for (int i = 0; i < s; ++i) {
		if (sz(newV[i]) > 2) {
			solve(newV[i], newX[i], newY[i], col + 1);
		}
	}
}

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

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int n, m;
	cin >> n >> m;
	vector<int> x(m), y(m);
	for (int i = 0; i < m; ++i) {
		cin >> x[i] >> y[i];
		--x[i]; --y[i];
	}

	vector<int> v(n);
	for (int i = 0; i < n; ++i)
		v[i] = i;

	pos.resize(n);

	for (int i = 0; i < n; ++i) {
		x.push_back(i);
		y.push_back((i + 1) % n);
	}

	solve(v, x, y, 1);

	sort(all(faces));

	for (int i = 0; i < sz(faces); ++i) {
		// for (int v : faces[i].imp)
		// 	cout << v << " ";
		// cout << endl;
		// cout << faces[i].col << endl;
		cout << faces[i].col << " ";
	}
	cout << endl;

}


#include <stdio.h>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <unordered_map>
#include <fstream>
#include <random>
#include <cstring>
#include <complex>
#include <bitset>

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()
#define pb push_back

using namespace std;

const int P = 1e9 + 7;

typedef long long ll;
typedef long double ld;
mt19937 rr(random_device{}());

struct Face {
	vector<int> imp;
	int col;
};

bool operator < (const Face &a, const Face &b) {
	for (int i = 0; i < min(sz(a.imp), sz(b.imp)); ++i) {
		if (a.imp[i] != b.imp[i])
			return a.imp[i] < b.imp[i];
	}
	return sz(a.imp) < sz(b.imp);
}

vector<Face> faces;

vector<int> pos;

int g(int x, int y, int n) {
	return min(abs(x - y), n - abs(x - y));
}

void solve(vector<int> ver, vector<int> x, vector<int> y, int col) {
	assert(col < 21);
	// cout << col << endl;
	int n = sz(ver);
	int m = sz(x);
	// for (int i = 0; i < n; ++i)
	// 	cout << ver[i] << " ";
	// cout << endl;

	// for (int i = 0; i < m; ++i)
	// 	cout << x[i] << ' ' << y[i] << endl;

	for (int i = 0; i < n; ++i)
		pos[ver[i]] = i;

	for (int i = 0; i < m; ++i) {
		if (pos[x[i]] > pos[y[i]]) {
			swap(x[i], y[i]);
		}
	}

	int k = 0;
	int cur = g(pos[x[0]], pos[y[0]], n);
	for (int i = 1; i < n; ++i) {
		if (cur < g(pos[x[i]], pos[y[i]], n)) {
			cur = g(pos[x[i]], pos[y[i]], n);
			k = i;
		}
	}

	vector<vector<int>> g(n);
	for (int i = 0; i < m; ++i) {
		g[pos[x[i]]].push_back(pos[y[i]]);
		g[pos[y[i]]].push_back(pos[x[i]]);
	}

	vector<int> d(n);

	int u = pos[x[k]];
	int v = pos[y[k]];
	cur = v;
	Face f;
	f.imp.push_back(v);
	d[u] = 1;
	d[v] = 1;

	// cout << u << endl << v << endl;

	if (v - u <= n / 2) {
		while (cur != u) {
			int t = -1;
			for (int w : g[cur]) {
				if ((u < w && w < v) || (cur == v && u == w))
					continue;
				if (t == -1 || (u - w + n) % n < (u - t + n) % n)
					t = w;
			}
			assert(t != -1);
			d[t] = 1;
			f.imp.push_back(ver[t]);
			cur = t;
			// cout << cur << endl;
		}
	} else {
		while (cur != u) {
			int t = -1;
			for (int w : g[cur]) {
				if (!(u <= w && w <= v) || (cur == v && u == w))
					continue;
				if (t == -1 || (w - u + n) % n < (t - u + n) % n)
					t = w;
			}
			assert(t != -1);
			d[t] = 1;
			f.imp.push_back(ver[t]);
			cur = t;
			// cout << cur << endl;
		}
	}
	// cout << endl;

	int s = sz(f.imp);

	f.col = col;
	sort(all(f.imp));
	reverse(all(f.imp));
	faces.push_back(f);

	vector<vector<int>> newV(s);
	vector<vector<int>> newX(s);
	vector<vector<int>> newY(s);
	vector<vector<int>> type(n);

	int cnt = 0;
	for (int i = 0; i < n; ++i) {
		newV[cnt % s].push_back(ver[i]);
		type[i].push_back(cnt % s);
		if (d[i]) {
			++cnt;
			newV[cnt % s].push_back(ver[i]);
			type[i].push_back(cnt % s);
		}
	}

	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < sz(type[pos[x[i]]]); ++j) {
			for (int k = 0; k < sz(type[pos[y[i]]]); ++k) {
				int u = type[pos[x[i]]][j];
				int v = type[pos[y[i]]][k];
				if (u == v) {
					newX[u].push_back(x[i]);
					newY[u].push_back(y[i]);
				}
			}
		}
	}

	for (int i = 0; i < s; ++i) {
		if (sz(newV[i]) > 2) {
			solve(newV[i], newX[i], newY[i], col + 1);
		}
	}
}

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

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int n, m;
	cin >> n >> m;
	vector<int> x(m), y(m);
	for (int i = 0; i < m; ++i) {
		cin >> x[i] >> y[i];
		--x[i]; --y[i];
	}

	vector<int> v(n);
	for (int i = 0; i < n; ++i)
		v[i] = i;

	pos.resize(n);

	for (int i = 0; i < n; ++i) {
		x.push_back(i);
		y.push_back((i + 1) % n);
	}

	solve(v, x, y, 1);

	sort(all(faces));

	for (int i = 0; i < sz(faces); ++i) {
		// for (int v : faces[i].imp)
		// 	cout << v << " ";
		// cout << endl;
		// cout << faces[i].col << endl;
		cout << faces[i].col << " ";
	}
	cout << endl;

}