#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;
}


#include <bits/stdc++.h>
#include<limits.h>
#include<stdio.h>
#include<cstring>
#include<string>
using namespace  std;
typedef long long ll;
typedef long double ld;
#define fast ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define mp make_pair
#define sz(a) a.size()
#define fi first
#define se second
#define rsz(a,n) a.resize(n)
#define test(t) ll t;cin>>t;while(t--)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define fillv(a,k) memset(a,k,sizeof(a))
#define leadzero(a) __builtin_clz(a) //count leading zeros
#define trailzero(a) __builtin_ctz(a) //count trailing zeros
#define bitcount(a) __builtin_popcount(a) // count set bits (add ll)
#define ln cout<<"\n"
#define sp cout<<" "
#define spaceprint(a,i,s,n) {forsn(i,s,n) { cout<<a[i]; sp;}}
#define lineprint(a,i,s,n) {forsn(i,s,n) {cout<<a[i]; ln;}}
#define maxe(a) *max_element(a.begin(),a.end())
#define maxi(a) max_element(a.begin(),a.end())-a.begin()
#define mine(a) *min_element(a.begin(),a.end())
#define mini(a) min_element(a.begin(),a.end())-a.begin()
#define all(c) c.begin(),c.end()
#define trav(container, it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define present(container, element) (container.find(element) != container.end())
#define cpresent(container, element)  (find(all(container),element) != container.end())// check the presence of element
//copy(from_begin, from_end, to_begin); copy function
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<ll,ll> p64;
typedef pair<int,int> p32;
typedef pair<int,p32> p96;
typedef vector<ll> v64;
typedef vector<string> vs;
typedef vector<int> v32;
typedef vector<v32> vv32;
typedef vector<v64> vv64;
typedef vector<p32> vp32;
typedef vector<p64> vp64;
typedef vector<vp32> vvp32;
typedef map<int,int> m32;
typedef map<ll,ll> m64;
const int LIM = 1e5+5, MOD =  1e9+7;
#define sumv(v) accumulate(all(v),ll(0))
#define productv(v) accumulate(all(v), ll(1), multiplies< ll >())
ll gcd(ll a, ll b) { if(b == 0) return a; return gcd(b, a % b); }
ll fastpowMOD(ll a, ll p,ll MOD){ if(p==0) return 1; ll z = fastpowMOD(a,p/2,MOD); z = (z*z)%MOD; if(p%2) z = (z*a)%MOD; return z; }
bool seive[100005];
void SieveOfEratosthenes(ll n)
{ memset(seive, true, sizeof(seive)); for (ll p=2; p*p<=n; p++) if (seive[p] == true) for (ll i=p*p; i<=n; i += p) seive[i] = false; }
int main()
{
    fast;
    ll n,m;
    cin>>n>>m;
    map <ll,ll> mp[n+5];
    v64 v[n+5];
    ll i,j;
    ll visited[n+5]={0};
    if(m==0)
    {
        cout<<-1;
        return 0;
    }
    ll x,y;
    vp64 edge;
    cin>>x>>y;
    visited[x]=1;
    visited[y]=2;
    mp[x][y]=1;
    mp[y][x]=1;
    edge.pb({x,y});
    v[x].pb(y);
    v[y].pb(x);
    for(i=1;i<m;i++)
    {
        ll x1,y1;
        cin>>x1>>y1;
        mp[x1][y1]=1;
        mp[y1][x1]=1;
        edge.pb({x1,y1});
        v[x1].pb(y1);
        v[y1].pb(x1);
    }
    v64 ans[4];
    ans[1].pb(x);
    ans[2].pb(y);
    ll flag=0;
    ll z;
    for(i=1;i<=n;i++)
    {
        if(mp[i][x]==1 and mp[i][y]==1)
        {
            flag=1;
            ans[3].pb(i);
            z=i;
        }
    }
    if(flag==0)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i][z]==1 and mp[i][y]==1)
        {
            if(x==i)
                continue;
            ans[1].pb(i);
            //z=i;
        }
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i][z]==1 and mp[i][x]==1)
        {
            if(y==i)
                continue;
            ans[2].pb(i);
            //z=i;
        }
    }
    ll k1=ans[1].size();
    ll k2=ans[2].size();
    ll k3=ans[3].size();
    if(m!=k1*k2+k2*k3+k3*k1)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=3;i++)
    {
        for(auto it:ans[i])
            visited[it]=i;
    }
    for(i=1;i<=n;i++)
    {
        if(visited[i]==0)
        {
            cout<<-1;
            return 0;
        }
    }
    ll b[4][4]={0};
    for(auto it:edge)
    {
        b[visited[it.fi]][visited[it.se]]++;
    }
    // cout<<visited[1];
    // cout<<b[2][1];
    if(b[1][2]+b[2][1]!=k1*k2)
    {
        cout<<-1;
        //cout<<"a";
        return 0;
    }
    if(b[3][2]+b[2][3]!=k3*k2)
    {
        cout<<-1;
        return 0;
    }
    if(b[3][1]+b[1][3]!=k3*k1)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=n;i++)
        cout<<visited[i]<<" ";

}


#include <bits/stdc++.h>
#include<limits.h>
#include<stdio.h>
#include<cstring>
#include<string>
using namespace  std;
typedef long long ll;
typedef long double ld;
#define fast ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define mp make_pair
#define sz(a) a.size()
#define fi first
#define se second
#define rsz(a,n) a.resize(n)
#define test(t) ll t;cin>>t;while(t--)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define fillv(a,k) memset(a,k,sizeof(a))
#define leadzero(a) __builtin_clz(a) //count leading zeros
#define trailzero(a) __builtin_ctz(a) //count trailing zeros
#define bitcount(a) __builtin_popcount(a) // count set bits (add ll)
#define ln cout<<"\n"
#define sp cout<<" "
#define spaceprint(a,i,s,n) {forsn(i,s,n) { cout<<a[i]; sp;}}
#define lineprint(a,i,s,n) {forsn(i,s,n) {cout<<a[i]; ln;}}
#define maxe(a) *max_element(a.begin(),a.end())
#define maxi(a) max_element(a.begin(),a.end())-a.begin()
#define mine(a) *min_element(a.begin(),a.end())
#define mini(a) min_element(a.begin(),a.end())-a.begin()
#define all(c) c.begin(),c.end()
#define trav(container, it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define present(container, element) (container.find(element) != container.end())
#define cpresent(container, element)  (find(all(container),element) != container.end())// check the presence of element
//copy(from_begin, from_end, to_begin); copy function
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<ll,ll> p64;
typedef pair<int,int> p32;
typedef pair<int,p32> p96;
typedef vector<ll> v64;
typedef vector<string> vs;
typedef vector<int> v32;
typedef vector<v32> vv32;
typedef vector<v64> vv64;
typedef vector<p32> vp32;
typedef vector<p64> vp64;
typedef vector<vp32> vvp32;
typedef map<int,int> m32;
typedef map<ll,ll> m64;
const int LIM = 1e5+5, MOD =  1e9+7;
#define sumv(v) accumulate(all(v),ll(0))
#define productv(v) accumulate(all(v), ll(1), multiplies< ll >())
ll gcd(ll a, ll b) { if(b == 0) return a; return gcd(b, a % b); }
ll fastpowMOD(ll a, ll p,ll MOD){ if(p==0) return 1; ll z = fastpowMOD(a,p/2,MOD); z = (z*z)%MOD; if(p%2) z = (z*a)%MOD; return z; }
bool seive[100005];
void SieveOfEratosthenes(ll n)
{ memset(seive, true, sizeof(seive)); for (ll p=2; p*p<=n; p++) if (seive[p] == true) for (ll i=p*p; i<=n; i += p) seive[i] = false; }
int main()
{
    fast;
    ll n,m;
    cin>>n>>m;
    map <ll> mp[n+5];
    v64 v[n+5];
    ll i,j;
    ll visited[n+5]={0};
    if(m==0)
    {
        cout<<-1;
        return 0;
    }
    ll x,y;
    vp64 edge;
    cin>>x>>y;
    visited[x]=1;
    visited[y]=2;
    mp[x][y]=1;
    mp[y][x]=1;
    edge.pb({x,y});
    v[x].pb(y);
    v[y].pb(x);
    for(i=1;i<m;i++)
    {
        ll x1,y1;
        cin>>x1>>y1;
        mp[x1][y1]=1;
        mp[y1][x1]=1;
        edge.pb({x1,y1});
        v[x1].pb(y1);
        v[y1].pb(x1);
    }
    v64 ans[4];
    ans[1].pb(x);
    ans[2].pb(y);
    ll flag=0;
    ll z;
    for(i=1;i<=n;i++)
    {
        if(mp[i][x]==1 and mp[i][y]==1)
        {
            flag=1;
            ans[3].pb(i);
            z=i;
        }
    }
    if(flag==0)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i][z]==1 and mp[i][y]==1)
        {
            if(x==i)
                continue;
            ans[1].pb(i);
            //z=i;
        }
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i][z]==1 and mp[i][x]==1)
        {
            if(y==i)
                continue;
            ans[2].pb(i);
            //z=i;
        }
    }
    ll k1=ans[1].size();
    ll k2=ans[2].size();
    ll k3=ans[3].size();
    if(m!=k1*k2+k2*k3+k3*k1)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=3;i++)
    {
        for(auto it:ans[i])
            visited[it]=i;
    }
    for(i=1;i<=n;i++)
    {
        if(visited[i]==0)
        {
            cout<<-1;
            return 0;
        }
    }
    ll b[4][4]={0};
    for(auto it:edge)
    {
        b[visited[it.fi]][visited[it.se]]++;
    }
    // cout<<visited[1];
    // cout<<b[2][1];
    if(b[1][2]+b[2][1]!=k1*k2)
    {
        cout<<-1;
        //cout<<"a";
        return 0;
    }
    if(b[3][2]+b[2][3]!=k3*k2)
    {
        cout<<-1;
        return 0;
    }
    if(b[3][1]+b[1][3]!=k3*k1)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=n;i++)
        cout<<visited[i]<<" ";

}


