#include <bits/stdc++.h>
using namespace std;
const long long LL_MIN = std::numeric_limits<long long>::min();
const long long LL_MAX = std::numeric_limits<long long>::max();
template <class T, class R>
ostream& operator<<(ostream& o, const pair<T, R>& p) {
  o << "(" << p.first << ", " << p.second << ")";
  return o;
}
template <class T, class R>
istream& operator>>(istream& o, pair<T, R>& p) {
  o >> p.first >> p.second;
  return o;
}
template <class T>
string to_string(const T& x) {
  stringstream o;
  o << "[";
  for (__typeof((x).begin()) i = ((x).begin()); i != (x).end(); ++i) {
    o << ((i != x.begin()) ? ", " : "") << *i;
  }
  o << "]";
  string r;
  getline(o, r);
  return r;
}
template <class T>
T get_next(string& s) {
  stringstream ss(s);
  T r;
  ss >> r;
  getline(ss, s);
  return r;
}
template <class T>
void split_string(const string& s, vector<T>& o) {
  stringstream ss(s);
  o.clear();
  T x;
  while (ss >> x) {
    o.push_back(x);
  }
}
void trim(string& s) {
  stringstream ss;
  ss << s;
  s.clear();
  ss >> s;
}
template <class T, class R>
ostream& operator<<(ostream& o, const map<T, R>& x) {
  o << to_string(x);
  return o;
}
template <class T>
ostream& operator<<(ostream& o, const vector<T>& x) {
  o << to_string(x);
  return o;
};
template <class T>
ostream& operator<<(ostream& o, const set<T>& x) {
  o << to_string(x);
  return o;
};
template <class T>
ostream& operator<<(ostream& o, const deque<T>& x) {
  o << to_string(x);
  return o;
};
const long long INFL = 1000000000LL * 1000000000LL + 1000LL;
const int INF = 1000000000 + 1000;
const long long MOD = 1000000009;
struct Tri {
  int a, b, c;
  Tri(int a, int b, int c) : a(a), b(b), c(c) {}
};
queue<Tri> q;
int n, m, a, b;
vector<int> graf[510];
bool sol[510][510][2];
int dist[510][510][2], f[510][510][2];
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d %d", &a, &b);
    graf[a].push_back(b);
    graf[b].push_back(a);
  }
  dist[1][n][0] = 0;
  q.push(Tri(1, n, 0));
  sol[1][n][0] = true;
  while (q.size()) {
    Tri t = q.front();
    q.pop();
    if (t.c == 0) {
      for (__typeof((graf[t.a]).begin()) a = ((graf[t.a]).begin());
           a != (graf[t.a]).end(); ++a) {
        if (!sol[*a][t.b][1]) {
          sol[*a][t.b][1] = true;
          dist[*a][t.b][1] = dist[t.a][t.b][0] + 1;
          q.push(Tri(*a, t.b, 1));
          f[*a][t.b][1] = t.a;
        }
      }
    } else {
      for (__typeof((graf[t.b]).begin()) b = ((graf[t.b]).begin());
           b != (graf[t.b]).end(); ++b) {
        if (!sol[t.a][*b][0] && t.a != *b) {
          sol[t.a][*b][0] = true;
          dist[t.a][*b][0] = dist[t.a][t.b][1];
          q.push(Tri(t.a, *b, 0));
          f[t.a][*b][0] = t.b;
        }
      }
    }
  }
  if (!sol[n][1][0]) {
    printf("-1\n");
  } else {
    printf("%d\n", dist[n][1][0]);
    a = n;
    b = 1;
    vector<int> ra, rb;
    ra.push_back(n);
    rb.push_back(1);
    while (make_pair(a, b) != make_pair(1, n)) {
      rb.push_back(f[a][b][0]);
      b = f[a][b][0];
      ra.push_back(f[a][b][1]);
      a = f[a][b][1];
    }
    for (__typeof((rb).begin()) it = ((rb).begin()); it != (rb).end(); ++it) {
      printf("%d ", *it);
    }
    printf("\n");
    for (__typeof((ra).begin()) it = ((ra).begin()); it != (ra).end(); ++it) {
      printf("%d ", *it);
    }
    printf("\n");
  }
}
