#include <bits/stdc++.h>
using namespace std;
int n, m, a, b;
int Judge[100010], A[100005], B[100005];
typedef struct Node {
  struct Node* next;
  int num;
} Node;
struct {
  Node* first;
} Graph[100005];
void Init() {
  memset(Judge, 0, sizeof(Judge));
  for (int i = 1; i <= n; i++) Graph[i].first = NULL;
}
void Insert(int x, int y) {
  Node *p = new Node, *q = new Node;
  p->num = y;
  p->next = Graph[x].first;
  Graph[x].first = p;
  q->num = x;
  q->next = Graph[y].first;
  Graph[y].first = q;
}
bool Solve() {
  a = 0;
  b = 0;
  Node* p;
  bool judge = true;
  queue<int> que;
  for (int i = 1; i <= n && judge; i++) {
    que.push(i);
    while (!que.empty()) {
      int k = que.front();
      que.pop();
      if (!Judge[k]) {
        p = Graph[k].first;
        if (p) {
          A[a++] = k;
          Judge[k] = 1;
        }
        while (p) {
          B[b++] = p->num;
          Judge[p->num] = 2;
          que.push(p->num);
          p = p->next;
        }
      } else if (Judge[k] == 1) {
        p = Graph[k].first;
        while (p) {
          if (Judge[p->num] == 1)
            judge = false;
          else if (Judge[p->num] == 0) {
            Judge[p->num] = 2;
            B[b++] = p->num;
            que.push(p->num);
          }
          p = p->next;
        }
      } else {
        p = Graph[k].first;
        while (p) {
          if (Judge[p->num] == 2)
            judge = false;
          else if (Judge[p->num] == 0) {
            Judge[p->num] = 1;
            A[a++] = p->num;
            que.push(p->num);
          }
          p = p->next;
        }
      }
    }
  }
  return judge;
}
int main() {
  int x, y;
  scanf("%d%d", &n, &m);
  Init();
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &x, &y);
    Insert(x, y);
  }
  bool key = Solve();
  if (key) {
    printf("%d\n", a);
    for (int i = 0; i < a; i++) printf("%d ", A[i]);
    printf("\n%d\n", b);
    for (int i = 0; i < b; i++) printf("%d ", B[i]);
    printf("\n");
  } else
    printf("-1\n");
  return 0;
}