#include <bits/stdc++.h>
#include<limits.h>
#include<stdio.h>
#include<cstring>
#include<string>
using namespace  std;
typedef long long ll;
typedef long double ld;
#define fast ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define mp make_pair
#define sz(a) a.size()
#define fi first
#define se second
#define rsz(a,n) a.resize(n)
#define test(t) ll t;cin>>t;while(t--)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define fillv(a,k) memset(a,k,sizeof(a))
#define leadzero(a) __builtin_clz(a) //count leading zeros
#define trailzero(a) __builtin_ctz(a) //count trailing zeros
#define bitcount(a) __builtin_popcount(a) // count set bits (add ll)
#define ln cout<<"\n"
#define sp cout<<" "
#define spaceprint(a,i,s,n) {forsn(i,s,n) { cout<<a[i]; sp;}}
#define lineprint(a,i,s,n) {forsn(i,s,n) {cout<<a[i]; ln;}}
#define maxe(a) *max_element(a.begin(),a.end())
#define maxi(a) max_element(a.begin(),a.end())-a.begin()
#define mine(a) *min_element(a.begin(),a.end())
#define mini(a) min_element(a.begin(),a.end())-a.begin()
#define all(c) c.begin(),c.end()
#define trav(container, it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define present(container, element) (container.find(element) != container.end())
#define cpresent(container, element)  (find(all(container),element) != container.end())// check the presence of element
//copy(from_begin, from_end, to_begin); copy function
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<ll,ll> p64;
typedef pair<int,int> p32;
typedef pair<int,p32> p96;
typedef vector<ll> v64;
typedef vector<string> vs;
typedef vector<int> v32;
typedef vector<v32> vv32;
typedef vector<v64> vv64;
typedef vector<p32> vp32;
typedef vector<p64> vp64;
typedef vector<vp32> vvp32;
typedef map<int,int> m32;
typedef map<ll,ll> m64;
const int LIM = 1e5+5, MOD =  1e9+7;
#define sumv(v) accumulate(all(v),ll(0))
#define productv(v) accumulate(all(v), ll(1), multiplies< ll >())
ll gcd(ll a, ll b) { if(b == 0) return a; return gcd(b, a % b); }
ll fastpowMOD(ll a, ll p,ll MOD){ if(p==0) return 1; ll z = fastpowMOD(a,p/2,MOD); z = (z*z)%MOD; if(p%2) z = (z*a)%MOD; return z; }
bool seive[100005];
void SieveOfEratosthenes(ll n)
{ memset(seive, true, sizeof(seive)); for (ll p=2; p*p<=n; p++) if (seive[p] == true) for (ll i=p*p; i<=n; i += p) seive[i] = false; }
int main()
{
    fast;
    ll n,m;
    cin>>n>>m;
    map <ll,ll> mp[n+5];
  //  v64 v[n+5];
    ll i,j;
    ll visited[n+5]={0};
    if(m==0)
    {
        cout<<-1;
        return 0;
    }
    ll x,y;
    vp64 edge;
    cin>>x>>y;
    visited[x]=1;
    visited[y]=2;
    mp[x][y]=1;
    mp[y][x]=1;
    edge.pb({x,y});
  //  v[x].pb(y);
    //v[y].pb(x);
    for(i=1;i<m;i++)
    {
        ll x1,y1;
        cin>>x1>>y1;
        mp[x1][y1]=1;
        mp[y1][x1]=1;
        edge.pb({x1,y1});
      //  v[x1].pb(y1);
        //v[y1].pb(x1);
    }
    v64 ans[4];
    ans[1].pb(x);
    ans[2].pb(y);
    ll flag=0;
    ll z;
    for(i=1;i<=n;i++)
    {
        if(mp[i][x]==1 and mp[i][y]==1)
        {
            flag=1;
            ans[3].pb(i);
            z=i;
        }
    }
    if(flag==0)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i][z]==1 and mp[i][y]==1)
        {
            if(x==i)
                continue;
            ans[1].pb(i);
            //z=i;
        }
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i][z]==1 and mp[i][x]==1)
        {
            if(y==i)
                continue;
            ans[2].pb(i);
            //z=i;
        }
    }
    ll k1=ans[1].size();
    ll k2=ans[2].size();
    ll k3=ans[3].size();
    if(m!=k1*k2+k2*k3+k3*k1)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=3;i++)
    {
        for(auto it:ans[i])
            visited[it]=i;
    }
    for(i=1;i<=n;i++)
    {
        if(visited[i]==0)
        {
            cout<<-1;
            return 0;
        }
    }
    ll b[4][4]={0};
    for(auto it:edge)
    {
        b[visited[it.fi]][visited[it.se]]++;
    }
    // cout<<visited[1];
    // cout<<b[2][1];
    if(b[1][2]+b[2][1]!=k1*k2)
    {
        cout<<-1;
        //cout<<"a";
        return 0;
    }
    if(b[3][2]+b[2][3]!=k3*k2)
    {
        cout<<-1;
        return 0;
    }
    if(b[3][1]+b[1][3]!=k3*k1)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=n;i++)
        cout<<visited[i]<<" ";

}


