//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  if(A[Left].X!=X||A[Left].Y!=Y)
    cout<<"Wrong"<<' '<<X<<' '<<Y<<' '<<A[Left].X<<' '<<A[Left].Y<<' '<<A[Left-1].X<<' '<<A[Left-1].Y<<endl;
  if(A[A[Left].Next].X!=X||A[A[Left].Next].Y!=Y)cout<<"Out"<<endl;
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  bool OK=(X[0]==1370)&&(M==6000);
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
          Color[i]?Count_1++:Count_0++;
	  if(N==5999)
	  cout<<"Count_0="<<Count_0<<"Count_1="<<Count_1<<endl;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  bool OK=(X[0]==1370)&&(M==6000);
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
			  if(OK&&(List[i]<1||List[i]>M))cout<<"BAD"<<endl;
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
			  if(OK&&(List[i]<1||List[i]>M))cout<<"BAD"<<endl;
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
		  if(Color[i])
		    Count_1++;
		  else
		    Count_0++;
	  for(int i=0;i<N;i++)
	    if(M==5999&&Color[i]!=0&&Color[i]!=1)
		  cout<<"BAD!!!!"<<' '<<i<<endl;
	  if(M==5999)
	  cout<<"N="<<N<<" Count_0="<<Count_0<<" Count_1="<<Count_1<<endl;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
          Color[i]?Count_1++:Count_0++;
	  if(M==5999)
	  cout<<"Count_0="<<Count_0<<"Count_1="<<Count_1<<endl;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
	  if(X[i]<0||Y[i]<0||X[i]>=N||Y[i]>=N)cout<<"BAD!!!"<<X[i]<<' '<<Y[i]<<endl;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
	  int Sum=0,All=0;
	  for(int i=0;i<N;i++)Sum+=Degree[i];
	  if(Sum&1)cout<<"BAD"<<endl;
      for(int i=0;i<N;i++)
        if(Degree[i]&1){All++;
		  if(Color[i])
		    Count_1++;
		  else
		    Count_0++;}
	  if(M==5999)
	  {cout<<"N="<<N<<" Count_0="<<Count_0<<" Count_1="<<Count_1<<endl;
	  cout<<"Sum="<<Sum<<" All="<<All<<endl;}
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  if(A[Left].X!=X||A[Left].Y!=Y)cout<<"Wrong"<<endl;
  if(A[A[Left].Next].X!=X||A[A[Left].Next].Y!=Y)cout<<"Out"<<endl;
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  bool OK=(X[0]==1370)&&(M==6000);
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
        List.push_back(G[V][i].Number+1);
      }
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  int M=Get();
  static int X[10001],Y[10001],K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  if(A[A[Left].Next].X!=X||A[A[Left].Next].Y!=Y)cout<<"Out"<<endl;
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  bool OK=(X[0]==1370)&&(M==6000);
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
        List.push_back(G[V][i].Number+1);
      }
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  int M=Get();
  static int X[10001],Y[10001],K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp);
          for(int i=Temp;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      int a=K[X[i]]-1,b=K[Y[i]]-1;
      Degree[a]++;Degree[b]++;
      G[a].push_back((Edge){b,i+1});
      G[b].push_back((Edge){a,i+1});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
          Color[i]?Count_1++:Count_0++;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M-1)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d\n",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d\n",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
	  if(X[i]<0||Y[i]<0||X[i]>=N||Y[i]>=N)cout<<"BAD!!!"<<X[i]<<' '<<Y[i]<<endl;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
		  if(Color[i])
		    Count_1++;
		  else
		    Count_0++;
	  for(int i=0;i<N;i++)
	    if(M==5999&&Color[i]!=0&&Color[i]!=1)
		  cout<<"BAD!!!!"<<' '<<i<<endl;
	  if(M==5999)
	  cout<<"N="<<N<<" Count_0="<<Count_0<<" Count_1="<<Count_1<<endl;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
          Color[i]?(Count_1++):(Count_0++);
	  if(M==5999)
	  cout<<"N="<<N<<"Count_0="<<Count_0<<"Count_1="<<Count_1<<endl;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
          Color[i]?Count_1++:Count_0++;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
	  if(M==5999)cout<<"Odd="<<Odd<<endl;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
        List.push_back(G[V][i].Number+1);
      }
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  int M=Get();
  static int X[10001],Y[10001],K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
          Color[i]?Count_1++:Count_0++;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  bool OK=(X[0]==1370)&&(M==6000);
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
		  memset(Used,0,sizeof(Used));
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);Used[List[i]-1]=true;
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);Used[List[i]-1]=true;
              putchar((i+1==List.size())?'\n':' ');
            }
		  for(int i=0;i<M;i++)
		    if(!Used[i])cout<<"BAD"<<endl;
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  bool OK=(X[0]==1370)&&(M==6000);
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
		  if(OK)cout<<S0<<' '<<S1<<endl;
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i+1});
      G[Y[i]].push_back((Edge){X[i],i+1});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
          Color[i]?Count_1++:Count_0++;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M-1)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d\n",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d\n",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
          Color[i]?Count_1++:Count_0++;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  if(A[Left].X!=X||A[Left].Y!=Y)
    cout<<"Wrong"<<' '<<X<<' '<<Y<<' '<<A[Left].X<<' '<<A[Left].Y<<endl;
  if(A[A[Left].Next].X!=X||A[A[Left].Next].Y!=Y)cout<<"Out"<<endl;
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  bool OK=(X[0]==1370)&&(M==6000);
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  if(Used[A[A[Left].Next].Number-1])cout<<"BAD"<<endl;
  Used[A[A[Left].Next].Number-1]=true;
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  memset(Used,0,sizeof(Used));
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  bool OK=(X[0]==1370)&&(M==6000);
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      int Count_0=0,Count_1=0;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}


