#pragma warning (disable : 4996)
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 2e5 + 10;
struct node {
int to, nxt;
}edge[maxn];
int head[maxn], col[maxn];
int ecnt = 0;
void addedge(int u, int v) {//邻接表比vector快
edge[ecnt].to = v;
edge[ecnt].nxt = head[u];
head[u] = ecnt++;
}
bool bfs(int s) {//染色 判断二分图
queue<int> q;
col[s] = 1;
q.push(s);
while (!q.empty()) {
s = q.front();
q.pop();
for (int i = head[s]; i + 1; i = edge[i].nxt) {
if (col[edge[i].to] == 0)
col[edge[i].to] = -col[s], q.push(edge[i].to);
if (col[edge[i].to] == col[s])
return false;
}
}
return true;
}
vector<int> ans1, ans2;
int main()
{
int n, m;
scanf("%d%d", &n, &m);
ans1.clear(); ans2.clear();
ecnt = 0;
memset(head, -1, sizeof head);
for (int i = 0; i < m; ++i) {
int a, b;
scanf("%d%d", &a, &b);
addedge(a, b);
addedge(b, a);//必须加双边,为什么?
}
memset(col, 0, sizeof(col));
bool flag = true;
for (int i = 1; i <= n; ++i) {//要历遍所有有边的点全部染色
if (head[i] == -1) continue;
if (col[i] == 0) flag = bfs(i);
if (!flag) break;
}
if (!flag) {
puts("-1");
}
else {
for (int i = 1; i <= n; ++i) {
if (col[i] == -1) {
ans1.push_back(i);
}
else if (col[i] == 1) {
ans2.push_back(i);
}
}
int len = ans1.size();
printf("%d\n", len);
for (int i = 0; i < len; ++i) {
if (i) printf(" ");
printf("%d", ans1[i]);
}
len = ans2.size();
printf("\n%d\n", len);
for (int i = 0; i < len; ++i) {
if (i) printf(" ");
printf("%d", ans2[i]);
}
puts("");
}
return 0;
}