#include <bits/stdc++.h>
#include<limits.h>
#include<stdio.h>
#include<cstring>
#include<string>
using namespace  std;
typedef long long ll;
typedef long double ld;
#define fast ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define mp make_pair
#define sz(a) a.size()
#define fi first
#define se second
#define rsz(a,n) a.resize(n)
#define test(t) ll t;cin>>t;while(t--)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define fillv(a,k) memset(a,k,sizeof(a))
#define leadzero(a) __builtin_clz(a) //count leading zeros
#define trailzero(a) __builtin_ctz(a) //count trailing zeros
#define bitcount(a) __builtin_popcount(a) // count set bits (add ll)
#define ln cout<<"\n"
#define sp cout<<" "
#define spaceprint(a,i,s,n) {forsn(i,s,n) { cout<<a[i]; sp;}}
#define lineprint(a,i,s,n) {forsn(i,s,n) {cout<<a[i]; ln;}}
#define maxe(a) *max_element(a.begin(),a.end())
#define maxi(a) max_element(a.begin(),a.end())-a.begin()
#define mine(a) *min_element(a.begin(),a.end())
#define mini(a) min_element(a.begin(),a.end())-a.begin()
#define all(c) c.begin(),c.end()
#define trav(container, it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define present(container, element) (container.find(element) != container.end())
#define cpresent(container, element)  (find(all(container),element) != container.end())// check the presence of element
//copy(from_begin, from_end, to_begin); copy function
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<ll,ll> p64;
typedef pair<int,int> p32;
typedef pair<int,p32> p96;
typedef vector<ll> v64;
typedef vector<string> vs;
typedef vector<int> v32;
typedef vector<v32> vv32;
typedef vector<v64> vv64;
typedef vector<p32> vp32;
typedef vector<p64> vp64;
typedef vector<vp32> vvp32;
typedef map<int,int> m32;
typedef map<ll,ll> m64;
const int LIM = 1e5+5, MOD =  1e9+7;
#define sumv(v) accumulate(all(v),ll(0))
#define productv(v) accumulate(all(v), ll(1), multiplies< ll >())
ll gcd(ll a, ll b) { if(b == 0) return a; return gcd(b, a % b); }
ll fastpowMOD(ll a, ll p,ll MOD){ if(p==0) return 1; ll z = fastpowMOD(a,p/2,MOD); z = (z*z)%MOD; if(p%2) z = (z*a)%MOD; return z; }
bool seive[100005];
void SieveOfEratosthenes(ll n)
{ memset(seive, true, sizeof(seive)); for (ll p=2; p*p<=n; p++) if (seive[p] == true) for (ll i=p*p; i<=n; i += p) seive[i] = false; }
int main()
{
    fast;
    ll n,m;
    cin>>n>>m;
    map <ll,ll> mp[n+5];
    v64 v[n+5];
    ll i,j;
    ll visited[n+5]={0};
    if(m==0)
    {
        cout<<-1;
        return 0;
    }
    ll x,y;
    vp64 edge;
    cin>>x>>y;
    visited[x]=1;
    visited[y]=2;
    mp[x][y]=1;
    mp[y][x]=1;
    edge.pb({x,y});
    v[x].pb(y);
    v[y].pb(x);
    for(i=1;i<m;i++)
    {
        ll x1,y1;
        cin>>x1>>y1;
        mp[x1][y1]=1;
        mp[y1][x1]=1;
        edge.pb({x1,y1});
        v[x1].pb(y1);
        v[y1].pb(x1);
    }
    v64 ans[4];
    ans[1].pb(x);
    ans[2].pb(y);
    ll flag=0;
    ll z;
    for(i=1;i<=n;i++)
    {
        if(mp[i][x]==1 and mp[i][y]==1)
        {
            flag=1;
            ans[3].pb(i);
            z=i;
        }
    }
    if(flag==0)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i][z]==1 and mp[i][y]==1)
        {
            if(x==i)
                continue;
            ans[1].pb(i);
            //z=i;
        }
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i][z]==1 and mp[i][x]==1)
        {
            if(y==i)
                continue;
            ans[2].pb(i);
            //z=i;
        }
    }
    ll k1=ans[1].size();
    ll k2=ans[2].size();
    ll k3=ans[3].size();
    if(m!=k1*k2+k2*k3+k3*k1)
    {
        cout<<-1;
        return 0;
    }
    for(i=1;i<=3;i++)
    {
        for(auto it:ans[i])
            visited[it]=i;
    }
    for(i=1;i<=n;i++)
    {
        if(visited[i]==0)
        {
            cout<<-1;
            return 0;
        }
    }

    // cout<<visited[1];
    // cout<<b[2][1];

    for(i=1;i<=n;i++)
        cout<<visited[i]<<" ";

}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int v,e;
  cin>>v>>e;
  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 && 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;
}


#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 && 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;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];

    int ans[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    for(int i =0;i<n;i++){
      ans[i] = 1;
    }
    for(int i = 0;i<g[0].size();i++){
      ans[g[0][i]] = -1;
    }
    int v1 = 0;
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        v1 = i;
        break;
      }
    }
    if(v1==0){
      cout<<-1<<1;
      return 0;
    }
    for(int i = 0;i<g[v1].size();i++){
      if(ans[g[v1][i]] == -1){
        ans[g[v1][i]] = 2;
      }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        ans[i] = 3;
      }
    }
    bfs(0);
    for(int i = 1;i<n;i++){
      if(d[i] == 2){
        if(ans[i]!=1){
          cout<<-1<<2;
          return 0;
        }
      }
      else if(ans[i] == 1){
        cout<<-1<<3;
        return 0;
      }
    }
    for(int i =0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));
      int bfsc = 0;
      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }
        else if(d[j]==1){
          if(ans[j]==i){
            is_ans = 0;
          }

        }

      }
      if(bfsc!=1){
          is_ans = 0;
        }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    for(int i =0;i<n;i++){
      if(ans[i] == -1){
        cout<<-1;
        return 0;
      }
      for(int j =0;j<g[i].size();j++){
        if(ans[g[i][j]]==ans[i]){
          cout<<-1;
          return 0;
        }
        if(ans[g[i][j]] == -1){
          cout<<-1;
          return 0;
        }
      }
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];

    int ans[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    for(int i =0;i<n;i++){
      ans[i] = 1;
    }
    for(int i = 0;i<g[0].size();i++){
      ans[g[0][i]] = -1;
    }
    int v1 = 0;
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        v1 = i;
      }
    }
    if(v1==0){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<g[v].size();i++){
      if(ans[g[v][i]] == -1){
        ans[g[v][i]] = 2;
      }
    }
    for(int i = 0;i<g[v].size();i++){
      if(ans[g[v][i]] == -1){
        ans[g[v][i]] == 3;
      }
    }
    bfs(0);
    for(int i = 0;i<n;i++){
      if(d[i] == 2){
        if(ans[i]!=1){
          cout<<-1;
          return 0;
        }
      }
      else if(ans[i] == 1){
        cout<<-1;
        return 0;
      }
    }
    for(int i =0;i<n;i++){
      cout<<ans<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));
      int bfsc = 0;
      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }
        else if(d[j]==1){
          if(ans[j]==i){
            is_ans = 0;
          }

        }

      }
      if(bfsc!=1){
          is_ans = 0;
        }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    for(int i =0;i<n;i++){
      if(ans[i] == -1){
        cout<<-1;
        return 0;
      }
      for(int j =0;j<g[i].size();j++){
        if(ans[g[i][j]]==ans[i]){
          cout<<-1;
          return 0;
        }
        if(ans[g[i][j]] == -1){
          cout<<-1;
          return 0;
        }
      }
    }
    if(!is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int p[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  p[v] = -1;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      p[u] = s;
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));
      for(int j = 0;j<n;j++){
        bool bfsd = 0;
        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
          bfsd = true;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }
        if(!bfsd){
          is_ans = 0;
        }
      }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));
      int bfsc = 0;
      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }
        else if(d[j]==1){
          if(ans[j]==i){
            is_ans = 0;
          }

        }

      }
      if(bfsc!=1){
          is_ans = 0;
        }
    }
    int ct[4];
    ct[1] = 0;ct[2] = 0;ct[3] = 0;ct[0] = 0;
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
      ct[ans[i]]++;
      ct[0]++;
    }
    if(ct[0] != n){
      is_ans = 0;
    }

    for(int i =0;i<n;i++){
      if(g[i].size()<ct[0]-ct[ans[i]]){
        is_ans = 0;
      }
      if(ans[i] == -1){
        is_ans = 0;
        }
      for(int j =0;j<g[i].size();j++){
        if(ans[g[i][j]]==ans[i]){
          is_ans = 0;
        }
        if(ans[g[i][j]] == -1){
          is_ans = 0;
        }
      }
    }

    if(!is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));
      int bfsc = 0;
      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }

      }
      if(bfsc!=1){
          is_ans = 0;
        }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));
      int bfsc = 0;
      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }
        else if(d[j]==1){
          if(ans[j]==i){
            is_ans = 0;
          }

        }

      }
      if(bfsc!=1){
          is_ans = 0;
        }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int p[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  p[v] = -1;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      p[u] = s;
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));
      bool bfsd = 0;
      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
          bfsd = true;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }

      }
      if(!bfsd){
          is_ans = 0;
        }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    int bfsc = 0;
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));

      for(int j = 0;j<n;j++){

        if(ans[j] == -1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;

          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }

      }
      if(bfsc==3){
          is_ans = 0;
        }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];

    int ans[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      d[u]=(d[s] +1);
      if(!used[u]){
      used[u] = true;
      q.push(u);

      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    for(int i =0;i<n;i++){
      ans[i] = 1;
    }
    for(int i = 0;i<g[0].size();i++){
      ans[g[0][i]] = -1;
    }
    int v1 = 0;
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        v1 = i;
        break;
      }
    }
    if(v1==0){
      cout<<-1;
      return 0;
    }
    ans[v1] = 2;
    for(int i = 0;i<g[v1].size();i++){
      if(ans[g[v1][i]] == -1){
        ans[g[v1][i]] = 2;
      }
    }
    bool ansex = 0;
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        ans[i] = 3;
        ansex = 1;
      }
    }
    if(!ansex){
      cout<<-1;
      return 0;
    }
    bfs(0);
    for(int i = 1;i<n;i++){
      if(d[i] == 2){
        if(ans[i]!=1){
          cout<<-1;
          return 0;
        }
      }
      else if(ans[i] == 1){
        cout<<-1;
        return 0;
      }
    }
    for(int i =0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];

    int ans[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    for(int i =0;i<n;i++){
      ans[i] = 1;
    }
    for(int i = 0;i<g[0].size();i++){
      ans[g[0][i]] = -1;
    }
    int v1 = 0;
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        v1 = i;
      }
    }
    if(v1==0){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<g[v].size();i++){
      if(ans[g[v][i]] == -1){
        ans[g[v][i]] = 2;
      }
    }
    for(int i = 0;i<n;i++){
      if(ans[g[v][i]] == -1){
        ans[g[v][i]] == 3;
      }
    }
    bfs(0);
    for(int i = 0;i<n;i++){
      if(d[i] == 2){
        if(ans[i]!=1){
          cout<<-1;
          return 0;
        }
      }
      else if(ans[i] == 1){
        cout<<-1;
        return 0;
      }
    }
    for(int i =0;i<n;i++){
      cout<<ans<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int p[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  p[v] = -1;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      p[u] = s;
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));

    memset(used,0,sizeof(used));
      for(int j = 0;j<n;j++){
        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }
      }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    int bfsc = 0;
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));

      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j] == -1 && bfsc==i-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;

          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
        }
        if(d[j] == -1){
          is_ans = 0;
        }

      }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }

    if(bfsc!=3){
          is_ans = 0;
        }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      p[u] = s;
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));
      int bfsc = 0;
      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j]==-1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;
          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
          else{
            is_ans = false;
          }
        }

      }
      if(bfsc!=1){
          is_ans = 0;
        }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N  = 1e5 +5;
