#include <bits/stdc++.h>   std::mt19937 rng(       (int)std::chrono::steady_clock::now().time_since_epoch().count());   using namespace std;   long long mod = (998244353LL);   inline long long Mod(long long a, long long b) { return (a % b); }   inline long long poww(long long a, long long b) {     long long res = 1;     while (b > 0) {       if (b & 1) res = (res * a) % mod;       a = (a * a) % mod;       b >>= 1;     }     return res;   }   long long gcd(long long a, long long b) {     while (b) {       a %= b, swap(a, b);     }     return a;   }   void read(vector<int> &w, int n) {     w.resize(n);     for (int i = 0; i < n; i++) cin >> w[i];   }   void print(vector<int> &w) {     for (int i = 0; i < (int)(w).size(); i++) {       if (i == (int)(w).size() - 1)         cout << w[i] <<   n ;       else         cout << w[i] <<    ;     }   }   int prodmod(vector<int> w);   int summod(vector<int> w);   int n, m, q, k, v[200010];   string second;   pair<int, int> w[200010];   vector<pair<int, int>> grafo[200010];   long long dist[200010][20][2];   void solve() {     priority_queue<vector<long long>, vector<vector<long long>>,                    greater<vector<long long>>>         pq;     pq.push({0, 1, 0, 0});     dist[1][0][0] = 0;     while (!pq.empty()) {       auto curr = pq.top();       pq.pop();       long long d = curr[0], x = curr[1], q = curr[2], flag = curr[3];       if (d > dist[x][q][flag]) continue;       for (auto v : grafo[x]) {         int T = (v.second != flag);         int qq = q + T, flag2 = v.second;         if (qq < 20 and             dist[v.first][qq][flag2] >                 dist[x][q][flag] + 1 + (1LL * T) * (1LL << (1LL * q))) {           dist[v.first][qq][flag2] =               dist[x][q][flag] + 1 + (1LL * T) * (1LL << (1LL * q));           pq.push({dist[v.first][qq][flag2], v.first, qq, flag2});         }       }     }   }   pair<int, int> dist2[200010][2];   const int inf = 0x3f3f3f3f;   int32_t main() {     memset(dist, inf, sizeof dist);     ios::sync_with_stdio(false);     cin.tie(0);     cin >> n >> m;     for (int i = 1, a, b; i <= m; i++) {       cin >> a >> b;       grafo[a].push_back({b, 0});       grafo[b].push_back({a, 1});     }     solve();     long long ans = inf;     for (int i = 0; i < 20; i++) ans = min({ans, dist[n][i][0], dist[n][i][1]});     if (ans != inf)       cout << ans % mod <<   n , exit(0);     else {       for (int i = 0; i < 200010; i++) dist2[i][0] = dist2[i][1] = {inf, inf};       priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> pq;       pq.push({0, 0, 1, 0});       dist2[1][0] = {0, 0};       while (!pq.empty()) {         auto curr = pq.top();         pq.pop();         int inv = curr[0], d = curr[1], x = curr[2], flag = curr[3];         if (pair<int, int>(inv, d) > dist2[x][flag]) continue;         for (auto v : grafo[x]) {           pair<int, int> novo = {inv + (v.second != flag), d + 1};           if (novo < dist2[v.first][v.second]) {             dist2[v.first][v.second] = novo;             pq.push({inv + (v.second != flag), d + 1, v.first, v.second});           }         }       }       pair<int, int> curr = min(dist2[n][0], dist2[n][1]);       int ans = curr.second, pot = 1LL;       for (int i = 0; i < curr.first; i++) {         ans += pot;         ans %= mod;         pot *= 2LL;         pot %= mod;       }       cout << ans % mod <<   n ;     }   }   int summod(vector<int> w) {     int curr = 0;     for (int i = 0; i < (int)(w).size(); i++) {       curr = (curr + w[i]) % mod;       if (curr < 0) curr += mod;     }     return curr;   }   int prodmod(vector<int> w) {     int curr = 1;     for (int i = 0; i < (int)(w).size(); i++) {       if (w[i] >= mod) w[i] %= mod;       curr = (curr * w[i]) % mod;       if (curr < 0) curr += mod;     }     return curr;   }