/**
Euler kor (infoarena ciclueuler)
Egy graf euler kor, ha minden csomopontjanak a fokszama paros. Elindulok egy random pontbol,
megyek a kovetkezo csomopontba, azon az elen, amelziken eljutottam oda, mar nem jarok tobbszor.
Ahogy belepek egy csomopontba beteszem egy verembe. Ha egy csomopontbol mar nincs hova menjek,
akkor azt beteszem a megoldas vektorom ELEJERE, es visszalepek.
Az eleket (egyik vege A, masik vege B) ugy tarolom, hogy az A eleinel, nem csak azt tarolom el,
hogy a B-be megy ut, hanem azt is, hogy az A a B elei kozott hol van. Igy ha vegigmegyek az A-B
elen, akkor be tudom jelolni az A-nal es B-nel is, hogy azon vegigmentem.
**/
#include <fstream>
#include <vector>
#include <deque>
#include <stack>
using namespace std;
ifstream cin("ciclueuler.in");
ofstream cout("ciclueuler.out");
int n,m,i,a,b;
struct el
{
int p,h; ///p-az el masik vege, h-az adott csp helye a p elei kozott
bool l; ///l-vegig mentem-e mar azon az elen
};
struct adat
{
int m; ///m-mennyi utjat nezetm mar meg
int t; ///t-hol tratok az e vektorban
vector<el>e; ///hova vezet ut az adott csp-bol
};
vector<adat>x;
deque<int>megold;
//stack<int>s;
void euler(int csp)
{
int i;
el k;
//s.push(csp);
for(i=x[csp].t;i<x[csp].e.size();++i) ///vegigmegyek az adott csp elein, onnantol kezdve, ahol meg nem jartam
if(!x[csp].e[i].l) ///ha az adott elen meg nem jartam
{
k=x[csp].e[i]; ///az el tulajdonsagai
x[csp].t=i; ///beallitom, hogy a csp eleit az i. elig megneztem
x[csp].e[i].l=1; ///beallitom, hogy atmentem az elen
x[k.p].e[k.h].l=1; ///beallitom, hogy atmentem az elen
x[csp].m++; ///novelem azt, hogy hany elen jartam mar
x[k.p].m++; ///novelem azt, hogy hany elen jartam mar
euler(k.p);
}
else
{
if(i<x[csp].t) i=x[csp].t; ///az x[csp].t-ig lattam az eleket, ezert az i mehet onnan
if(x[csp].m==x[csp].e.size()) break; ///leallitom az elek nezeset, ha mer mindet lattam
}
megold.push_front(csp); ///mar nincs hova menjek az adott csp-bol, ezert beteszem a megoldasok elejere
//s.pop();
}
int main()
{
cin>>n>>m;
x.resize(n+1);
for(i=1;i<=m;++i)
{
cin>>a>>b;
if(a!=b)
{
x[a].e.push_back({b,x[b].e.size(),0}); ///az "a" helye a "b"-ben a "b" elvektoranak a merete
x[b].e.push_back({a,x[a].e.size()-1,0}); /**az "b" helye a "a"-ban a "a" elvektoranak a merete -1,
mert az "a" elei koze mar be van teve az adott "a-b" el, es ez az utolso, ami be van teve**/
}
else
{
x[a].e.push_back({b,x[b].e.size()+1,0}); /**az "a" meg a "b" megegyezik, szoval az "a" helye a
"b"-ben az adott csp elvektoranak merete+1 lesz, mert a merete az onmaga lenne**/
x[b].e.push_back({a,x[a].e.size()-1,0}); /**a "b"helye pedig az elvektor merete-1, mert a merete
az onmaga lenne**/
}
}
bool ok=true;
for(i=1;i<=n;++i) ///itt nezem meg, hogy a csomopontok paros fokszamuak-e
if(x[i].e.size()%2)
{
ok=false;
break;
}
/* else{
for(auto f : x[i].e) cout<<f.p<<" "<<f.h<<" ";
cout<<"\n";
}*/
if(!ok) cout<<"-1\n";
else
{
euler(1); ///ebben toltom fel a megoldas-vektort
megold.pop_back();
for(auto e : megold) cout<<e<<" ";
}
return 0;
}