queue<int> q;
std::vector<int> g[N];
bool used[N];
int d[N];
void bfs(int v){
  q.push(v);
  d[v] = 0;
  used[v] = true;
  while(!q.empty()){

    int s = q.front();
    q.pop();
    for(int i = 0;i<g[s].size();i++){
      int u = g[s][i];
      if(!used[u]){
      used[u] = true;
      q.push(u);
      d[u] = d[s] +1;
      }
    }
  }

}

int main()

{
ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
   freopen("error.txt", "w", stderr);
   #endif
    int n,m;cin>>n>>m;
    int v,u;
    //cout<<1;
    for(int i = 0;i<m;i++){
      cin>>v>>u;v--;u--;
      g[v].push_back(u);
      g[u].push_back(v);
      //cout<<2;
    }
    bool is_ans = true;
    int ans[n];
    memset(used,0,sizeof(used));
    memset(ans,-1,sizeof(ans));
    int bfsc = 0;
    for(int i = 1;i<4;i++){
      memset(d,-1,sizeof(d));
      memset(used,0,sizeof(used));

      for(int j = 0;j<n;j++){

        if(ans[j] == -1 && d[j] == -1){
          bfs(j);
          // for(int k = 0;k<n;k++){
          //   cout<<d[k]<<" ";
          // }
          // cout<<'\n';
          ans[j] = i;

          bfsc++;
        }
        if(d[j] == 2){
          if(ans[j]==-1){
            ans[j] =i;
          }
        }

      }
    }
    for(int i = 0;i<n;i++){
      if(ans[i] == -1){
        is_ans = false;
      }
    }

    if(bfsc!=3){
          is_ans = 0;
        }
    if( ! is_ans){
      cout<<-1;
      return 0;
    }
    for(int i = 0;i<n;i++){
      cout<<ans[i]<<" ";
    }

}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

