#include using namespace std; #define MOD 1000000007 #define MOD2 998244353 #define rep(i,n) for (int i = 0; i < (int)(n); i++) #define reps(i,s,n) for (int i = (int)(s); i < (int)(n); i++) #define repit(i,C) for (auto i = (C).begin(); i != (C).end(); i++) #define pr(a) cout << a #define prl(a) cout << (a) << endl #define prld(a) cout << setprecision(15)<< (a) << endl #define allrange(a) a.begin(),a.end() template struct Edge { int src, dst; T weight; Edge(int src, int dst, T weight) : src(src), dst(dst), weight(weight) { }; Edge() {}; }; template bool operator < (const Edge &e, const Edge &f) { return e.weight != f.weight ? e.weight < f.weight : // コストが低いほう優先 e.src != f.src ? e.src < f.src : e.dst < f.dst; }; template using Edges = std::vector>; using Vertexs = std::vector; template struct Graph { //directed graph Vertexs vertexs; map vindex; Edges edges; std::vector< std::vector< std::pair >> adjacent_to, adjacent_from; Graph(): vertexs(Vertexs (0)),edges(Edges(0)),vindex(), adjacent_to(std::vector>>(0)), adjacent_from(std::vector>>(0)) {}; void addv(int t){ vertexs.push_back(t); vindex[t]=vertexs.size()-1; adjacent_to.push_back(std::vector>(0)); adjacent_from.push_back(std::vector>(0)); } void adde(int s,int d,T w){ edges.push_back(Edge(s,d,w)); adjacent_to.at(vindex[s]).push_back(std::make_pair(w,d)); adjacent_from.at(vindex[s]).push_back(std::make_pair(w,d)); } }; template struct UndirectedGraph : Graph{ //undirected graph void adde(int s,int d,T w){ this.adde(s,d,w); this.adjacent_to.at(d).push_back(std::make_pair(w,s)); this.adjacent_from.at(d).push_back(std::make_pair(w,s)); } }; /* 2021/06/20 unordered_setを使って拡張可能なデータ構造。 find  所属判定 insert 元の挿入 が平均o(1)で可能。 グループの合併は再帰関数を使用 元の削除はできない */ vector graph_bfs(struct Graph& G,int s=0) { int N = G.vertexs.size(); vector out(N); vector visited(N); queue work; for(int i=0;i> N >> M; Graph G; rep(i,N) G.addv(i); rep(i,M){ int u,v; cin >> u >> v; u--;v--; G.adde(u,v,1); G.adde(v,u,1); } auto ans = graph_bfs(G,0); prl(ans[N-1]); }