//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

void dfs(int s)
{
    vis[s] = 1;
    for(int x:g[s]){
        if(!vis[x]){
            dfs(x);
        }
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    dfs(1);
    f(i, 1, n){
        if(!vis[i]){
            cout<<-1;
            rr;
        }
    }

    mem(vis);

    int s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 1;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 1;
        }
    }

    f(i, 1, n){
        if(col[i] == 1){
            for(int x:g[i]){
                if(col[x] == 1){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    mem(vis);

    ///2
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 2;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 2;
        }
    }

    f(i, 1, n){
        if(col[i] == 2){
            for(int x:g[i]){
                if(col[x] == 2){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    mem(vis);

    ///3
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 3;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 3;
        }
    }

    f(i, 1, n){
        if(col[i] == 3){
            for(int x:g[i]){
                if(col[x] == 3){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    mem(vis);

    ///last
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s != -1){
        cout<<-1;
        rr;
    }

    ///sesh
    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

void dfs(int s)
{
    vis[s] = 1;
    for(int x:g[s]){
        if(!vis[x]){
            dfs(x);
        }
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    dfs(1);
    f(i, 1, n){
        if(!vis[i]){
            cout<<-1;
            rr;
        }
    }

    mem(vis);

    int s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 1;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 1;
        }
    }

    int ok = 0, tot = 0;
    f(i, 1, n){
        if(col[i] == 1){
            ok = 1;
            tot++;
            for(int x:g[i]){
                if(col[x] == 1){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    if(!ok){
        cout<<-1;
        rr;
    }

    if(n==27653 && m==165889){
        cout<<tot<<" ";
    }

    mem(vis);

    ///2
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 2;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 2;
        }
    }

    ok = 0, tot = 0;
    f(i, 1, n){
        if(col[i] == 2){
            ok = 1;
            tot++;
            for(int x:g[i]){
                if(col[x] == 2){
                    cout<<-1;
                    rr;
                }
            }
        }
    }
    if(n==27653 && m==165889){
        cout<<tot<<" ";
    }
    if(!ok){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///3
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 3;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 3;
        }
    }

    ok = 0, tot = 0;
    f(i, 1, n){
        if(col[i] == 3){
            ok = 1;
            tot++;
            for(int x:g[i]){
                if(col[x] == 3){
                    cout<<-1;
                    rr;
                }
            }
        }
    }
    if(n==27653 && m==165889){
        cout<<tot<<"\n";
    }
    if(!ok){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///last
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s != -1){
        cout<<-1;
        rr;
    }

    ///sesh
    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

void dfs(int s)
{
    vis[s] = 1;
    for(int x:g[s]){
        if(!vis[x]){
            dfs(x);
        }
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    dfs(1);
    f(i, 1, n){
        if(!vis[i]){
            cout<<-1;
            rr;
        }
    }

    mem(vis);

    int s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 1;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 1;
        }
    }

    int ok = 0, tot1 = 0, tot2=0, tot3=0;
    f(i, 1, n){
        if(col[i] == 1){
            ok = 1;
            tot1++;
            for(int x:g[i]){
                if(col[x] == 1){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    if(!ok){
        cout<<-1;
        rr;
    }

//    if(n==27653 && m==165889){
//        cout<<tot<<" ";
//    }

    mem(vis);

    ///2
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 2;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 2;
        }
    }

    ok = 0;
    f(i, 1, n){
        if(col[i] == 2){
            ok = 1;
            tot2++;
            for(int x:g[i]){
                if(col[x] == 2){
                    cout<<-1;
                    rr;
                }
            }
        }
    }
//    if(n==27653 && m==165889){
//        cout<<tot<<" ";
//    }
    if(!ok){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///3
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 3;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 3;
        }
    }

    ok = 0;
    f(i, 1, n){
        if(col[i] == 3){
            ok = 1;
            tot3++;
            for(int x:g[i]){
                if(col[x] == 3){
                    cout<<-1;
                    rr;
                }
            }
        }
    }
//    if(n==27653 && m==165889){
//        cout<<tot<<"\n";
//    }
    if(!ok || (tot1*tot2 + tot2*tot3 + tto3*tot1 != m)){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///last
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s != -1){
        cout<<-1;
        rr;
    }

    ///sesh
    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

void dfs(int s)
{
    vis[s] = 1;
    for(int x:g[s]){
        if(!vis[x] && !col[x]){
            dfs(x);
        }
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }
    int s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 1;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 1;
        }
    }

    mem(vis);

    ///2
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 2;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 2;
        }
    }

    mem(vis);

    ///3
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 3;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 3;
        }
    }

    mem(vis);

    ///last
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s != -1){
        cout<<-1;
        rr;
    }

    ///sesh
    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

void dfs(int s)
{
    vis[s] = 1;
    for(int x:g[s]){
        if(!vis[x] && !col[x]){
            dfs(x);
        }
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }
    int s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 1;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 1;
        }
    }

    f(i, 1, n){
        if(col[i] == 1){
            for(int x:g[i]){
                if(col[x] == 1)
                    col[x] = 0;
            }
        }
    }

    mem(vis);

    ///2
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 2;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 2;
        }
    }

    f(i, 1, n){
        if(col[i] == 2){
            for(int x:g[i]){
                if(col[x] == 2)
                    col[x] = 0;
            }
        }
    }

    mem(vis);

    ///3
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 3;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 3;
        }
    }

    f(i, 1, n){
        if(col[i] == 3){
            for(int x:g[i]){
                if(col[x] == 3)
                    col[x] = 0;
            }
        }
    }

    mem(vis);

    ///last
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s != -1){
        cout<<-1;
        rr;
    }

    ///sesh
    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