unordered_set<int>mm;
void foo(int n){
	while (n % 2 == 0)
    {
    	mm.insert(2);
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (int i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
        	mm.insert(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        mm.insert(n);
}
void func(){

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

	vector<unordered_set<int>>v;

	v.resize(n+1);

	int a,b;

	loop(m){
		cin>>a>>b;
		v[a].insert(b);
		v[b].insert(a);
	}

	loop(n){
		if(v[i].size()<2){
			cout<<-1;
			return;
		}
	}

	unordered_map<int,unordered_set<int>>colors;
	unordered_map<int,int>color_ans;

	vector<int>checker;

		queue<int>q;

		q.push(1);

		while(!q.empty()){
			int curr=q.front();
			checker.push_back(curr);
			if(colors[curr].empty()){
				color_ans[curr]=0;
			}

			else {

				if(colors[curr].size()==3){
					cout<<-1;
					return;
				}
				else {
					if(!colors[curr].count(0)){
						color_ans[curr]=0;
					}
					else if(!colors[curr].count(1)){
						color_ans[curr]=1;
					}
					else color_ans[curr]=2;
				}
			}

			q.pop();

			rep(v[curr]){
				if(colors[curr].size()==0){
					q.push(it);
				}
				colors[it].insert(color_ans[curr]);
				if(colors[it].size()==3){
					cout<<-1;
					return;
				}
			}

		}

	if(checker.size()!=n){
		cout<<-1;
		return;
	}

	loop(n)cout<<color_ans[i]+1<<" ";

}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

void func()
{

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

	vector<unordered_set<int>> v;

	v.resize(n + 1);

	int a, b;

	loop(m)
	{
		cin >> a >> b;
		v[a].insert(b);
		v[b].insert(a);
	}

	unordered_set<int>p,q,r,vis;

	p.insert(1);

	loop(n){
		if(!v[1].count(i))p.insert(i);
	}

	if(v[1].size()){

		int val = *v[1].begin();
		q.insert(val);

		loop(n){
			if(!v[val].count(i))q.insert(i);
		}
	}

	loop(n){
		if(!p.count(i) && !q.count(i))r.insert(i);
	}

	if(p.size() && q.size() && r.size()){
		if(m==p.size()*r.size() + q.size()*r.size() + p.size()*q.size() && p.size()+q.size()+r.size()==n){
			loop(n){
				if(p.count(i))cout<<1;
				else if(q.count(i))cout<<2;
				else cout<<3;
				cout<<" ";
			}
			return;
		}
	}

	cout<<-1;

}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
    ll res = 1;
    while (p > 0)
    {
        if (p & 1)
            res = (res * a) % m;
        a = (a * a) % m;
        p >>= 1;
    }
    return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
    ll res = 1;
    while (p > 0)
    {
        if (p & 1)
            res = res * a;
        a = a * a;
        p >>= 1;
    }
    return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

void func()
{

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

    vector<unordered_set<int>> v;

    v.resize(n + 1);

    int a,b;

    loop(m)
    {
        cin >> a >> b;
        v[a].insert(b);
        v[b].insert(a);
    }

    unordered_set<int> p, q, r, vis, temp;

    p.insert(1);

    loop(n)
    {
        if (!v[1].count(i))
            p.insert(i);
    }

    loop(n)
    {
        if (!p.count(i))
        {
            temp.insert(i);
        }
    }

    rep(temp){
    	if(vis.count(it))continue;
    	q.insert(it);
    	vis.insert(it);

    	repp(v[it]){
    		if(temp.count(ptr) && !vis.count(ptr)){
    			r.insert(ptr);
    			vis.insert(ptr);
    		}
    	}
    }

    if (p.size() && q.size() && r.size())
    {
        if (m == p.size() * r.size() + q.size() * r.size() + p.size() * q.size() && p.size() + q.size() + r.size() == n)
        {
            loop(n)
            {
                if (p.count(i))
                    cout << 1;
                else if (q.count(i))
                    cout << 2;
                else
                    cout << 3;
                cout << " ";
            }
            return;
        }
    }

    cout << -1;
}

int main()
{

    ios_base::sync_with_stdio(0);

    cin.tie(0);
    cout.tie(0);

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif

    func();
    return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

unordered_set<int> mm;
void func()
{

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

	vector<unordered_set<int>> v;

	v.resize(n + 1);

	int a, b;

	loop(m)
	{
		cin >> a >> b;
		v[a].insert(b);
		v[b].insert(a);
	}

	loop(n)
	{
		if (v[i].size() < 2)
		{
			cout << -1;
			return;
		}
	}

	unordered_map<int, unordered_set<int>> colors;
	unordered_map<int, int> color_ans;

	vector<int> checker;

	queue<int> q;

	int cnt = 0;
	unordered_set<int> vis;
	for (int i = 1; i <= n; i++)
	{
		if (vis.count(i))
			continue;
		cnt++;
		q.push(i);
		while (!q.empty())
		{
			auto curr = q.front();
			q.pop();
			vis.insert(curr);
			rep(v[curr])
			{
				if (!vis.count(it))
					vis.insert(it), q.push(it);
			}
		}
	}

	if (cnt > 1)
	{
		cout << -1;
		if (m == 199997)
			dbg return;
	}

	q.push(1);

	while (!q.empty())
	{
		int curr = q.front();
		checker.push_back(curr);
		if (colors[curr].empty())
		{
			color_ans[curr] = 0;
		}

		else
		{

			if (colors[curr].size() == 3)
			{
				cout << -1;
				return;
			}
			else
			{
				if (!colors[curr].count(0))
				{
					color_ans[curr] = 0;
				}
				else if (!colors[curr].count(1))
				{
					color_ans[curr] = 1;
				}
				else
					color_ans[curr] = 2;
			}
		}

		q.pop();

		rep(v[curr])
		{
			if (colors[curr].size() == 0)
			{
				q.push(it);
			}
			colors[it].insert(color_ans[curr]);
			if (colors[it].size() == 3)
			{
				cout << -1;
				return;
			}
		}
	}

	if (checker.size() != n)
	{
		cout << -1;
		return;
	}

	loop(n) cout << color_ans[i] + 1 << " ";
}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

void func()
{

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

	vector<unordered_set<int>> v;

	v.resize(n + 1);

	int a, b;

	loop(m)
	{
		cin >> a >> b;
		v[a].insert(b);
		v[b].insert(a);
	}

	unordered_set<int>p,q,r,vis;

	p.insert(1);

	loop(n){
		if(!v[1].count(i))p.insert(i);
	}

	if(v[1].size()){

		int val = *v[1].begin();
		q.insert(val);

		loop(n){
			if(!v[val].count(i))q.insert(i);
		}
	}

	loop(n){
		if(!p.count(i) && !q.count(i))r.insert(i);
	}

	if(p.size() && q.size() && r.size()){
		if(m==p.size()*r.size() + q.size()*r.size() + p.size()*q.size()){
			loop(n){
				if(p.count(i))cout<<1;
				else if(q.count(i))cout<<2;
				else cout<<3;
				cout<<" ";
			}
			return;
		}
	}

	cout<<-1;

}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

void func()
{

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

	vector<unordered_set<int>> v;

	v.resize(n + 1);

	int a, b;

	loop(m)
	{
		cin >> a >> b;
		v[a].insert(b);
		v[b].insert(a);
	}

	unordered_set<int>p,q,r,vis;

	p.insert(1);

	loop(n){
		if(!v[1].count(i))p.insert(i);
	}

	if(v[1].size()){

		int val = *v[1].begin();
		q.insert(val);

		loop(n){
			if(!v[val].count(i) && !p.count(i))q.insert(i);
		}
	}

	loop(n){
		if(!p.count(i) && !q.count(i))r.insert(i);
	}

	if(p.size() && q.size() && r.size()){
		if(m==p.size()*r.size() + q.size()*r.size() + p.size()*q.size()){
			loop(n){
				if(p.count(i))cout<<1;
				else if(q.count(i))cout<<2;
				else cout<<3;
				cout<<" ";
			}
			return;
		}
	}

	cout<<-1;

}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
    ll res = 1;
    while (p > 0)
    {
        if (p & 1)
            res = (res * a) % m;
        a = (a * a) % m;
        p >>= 1;
    }
    return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
    ll res = 1;
    while (p > 0)
    {
        if (p & 1)
            res = res * a;
        a = a * a;
        p >>= 1;
    }
    return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

vector<unordered_set<int>> v;

bool check(unordered_set<int>&mm){

	rep(mm){
		rep(v[it]){
			if(mm.count(it))return false;
		}
	}
}
void func()
{

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

    v.resize(n + 1);

    int a,b;

    loop(m)
    {
        cin >> a >> b;
        v[a].insert(b);
        v[b].insert(a);
    }

    unordered_set<int> p, q, r, vis, temp;

    p.insert(1);

    loop(n)
    {
        if (!v[1].count(i))
            p.insert(i);
    }

    loop(n)
    {
        if (!p.count(i))
        {
            temp.insert(i);
        }
    }

    rep(temp){
    	if(vis.count(it))continue;
    	q.insert(it);
    	vis.insert(it);

    	repp(v[it]){
    		if(temp.count(ptr) && !vis.count(ptr)){
    			r.insert(ptr);
    			vis.insert(ptr);
    		}
    	}
    }

    if (p.size() && q.size() && r.size())
    {
        if (m == p.size() * r.size() + q.size() * r.size() + p.size() * q.size() && p.size() + q.size() + r.size() == n && check(p) && check(q) && check(r))
        {
            loop(n)
            {
                if (p.count(i))
                    cout << 1;
                else if (q.count(i))
                    cout << 2;
                else
                    cout << 3;
                cout << " ";
            }
            return;
        }
    }

    cout << -1;
}

int main()
{

    ios_base::sync_with_stdio(0);

    cin.tie(0);
    cout.tie(0);

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif

    func();
    return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

unordered_set<int> mm;
void func()
{

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

	vector<unordered_set<int>> v;

	v.resize(n + 1);

	int a, b;

	loop(m)
	{
		cin >> a >> b;
		v[a].insert(b);
		v[b].insert(a);
	}

	loop(n)
	{
		if (v[i].size() < 2)
		{
			cout << -1;
			return;
		}
	}

	unordered_map<int, unordered_set<int>> colors;
	unordered_map<int, int> color_ans;

	vector<int> checker;

	queue<int> q;

	int cnt = 0;
	unordered_set<int> vis;
	for (int i = 1; i <= n; i++)
	{
		if (vis.count(i))
			continue;
		cnt++;
		q.push(i);
		while (!q.empty())
		{
			auto curr = q.front();
			q.pop();
			vis.insert(curr);
			rep(v[curr])
			{
				if (!vis.count(it))
					vis.insert(it), q.push(it);
			}
		}
	}

	if (cnt > 1)
	{
		cout << -1;
		if (m == 199997){
			dbg
		}
		return;
	}

	q.push(1);

	while (!q.empty())
	{
		int curr = q.front();
		checker.push_back(curr);
		if (colors[curr].empty())
		{
			color_ans[curr] = 0;
		}

		else
		{

			if (colors[curr].size() == 3)
			{
				cout << -1;
				return;
			}
			else
			{
				if (!colors[curr].count(0))
				{
					color_ans[curr] = 0;
				}
				else if (!colors[curr].count(1))
				{
					color_ans[curr] = 1;
				}
				else
					color_ans[curr] = 2;
			}
		}

		q.pop();

		rep(v[curr])
		{
			if (colors[curr].size() == 0)
			{
				q.push(it);
			}
			colors[it].insert(color_ans[curr]);
			if (colors[it].size() == 3)
			{
				cout << -1;
				return;
			}
		}
	}

	if (checker.size() != n)
	{
		cout << -1;
		return;
	}

	loop(n) cout << color_ans[i] + 1 << " ";
}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

unordered_set<int>mm;
void func(){

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

	vector<unordered_set<int>>v;

	v.resize(n+1);

	int a,b;

	loop(m){
		cin>>a>>b;
		v[a].insert(b);
		v[b].insert(a);
	}

	loop(n){
		if(v[i].size()<2){
			if(m==199997){
						cout<<"init";
					}
			cout<<-1;
			return;
		}
	}

	unordered_map<int,unordered_set<int>>colors;
	unordered_map<int,int>color_ans;

	vector<int>checker;

		queue<int>q;

		q.push(1);

		while(!q.empty()){
			int curr=q.front();
			checker.push_back(curr);
			if(colors[curr].empty()){
				color_ans[curr]=0;
			}

			else {

				if(colors[curr].size()==3){
					cout<<-1;
					return;
				}
				else {
					if(!colors[curr].count(0)){
						color_ans[curr]=0;
					}
					else if(!colors[curr].count(1)){
						color_ans[curr]=1;
					}
					else color_ans[curr]=2;
				}
			}

			q.pop();

			rep(v[curr]){
				if(colors[curr].size()==0){
					q.push(it);
				}
				colors[it].insert(color_ans[curr]);
				if(colors[it].size()==3){
					if(m==199997){
						cout<<"inside queue loop";
					}
					cout<<-1;
					return;
				}
			}

		}

	if(checker.size()!=n){
		if(m==199997){
						cout<<"checker";
					}
		cout<<-1;
		return;
	}

	loop(n)cout<<color_ans[i]+1<<" ";

}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

void func()
{

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

	vector<unordered_set<int>> v;

	v.resize(n + 1);

	int a, b;

	loop(m)
	{
		cin >> a >> b;
		v[a].insert(b);
		v[b].insert(a);
	}

	unordered_set<int>p,q,r,vis;

	p.insert(1);

	loop(n){
		if(!v[1].count(i))p.insert(i);
	}

	if(v[1].size()){

		int val = *v[1].begin();
		q.insert(val);

		loop(n){
			if(!v[val].count(i))q.insert(i);
		}
	}

	loop(n){
		unordered_set<int>temp;
		if(!p.count(i) && !q.count(i)){
			temp.insert(i);
		}

		rep(temp){
			repp(v[it]){
				vis.insert(ptr);
			}
		}

		rep(temp)r.insert(it);
		for(int j=1;j<=n;j++){
			if(!vis.count(j))r.insert(j);
		}
	}

	if(p.size() && q.size() && r.size()){
		if(m==p.size()*r.size() + q.size()*r.size() + p.size()*q.size() && p.size()+q.size()+r.size()==n){
			loop(n){
				if(p.count(i))cout<<1;
				else if(q.count(i))cout<<2;
				else cout<<3;
				cout<<" ";
			}
			return;
		}
	}

	cout<<-1;

}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

unordered_set<int>mm;
void foo(int n){
	while (n % 2 == 0)
    {
    	mm.insert(2);
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (int i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
        	mm.insert(i);
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        mm.insert(n);
}
void func(){

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

	vector<unordered_set<int>>v;

	v.resize(n+1);

	int a,b;

	loop(m){
		cin>>a>>b;
		v[a].insert(b);
		v[b].insert(a);
	}

	loop(n){
		if(v[i].size()<2){
			cout<<-1;
			return;
		}
	}

	unordered_set<int>p,q,r;

	unordered_set<int>vis;

	unordered_map<int,unordered_set<int>>colors;
	unordered_map<int,int>color_ans;

	loop(n){
		if(vis.count(i))continue;

		queue<int>q;

		q.push(i);

		while(!q.empty()){
			int curr=q.front();
			if(colors[curr].empty()){
				color_ans[curr]=0;
			}

			else {

				if(colors[curr].size()==3){
					cout<<-1;
					return;
				}
				else {
					if(!colors[curr].count(0)){
						color_ans[curr]=0;
					}
					else if(!colors[curr].count(1)){
						color_ans[curr]=1;
					}
					else color_ans[curr]=2;
				}
			}

			vis.insert(curr);
			q.pop();

			rep(v[curr]){
				if(!vis.count(it)){
					colors[it].insert(color_ans[curr]);
					if(colors[it].size()==3){
						cout<<-1;
						return;
					}
				}
			}

		}

	}

	loop(n)cout<<color_ans[i]+1<<" ";

}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = (res * a) % m;
		a = (a * a) % m;
		p >>= 1;
	}
	return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
	ll res = 1;
	while (p > 0)
	{
		if (p & 1)
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

unordered_set<int> mm;
void func()
{

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

	vector<unordered_set<int>> v;

	v.resize(n + 1);

	int a, b;

	loop(m)
	{
		cin >> a >> b;
		v[a].insert(b);
		v[b].insert(a);
	}

	loop(n)
	{
		if (v[i].size() < 2)
		{
			cout << -1;
			return;
		}
	}

	unordered_map<int, unordered_set<int>> colors;
	unordered_map<int, int> color_ans;

	vector<int> checker;

	queue<int> q;

	unordered_set<int>vis;

	q.push(1);

	while (!q.empty())
	{
		int curr = q.front();
		vis.insert(curr);
		checker.push_back(curr);
		if (colors[curr].empty())
		{
			color_ans[curr] = 0;
		}

		else
		{

			if (colors[curr].size() == 3)
			{
				cout << -1;
				return;
			}
			else
			{
				if (!colors[curr].count(0))
				{
					color_ans[curr] = 0;
				}
				else if (!colors[curr].count(1))
				{
					color_ans[curr] = 1;
				}
				else
					color_ans[curr] = 2;
			}
		}

		q.pop();

		rep(v[curr])
		{
			if(!vis.count(it))q.push(it),vis.insert(it);
			colors[it].insert(color_ans[curr]);
			if (colors[it].size() == 3)
			{
				cout << -1;
				return;
			}
		}
	}

	if (checker.size() != n)
	{
		cout << -1;
		return;
	}

	loop(n) cout << color_ans[i] + 1 << " ";
}

int main()
{

	ios_base::sync_with_stdio(0);

	cin.tie(0);
	cout.tie(0);

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	func();
	return 0;
}


#include <iostream>
#include <random>
#include <iomanip>
#include <math.h>
#include "vector"
#include "string"
#include "algorithm"
#include "iterator"
#include "map"
#include "set"
#include "stack"
#include "queue"
#include "unordered_map"
#include "unordered_set"
#include "deque"
#define ll long long
#define ld long double
#define uint unsigned long
#define repp(a) for (auto &ptr : (a))
#define dbg cout << "hello" << endl;
#define loop(n) for (int i = 1; i <= (n); i++)
#define MOD 1000000007
#define MAX INT32_MAX
#define MIN INT32_MIN
#define MAXL INT64_MAX
#define MINL INT64_MIN
#define pset(n) setprecision(n)

using namespace std;
typedef priority_queue<int, vector<int>, greater<int>> min_pq;
int delta[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

ll calc_pow(ll a, ll p, ll m = MOD)
{
    ll res = 1;
    while (p > 0)
    {
        if (p & 1)
            res = (res * a) % m;
        a = (a * a) % m;
        p >>= 1;
    }
    return res;
}

ll calc_pow_without_mod(ll a, ll p)
{
    ll res = 1;
    while (p > 0)
    {
        if (p & 1)
            res = res * a;
        a = a * a;
        p >>= 1;
    }
    return res;
}

#define rep(v) for (auto &it : (v))
typedef pair<int, int> pp;
typedef pair<ll, ll> ppl;

vector<unordered_set<int>> v;

bool check(unordered_set<int>&mm){

	rep(mm){
		rep(v[it]){
			if(mm.count(it))return false;
		}
	}

	return true;
}
void func()
{

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

    v.resize(n + 1);

    int a,b;

    loop(m)
    {
        cin >> a >> b;
        v[a].insert(b);
        v[b].insert(a);
    }

    unordered_set<int> p, q, r, vis, temp;

    p.insert(1);

    loop(n)
    {
        if (!v[1].count(i))
            p.insert(i);
    }

    loop(n)
    {
        if (!p.count(i))
        {
            temp.insert(i);
        }
    }

    rep(temp){
    	if(vis.count(it))continue;
    	q.insert(it);
    	vis.insert(it);

    	repp(v[it]){
    		if(temp.count(ptr) && !vis.count(ptr)){
    			r.insert(ptr);
    			vis.insert(ptr);
    		}
    	}
    }

    if (p.size() && q.size() && r.size())
    {
        if (m == p.size() * r.size() + q.size() * r.size() + p.size() * q.size() && p.size() + q.size() + r.size() == n && check(p) && check(q) && check(r))
        {
            loop(n)
            {
                if (p.count(i))
                    cout << 1;
                else if (q.count(i))
                    cout << 2;
                else
                    cout << 3;
                cout << " ";
            }
            return;
        }
    }

    cout << -1;
}

int main()
{

    ios_base::sync_with_stdio(0);

    cin.tie(0);
    cout.tie(0);

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif

    func();
    return 0;
}


/*
include
push_back
pop_back
vector
resize
clear
namespace
algorithm
stdio.h
fuctional
queue
priority_queue
greater
iostream
*/
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
vector<int> edge[150000];
int set_number[150000];

vector<bool> visited(150000,false);

void bfs(int start,int num, int dist){
	queue<int> q;
	q.push(start);
	visited[start] = true;
	dist = 0;
	while(!q.empty()){
		int qsize = q.size();
		for(int i = 0;i<qsize;i++){
			int cur = q.front();
			if(dist%2==0) set_number[cur] = num;
			q.pop();
			for(int next : edge[cur]){
				if(!visited[next]){
					q.push(next);
					visited[next] = true;
				}
			}
		}
		dist++;
	}
}

int main(){
	int n,m; scanf("%d %d",&n,&m);
	for(int i = 0;i<m;i++){
		int x,y; scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	for(int j = 1;j<=3;j++){
		bool ch = false;
		for(int i = 1;i<=n;i++){
			if(!visited[i]&&set_number[i]==0) {
				bfs(i,j,0);
				ch = true;
			}
		}
		if(!ch) {printf("-1"); return 0;}
		visited = vector<bool>(150000,false);
	}
	int v[3]={0};
	for(int i = 1;i<=n;i++){
		if(set_number[i]==0){printf("-1");return 0;}
		else{
			v[set_number[i]-1]++;
		}
	}
	if(m!=v[0]*v[1]+v[1]*v[2]+v[2]*v[1]||v[0]==0||v[1]==0||v[2]==0){ printf("-1"); return 0;}
	for(int i = 1;i<=n;i++){
		printf("%d ",set_number[i]);
	}

	return 0;
}


/*
include
push_back
pop_back
vector
resize
clear
namespace
algorithm
stdio.h
fuctional
queue
priority_queue
greater
iostream
*/
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
vector<int> edge[150000];
int set_number[150000];

vector<bool> visited(150000,false);

void bfs(int start,int num, int dist){
	queue<int> q;
	q.push(start);
	visited[start] = true;
	dist = 0;
	while(!q.empty()){
		int qsize = q.size();
		for(int i = 0;i<qsize;i++){
			int cur = q.front();
			if(dist%2==0) set_number[cur] = num;
			q.pop();
			for(int next : edge[cur]){
				if(!visited[next]){
					q.push(next);
					visited[next] = true;
				}
			}
		}
		dist++;
	}
}

int main(){
	int n,m; scanf("%d %d",&n,&m);
	for(int i = 0;i<m;i++){
		int x,y; scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	for(int j = 1;j<=3;j++){
		bool ch = false;
		for(int i = 1;i<=n;i++){
			if(!visited[i]&&set_number[i]==0) {
				bfs(i,j,0);
				ch = true;
			}
		}
		if(!ch) {printf("-1"); return 0;}
		visited = vector<bool>(150000,false);
	}
	for(int i = 1;i<=n;i++){
		if(set_number[i]==0){printf("-1"); return 0;}
	}
	for(int i = 1;i<=n;i++){
		printf("%d ",set_number[i]);
	}

	return 0;
}


/*
include
push_back
pop_back
vector
resize
clear
namespace
algorithm
stdio.h
fuctional
queue
priority_queue
greater
iostream
*/
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
vector<int> edge[150000];
int set_number[150000];

vector<bool> visited(150000,false);

void bfs(int start,int num, int dist){
	queue<int> q;
	q.push(start);
	visited[start] = true;
	dist = 0;
	while(!q.empty()){
		int qsize = q.size();
		for(int i = 0;i<qsize;i++){
			int cur = q.front();
			if(dist%2==0) set_number[cur] = num;
			q.pop();
			for(int next : edge[cur]){
				if(!visited[next]){
					q.push(next);
					visited[next] = true;
				}
			}
		}
		dist++;
	}
}

int main(){
	int n,m; scanf("%d %d",&n,&m);
	for(int i = 0;i<m;i++){
		int x,y; scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	for(int j = 1;j<=3;j++){
		bool ch = false;
		for(int i = 1;i<=n;i++){
			if(!visited[i]&&set_number[i]==0) {
				bfs(i,j,0);
				ch = true;
			}
		}
		if(!ch) {printf("-1"); return 0;}
		visited = vector<bool>(150000,false);
	}
	int v[3]={0};
	for(int i = 1;i<=n;i++){
		if(set_number[i]==0){printf("-1");}
		else{
			v[i-1]++;
		}
	}
	if(m!=v[0]*v[1]+v[1]*v[2]+v[2]*v[1]){ printf("-1"); return 0;}
	for(int i = 1;i<=n;i++){
		printf("%d ",set_number[i]);
	}

	return 0;
}


// Standard libraries
#include <stdio.h>
#include <vector>
#include <set>

// Main
int main(int argc, char **argv){

#ifdef __McDic__ // Local testing I/O
    freopen("VScode/IO/input.txt", "r", stdin);
    freopen("VScode/IO/output.txt", "w", stdout);
#endif

    // Get input
    int v, e; scanf("%d %d", &v, &e);
    std::vector<std::set<int>> edges(v+1);
    for(int i=0; i<e; i++){
        int e[2]; scanf("%d %d", e, e+1);
        edges[e[0]].insert(e[1]);
        edges[e[1]].insert(e[0]);
    }

    // Assign groups
    std::vector<int> group(v+1, -1);
    for(int g = 0; g < 3; g++){

        // Find first point of group
        int first;
        for(first=1; first<=v; first++) if(group[first] == -1) break;
        if(first == v+1){ printf("-1\n"); return 0;} // All are in some group

        // Group settings
        group[first] = g;
        for(int second = 1; second <= v; second++) if(first != second && group[second] == -1
        && edges[first].find(second) == edges[first].end()) group[second] = g;
    }

    // All vertices should be in some group
    std::vector<std::vector<int>> groups(3);
    for(int now=1; now<=v; now++){
        if(group[now] == -1){ printf("-1\n"); return 0;} // Non grouped vertex exist
        else groups[group[now]].push_back(now);
    }

    // Edge counting
    int found_edges = 0;
    for(int g1=0; g1<3; g1++){
        for(int g2=g1+1; g2<3; g2++){
            for(int v1: groups[g1]) for(int v2: groups[g2]){
                if(edges[v1].find(v2) == edges[v1].end()){ printf("-1\n"); return 0;} // Non complete bipartite
                else found_edges++;
            }
        }
    }

    // Edge validation
    if(found_edges != e){ printf("-1\n"); return 0;} // Remaining edges detected
    for(int now=1; now<=v; now++) printf("%d ", group[now] + 1); // OK!!
    return 0;
}


/*
include
push_back
pop_back
vector
resize
clear
namespace
algorithm
stdio.h
fuctional
queue
priority_queue
greater
iostream
*/
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
vector<int> edge[150000];
int set_number[150000];

vector<bool> visited(150000,false);

void bfs(int start,int num, int dist){
	queue<int> q;
	q.push(start);
	visited[start] = true;
	dist = 0;
	while(!q.empty()){
		int qsize = q.size();
		for(int i = 0;i<qsize;i++){
			int cur = q.front();
			if(dist%2==0) set_number[cur] = num;
			q.pop();
			for(int next : edge[cur]){
				if(!visited[next]){
					q.push(next);
					visited[next] = true;
				}
			}
		}
		dist++;
	}
}

int main(){
	int n,m; scanf("%d %d",&n,&m);
	for(int i = 0;i<m;i++){
		int x,y; scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	for(int j = 1;j<=3;j++){
		bool ch = false;
		for(int i = 1;i<=n;i++){
			if(!visited[i]&&set_number[i]==0) {
				bfs(i,j,0);
				ch = true;
			}
		}
		if(!ch) {printf("-1"); return 0;}
		visited = vector<bool>(150000,false);
	}
	int v[3]={0};
	for(int i = 1;i<=n;i++){
		if(set_number[i]==0){printf("-1");return 0;}
		else{
			v[set_number[i]-1]++;
		}
	}
	if(m!=v[0]*v[1]+v[1]*v[2]+v[2]*v[1]){ printf("-1"); return 0;}
	for(int i = 1;i<=n;i++){
		printf("%d ",set_number[i]);
	}

	return 0;
}


/*
include
push_back
pop_back
vector
resize
clear
namespace
algorithm
stdio.h
fuctional
queue
priority_queue
greater
iostream
*/
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
vector<int> edge[150000];
int set_number[150000];

vector<bool> visited(150000,false);

void bfs(int start,int num, int dist){
	queue<int> q;
	q.push(start);
	visited[start] = true;
	dist = 0;
	while(!q.empty()){
		int qsize = q.size();
		for(int i = 0;i<qsize;i++){
			int cur = q.front();
			if(dist%2==0) set_number[cur] = num;
			q.pop();
			for(int next : edge[cur]){
				if(!visited[next]){
					q.push(next);
					visited[next] = true;
				}
			}
		}
		dist++;
	}
}

int main(){
	int n,m; scanf("%d %d",&n,&m);
	for(int i = 0;i<m;i++){
		int x,y; scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	for(int j = 1;j<=3;j++){
		bool ch = false;
		for(int i = 1;i<=n;i++){
			if(!visited[i]&&set_number[i]==0) {
				bfs(i,j,0);
				ch = true;
			}
		}
		if(!ch) {printf("-1"); return 0;}
		visited = vector<bool>(150000,false);
	}
	int v[3]={0};
	for(int i = 1;i<=n;i++){
		if(set_number[i]==0){printf("-1");return 0;}
		else{
			v[set_number[i]-1]++;
		}
	}
	if(m!=v[0]*v[1]+v[1]*v[2]+v[2]*v[0]){ printf("-1"); return 0;}
	for(int i = 1;i<=n;i++){
		printf("%d ",set_number[i]);
	}

	return 0;
}


/*
include
push_back
pop_back
vector
resize
clear
namespace
algorithm
stdio.h
fuctional
queue
priority_queue
greater
iostream
*/
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
vector<int> edge[150000];
int set_number[150000];

vector<bool> visited(150000,false);

void bfs(int start,int num, int dist){
	queue<int> q;
	q.push(start);
	visited[start] = true;
	dist = 0;
	while(!q.empty()){
		int qsize = q.size();
		for(int i = 0;i<qsize;i++){
			int cur = q.front();
			if(dist%2==0) set_number[cur] = num;
			q.pop();
			for(int next : edge[cur]){
				if(!visited[next]){
					q.push(next);
					visited[next] = true;
				}
			}
		}
		dist++;
	}
}

int main(){
	int n,m; scanf("%d %d",&n,&m);
	for(int i = 0;i<m;i++){
		int x,y; scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	for(int j = 1;j<=3;j++){
		bool ch = false;
		for(int i = 1;i<=n;i++){
			if(!visited[i]&&set_number[i]==0) {
				bfs(i,j,0);
				ch = true;
			}
		}
		if(!ch) {printf("-1"); return 0;}
		visited = vector<bool>(150000,false);
	}
	int v[3]={0};
	for(int i = 1;i<=n;i++){
		if(set_number[i]==0){printf("-1");}
		else{
			v[set_number[i-1]]++;
		}
	}
	if(m!=v[0]*v[1]+v[1]*v[2]+v[2]*v[1]){ printf("-1"); return 0;}
	for(int i = 1;i<=n;i++){
		printf("%d ",set_number[i]);
	}

	return 0;
}


/*
include
push_back
pop_back
vector
resize
clear
namespace
algorithm
stdio.h
fuctional
queue
priority_queue
greater
iostream
*/
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
vector<int> edge[150000];
int set_number[150000];

vector<bool> visited(150000,false);

void bfs(int start,int num, int dist){
	queue<int> q;
	q.push(start);
	visited[start] = true;
	dist = 0;
	while(!q.empty()){
		int qsize = q.size();
		for(int i = 0;i<qsize;i++){
			int cur = q.front();
			if(dist%2==0) set_number[cur] = num;
			q.pop();
			for(int next : edge[cur]){
				if(!visited[next]){
					q.push(next);
					visited[next] = true;
				}
			}
		}
		dist++;
	}
}

int main(){
	int n,m; scanf("%d %d",&n,&m);
	for(int i = 0;i<m;i++){
		int x,y; scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	for(int j = 1;j<=3;j++){
		for(int i = 1;i<=n;i++){
			if(!visited[i]&&set_number[i]==0) bfs(i,j,0);
		}
		visited = vector<bool>(150000,false);
	}
	for(int i = 1;i<=n;i++){
		if(set_number[i]==0){printf("-1"); return 0;}
	}
	for(int i = 1;i<=n;i++){
		printf("%d ",set_number[i]);
	}

	return 0;
}


#include <bits/stdc++.h>
#define N 100005
#define task "t"
#define mu(x) x*x

using namespace std;
using ll=long long;
using pii=pair<int,int>;
using piii=pair<int,pii>;
const int inf=1e9+7;

int n,m,mark[N],col[N],dem[N];
vector<int> ke[N];

void dfs(int u)
{
    mark[u]=1;
    for (int v:ke[u])
        if (!mark[v]) dfs(v);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie();cout.tie();
    #ifndef ONLINE_JUDGE
    freopen(task".inp","r",stdin);
    freopen(task".out","w",stdout);
    #endif // ONLINE_JUDGE
    cin>>n>>m;
    for (int i=1;i<=m;i++) {
        int u,v;
        cin>>u>>v;
        ke[u].push_back(v);
        ke[v].push_back(u);
    }
    dfs(1);
    for (int i=1;i<=n;i++)
    if (!mark[i]) {
        cout<<-1;
        return 0;
    }
    for (int i=1;i<=n;i++) mark[i]=0;
    int cnt=1;
    for (int u=1;u<=n;u++)
        if (mark[u]!=cnt) {
            col[u]=1;
            for (int v:ke[u]) mark[v]=cnt;
        }
    cnt++;
    for (int u=1;u<=n;u++)
        if (mark[u]==1 && !col[u]) {
            col[u]=2;
            for (int v:ke[u]) mark[v]=cnt;
        }
    cnt++;
    //for (int i=1;i<=n;i++) cout<<col[i]<<" ";
     for (int u=1;u<=n;u++)
        if ((mark[u]==2 || mark[u]==1)  && !col[u]) {
            col[u]=3;
            for (int v:ke[u]) mark[v]=cnt;

    }
    for (int i=1;i<=n;i++)
    if (!col[i]) {
        cout<<-1;
        return 0;
    }
    else dem[col[i]]++;
    if (!dem[1] || !dem[2] || !dem[3]) {
        cout<<-1;
        return 0;
    }
    for (int i=1;i<=n;i++) cout<<col[i]<<" ";
    return 0;
}


#include <bits/stdc++.h>
#define N 100005
#define task "t"
#define mu(x) x*x

using namespace std;
using ll=long long;
using pii=pair<int,int>;
using piii=pair<int,pii>;
const int inf=1e9+7;

int n,m,mark[N],col[N],dem[N];
vector<int> ke[N];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie();cout.tie();
    #ifndef ONLINE_JUDGE
    freopen(task".inp","r",stdin);
    freopen(task".out","w",stdout);
    #endif // ONLINE_JUDGE
    cin>>n>>m;
    for (int i=1;i<=m;i++) {
        int u,v;
        cin>>u>>v;
        ke[u].push_back(v);
        ke[v].push_back(u);
    }
    int cnt=1;
    for (int u=1;u<=n;u++)
        if (mark[u]!=cnt) {
            col[u]=1;
            for (int v:ke[u]) mark[v]=cnt;
        }
    cnt++;
    for (int u=1;u<=n;u++)
        if (mark[u]!=cnt && !col[u]) {
            col[u]=2;
            for (int v:ke[u]) mark[v]=cnt;
        }
    cnt++;
    //for (int i=1;i<=n;i++) cout<<col[i]<<" ";
     for (int u=1;u<=n;u++)
        if (mark[u]!=cnt && !col[u]) {
            col[u]=3;
            for (int v:ke[u]) mark[v]=cnt;

    }
    for (int i=1;i<=n;i++)
    if (!col[i]) {
        cout<<-1;
        return 0;
    }
    else dem[col[i]]++;
    if (!col[1] || !col[2] || !col[3]) {
        cout<<-1;
        return 0;
    }
    for (int i=1;i<=n;i++) cout<<col[i]<<" ";
    return 0;
}


#include <bits/stdc++.h>
#define N 100005
#define task "t"
#define mu(x) x*x

using namespace std;
using ll=long long;
using pii=pair<int,int>;
using piii=pair<int,pii>;
const int inf=1e9+7;

int n,m,mark[N],col[N],dem[N];
vector<int> ke[N];

void dfs(int u)
{
    mark[u]=1;
    for (int v:ke[u])
        if (!mark[v]) dfs(v);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie();cout.tie();
    #ifndef ONLINE_JUDGE
    freopen(task".inp","r",stdin);
    freopen(task".out","w",stdout);
    #endif // ONLINE_JUDGE
    cin>>n>>m;
    for (int i=1;i<=m;i++) {
        int u,v;
        cin>>u>>v;
        ke[u].push_back(v);
        ke[v].push_back(u);
    }
    dfs(1);
    for (int i=1;i<=n;i++)
    if (!mark[i]) {
        cout<<-1;
        return 0;
    }
    for (int i=1;i<=n;i++) mark[i]=0;
    int cnt=1;
    for (int u=1;u<=n;u++)
        if (mark[u]!=cnt) {
            col[u]=1;
            for (int v:ke[u]) mark[v]=cnt;
        }
    cnt++;
    for (int u=1;u<=n;u++)
        if (mark[u]==1 && !col[u]) {
            col[u]=2;
            for (int v:ke[u]) mark[v]=cnt;
        }
    cnt++;
    //for (int i=1;i<=n;i++) cout<<col[i]<<" ";
     for (int u=1;u<=n;u++)
        if ((mark[u]==2)  && !col[u]) {
            col[u]=3;
            for (int v:ke[u]) {
                mark[v]=cnt;
            }
        }
    for (int i=1;i<=n;i++)
    if (!col[i]) {
        cout<<-1;
        return 0;
    }
    else dem[col[i]]++;
     for (int u=1;u<=n;u++){
        if (!dem[1] || !dem[2] || !dem[3]) {
            cout<<-1;
            return 0;
        }
    for (int v:ke[u])
        if (col[u]==col[v]) {
            cout<<-1;
            return 0;
        }
        else {
            if (ke[u].size()!=n-dem[col[u]]) {
                cout<<-1;
                return 0;
            }
        }
     }
    for (int i=1;i<=n;i++) cout<<col[i]<<" ";
    return 0;
}