/**
* created by : Mostafa Wael (Phoenix)
* problem name : Number of Shortest paths
*/
#include <bits/stdc++.h>
using namespace std;
void make_edge(int &u,int &v,vector<vector<int>>&graph){
graph[u].push_back(v);
graph[v].push_back(u);
}
const int mod=1e9+7;
int bfs(int source,int n,vector<vector<int>>& graph){
vector<int>distance(n,2e9),counter(n,0);
vector<bool>isVisited(n);
queue<int>q;
distance[source]=0;
counter[source]=1;
q.push(source);
while(!q.empty()){
int u=q.front(); q.pop();
if(isVisited[u]) continue;
isVisited[u]=true;
for(auto v:graph[u])
if(distance[u]+1<distance[v]){
distance[v]=distance[u]+1;
counter[v]=counter[u];
q.push(v);
}else if(distance[u]+1==distance[v]){
// if i can visit node with the same distance then number of ways should be number of node v and number of node u
counter[v]=(counter[v]+counter[u])%mod;
q.push(v);
}
}
return counter[n-1];
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
/**
* using normal bfs but we can use array to keep track number of ways
*/
int n,m; cin>>n>>m;
vector<vector<int>>graph(n);
while(m--){
int u,v;
cin>>u>>v;
make_edge(--u,--v,graph);
}
cout<<bfs(0,n,graph);
return 0;
}
LyoqCiAqIGNyZWF0ZWQgYnkgOiBNb3N0YWZhIFdhZWwgKFBob2VuaXgpCiAqIHByb2JsZW0gbmFtZSA6IE51bWJlciBvZiBTaG9ydGVzdCBwYXRocwogKi8KI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnZvaWQgbWFrZV9lZGdlKGludCAmdSxpbnQgJnYsdmVjdG9yPHZlY3RvcjxpbnQ+PiZncmFwaCl7CiAgICBncmFwaFt1XS5wdXNoX2JhY2sodik7CiAgICBncmFwaFt2XS5wdXNoX2JhY2sodSk7Cn0KY29uc3QgaW50IG1vZD0xZTkrNzsKaW50IGJmcyhpbnQgc291cmNlLGludCBuLHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIGdyYXBoKXsKICAgIHZlY3RvcjxpbnQ+ZGlzdGFuY2UobiwyZTkpLGNvdW50ZXIobiwwKTsKICAgIHZlY3Rvcjxib29sPmlzVmlzaXRlZChuKTsKICAgIHF1ZXVlPGludD5xOwogICAgZGlzdGFuY2Vbc291cmNlXT0wOwogICAgY291bnRlcltzb3VyY2VdPTE7CiAgICBxLnB1c2goc291cmNlKTsKICAgIHdoaWxlKCFxLmVtcHR5KCkpewogICAgICAgIGludCB1PXEuZnJvbnQoKTsgcS5wb3AoKTsKICAgICAgICBpZihpc1Zpc2l0ZWRbdV0pIGNvbnRpbnVlOwogICAgICAgIGlzVmlzaXRlZFt1XT10cnVlOwogICAgICAgIGZvcihhdXRvIHY6Z3JhcGhbdV0pCiAgICAgICAgCiAgICAgICAgaWYoZGlzdGFuY2VbdV0rMTxkaXN0YW5jZVt2XSl7CiAgICAgICAgICAgIGRpc3RhbmNlW3ZdPWRpc3RhbmNlW3VdKzE7CiAgICAgICAgICAgIGNvdW50ZXJbdl09Y291bnRlclt1XTsKICAgICAgICAgICAgcS5wdXNoKHYpOwogICAgICAgIH1lbHNlIGlmKGRpc3RhbmNlW3VdKzE9PWRpc3RhbmNlW3ZdKXsgCiAgICAgICAgICAgIC8vIGlmIGkgY2FuIHZpc2l0IG5vZGUgd2l0aCB0aGUgc2FtZSBkaXN0YW5jZSB0aGVuIG51bWJlciBvZiB3YXlzIHNob3VsZCBiZSBudW1iZXIgb2Ygbm9kZSB2IGFuZCBudW1iZXIgb2Ygbm9kZSB1CiAgICAgICAgICAgIGNvdW50ZXJbdl09KGNvdW50ZXJbdl0rY291bnRlclt1XSklbW9kOwogICAgICAgICAgICBxLnB1c2godik7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGNvdW50ZXJbbi0xXTsKfQppbnQgbWFpbigpCnsKICAgIGlvczo6c3luY193aXRoX3N0ZGlvKDApOwogICAgY2luLnRpZSgwKTsKICAgIGNvdXQudGllKDApOwogICAgLyoqCiAgICAgKiAgdXNpbmcgbm9ybWFsIGJmcyBidXQgd2UgY2FuIHVzZSBhcnJheSB0byBrZWVwIHRyYWNrIG51bWJlciBvZiB3YXlzIAogICAgICovCiAgICBpbnQgbixtOyBjaW4+Pm4+Pm07CiAgICB2ZWN0b3I8dmVjdG9yPGludD4+Z3JhcGgobik7CiAgICB3aGlsZShtLS0pewogICAgICAgIGludCB1LHY7CiAgICAgICAgY2luPj51Pj52OwogICAgICAgIG1ha2VfZWRnZSgtLXUsLS12LGdyYXBoKTsKICAgIH0KICAgIGNvdXQ8PGJmcygwLG4sZ3JhcGgpOwogICAgcmV0dXJuIDA7Cn0K