//program 36-E

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

using namespace std;

struct Edge
{
  int Data,Number;
};

struct Record
{
  int X,Y,Number,Next;
};

bool operator <(Record A,Record B)
{
  return (A.X==B.X)?(A.Y<B.Y):(A.X<B.X);
}

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int M;
int X[10000],Y[10000];
vector<Edge> G[10000];
bool Visited[10000],Used[10001];
int Color[10000];
vector<int> List;
Record A[10001];

void Floodfill(int V,int Number)
{
  Visited[V]=true;Color[V]=Number;
  for(int i=0;i<G[V].size();i++)
    if(!Visited[G[V][i].Data])
      Floodfill(G[V][i].Data,Number);
}

void DFS(int V)
{
  for(int i=0;i<G[V].size();i++)
    if(!Used[G[V][i].Number])
      {
        Used[G[V][i].Number]=true;
        DFS(G[V][i].Data);
      }
  List.push_back(V);
}

int Find(int X,int Y)
{
  if(X>Y)swap(X,Y);
  int Left=0,Right=M-1;
  while(Left<Right)
    {
      int Mid=(Left+Right)/2;
      if(X<A[Mid].X||(X==A[Mid].X&&Y<=A[Mid].Y))
        Right=Mid;
      else
        Left=Mid+1;
    }
  return A[A[Left].Next++].Number;
}

void Calc()
{
  for(int i=0;i<M;i++)
    {
      A[i].X=min(X[i],Y[i]);
      A[i].Y=max(X[i],Y[i]);
      A[i].Number=i+1;
    }
  sort(A,A+M);
  for(int i=0;i<M;i++)A[i].Next=i;
  vector<int> Temp;
  for(int i=1;i<List.size();i++)
    Temp.push_back(Find(List[i-1],List[i]));
  List=Temp;
}

int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  M=Get();static int K[10000];
  memset(K,0,sizeof(K));
  for(int i=0;i<M;i++)
    K[X[i]=Get()-1]=K[Y[i]=Get()-1]=1;
  for(int i=1;i<10000;i++)K[i]+=K[i-1];
  int N=K[9999];
  static int Degree[10000];
  memset(Degree,0,sizeof(Degree));
  for(int i=0;i<M;i++)
    {
      X[i]=K[X[i]]-1;Y[i]=K[Y[i]]-1;
	  if(X[i]<0||Y[i]<0||X[i]>=N||Y[i]>=N)cout<<"BAD!!!"<<X[i]<<' '<<Y[i]<<endl;
      Degree[X[i]]++;Degree[Y[i]]++;
      G[X[i]].push_back((Edge){Y[i],i});
      G[Y[i]].push_back((Edge){X[i],i});
    }
  int Total=0;
  memset(Visited,0,sizeof(Visited));
  memset(Used,0,sizeof(Used));
  for(int i=0;i<N;i++)
    if(!Visited[i])Floodfill(i,Total++);
  if(Total>2||M<2)
    printf("-1\n");
  else if(Total==2)
    {
      bool Count_0=0,Count_1=0;
	  int Sum=0;
	  for(int i=0;i<N;i++)Sum+=Degree[i];
	  if(Sum&1)cout<<"BAD"<<endl;
      for(int i=0;i<N;i++)
        if(Degree[i]&1)
		  if(Color[i])
		    Count_1++;
		  else
		    Count_0++;
	  for(int i=0;i<N;i++)
	    if(M==5999&&Color[i]!=0&&Color[i]!=1)
		  cout<<"BAD!!!!"<<' '<<i<<endl;
	  if(M==5999)
	  cout<<"N="<<N<<" Count_0="<<Count_0<<" Count_1="<<Count_1<<endl;
      if(Count_0>2||Count_1>2)
        printf("-1\n");
      else
        {
          int S0=-1,S1=-1;
          for(int i=0;S0==-1;i++)
            if(!Color[i]&&(!Count_0||(Degree[i]&1)))S0=i;
          for(int i=0;S1==-1;i++)
            if(Color[i]&&(!Count_1||(Degree[i]&1)))S1=i;
          List.clear();DFS(S0);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
          List.clear();DFS(S1);Calc();
          printf("%d\n",List.size());
          for(int i=0;i<List.size();i++)
            {
              printf("%d",List[i]);
              putchar((i+1==List.size())?'\n':' ');
            }
        }
    }
  else
    {
      int Odd=0;
      for(int i=0;i<N;i++)
        Odd+=Degree[i]&1;
      if(Odd>4)
        printf("-1\n");
      else if(Odd<=2)
        {
          int Start=0;
          while(Odd&&(~Degree[Start]&1))Start++;
          List.clear();DFS(Start);Calc();
          printf("1\n%d\n",List[0]);
          printf("%d\n",M-1);
          for(int i=1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
      else
        {
          int P=0;while(~Degree[P]&1)P++;
          int Q=P+1;while(~Degree[Q]&1)Q++;
          G[P].push_back((Edge){Q,M});
          G[Q].push_back((Edge){P,M});
          X[M]=P;Y[M]=Q;M++;
          int Start=Q+1;while(~Degree[Start]&1)Start++;
          List.clear();DFS(Start);Calc();
          int Temp=0;while(List[Temp]!=M)Temp++;
          printf("%d\n",Temp);
          for(int i=0;i<Temp;i++)
            {
              printf("%d",List[i]);
              putchar((i==Temp-1)?'\n':' ');
            }
          printf("%d\n",M-Temp-1);
          for(int i=Temp+1;i<M;i++)
            {
              printf("%d",List[i]);
              putchar((i==M-1)?'\n':' ');
            }
        }
    }
  return 0;
}