void dfs(int s)
{
    vis[s] = 1;
    for(int x:g[s]){
        if(!vis[x] && !col[x]){
            dfs(x);
        }
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }
    int s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 1;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 1;
        }
    }

    f(i, 1, n){
        if(col[i] == 1){
            for(int x:g[i]){
                if(col[x] == 1){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    mem(vis);

    ///2
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 2;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 2;
        }
    }

    f(i, 1, n){
        if(col[i] == 2){
            for(int x:g[i]){
                if(col[x] == 2){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    mem(vis);

    ///3
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 3;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 3;
        }
    }

    f(i, 1, n){
        if(col[i] == 3){
            for(int x:g[i]){
                if(col[x] == 3){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    mem(vis);

    ///last
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s != -1){
        cout<<-1;
        rr;
    }

    ///sesh
    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

void dfs(int s)
{
    vis[s] = 1;
    for(int x:g[s]){
        if(!vis[x]){
            dfs(x);
        }
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    dfs(1);
    f(i, 1, n){
        if(!vis[i]){
            cout<<-1;
            rr;
        }
    }

    mem(vis);

    int s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 1;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 1;
        }
    }

    int ok = 0, tot1 = 0, tot2=0, tot3=0;
    f(i, 1, n){
        if(col[i] == 1){
            ok = 1;
            tot1++;
            for(int x:g[i]){
                if(col[x] == 1){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    if(!ok){
        cout<<-1;
        rr;
    }

//    if(n==27653 && m==165889){
//        cout<<tot<<" ";
//    }

    mem(vis);

    ///2
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 2;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 2;
        }
    }

    ok = 0;
    f(i, 1, n){
        if(col[i] == 2){
            ok = 1;
            tot2++;
            for(int x:g[i]){
                if(col[x] == 2){
                    cout<<-1;
                    rr;
                }
            }
        }
    }
//    if(n==27653 && m==165889){
//        cout<<tot<<" ";
//    }
    if(!ok){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///3
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 3;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 3;
        }
    }

    ok = 0;
    f(i, 1, n){
        if(col[i] == 3){
            ok = 1;
            tot3++;
            for(int x:g[i]){
                if(col[x] == 3){
                    cout<<-1;
                    rr;
                }
            }
        }
    }
//    if(n==27653 && m==165889){
//        cout<<tot<<"\n";
//    }
    if(!ok || (tot1*tot2 + tot2*tot3 + tot3*tot1 != m)){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///last
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s != -1){
        cout<<-1;
        rr;
    }

    ///sesh
    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

int mex(int x)
{
    if(st[x].find(1) != st[x].end()){
        if(st[x].find(2) != st[x].end()){
            if(st[x].find(3) != st[x].end()){
                return -1;
            }
            else{
                return 3;
            }
        }
        else{
            return 2;
        }
    }
    else{
        return 1;
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    f(i, 1, n){
        if(g[i].empty()){
            cout<<-1;
            rr;
        }
        if(!vis[i]){
            vis[i] = 1;

            queue<int>q;
            q.push(i);

            while(!q.empty()){
                int s = q.front();
                q.pop();

                col[s] = mex(s);
                if(col[s] == -1){
                    cout<<-1;
                    rr;
                }

                for(int x:g[s]){
                    if(!vis[x]){
                        vis[x] = 1;
                        q.push(x);
                    }
                    st[x].insert(col[s]);
                }
            }
        }
    }

    int p[4] = {0, 0, 0, 0};
    f(i, 1, n){
        p[col[i]] = 1;
    }

    if(!(p[1] && p[2] && p[3])){
        cout<<-1;
        rr;
    }

    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

int mex(int x)
{
    if(st[x].find(1) != st[x].end()){
        if(st[x].find(2) != st[x].end()){
            if(st[x].find(3) != st[x].end()){
                return -1;
            }
            else{
                return 3;
            }
        }
        else{
            return 2;
        }
    }
    else{
        return 1;
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    f(i, 1, n){
        if(g[i].empty()){
            cout<<-1;
            rr;
        }
        if(!vis[i]){
            vis[i] = 1;

            queue<int>q;
            q.push(i);

            while(!q.empty()){
                int s = q.front();
                q.pop();

                col[s] = mex(s);
                if(col[s] == -1){
                    cout<<-1;
                    rr;
                }

                for(int x:g[s]){
                    if(!vis[x]){
                        vis[x] = 1;
                        q.push(x);
                    }
                    st[x].insert(col[s]);
                }
            }
        }
    }

    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

int mex(int x)
{
    if(st[x].find(1) != st[x].end()){
        if(st[x].find(2) != st[x].end()){
            if(st[x].find(3) != st[x].end()){
                return -1;
            }
            else{
                return 3;
            }
        }
        else{
            return 2;
        }
    }
    else{
        return 1;
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    f(i, 1, n){
        if(!vis[i]){
            vis[i] = 1;

            queue<int>q;
            q.push(i);

            while(!q.empty()){
                int s = q.front();
                q.pop();

                col[s] = mex(s);
                if(col[s] == -1){
                    cout<<-1;
                    rr;
                }

                for(int x:g[s]){
                    if(!vis[x]){
                        vis[x] = 1;
                        q.push(x);
                    }
                    st[x].insert(col[s]);
                }
            }
        }
    }

    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define PI              acos(-1.0)
#define No              cout<<"No\n"
#define Yes             cout<<"Yes\n"
#define no              cout<<"no\n"
#define yes             cout<<"yes\n"
#define NO              cout<<"NO\n"
#define YES             cout<<"YES\n"
#define MOD             (int)1000000007
#define int             long long
#define ll              long long
#define pii             pair<int, int>
#define fi               first
#define se              second
#define sf(a)           scanf("%lld", &a)
#define pf(a)           printf("%lld ", a)
#define case(a)         cout<<"Case "<<a<<": ";
#define FASTIO          ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define pb              emplace_back
#define mp              make_pair
#define mem(arr)        memset(arr, 0, sizeof(arr))
#define mem1(arr)       memset(arr, -1, sizeof(arr))
#define all(a)          a.begin(),a.end()
#define f(i,a,b)        for (int i = a; i<=b; i++)
#define fr(i,a,b)       for (int i = a; i>=b; i--)
#define rr              return 0
#define prec(n)         fixed<<setprecision(n)
#define maxpq           priority_queue<int>
#define minpq           priority_queue<int, vector<int>, greater<int> >
#define inf             (int)(1e18)
#define vi              vector<int>
#define endl            "\n"
#define vii             vector<pii>
#define sz(s)           s.size()
#define bits(n)         __builtin_popcount(n)
#define lcm(a,b)        (a*(b/gcd(a,b)))
#define MX              500005

int gcd(int a, int b)   {return __gcd(a,b);}

inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while(p) { if(p & 1LL) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
inline ll modInverse(ll a) { return modPow(a, MOD-2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n or (1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

const double eps = 1e-9;

int dx[5] = {+1, +0, -1, -0};
int dy[5] = {+0, +1, -0, -1};
int XX[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int YY[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

bool Equal(double x, double y)
{
    return fabs(x-y)<eps; ///x==y
}

bool Greater(double x, double y)
{
    return x-eps>y; ///x>y
}

bool Lesser(double x, double y)
{
    return x+eps<y; ///x<y
}

struct point
{
    double x, y, ang;
};

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr << '\n'; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << " "; err(++it, args...); }

///Write what you need -->
/// nt, ft, kmp, tri, sufarr, ub_lb, lis
/// dsu

///Template Ends Here////////////////////////////
const int N = 100005;
vi g[N];
set<int>st[N];
int col[N], vis[N];

void dfs(int s)
{
    vis[s] = 1;
    for(int x:g[s]){
        if(!vis[x]){
            dfs(x);
        }
    }
}
signed main()
{
//    root = new trinode();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    FASTIO

//    int n;
//    cin>>n;
//
//    int a[n+1];
//    f(i, 1, n){
//        cin>>a[i];
//    }

    int n, m, x, y;
    cin>>n>>m;

    f(i, 1, m){
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    dfs(1);
    f(i, 1, n){
        if(!vis[i]){
            cout<<-1;
            rr;
        }
    }

    mem(vis);

    int s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 1;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 1;
        }
    }

    int ok = 0;
    f(i, 1, n){
        if(col[i] == 1){
            ok = 1;
            for(int x:g[i]){
                if(col[x] == 1){
                    cout<<-1;
                    rr;
                }
            }
        }
    }

    if(!ok){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///2
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 2;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 2;
        }
    }

    ok = 0;
    f(i, 1, n){
        if(col[i] == 2){
            ok = 1;
            for(int x:g[i]){
                if(col[x] == 2){
                    cout<<-1;
                    rr;
                }
            }
        }
    }
    if(!ok){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///3
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s == -1){
        cout<<-1;
        rr;
    }

    for(int x:g[s]){
        vis[x] = 1;
    }

    col[s] = 3;
    f(i, 1, n){
        if(!vis[i] && !col[i]){
            col[i] = 3;
        }
    }

    ok = 0;
    f(i, 1, n){
        if(col[i] == 3){
            ok = 1;
            for(int x:g[i]){
                if(col[x] == 3){
                    cout<<-1;
                    rr;
                }
            }
        }
    }
    if(!ok){
        cout<<-1;
        rr;
    }

    mem(vis);

    ///last
    s = -1;
    f(i, 1, n){
        if(!col[i]){
            s = i;
            break;
        }
    }
    if(s != -1){
        cout<<-1;
        rr;
    }

    ///sesh
    f(i, 1, n){
        cout<<col[i]<<" ";
    }

//    tridel(root);
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 300005
#define IOS  ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
vector<int> g[maxn];
int vis[maxn],tmp[maxn];
signed main(){
    IOS
    int n,m;
    cin>>n>>m;
    while(m--){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int cnt=1;
    for (int i = 1; i <=n ; ++i) {
        if(tmp[i]==cnt-1)
        {int fl=0;
        for(auto j:g[i]){
            if(j>i&&tmp[j]==cnt-1){tmp[j]=cnt;fl=1;}
        }
        if(fl)cnt++;}
    }
    if(cnt!=3)cout<<-1;
    else {
        for (int i = 1; i <=n ; ++i) {
            cout<<tmp[i]+1<<" ";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 300005
#define IOS  ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
vector<int> g[maxn];
int vis[maxn],tmp[maxn];
signed main(){
    IOS
    int n,m;
    cin>>n>>m;
    int t=m;
    while(t--){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int cnt=1;
    for (int i = 1; i <=n ; ++i) {
        if(tmp[i]==cnt-1)
        {int fl=0;
        for(auto j:g[i]){
            if(j>i&&tmp[j]==cnt-1){tmp[j]=cnt;fl=1;}
        }
        if(fl)cnt++;}
    }
    if(cnt!=3)cout<<-1;
    else {
        int a=0,b=0,c=0;
        for (int i = 1; i <=n ; ++i) {
            if(tmp[i]==0)a++;
            if(tmp[i]==1)b++;
            if(tmp[i]==2)c++;
        }
        if(a*b+b*c+c*a!=m)cout<<-1;
        else{
            for (int i = 1; i <=n ; ++i) {
                cout<<tmp[i]+1<<" ";
            }
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 300005
#define IOS  ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
vector<int> g[maxn];
int ans[maxn],tmp[maxn];
signed main(){
    IOS
    int n,m;
    cin>>n>>m;
    while(m--){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int cnt=1;
    for (int i = 1; i <=n ; ++i) {
        if(tmp[i]==cnt-2)continue;
        int fl=0;
        for(auto j:g[i]){
            if(i==1||tmp[j]>cnt-2){tmp[j]=cnt;fl=1;}
        }
        if(fl)cnt++;
    }
    if(cnt>3)cout<<-1;
    else {
        for (int i = 1; i <=n ; ++i) {
            cout<<tmp[i]+1<<" ";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 300005
#define IOS  ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
vector<int> g[maxn];
int vis[maxn],tmp[maxn];
signed main(){
    IOS
    int n,m;
    cin>>n>>m;
    int t=m;
    while(t--){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int cnt=-1;
    for (int i = 1; i <=n ; ++i) {
        for(auto j:g[i]){
            if(j>i&&tmp[j]==tmp[i]){tmp[j]=tmp[i]+1;}
        }
        cnt=max(cnt,tmp[i]);
    }
    if(cnt!=2)cout<<-1;
    else {
        int a=0,b=0,c=0;
        for (int i = 1; i <=n ; ++i) {
            if(tmp[i]==0)a++;
            if(tmp[i]==1)b++;
            if(tmp[i]==2)c++;
        }
        if(a*b+b*c+c*a!=m)cout<<-1;
        else{
            for (int i = 1; i <=n ; ++i) {
                cout<<tmp[i]+1<<" ";
            }
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 300005
#define IOS  ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
vector<int> g[maxn];
int ans[maxn],tmp[maxn];
signed main(){
    IOS
    int n,m;
    cin>>n>>m;
    while(m--){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int cnt=1;
    for (int i = 1; i <=n ; ++i) {
        if(tmp[i]<=cnt-2)continue;
        int fl=0;
        for(auto j:g[i]){
            if(tmp[j]>cnt-2){tmp[j]=cnt;fl=1;}
        }
        if(fl)cnt++;
    }
    if(cnt!=3)cout<<-1;
    else {
        for (int i = 1; i <=n ; ++i) {
            cout<<tmp[i]+1<<" ";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 300005
#define IOS  ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
vector<int> g[maxn];
int ans[maxn],tmp[maxn];
signed main(){
    IOS
    int n,m;
    cin>>n>>m;
    while(m--){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int cnt=1;
    for (int i = 1; i <=n ; ++i) {
        if(tmp[i]<=cnt-2)continue;
        int fl=0;
        for(auto j:g[i]){
            if(tmp[j]>cnt-2){tmp[j]=cnt;}
        }
        cnt++;
    }
    if(cnt!=4)cout<<-1;
    else {
        for (int i = 1; i <=n ; ++i) {
            cout<<tmp[i]+1<<" ";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 300005
#define IOS  ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
vector<int> g[maxn];
int ans[maxn],tmp[maxn];
signed main(){
    IOS
    int n,m;
    cin>>n>>m;
    while(m--){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int cnt=1;
    for (int i = 1; i <=n ; ++i) {
        if(tmp[i]==cnt-2)continue;
        int fl=0;
        for(auto j:g[i]){
            if(i==1||tmp[j]>cnt-2){tmp[j]=cnt;fl=1;}
        }
        if(fl)cnt++;
    }
    if(cnt!=3)cout<<-1;
    else {
        for (int i = 1; i <=n ; ++i) {
            cout<<tmp[i]+1<<" ";
        }
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const int NMAX = 1e5;

int N, M;

bool d[NMAX + 5];
vector <int> g[NMAX + 5];

vector < pair <int, int> > edges;

int deg[NMAX + 5], sortedDeg[NMAX + 5];
int difDegs[5];

int col[NMAX + 5], saveDeg;

void dfs(int node)
{
    d[node] = 1;

    for(auto it : g[node])
        if(!d[it])
            dfs(it);
}

void DfsBipartire(int node, int color)
{
    d[node] = 1;
    col[node] = color;

    for(auto it : g[node])
        if(!d[it] && deg[it] == saveDeg)
            DfsBipartire(it, 3 - color);
}

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y), g[y].push_back(x);

        edges.push_back({x, y});

        deg[x]++, deg[y]++;
    }

    dfs(1);
    for(int i = 2; i <= N; i++)
        if(!d[i])
        {
            cout << -1 << '\n';
            return 0;
        }

    for(int i = 1; i <= N; i++)
        sortedDeg[i] = deg[i];

    sort(sortedDeg + 1, sortedDeg + N + 1);

    int ctDif = 1;
    difDegs[1] = sortedDeg[1];

    for(int i = 2; i <= N; i++)
        if(sortedDeg[i] != sortedDeg[i - 1])
        {
            difDegs[++ctDif] = sortedDeg[i];

            if(ctDif > 3)
            {
                cout << -1 << '\n';
                return 0;
            }
        }

    if(ctDif == 3)
    {
        for(auto it : edges)
            if(deg[it.first] == deg[it.second])
        {
            cout << -1 << '\n';
            return 0;
        }

        for(int i = 1; i <= N; i++)
            if(deg[i] == difDegs[1])
                cout << "1 ";
            else if(deg[i] == difDegs[2])
                cout << "2 ";
            else
                cout << "3 ";
    }
    else if(ctDif == 2)
    {
        int saveNode = -1;

        for(auto it : edges)
            if(deg[it.first] == deg[it.second])
            {
                saveNode = it.first;
                saveDeg = deg[it.first];
                break;
            }

        if(saveNode == -1)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        DfsBipartire(saveNode, 1);

        for(auto it : edges)
            if(col[it.first] == col[it.second])
            {
                cout << -1 << '\n';
                return 0;
            }

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
                cout << "3 ";
            else
                cout << col[i] << ' ';
    }
    else
    {
        ///vedem tote nodurile care nu ajunge 1 in ele

        memset(d, 0, sizeof(d));

        d[1] = 1;
        col[1] = 3;

        for(auto it : g[1])
            d[it] = 1;

        for(int i = 2; i <= N; i++)
            if(!d[i])
                col[i] = 3;

        int ctGrp = 0;
        for(int i = 2; i <= N; i++)
            if(col[i] == 3)
                ctGrp++;

        if(N % 3 != 0 && ctGrp != N / 3)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        for(int i = 1; i <= N; i++)
            if(col[i] == 3)
                d[i] = 1;

        saveDeg = difDegs[1];
        int saveNode = -1;

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
            {
                saveNode = i;
                break;
            }

        DfsBipartire(saveNode, 1);

        for(auto it : edges)
            if(col[it.first] == col[it.second])
            {
                cout << -1 << '\n';
                return 0;
            }

        for(int i = 1; i <= N; i++)
            cout << col[i] << ' ';
    }

    return 0;
}


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

using namespace std;

const int NMAX = 1e5;

int N, M, col[NMAX + 5];
vector < int > g[NMAX + 5];
vector < pair <int, int> > edges;

const long long BASE1 = 104729;
const long long MOD1 = 1299709;

const long long BASE2 = 104743;
const long long MOD2 = 1299721;

pair < pair <long, long>, int > hashes[NMAX + 5];

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y; cin >> x >> y;
        edges.push_back({x, y});
        g[x].push_back(y);
        g[y].push_back(x);
    }

    for(int i = 1; i <= N; i++)
        sort(g[i].begin(), g[i].end());

    for(int i = 1; i <= N; i++)
    {
        long long h1 = 0LL;
        long long h2 = 0LL;

        long long powBase1 = BASE1;
        long long powBase2 = BASE2;

        for(auto it : g[i])
        {
            h1 = (1LL * h1 + it * powBase1) % MOD1;
            h2 = (1LL * h2 + it * powBase2) % MOD2;

            powBase1 = (1LL * powBase1 * BASE1) % MOD1;
            powBase2 = (1LL * powBase2 * BASE2) % MOD2;
        }

        hashes[i] = {{h1, h2}, i};
    }

    sort(hashes + 1, hashes + N + 1);

    int ctDif = 1;
    col[1] = 1;

    for(int i = 2; i <= N; i++)
        {
            if(!(hashes[i].first.first == hashes[i - 1].first.first && hashes[i].first.second == hashes[i - 1].first.second))
                ctDif++;

            col[hashes[i].second] = ctDif;
        }

    if(ctDif != 3)
    {
        cout << -1 << '\n';
        return 0;
    }

    for(auto it : edges)
        if(col[it.first] == col[it.second])
            {
                cout << -1 << '\n';
                return 0;
            }

    for(int i = 1; i <= N; i++)
        cout << col[i] << ' ';

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const int NMAX = 1e5;

int N, M;

bool d[NMAX + 5];
vector <int> g[NMAX + 5];

vector < pair <int, int> > edges;

int deg[NMAX + 5], sortedDeg[NMAX + 5];
int difDegs[5];

int col[NMAX + 5], saveDeg;

void dfs(int node)
{
    d[node] = 1;

    for(auto it : g[node])
        if(!d[it])
            dfs(it);
}

void DfsBipartire(int node, int color)
{
    d[node] = 1;
    col[node] = color;

    for(auto it : g[node])
        if(!d[it] && deg[it] == saveDeg)
            DfsBipartire(it, 3 - color);
}

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y), g[y].push_back(x);

        edges.push_back({x, y});

        deg[x]++, deg[y]++;
    }

    dfs(1);
    for(int i = 2; i <= N; i++)
        if(!d[i])
        {
            cout << -1 << '\n';
            return 0;
        }

    for(int i = 1; i <= N; i++)
        sortedDeg[i] = deg[i];

    sort(sortedDeg + 1, sortedDeg + N + 1);

    int ctDif = 1;
    difDegs[1] = sortedDeg[1];

    for(int i = 2; i <= N; i++)
        if(sortedDeg[i] != sortedDeg[i - 1])
        {
            difDegs[++ctDif] = sortedDeg[i];

            if(ctDif > 3)
            {
                cout << -1 << '\n';
                return 0;
            }
        }

    if(ctDif == 3)
    {
        for(auto it : edges)
            if(deg[it.first] == deg[it.second])
        {
            cout << -1 << '\n';
            return 0;
        }

        for(int i = 1; i <= N; i++)
            if(deg[i] == difDegs[1])
                cout << "1 ";
            else if(deg[i] == difDegs[2])
                cout << "2 ";
            else
                cout << "3 ";
    }
    else if(ctDif == 2)
    {
        int saveNode = -1;

        for(auto it : edges)
            if(deg[it.first] == deg[it.second])
            {
                saveNode = it.first;
                saveDeg = deg[it.first];
                break;
            }

        if(saveNode == -1)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        DfsBipartire(saveNode, 1);

        for(auto it : edges)
            if(deg[it.first] == deg[it.second] && (col[it.first] == 0 || col[it.second] == 0))
            {
                cout << -1 << '\n';
                return 0;
            }

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
                cout << "3 ";
            else
                cout << col[i] << ' ';
    }
    else
    {
        ///vedem tote nodurile care nu ajunge 1 in ele

        memset(d, 0, sizeof(d));

        d[1] = 1;
        col[1] = 3;

        for(auto it : g[1])
            d[it] = 1;

        for(int i = 2; i <= N; i++)
            if(!d[i])
                col[i] = 3;

        int ctGrp = 0;
        for(int i = 2; i <= N; i++)
            if(col[i] == 3)
                ctGrp++;

        if(N % 3 != 0 && ctGrp != N / 3)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        for(int i = 1; i <= N; i++)
            if(col[i] == 3)
                d[i] = 1;

        saveDeg = difDegs[1];
        int saveNode = -1;

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
            {
                saveNode = i;
                break;
            }

        DfsBipartire(saveNode, 1);

        for(int i = 1; i <= N; i++)
            cout << col[i] << ' ';
    }

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const int NMAX = 1e5;

int N, M;

bool d[NMAX + 5];
vector <int> g[NMAX + 5];

vector < pair <int, int> > edges;

int deg[NMAX + 5], sortedDeg[NMAX + 5];
int difDegs[5];

int col[NMAX + 5], saveDeg;

void dfs(int node)
{
    d[node] = 1;

    for(auto it : g[node])
        if(!d[it])
            dfs(it);
}

void DfsBipartire(int node, int color)
{
    d[node] = 1;
    col[node] = color;

    for(auto it : g[node])
        if(!d[it] && deg[it] == saveDeg)
            DfsBipartire(it, 3 - color);
}

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y), g[y].push_back(x);

        edges.push_back({x, y});

        deg[x]++, deg[y]++;
    }

    dfs(1);
    for(int i = 2; i <= N; i++)
        if(!d[i])
        {
            cout << -1 << '\n';
            return 0;
        }

    for(int i = 1; i <= N; i++)
        sortedDeg[i] = deg[i];

    sort(sortedDeg + 1, sortedDeg + N + 1);

    int ctDif = 1;
    difDegs[1] = sortedDeg[1];

    for(int i = 2; i <= N; i++)
        if(sortedDeg[i] != sortedDeg[i - 1])
        {
            difDegs[++ctDif] = sortedDeg[i];

            if(ctDif > 3)
            {
                cout << -1 << '\n';
                return 0;
            }
        }

    if(ctDif == 3)
    {
        for(int i = 1; i <= N; i++)
            if(deg[i] == difDegs[1])
                cout << "1 ";
            else if(deg[i] == difDegs[2])
                cout << "2 ";
            else
                cout << "3 ";
    }
    else if(ctDif == 2)
    {
        int saveNode = -1;

        for(auto it : edges)
            if(deg[it.first] == deg[it.second])
            {
                saveNode = it.first;
                saveDeg = deg[it.first];
                break;
            }

        if(saveNode == -1)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        DfsBipartire(saveNode, 1);

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
                cout << "3 ";
            else
                cout << col[i] << ' ';
    }
    else
    {
        ///vedem tote nodurile care nu ajunge 1 in ele

        memset(d, 0, sizeof(d));

        d[1] = 1;
        col[1] = 3;

        for(auto it : g[1])
            d[it] = 1;

        for(int i = 2; i <= N; i++)
            if(!d[i])
                col[i] = 3;

        memset(d, 0, sizeof(d));
        for(int i = 1; i <= N; i++)
            if(col[i] == 3)
                d[i] = 1;

        saveDeg = difDegs[1];
        int saveNode = -1;

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
            {
                saveNode = i;
                break;
            }

        if(saveNode == -1)
        {
            cout << -1 << '\n';
            return 0;
        }

        DfsBipartire(saveNode, 1);

        for(int i = 1; i <= N; i++)
            cout << col[i] << ' ';
    }

    return 0;
}


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

using namespace std;

const int NMAX = 1e5;

int N, M, col[NMAX + 5];
vector < int > g[NMAX + 5];
vector < pair <int, int> > edges;

const long long BASE1 = 104729;
const long long MOD1 = 1299709;

const long long BASE2 = 104743;
const long long MOD2 = 1299721;

pair < pair <long, long>, int > hashes[NMAX + 5];

bool d[NMAX + 5];
void dfs(int node)
{
    d[node] = 1;

    for(auto it : g[node])
        if(!d[it]) dfs(it);
}

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y; cin >> x >> y;
        edges.push_back({x, y});
        g[x].push_back(y);
        g[y].push_back(x);
    }

    dfs(1);
    for(int i = 1; i <= N; i++)
    if(!d[i]) {
        cout << -1 << '\n';
        return 0;
    }

    for(int i = 1; i <= N; i++)
        sort(g[i].begin(), g[i].end());

    for(int i = 1; i <= N; i++)
    {
        long long h1 = 0LL;
        long long h2 = 0LL;

        long long powBase1 = BASE1;
        long long powBase2 = BASE2;

        for(auto it : g[i])
        {
            h1 = (1LL * h1 + it * powBase1) % MOD1;
            h2 = (1LL * h2 + it * powBase2) % MOD2;

            powBase1 = (1LL * powBase1 * BASE1) % MOD1;
            powBase2 = (1LL * powBase2 * BASE2) % MOD2;
        }

        hashes[i] = {{h1, h2}, i};
    }

    sort(hashes + 1, hashes + N + 1);

    int ctDif = 1;
    col[hashes[1].second] = 1;

    for(int i = 2; i <= N; i++)
        {
            if(!(hashes[i].first.first == hashes[i - 1].first.first && hashes[i].first.second == hashes[i - 1].first.second))
                ctDif++;

            col[hashes[i].second] = ctDif;
        }

    if(ctDif != 3)
    {
        cout << -1 << '\n';
        return 0;
    }

    for(auto it : edges)
        if(col[it.first] == col[it.second])
            {
                cout << -1 << '\n';
                return 0;
            }

    for(int i = 1; i <= N; i++)
        cout << col[i] << ' ';

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const int NMAX = 1e5;

int N, M;

bool d[NMAX + 5];
vector <int> g[NMAX + 5];

vector < pair <int, int> > edges;

int deg[NMAX + 5], sortedDeg[NMAX + 5];
int difDegs[5];

int col[NMAX + 5], saveDeg;

void dfs(int node)
{
    d[node] = 1;

    for(auto it : g[node])
        if(!d[it])
            dfs(it);
}

void DfsBipartire(int node, int color)
{
    d[node] = 1;
    col[node] = color;

    for(auto it : g[node])
        if(!d[it] && deg[it] == saveDeg)
            DfsBipartire(it, 3 - color);
}

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y), g[y].push_back(x);

        edges.push_back({x, y});

        deg[x]++, deg[y]++;
    }

    dfs(1);
    for(int i = 2; i <= N; i++)
        if(!d[i])
        {
            cout << -1 << '\n';
            return 0;
        }

    for(int i = 1; i <= N; i++)
        sortedDeg[i] = deg[i];

    sort(sortedDeg + 1, sortedDeg + N + 1);

    int ctDif = 1;
    difDegs[1] = sortedDeg[1];

    for(int i = 2; i <= N; i++)
        if(sortedDeg[i] != sortedDeg[i - 1])
        {
            difDegs[++ctDif] = sortedDeg[i];

            if(ctDif > 3)
            {
                cout << -1 << '\n';
                return 0;
            }
        }

    if(ctDif == 3)
    {
        for(int i = 1; i <= N; i++)
            if(deg[i] == difDegs[1])
                cout << "1 ";
            else if(deg[i] == difDegs[2])
                cout << "2 ";
            else
                cout << "3 ";
    }
    else if(ctDif == 2)
    {
        int saveNode = -1;

        for(auto it : edges)
            if(deg[it.first] == deg[it.second])
            {
                saveNode = it.first;
                saveDeg = deg[it.first];
                break;
            }

        if(saveNode == -1)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        DfsBipartire(saveNode, 1);

        for(auto it : edges)
            if(deg[it.first] == deg[it.second] && (col[it.first] == 0 || col[it.second] == 0))
            {
                cout << -1 << '\n';
                return 0;
            }

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
                cout << "3 ";
            else
                cout << col[i] << ' ';
    }
    else
    {
        ///vedem tote nodurile care nu ajunge 1 in ele

        memset(d, 0, sizeof(d));

        d[1] = 1;
        col[1] = 3;

        for(auto it : g[1])
            d[it] = 1;

        for(int i = 2; i <= N; i++)
            if(!d[i])
                col[i] = 3;

        int ctGrp = 0;
        for(int i = 2; i <= N; i++)
            if(col[i] == 3)
                ctGrp++;

        if(N % 3 != 0 && ctGrp != N / 3)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        for(int i = 1; i <= N; i++)
            if(col[i] == 3)
                d[i] = 1;

        saveDeg = difDegs[1];
        int saveNode = -1;

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
            {
                saveNode = i;
                break;
            }

        DfsBipartire(saveNode, 1);

        for(int i = 1; i <= N; i++)
            cout << col[i] << ' ';
    }

    return 0;
}


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

using namespace std;

const int NMAX = 1e5;

int N, M, col[NMAX + 5];
vector < int > g[NMAX + 5];
vector < pair <int, int> > edges;

const long long BASE1 = 104729;
const long long MOD1 = 1299709;

const long long BASE2 = 104743;
const long long MOD2 = 1299721;

pair <long, long> hashes[NMAX + 5];

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y; cin >> x >> y;
        edges.push_back({x, y});
        g[x].push_back(y);
        g[y].push_back(x);
    }

    for(int i = 1; i <= N; i++)
        sort(g[i].begin(), g[i].end());

    for(int i = 1; i <= N; i++)
    {
        long long h1 = 0LL;
        long long h2 = 0LL;

        long long powBase1 = BASE1;
        long long powBase2 = BASE2;

        for(auto it : g[i])
        {
            h1 = (1LL * h1 + it * powBase1) % MOD1;
            h2 = (1LL * h2 + it * powBase2) % MOD2;

            powBase1 = (1LL * powBase1 * BASE1) % MOD1;
            powBase2 = (1LL * powBase2 * BASE2) % MOD2;
        }

        hashes[i] = {h1, h2};
    }

    sort(hashes + 1, hashes + N + 1);

    int ctDif = 1;
    col[1] = 1;

    for(int i = 2; i <= N; i++)
        {
            if(!(hashes[i].first == hashes[i - 1].first && hashes[i].second == hashes[i - 1].second))
                ctDif++;

            col[i] = ctDif;
        }

    if(ctDif != 3)
    {
        cout << -1 << '\n';
        return 0;
    }

    for(auto it : edges)
        if(col[it.first] == col[it.second])
            {
                cout << -1 << '\n';
                return 0;
            }

    for(int i = 1; i <= N; i++)
        cout << col[i] << ' ';

    return 0;
}


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

using namespace std;

const int NMAX = 1e5;

int N, M, col[NMAX + 5];
vector < int > g[NMAX + 5];
vector < pair <int, int> > edges;

const long long BASE1 = 666013;
const long long MOD1 = 1181923;

const long long BASE2 = 661477;
const long long MOD2 = 1181927;

pair <long, long> hashes[NMAX + 5];

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y; cin >> x >> y;
        edges.push_back({x, y});
        g[x].push_back(y);
        g[y].push_back(x);
    }

    for(int i = 1; i <= N; i++)
        sort(g[i].begin(), g[i].end());

    for(int i = 1; i <= N; i++)
    {
        long long h1 = 0LL;
        long long h2 = 0LL;

        long long powBase1 = BASE1;
        long long powBase2 = BASE2;

        for(auto it : g[i])
        {
            h1 = (1LL * h1 + it * powBase1) % MOD1;
            h2 = (1LL * h2 + it * powBase2) % MOD2;

            powBase1 = (1LL * powBase1 * BASE1) % MOD1;
            powBase2 = (1LL * powBase2 * BASE2) % MOD2;
        }

        hashes[i] = {h1, h2};
    }

    sort(hashes + 1, hashes + N + 1);

    int ctDif = 1;
    col[1] = 1;

    for(int i = 2; i <= N; i++)
        {
            if(!(hashes[i].first == hashes[i - 1].first && hashes[i].second == hashes[i - 1].second))
                ctDif++;

            col[i] = ctDif;
        }

    if(ctDif != 3)
    {
        cout << -1 << '\n';
        return 0;
    }

    for(int i = 1; i <= N; i++)
        cout << col[i] << ' ';

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const int NMAX = 1e5;

int N, M;

bool d[NMAX + 5];
vector <int> g[NMAX + 5];

vector < pair <int, int> > edges;

int deg[NMAX + 5], sortedDeg[NMAX + 5];
int difDegs[5];

int col[NMAX + 5], saveDeg;

void dfs(int node)
{
    d[node] = 1;

    for(auto it : g[node])
        if(!d[it])
            dfs(it);
}

void DfsBipartire(int node, int color)
{
    d[node] = 1;
    col[node] = color;

    for(auto it : g[node])
        if(!d[it] && deg[it] == saveDeg)
            DfsBipartire(it, 3 - color);
}

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y), g[y].push_back(x);

        edges.push_back({x, y});

        deg[x]++, deg[y]++;
    }

    dfs(1);
    for(int i = 2; i <= N; i++)
        if(!d[i])
        {
            cout << -1 << '\n';
            return 0;
        }

    for(int i = 1; i <= N; i++)
        sortedDeg[i] = deg[i];

    sort(sortedDeg + 1, sortedDeg + N + 1);

    int ctDif = 1;
    difDegs[1] = sortedDeg[1];

    for(int i = 2; i <= N; i++)
        if(sortedDeg[i] != sortedDeg[i - 1])
        {
            difDegs[++ctDif] = sortedDeg[i];

            if(ctDif > 3)
            {
                cout << -1 << '\n';
                return 0;
            }
        }

    if(ctDif == 3)
    {
        for(int i = 1; i <= N; i++)
            if(deg[i] == difDegs[1])
                cout << "1 ";
            else if(deg[i] == difDegs[2])
                cout << "2 ";
            else
                cout << "3 ";
    }
    else if(ctDif == 2)
    {
        int saveNode = -1;

        for(auto it : edges)
            if(deg[it.first] == deg[it.second])
            {
                saveNode = it.first;
                saveDeg = deg[it.first];
                break;
            }

        if(saveNode == -1)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        DfsBipartire(saveNode, 1);

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
                cout << "3 ";
            else
                cout << col[i] << ' ';
    }
    else
    {
        ///vedem tote nodurile care nu ajunge 1 in ele

        memset(d, 0, sizeof(d));

        d[1] = 1;
        col[1] = 3;

        for(auto it : g[1])
            d[it] = 1;

        for(int i = 2; i <= N; i++)
            if(!d[i])
                col[i] = 3;

        int ctGrp = 0;
        for(int i = 2; i <= N; i++)
            if(col[i] == 3)
                ctGrp++;

        if(N % 3 != 0 && ctGrp != N / 3)
        {
            cout << -1 << '\n';
            return 0;
        }

        memset(d, 0, sizeof(d));
        for(int i = 1; i <= N; i++)
            if(col[i] == 3)
                d[i] = 1;

        saveDeg = difDegs[1];
        int saveNode = -1;

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
            {
                saveNode = i;
                break;
            }

        DfsBipartire(saveNode, 1);

        for(int i = 1; i <= N; i++)
            cout << col[i] << ' ';
    }

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const int NMAX = 1e5;

int N, M;

bool d[NMAX + 5];
vector <int> g[NMAX + 5];

vector < pair <int, int> > edges;

int deg[NMAX + 5], sortedDeg[NMAX + 5];
int difDegs[5];

int col[NMAX + 5], saveDeg;

void dfs(int node)
{
    d[node] = 1;

    for(auto it : g[node])
        if(!d[it])
            dfs(it);
}

void DfsBipartire(int node, int color)
{
    d[node] = 1;
    col[node] = color;

    for(auto it : g[node])
        if(!d[it] && deg[it] == saveDeg)
            DfsBipartire(it, 3 - color);
}

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y), g[y].push_back(x);

        edges.push_back({x, y});

        deg[x]++, deg[y]++;
    }

    dfs(1);
    for(int i = 2; i <= N; i++)
        if(!d[i])
        {
            cout << -1 << '\n';
            return 0;
        }

    for(int i = 1; i <= N; i++)
        sortedDeg[i] = deg[i];

    sort(sortedDeg + 1, sortedDeg + N + 1);

    int ctDif = 1;
    difDegs[1] = sortedDeg[1];

    for(int i = 2; i <= N; i++)
        if(sortedDeg[i] != sortedDeg[i - 1])
        {
            difDegs[++ctDif] = sortedDeg[i];

            if(ctDif > 3)
            {
                cout << -1 << '\n';
                return 0;
            }
        }

    if(ctDif == 3)
    {
        for(int i = 1; i <= N; i++)
            if(deg[i] == difDegs[1])
                cout << "1 ";
            else if(deg[i] == difDegs[2])
                cout << "2 ";
            else
                cout << "3 ";
    }
    else if(ctDif == 2)
    {
        int saveNode;

        for(auto it : edges)
            if(deg[it.first] == deg[it.second])
            {
                saveNode = it.first;
                saveDeg = deg[it.first];
                break;
            }

        memset(d, 0, sizeof(d));
        DfsBipartire(saveNode, 1);

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
                cout << "3 ";
            else
                cout << col[i] << ' ';
    }
    else
    {
        ///vedem tote nodurile care nu ajunge 1 in ele

        memset(d, 0, sizeof(d));

        d[1] = 1;
        col[1] = 3;

        for(auto it : g[1])
            d[it] = 1;

        for(int i = 2; i <= N; i++)
            if(!d[i])
                col[i] = 3;

        memset(d, 0, sizeof(d));
        for(int i = 1; i <= N; i++)
            if(col[i] == 3)
                d[i] = 1;

        saveDeg = difDegs[1];
        int saveNode;

        for(int i = 1; i <= N; i++)
            if(col[i] == 0)
            {
                saveNode = i;
                break;
            }

        DfsBipartire(saveNode, 1);

        for(int i = 1; i <= N; i++)
            cout << col[i] << ' ';
    }

    return 0;
}


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

using namespace std;

const int NMAX = 1e5;

int N, M, col[NMAX + 5];
vector < int > g[NMAX + 5];
vector < pair <int, int> > edges;

const long long BASE1 = 666013;
const long long MOD1 = 1181923;

const long long BASE2 = 661477;
const long long MOD2 = 1181927;

pair <long, long> hashes[NMAX + 5];

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y; cin >> x >> y;
        edges.push_back({x, y});
        g[x].push_back(y);
        g[y].push_back(x);
    }

    for(int i = 1; i <= N; i++)
        sort(g[i].begin(), g[i].end());

    for(int i = 1; i <= N; i++)
    {
        long long h1 = 0LL;
        long long h2 = 0LL;

        long long powBase1 = BASE1;
        long long powBase2 = BASE2;

        for(auto it : g[i])
        {
            h1 = (1LL * h1 + it * powBase1) % MOD1;
            h2 = (1LL * h2 + it * powBase2) % MOD2;

            powBase1 = (powBase1 * BASE1) % MOD1;
            powBase2 = (powBase2 * BASE2) % MOD2;
        }

        hashes[i] = {h1, h2};
    }

    sort(hashes + 1, hashes + N + 1);

    int ctDif = 1;
    col[1] = 1;

    for(int i = 2; i <= N; i++)
        {
            if(!(hashes[i].first == hashes[i - 1].first && hashes[i].second == hashes[i - 1].second))
                ctDif++;

            col[i] = ctDif;
        }

    if(ctDif != 3)
    {
        cout << -1 << '\n';
        return 0;
    }

    for(auto it : edges)
        if(col[it.first] == col[it.second])
            {
                cout << -1 << '\n';
                return 0;
            }

    for(int i = 1; i <= N; i++)
        cout << col[i] << ' ';

    return 0;
}


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

using namespace std;

const int NMAX = 1e5;

int N, M, col[NMAX + 5];
vector < int > g[NMAX + 5];
vector < pair <int, int> > edges;

const long long BASE1 = 104729;
const long long MOD1 = 1299709;

const long long BASE2 = 104743;
const long long MOD2 = 1299721;

pair < pair <long, long>, int > hashes[NMAX + 5];

int main()
{
    cin >> N >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y; cin >> x >> y;
        edges.push_back({x, y});
        g[x].push_back(y);
        g[y].push_back(x);
    }

    for(int i = 1; i <= N; i++)
        sort(g[i].begin(), g[i].end());

    for(int i = 1; i <= N; i++)
    {
        long long h1 = 0LL;
        long long h2 = 0LL;

        long long powBase1 = BASE1;
        long long powBase2 = BASE2;

        for(auto it : g[i])
        {
            h1 = (1LL * h1 + it * powBase1) % MOD1;
            h2 = (1LL * h2 + it * powBase2) % MOD2;

            powBase1 = (1LL * powBase1 * BASE1) % MOD1;
            powBase2 = (1LL * powBase2 * BASE2) % MOD2;
        }

        hashes[i] = {{h1, h2}, i};
    }

    sort(hashes + 1, hashes + N + 1);

    int ctDif = 1;
    col[hashes[1].second] = 1;

    for(int i = 2; i <= N; i++)
        {
            if(!(hashes[i].first.first == hashes[i - 1].first.first && hashes[i].first.second == hashes[i - 1].first.second))
                ctDif++;

            col[hashes[i].second] = ctDif;
        }

    if(ctDif != 3)
    {
        cout << -1 << '\n';
        return 0;
    }

    for(auto it : edges)
        if(col[it.first] == col[it.second])
            {
                cout << -1 << '\n';
                return 0;
            }

    for(int i = 1; i <= N; i++)
        cout << col[i] << ' ';

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int v,e;
  cin>>v>>e;
  if(e==0)
  {
    cout<<-1<<endl;
    return 0;
  }
  vector< vector<int> >graph(v);
  for(int i=0;i<v;i++)
    graph[i].resize(v);
  int a,b;
  for(int i=0;i<v;i++)
    for(int j=0;j<v;j++)
    {
        if(i==j)
          graph[i][j]=-1;
        else
          graph[i][j]=0;
    }
  for(int i=0;i<e;i++)
  {
    cin>>a>>b;
    graph[a-1][b-1]=graph[b-1][a-1]=1;
  }
  vector<int>visited(v,0);
  vector<int>pos(v);
  vector<int>s[3];
  int cnt=0;
  for(int i=0;i<v;i++)
  {
    if(visited[i]==1)
      continue;
    visited[i]=1;
    pos[i]=cnt+1;
    s[cnt].push_back(i);
    for(int j=0;j<v;j++)
    {
      if(graph[i][j]==0)
      {
        visited[j]=1;
        s[cnt].push_back(j);
        pos[j]=cnt+1;
      }
    }
    cnt++;
    if(cnt==3)
      break;
  }
  int flag=0;
  for(int i=0;i<v;i++)
  {
    if(visited[i]==0)
    {
      flag=1;
      break;
    }
  }
  if( flag!=1 && s[0].size()!=0 && s[1].size()!=0 && s[2].size()!=0 && e==s[0].size()*s[1].size()+s[1].size()*s[2].size()+s[0].size()*s[2].size())
  {
    //  cout<<"yes"<<endl;
      for(int i=0;i<v;i++)
        cout<<pos[i]<<" ";
      cout<<endl;
  }

  else
  cout<<-1<<endl;
  return 0;
}