You are given $$$n$$$ pairwise non-collinear two-dimensional vectors. You can make shapes in the two-dimensional plane with these vectors in the following fashion: Start at the origin $$$(0, 0)$$$. Choose a vector and add the segment of the vector to the current point. For example, if your current point is at $$$(x, y)$$$ and you choose the vector $$$(u, v)$$$, draw a segment from your current point to the point at $$$(x + u, y + v)$$$ and set your current point to $$$(x + u, y + v)$$$. Repeat step 2 until you reach the origin again.You can reuse a vector as many times as you want.Count the number of different, non-degenerate (with an area greater than $$$0$$$) and convex shapes made from applying the steps, such that the shape can be contained within a $$$m \times m$$$ square, and the vectors building the shape are in counter-clockwise fashion. Since this number can be too large, you should calculate it by modulo $$$998244353$$$.Two shapes are considered the same if there exists some parallel translation of the first shape to another.A shape can be contained within a $$$m \times m$$$ square if there exists some parallel translation of this shape so that every point $$$(u, v)$$$ inside or on the border of the shape satisfies $$$0 \leq u, v \leq m$$$.

The first line contains two integers $$$n$$$ and $$$m$$$  — the number of vectors and the size of the square ($$$1 \leq n \leq 5$$$, $$$1 \leq m \leq 10^9$$$). Each of the next $$$n$$$ lines contains two integers $$$x_i$$$ and $$$y_i$$$  — the $$$x$$$-coordinate and $$$y$$$-coordinate of the $$$i$$$-th vector ($$$|x_i|, |y_i| \leq 4$$$, $$$(x_i, y_i) \neq (0, 0)$$$). It is guaranteed, that no two vectors are parallel, so for any two indices $$$i$$$ and $$$j$$$ such that $$$1 \leq i < j \leq n$$$, there is no real value $$$k$$$ such that $$$x_i \cdot k = x_j$$$ and $$$y_i \cdot k = y_j$$$.

Output a single integer  — the number of satisfiable shapes by modulo $$$998244353$$$.

NoteThe shapes for the first sample are:  The only shape for the second sample is:  The only shape for the fourth sample is:

    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #pragma GCC optimize("unroll-loops")
    #include <bits/stdc++.h>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> P;
    typedef pair<int,P> P1;
    typedef pair<P,P> P2;
    #define pu push
    #define pb push_back
    #define mp make_pair
    #define eps 1e-7
    #define INF 1000000000
    #define fi first
    #define sc second
    #define rep(i,x) for(int i=0;i<x;i++)
    #define repn(i,x) for(int i=1;i<=x;i++)
    #define SORT(x) sort(x.begin(),x.end())
    #define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
    #define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
    #define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
    template<class T>
    void dmp(T a){
    	rep(i,a.size()) cout << a[i] << " ";
    	cout << endl;
    }
    template<class T>
    bool chmax(T&a, T b){
    	if(a < b){
    		a = b;
    		return 1;
    	}
    	return 0;
    }
    template<class T>
    bool chmin(T&a, T b){
    	if(a > b){
    		a = b;
    		return 1;
    	}
    	return 0;
    }
    const ll mod = 998244353;
    template<class T>
    void add(T&a,T b){
    	a += b;
    	if(a >= mod) a-= mod;
    }
    int n,m;
    int x[5],y[5];
    int dp[32][21][21][21][21][2][2];
    vector<int>v[4];
    int sum[4];
    int vv[2][5];
    int main(){
    	cin >> n >> m;
    	rep(i,n){
    		int a,b; cin >> a >> b;
    		if(a > 0) v[0].pb(a);
    		else if(a < 0) v[1].pb(-a);

    		if(b > 0) v[2].pb(b);
    		else if(b < 0) v[3].pb(-b);
    		vv[0][i] = a;
    		vv[1][i] = b;
    	}
    	rep(w,4){
    		for(auto a:v[w]) sum[w] += a;
    	}
    	dp[0][0][0][0][0][0][0] = 1;
    	for(int i=0;i<31;i++){
    		int b = ((m>>i)&1);
    		rep(p,sum[0]+1)rep(q,sum[1]+1)rep(r,sum[2]+1)rep(s,sum[3]+1){
    			rep(c1,2)rep(c2,2){
    				if(dp[i][p][q][r][s][c1][c2] == 0) continue;
    				rep(mask,(1<<n)){
    					int ap = p, aq = q, ar = r, as = s;
    					rep(i,n){
    						if(((mask>>i)&1) == 0) continue;
    						if(vv[0][i] > 0) ap += vv[0][i];
    						else aq -= vv[0][i];

    						if(vv[1][i] > 0) ar += vv[1][i];
    						else as -= vv[1][i];
    					}
    					int bp = ap%2, np = ap/2;
    					int bq = aq%2, nq = aq/2;
    					int br = ar%2, nr = ar/2;
    					int bs = as%2, ns = as/2;
    					if(bp != bq || br != bs);
    					else{
    						int nc1,nc2;
    						if(b > bp) nc1 = 0;
    						else if(b == bp) nc1 = c1;
    						else nc1 = 1;
    						if(b > br) nc2 = 0;
    						else if(b == br) nc2 = c2;
    						else nc2 = 1;
    						add(dp[i+1][np][nq][nr][ns][nc1][nc2],dp[i][p][q][r][s][c1][c2]);
    					}
    				}
    			}
    		}
    	}
    	ll ans = dp[31][0][0][0][0][0][0];
    	ans += mod-1;
    	cout << (ans%mod+mod)%mod << endl;
    }

#include<bits/stdc++.h>

using namespace std;

constexpr int mod = 998244353;
int x[5], y[5];
int px[32], nx[32], py[32], ny[32];
int dp[32][20][20][20][20][2][2];
void add(int &x, const int& y)
{
    x += y;
    if(x >= mod)
        x -= mod;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < n; i += 1)
        cin >> x[i] >> y[i];
    for(int mask = 0; mask < (1 << n); mask += 1)
        for(int i = 0; i < n; i += 1)
            if((mask >> i) & 1)
            {
                (x[i] > 0 ? px : nx)[mask] += abs(x[i]);
                (y[i] > 0 ? py : ny)[mask] += abs(y[i]);
            }
    dp[0][0][0][0][0][0][0] = 1;
#define FOR(i, n) for(int i = 0; i < (n); i += 1)
    FOR(i, 30)FOR(cpx, 20)FOR(cnx, 20)FOR(cpy, 20)FOR(cny, 20)
    FOR(bx, 2)FOR(by, 2)FOR(mask, 1 << n)
    if(dp[i][cpx][cnx][cpy][cny][bx][by])
    {
        if(0)
            cout << i << " " << cpx << " " << cny << " " << cpy << " " << cny
                 << " " << bx << " " << by << " "
                 << dp[i][cpx][cnx][cpy][cny][bx][by] << endl;
        int npx = cpx + px[mask],
            nnx = cnx + nx[mask],
            npy = cpy + py[mask],
            nny = cny + ny[mask];
        if((npx ^ nnx) & 1)
            continue;
        if((npy ^ nny) & 1)
            continue;
        int cx = npx & 1, mx = (m >> i) & 1;
        int cy = npy & 1, my = (m >> i) & 1;
        add(dp[i + 1][npx >> 1][nnx >> 1][npy >> 1][nny >> 1]
            [cx != mx ? (cx > mx) : bx][cy != my ? (cy > my) : by],
            dp[i][cpx][cnx][cpy][cny][bx][by]);
    }
    cout << (dp[30][0][0][0][0][0][0] + mod - 1) % mod;
    return 0;
}

#define MST(a, b) memset(a,b,sizeof(a))
#define ALL(v) (v).begin(),(v).end()
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef pair<LL,LL> pll;
#include <ext/pb_ds/priority_queue.hpp>
#define rep(i,a,b) for(int i = (a) ; i <= (b) ; ++i)
#define per(i,a,b) for(int i = (a) ; i >= (b) ; --i)
#define fors(i,S) for(int i = (S) ; i ; i = (i-1)&(S))
#define forn(i,n) for(int i = 0 ; i < (n) ; ++i)

using namespace __gnu_pbds;
//typedef __gnu_pbds::priority_queue<pii, greater<pii>, pairing_heap_tag> heap;
//typedef heap::point_iterator iter;
typedef unsigned long long ULL;
//typedef __int128 LL128;
mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());

int system_const;
namespace fast_IO{
    const int maxbuff = 1<<17;
    char ibuff[maxbuff],obuff[maxbuff];
    inline char Getchar(){
        static char *p1=ibuff,*p2=ibuff;
        if(p1 == p2) {
            p1 = ibuff;
            p2 = ibuff+fread(ibuff,1,maxbuff,stdin);
            if(p1 == p2) return -1;
        }
        return *p1++;
    }

    int optr = 0;
    inline void Putchar(char c) {
        if(optr == maxbuff) {fwrite(obuff,1,optr,stdout);optr = 0;}
        obuff[optr++] = c;
    }

    inline void Flush() {
        fwrite(obuff,1,optr,stdout);
    }

    template<class T>
    void read_number(T &x) {
        x = 0;
        char c;int f = 0;
        for(c = Getchar() ; c != '-' && (c < '0' || c > '9') ; c = Getchar());
        if(c == '-') f = 1;
        else x = c-'0';
        for(c = Getchar() ; c >= '0' && c <= '9' ; c = Getchar()) x = x*10+c-'0';
        if(f) x = -x;
    }

    void read_string(string &s) {
        s.clear();
        char c;
        for(c = Getchar() ; c == ' ' || c == '\n' ; c = Getchar());
        s.push_back(c);
        for(c = Getchar() ; c != ' ' && c != '\n' ; c = Getchar())
            s.push_back(c);
    }

    template<class T>
    void write_number(T &x) {
        static int dec[20];int len = 0;
        if(x == 0) {Putchar('0');return ;}
        if(x < 0) {Putchar('-');x = -x;}
        while(x) {
            dec[++len] = x%10;
            x /= 10;
        }
        while(len) Putchar(dec[len--]+'0');
    }

    void write_string(const string &s) {
        for(int i = 0 ;i < s.size() ; ++i)
            Putchar(s[i]);
    }
}
void read(string &s) {
    if(system_const == 0) {
        using namespace fast_IO;
        read_string(s);
    }
    else cin >> s;
}
template<class T> void read(T &x) {
    if(system_const == 0) {
        using namespace fast_IO;
        read_number(x);
    }
    else cin >> x;
}
void write(const string &s) {
    if(system_const == 0) {
        fast_IO::write_string(s);
    }
    else cout << s;
}
template<class T> void write(T &x) {
    if(system_const == 0) {
        fast_IO::write_number(x);
    }
    else cout << x;
}
void writeln(const string &s) {
    write(s);
    if(system_const == 0) {
        using namespace fast_IO;
        Putchar('\n');
    }
    else cout << endl;
}
template<class T> void writeln(T x) {
    write(x);
    if(system_const == 0) {
        using namespace fast_IO;
        Putchar('\n');
    }
    else cout << '\n';
}
void writesp(const string &s) {
    write(s);
    if(system_const == 0) {
        using namespace fast_IO;
        Putchar(' ');
    }
    else cout << ' ';
}

template<class T> void writesp(T x) {
    write(x);
    if(system_const == 0) {
        using namespace fast_IO;
        Putchar(' ');
    }
    else cout << ' ';
}
void set_program_type(int t = 0) {
    system_const = t;
    if(t) {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
    }
}
void finish_program(int t = 0) {
    if(!t) fast_IO::Flush();
}

void init_all(int t = 0,string s = "output") {
#ifdef LOCAL
    if ((t >> 1) & 1) freopen("input", "r", stdin);
    if ((t >> 2) & 1) freopen(s.c_str(), "w", stdout);
#endif
}

template <int MOD=998244353, class T = int> struct Modular {
    T value;
    static const T MOD_value = MOD;

    Modular(T v = 0) { value = v % MOD; if (value < 0) value += MOD;}
    Modular(T a, T b) : value(0){ *this += a; *this /= b;}

    Modular& operator+=(Modular const& b) {value += b.value; if (value >= MOD) value -= MOD; return *this;}
    Modular& operator-=(Modular const& b) {value -= b.value; if (value < 0) value += MOD;return *this;}
    Modular& operator*=(Modular const& b) {value = (long long)value * b.value % MOD;return *this;}

    friend Modular mexp(Modular a, long long e) {
        Modular res = 1; while (e) { if (e&1) res *= a; a *= a; e >>= 1; }
        return res;
    }
    friend Modular inverse(Modular a) { return mexp(a, MOD - 2); }

    Modular& operator/=(Modular const& b) { return *this *= inverse(b); }
    friend Modular operator+(Modular a, Modular const &b) { return a += b; }
    friend Modular operator-(Modular a, Modular const &b) { return a -= b; }
    friend Modular operator-(Modular const &a) { return 0 - a; }
    friend Modular operator*(Modular a, Modular const &b) { return a *= b; }
    friend Modular operator/(Modular a, Modular const &b) { return a /= b; }
    friend std::ostream& operator<<(std::ostream& os, Modular const& a) {return os << a.value;}
    friend bool operator==(Modular const& a, Modular const& b) {return a.value == b.value;}
    friend bool operator!=(Modular const& a, Modular const& b) {return a.value != b.value;}

};

int pre_ask_time;
void show_time() {
    int now = clock();
    cout << now-pre_ask_time << endl;
    pre_ask_time = now;
}

template<class T> void cmin(T &x,const T&y) {if(x > y) x = y;}
template<class T> void cmax(T &x,const T&y) {if(x < y) x = y;}

const int N = 6,NX = 21,D = 31,P = 998244353;

int f[D+1][NX][NX][NX][NX][2][2];
int n,m,x[N],y[N];
int px[1<<N],py[1<<N],nx[1<<N],ny[1<<N];

void add(int &x,int y) {if (x==-1) x = 0;x += y;if(x >= P) x -= P;}
inline int eq(int x,int y) {return !((x^y)&1);}
inline int gr(int x,int y) {return (x&1)>(y&1);}
inline int ls(int x,int y) {return (x&1)<(y&1);}

void solve() {
    read(n);read(m);
    forn(i,n) {read(x[i]);read(y[i]);}
    MST(f,-1);
    int fmsk = (1<<n)-1;
    rep(i,1,fmsk) rep(j,0,n-1) if(i>>j&1) {
        if(x[j] > 0) px[i] += x[j];
        else nx[i] -= x[j];
        if(y[j] > 0) py[i] += y[j];
        else ny[i] -= y[j];
    }
    f[0][0][0][0][0][0][0] = 1;
    forn(d,D) forn(cpx,NX) forn(cpy,NX) forn(cnx,NX) forn(cny,NX) forn(i,2) forn(j,2) {
        if(f[d][cpx][cpy][cnx][cny][i][j] == -1) continue;
        rep(msk,0,fmsk) {
            int npx = cpx+px[msk];
            int npy = cpy+py[msk];
            int nnx = cnx+nx[msk];
            int nny = cny+ny[msk];
            if(!eq(npx,nnx) || !eq(npy,nny)) continue;
            int sx = !ls(npx,m>>d),sy = !ls(npy,m>>d);
            if(sx) {
                if(gr(npx,m>>d)) sx = 1;
                else sx = i;
            }
            if(sy) {
                if(gr(npy,m>>d)) sy = 1;
                else sy = j;
            }

//cout << f[d+1][npx/2][npy/2][nnx/2][nny/2][sx][sy] << ' ' << f[d][cpx][cpy][cnx][cny][i][j] << endl;

            add(f[d+1][npx/2][npy/2][nnx/2][nny/2][sx][sy],f[d][cpx][cpy][cnx][cny][i][j]);
        }
    }
    cout << (f[D][0][0][0][0][0][0]-1+P)%P << endl;
}

signed main() {
    //srand((int)time(0));
    pre_ask_time = clock();
    init_all(3);

    //init();

    set_program_type(0);

    int T = 1;
    //read(T);
    //cin >> T;
    //scanf("%d",&T);
    rep(i,1,T) {
        //printf("Case #%d: ",i);
        solve();
    }

    finish_program(0);

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
constexpr int mod = 998244353;
int x[5], y[5];
int px[32], nx[32], py[32], ny[32];
int dp[32][20][20][20][20][2][2];
void add(int &x, const int& y){
    x += y;
    if(x >= mod) x -= mod;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < n; i += 1)
        cin >> x[i] >> y[i];
    for(int mask = 0; mask < (1 << n); mask += 1)
        for(int i = 0; i < n; i += 1)
            if((mask >> i) & 1){
                (x[i] > 0 ? px : nx)[mask] += abs(x[i]);
                (y[i] > 0 ? py : ny)[mask] += abs(y[i]);
            }
    dp[0][0][0][0][0][0][0] = 1;
    #define FOR(i, n) for(int i = 0; i < (n); i += 1)
    FOR(i, 30)FOR(cpx, 20)FOR(cnx, 20)FOR(cpy, 20)FOR(cny, 20)
        FOR(bx, 2)FOR(by, 2)FOR(mask, 1 << n)
        if(dp[i][cpx][cnx][cpy][cny][bx][by]){
        if(0)cout << i << " " << cpx << " " << cny << " " << cpy << " " << cny
                << " " << bx << " " << by << " "
                << dp[i][cpx][cnx][cpy][cny][bx][by] << endl;
        int npx = cpx + px[mask],
        nnx = cnx + nx[mask],
        npy = cpy + py[mask],
        nny = cny + ny[mask];
        if((npx ^ nnx) & 1) continue;
        if((npy ^ nny) & 1) continue;
        int cx = npx & 1, mx = (m >> i) & 1;
        int cy = npy & 1, my = (m >> i) & 1;
        add(dp[i + 1][npx >> 1][nnx >> 1][npy >> 1][nny >> 1]
            [cx != mx ? (cx > mx) : bx][cy != my ? (cy > my) : by],
            dp[i][cpx][cnx][cpy][cny][bx][by]);
    }
    cout << (dp[30][0][0][0][0][0][0] + mod - 1) % mod;
    return 0;
}

/**
 *    author:  tourist
 *    created: 02.02.2020 17:52:33
**/
#include <bits/stdc++.h>

using namespace std;

template <typename T>
T inverse(T a, T m) {
  T u = 0, v = 1;
  while (a != 0) {
    T t = m / a;
    m -= t * a; swap(a, m);
    u -= t * v; swap(u, v);
  }
  assert(m == 1);
  return u;
}

template <typename T>
class Modular {
 public:
  using Type = typename decay<decltype(T::value)>::type;

  constexpr Modular() : value() {}
  template <typename U>
  Modular(const U& x) {
    value = normalize(x);
  }

  template <typename U>
  static Type normalize(const U& x) {
    Type v;
    if (-mod() <= x && x < mod()) v = static_cast<Type>(x);
    else v = static_cast<Type>(x % mod());
    if (v < 0) v += mod();
    return v;
  }

  const Type& operator()() const { return value; }
  template <typename U>
  explicit operator U() const { return static_cast<U>(value); }
  constexpr static Type mod() { return T::value; }

  Modular& operator+=(const Modular& other) { if ((value += other.value) >= mod()) value -= mod(); return *this; }
  Modular& operator-=(const Modular& other) { if ((value -= other.value) < 0) value += mod(); return *this; }
  template <typename U> Modular& operator+=(const U& other) { return *this += Modular(other); }
  template <typename U> Modular& operator-=(const U& other) { return *this -= Modular(other); }
  Modular& operator++() { return *this += 1; }
  Modular& operator--() { return *this -= 1; }
  Modular operator++(int) { Modular result(*this); *this += 1; return result; }
  Modular operator--(int) { Modular result(*this); *this -= 1; return result; }
  Modular operator-() const { return Modular(-value); }

  template <typename U = T>
  typename enable_if<is_same<typename Modular<U>::Type, int>::value, Modular>::type& operator*=(const Modular& rhs) {
#ifdef _WIN32
    uint64_t x = static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value);
    uint32_t xh = static_cast<uint32_t>(x >> 32), xl = static_cast<uint32_t>(x), d, m;
    asm(
      "divl %4; \n\t"
      : "=a" (d), "=d" (m)
      : "d" (xh), "a" (xl), "r" (mod())
    );
    value = m;
#else
    value = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value));
#endif
    return *this;
  }
  template <typename U = T>
  typename enable_if<is_same<typename Modular<U>::Type, int64_t>::value, Modular>::type& operator*=(const Modular& rhs) {
    int64_t q = static_cast<int64_t>(static_cast<long double>(value) * rhs.value / mod());
    value = normalize(value * rhs.value - q * mod());
    return *this;
  }
  template <typename U = T>
  typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs) {
    value = normalize(value * rhs.value);
    return *this;
  }

  Modular& operator/=(const Modular& other) { return *this *= Modular(inverse(other.value, mod())); }

  template <typename U>
  friend const Modular<U>& abs(const Modular<U>& v) { return v; }

  template <typename U>
  friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs);

  template <typename U>
  friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs);

  template <typename U>
  friend std::istream& operator>>(std::istream& stream, Modular<U>& number);

 private:
  Type value;
};

template <typename T> bool operator==(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value == rhs.value; }
template <typename T, typename U> bool operator==(const Modular<T>& lhs, U rhs) { return lhs == Modular<T>(rhs); }
template <typename T, typename U> bool operator==(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) == rhs; }

template <typename T> bool operator!=(const Modular<T>& lhs, const Modular<T>& rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator!=(const Modular<T>& lhs, U rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator!=(U lhs, const Modular<T>& rhs) { return !(lhs == rhs); }

template <typename T> bool operator<(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value < rhs.value; }

template <typename T> Modular<T> operator+(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }
template <typename T, typename U> Modular<T> operator+(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) += rhs; }
template <typename T, typename U> Modular<T> operator+(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }

template <typename T> Modular<T> operator-(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T, typename U> Modular<T> operator-(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T, typename U> Modular<T> operator-(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }

template <typename T> Modular<T> operator*(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T, typename U> Modular<T> operator*(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T, typename U> Modular<T> operator*(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }

template <typename T> Modular<T> operator/(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }
template <typename T, typename U> Modular<T> operator/(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) /= rhs; }
template <typename T, typename U> Modular<T> operator/(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }

template<typename T, typename U>
Modular<T> power(const Modular<T>& a, const U& b) {
  assert(b >= 0);
  Modular<T> x = a, res = 1;
  U p = b;
  while (p > 0) {
    if (p & 1) res *= x;
    x *= x;
    p >>= 1;
  }
  return res;
}

template <typename T>
bool IsZero(const Modular<T>& number) {
  return number() == 0;
}

template <typename T>
string to_string(const Modular<T>& number) {
  return to_string(number());
}

template <typename T>
std::ostream& operator<<(std::ostream& stream, const Modular<T>& number) {
  return stream << number();
}

template <typename T>
std::istream& operator>>(std::istream& stream, Modular<T>& number) {
  typename common_type<typename Modular<T>::Type, int64_t>::type x;
  stream >> x;
  number.value = Modular<T>::normalize(x);
  return stream;
}

/*
using ModType = int;

struct VarMod { static ModType value; };
ModType VarMod::value;
ModType& md = VarMod::value;
using Mint = Modular<VarMod>;
*/

constexpr int md = 998244353;
using Mint = Modular<std::integral_constant<decay<decltype(md)>::type, md>>;

const int MAX = 20;

Mint dp[MAX][MAX][MAX][MAX][2][2];
Mint new_dp[MAX][MAX][MAX][MAX][2][2];

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<int> x(n), y(n);
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }
  memset(dp, 0, sizeof(dp));
  dp[0][0][0][0][0][0] = 1;
  while (m > 0) {
    int bit = m & 1;
    memset(new_dp, 0, sizeof(new_dp));
    for (int cpx = 0; cpx < MAX; cpx++) {
      for (int cmx = 0; cmx < MAX; cmx++) {
        for (int cpy = 0; cpy < MAX; cpy++) {
          for (int cmy = 0; cmy < MAX; cmy++) {
            for (int fx = 0; fx < 2; fx++) {
              for (int fy = 0; fy < 2; fy++) {
                Mint ft = dp[cpx][cmx][cpy][cmy][fx][fy];
                if (ft == 0) {
                  continue;
                }
                for (int mask = 0; mask < (1 << n); mask++) {
                  int dpx = cpx;
                  int dpy = cpy;
                  int dmx = cmx;
                  int dmy = cmy;
                  for (int i = 0; i < n; i++) {
                    if (mask & (1 << i)) {
                      dpx += max(x[i], 0);
                      dmx -= min(x[i], 0);
                      dpy += max(y[i], 0);
                      dmy -= min(y[i], 0);
                    }
                  }
                  if ((dpx & 1) != (dmx & 1)) {
                    continue;
                  }
                  if ((dpy & 1) != (dmy & 1)) {
                    continue;
                  }
                  int new_fx = ((dpx & 1) > bit ? 1 : ((dpx & 1) < bit ? 0 : fx));
                  int new_fy = ((dpy & 1) > bit ? 1 : ((dpy & 1) < bit ? 0 : fy));
                  dpx >>= 1;
                  dmx >>= 1;
                  dpy >>= 1;
                  dmy >>= 1;
                  assert(dpx < MAX && dpy < MAX && dmx < MAX && dmy < MAX);
                  new_dp[dpx][dmx][dpy][dmy][new_fx][new_fy] += ft;
                }
              }
            }
          }
        }
      }
    }
    swap(dp, new_dp);
    m >>= 1;
  }
  cout << dp[0][0][0][0][0][0] - 1 << '\n';
  return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int N = 5, MX = 4 * N, LG = 31, MOD = 998244353;

int n, m, x[N], y[N];
int px[1 << N], nx[1 << N], py[1 << N], ny[1 << N];
int dp[LG][MX][MX][MX][MX][2][2];

void add(int &x, int y) {
    x += y;
    if (x >= MOD) {
        x -= MOD;
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> x[i] >> y[i];
    }
    for (int msk = 0; msk < (1 << n); msk++) {
        for (int i = 0; i < n; i++) {
            if (msk >> i & 1) {
                (x[i] < 0 ? nx : px)[msk] += abs(x[i]);
                (y[i] < 0 ? ny : py)[msk] += abs(y[i]);
            }
        }
    }
    int mpx = max(1, px[(1 << n) - 1]);
    int mpy = max(1, py[(1 << n) - 1]);
    int mnx = max(1, nx[(1 << n) - 1]);
    int mny = max(1, ny[(1 << n) - 1]);
    dp[0][0][0][0][0][0][0] = 1;
    for (int lg = 0; (1 << lg) <= m; lg++) {
        for (int cpx = 0; cpx < mpx; cpx++) {
            for (int cpy = 0; cpy < mpy; cpy++) {
                for (int cnx = 0; cnx < mnx; cnx++) {
                    for (int cny = 0; cny < mny; cny++) {
                        for (int sx = 0; sx < 2; sx++) {
                            for (int sy = 0; sy < 2; sy++) {
                                for (int msk = 0; msk < (1 << n); msk++) {
                                    int spx = cpx + px[msk];
                                    int spy = cpy + py[msk];
                                    int snx = cnx + nx[msk];
                                    int sny = cny + ny[msk];
                                    if (((spx ^ snx) & 1) || ((spy ^ sny) & 1)) {
                                        continue;
                                    }
                                    int bx = spx & 1, by = spy & 1;
                                    int nsx = (bx < (m >> lg & 1) ? 0 : bx > (m >> lg & 1) ? 1 : sx);
                                    int nsy = (by < (m >> lg & 1) ? 0 : by > (m >> lg & 1) ? 1 : sy);
                                    add(dp[lg + 1][spx / 2][spy / 2][snx / 2][sny / 2][nsx][nsy], dp[lg][cpx][cpy][cnx][cny][sx][sy]);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    cout << (dp[__lg(m) + 1][0][0][0][0][0][0] + MOD - 1) % MOD << '\n';
}

//#pragma comment(linker, "/stack:200000000")
#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set =
	tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

#define pb push_back
#define mp make_pair
#define st first
#define nd second
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define un(x) x.erase(unique(ALL(x)),x.end())
#define REP(i,x,v)for(int i=x;i<=v;i++)
#define REPD(i,x,v)for(int i=x;i>=v;i--)
#define FOR(i,v)for(int i=0;i<v;i++)

using ll=long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vll=vector<ll>;
const int MOD=998244353;

struct mi {
	typedef decay<decltype(MOD)>::type T;
	T val;
	explicit operator T() const { return val; }
	mi() { val = 0; }
	mi(ll v) {
		val = (-MOD <= v && v <= MOD) ? v : v % MOD;
		if (val < 0) val += MOD;
	}
	friend bool operator==(const mi& a, const mi& b) {
		return a.val == b.val; }
	friend bool operator!=(const mi& a, const mi& b) {
		return !(a == b); }
	friend bool operator<(const mi& a, const mi& b) {
		return a.val < b.val; }
	friend ostream& operator<<(ostream& os, const mi& a) {
		return os << a.val; }

	mi operator-() const { return mi(-val); }
	mi& operator+=(const mi& m) {
		if ((val += m.val) >= MOD) val -= MOD;
		return *this; }
	mi& operator-=(const mi& m) {
		if ((val -= m.val) < 0) val += MOD;
		return *this; }
	mi& operator++() { return *this += 1; }
	mi& operator--() { return *this -= 1; }
	friend mi operator+(mi a, const mi& b) { return a += b; }
	friend mi operator-(mi a, const mi& b) { return a -= b; }

	mi& operator*=(const mi& m) {
		val = (ll)val*m.val%MOD; return *this; }
	friend mi pow(mi a, ll p) {
		mi ans = 1; assert(p >= 0);
		for (; p; p /= 2, a *= a) if (p&1) ans *= a;
		return ans;
	}
	friend mi inv(const mi& a) {
		assert(!(a == 0)); return pow(a,MOD-2); }
	mi& operator/=(const mi& m) { return (*this) *= inv(m); }
	friend mi operator*(mi a, const mi& b) { return a *= b; }
	friend mi operator/(mi a, const mi& b) { return a /= b; }
};

mi dp[32][13][13][13][13][2][2];
int x[5];
int y[5];
int dpx[1<<5],dnx[1<<5],dpy[1<<5],dny[1<<5];

int bts[2][2][2][2];

bool mxx(int bitm,int bitx,int ok,int nok) {
	if (nok==0) return (bitx>bitm || (bitx==bitm && ok==0));
	return (bitx<bitm || (bitx==bitm && ok==1));
}

int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);
	cout << fixed << setprecision(11);
	cerr << fixed << setprecision(6);
	FOR(bitm,2)FOR(bitx,2)FOR(ok,2)FOR(nok,2) bts[bitm][bitx][ok][nok]=mxx(bitm,bitx,ok,nok);
	int n;cin>>n;
	int m;cin>>m;
	FOR(i,n) cin>>x[i]>>y[i];
	int spx,snx,spy,sny;
	spx=0;FOR(i,n) if (x[i]>0) spx+=x[i]; if (spx==0) {cout<<0;return 0;}
	snx=0;FOR(i,n) if (x[i]<0) snx-=x[i]; if (snx==0) {cout<<0;return 0;}
	spy=0;FOR(i,n) if (y[i]>0) spy+=y[i]; if (spy==0) {cout<<0;return 0;}
	sny=0;FOR(i,n) if (y[i]<0) sny-=y[i]; if (sny==0) {cout<<0;return 0;}
	dp[0][0][0][0][0][1][1]=1;
	int mxk;
	int ncpx,ncnx,ncpy,ncny;
	int bx,by;
	for(int k=1;m>=(1<<(k-1));k++) {

		mxk=k;
		int bitm=!!((1<<(k-1))&m);

		FOR(c,(1<<n)){
			dpx[c]=dnx[c]=dpy[c]=dny[c]=0;
			FOR(i,n) {
				if (x[i]>0 && (c>>i)&1) dpx[c]+=x[i];
				if (x[i]<0 && (c>>i)&1) dnx[c]-=x[i];
				if (y[i]>0 && (c>>i)&1) dpy[c]+=y[i];
				if (y[i]<0 && (c>>i)&1) dny[c]-=y[i];
			}
		}
		FOR(cpx,13)FOR(cnx,13)FOR(cpy,13)FOR(cny,13)FOR(xok,2)FOR(yok,2) {
			if (dp[k-1][cpx][cnx][cpy][cny][xok][yok]!=0) {
				//debug()<<imie(k)<<imie(cpx)<<imie(cnx)<<imie(cpy)<<imie(cny)<<imie(xok)<<imie(yok);
				mi val=dp[k-1][cpx][cnx][cpy][cny][xok][yok];
				FOR(c,(1<<n)) {
					ncpx=cpx+dpx[c];
					ncnx=cnx+dnx[c];
					ncpy=cpy+dpy[c];
					ncny=cny+dny[c];
					bx=ncpx&1;
					by=ncpy&1;
					if ((ncnx&1)==bx && (ncny&1)==by) {
						FOR(nxok,2) {
							if (bts[bitm][bx][xok][nxok]) {
								FOR(nyok,2) {
									if (bts[bitm][by][yok][nyok]) {
										dp[k][ncpx/2][ncnx/2][ncpy/2][ncny/2][nxok][nyok]+=val;
									}
								}
							}
						}
					}
				}
			}
		}
	}
	//debug()<<imie(mxk);
	cout<<dp[mxk][0][0][0][0][1][1]-1<<endl;

    return 0;
}

//#pragma comment(linker, "/stack:200000000")
#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set =
	tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

#define pb push_back
#define mp make_pair
#define st first
#define nd second
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define un(x) x.erase(unique(ALL(x)),x.end())
#define REP(i,x,v)for(int i=x;i<=v;i++)
#define REPD(i,x,v)for(int i=x;i>=v;i--)
#define FOR(i,v)for(int i=0;i<v;i++)

using ll=long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vll=vector<ll>;
const int MOD=998244353;

struct mi {
	typedef decay<decltype(MOD)>::type T;
	T val;
	explicit operator T() const { return val; }
	mi() { val = 0; }
	mi(ll v) {
		val = (-MOD <= v && v <= MOD) ? v : v % MOD;
		if (val < 0) val += MOD;
	}
	friend bool operator==(const mi& a, const mi& b) {
		return a.val == b.val; }
	friend bool operator!=(const mi& a, const mi& b) {
		return !(a == b); }
	friend bool operator<(const mi& a, const mi& b) {
		return a.val < b.val; }
	friend ostream& operator<<(ostream& os, const mi& a) {
		return os << a.val; }

	mi operator-() const { return mi(-val); }
	mi& operator+=(const mi& m) {
		if ((val += m.val) >= MOD) val -= MOD;
		return *this; }
	mi& operator-=(const mi& m) {
		if ((val -= m.val) < 0) val += MOD;
		return *this; }
	mi& operator++() { return *this += 1; }
	mi& operator--() { return *this -= 1; }
	friend mi operator+(mi a, const mi& b) { return a += b; }
	friend mi operator-(mi a, const mi& b) { return a -= b; }

	mi& operator*=(const mi& m) {
		val = (ll)val*m.val%MOD; return *this; }
	friend mi pow(mi a, ll p) {
		mi ans = 1; assert(p >= 0);
		for (; p; p /= 2, a *= a) if (p&1) ans *= a;
		return ans;
	}
	friend mi inv(const mi& a) {
		assert(!(a == 0)); return pow(a,MOD-2); }
	mi& operator/=(const mi& m) { return (*this) *= inv(m); }
	friend mi operator*(mi a, const mi& b) { return a *= b; }
	friend mi operator/(mi a, const mi& b) { return a /= b; }
};

mi dp[13][13][13][13][2][2];
mi ndp[13][13][13][13][2][2];
int x[5];
int y[5];
int dpx[1<<5],dnx[1<<5],dpy[1<<5],dny[1<<5];

int bts[2][2][2][2];

bool mxx(int bitm,int bitx,int ok,int nok) {
	if (nok==0) return (bitx>bitm || (bitx==bitm && ok==0));
	return (bitx<bitm || (bitx==bitm && ok==1));
}

int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);
	cout << fixed << setprecision(11);
	cerr << fixed << setprecision(6);
	FOR(bitm,2)FOR(bitx,2)FOR(ok,2)FOR(nok,2) bts[bitm][bitx][ok][nok]=mxx(bitm,bitx,ok,nok);
	int n;cin>>n;
	int m;cin>>m;
	FOR(i,n) cin>>x[i]>>y[i];
	int spx,snx,spy,sny;
	spx=0;FOR(i,n) if (x[i]>0) spx+=x[i]; if (spx==0) {cout<<0;return 0;}
	snx=0;FOR(i,n) if (x[i]<0) snx-=x[i]; if (snx==0) {cout<<0;return 0;}
	spy=0;FOR(i,n) if (y[i]>0) spy+=y[i]; if (spy==0) {cout<<0;return 0;}
	sny=0;FOR(i,n) if (y[i]<0) sny-=y[i]; if (sny==0) {cout<<0;return 0;}
	dp[0][0][0][0][1][1]=1;
	int ncpx,ncnx,ncpy,ncny;
	int bx,by;
	while(m){
		memset(ndp,0,sizeof(ndp));
		int bitm=m&1;
		m/=2;
		FOR(c,(1<<n)){
			dpx[c]=dnx[c]=dpy[c]=dny[c]=0;
			FOR(i,n) {
				if (x[i]>0 && (c>>i)&1) dpx[c]+=x[i];
				if (x[i]<0 && (c>>i)&1) dnx[c]-=x[i];
				if (y[i]>0 && (c>>i)&1) dpy[c]+=y[i];
				if (y[i]<0 && (c>>i)&1) dny[c]-=y[i];
			}
		}
		FOR(cpx,13)FOR(cnx,13)FOR(cpy,13)FOR(cny,13)FOR(xok,2)FOR(yok,2) {
			if (dp[cpx][cnx][cpy][cny][xok][yok]!=0) {
				mi val=dp[cpx][cnx][cpy][cny][xok][yok];
				FOR(c,(1<<n)) {
					ncpx=cpx+dpx[c];
					ncnx=cnx+dnx[c];
					ncpy=cpy+dpy[c];
					ncny=cny+dny[c];
					bx=ncpx&1;
					by=ncpy&1;
					if ((ncnx&1)==bx && (ncny&1)==by) {
						FOR(nxok,2) {
							if (bts[bitm][bx][xok][nxok]) {
								FOR(nyok,2) {
									if (bts[bitm][by][yok][nyok]) {
										ndp[ncpx/2][ncnx/2][ncpy/2][ncny/2][nxok][nyok]+=val;
									}
								}
							}
						}
					}
				}
			}
		}
		swap(dp,ndp);
	}
	cout<<dp[0][0][0][0][1][1]-1<<endl;

    return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int N = 5, MX = 4 * N, LG = 31, MOD = 998244353;

int n, m, x[N], y[N];
int px[1 << N], nx[1 << N], py[1 << N], ny[1 << N];
int dp[LG][MX][MX][MX][MX][2][2];

void add(int &x, int y) {
    x += y;
    if (x >= MOD) {
        x -= MOD;
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> x[i] >> y[i];
    }
    for (int msk = 0; msk < (1 << n); msk++) {
        for (int i = 0; i < n; i++) {
            if (msk >> i & 1) {
                (x[i] < 0 ? nx : px)[msk] += abs(x[i]);
                (y[i] < 0 ? ny : py)[msk] += abs(y[i]);
            }
        }
    }
    int mpx = max(1, px[(1 << n) - 1]);
    int mpy = max(1, py[(1 << n) - 1]);
    int mnx = max(1, nx[(1 << n) - 1]);
    int mny = max(1, ny[(1 << n) - 1]);
    dp[0][0][0][0][0][0][0] = 1;
    for (int lg = 0; (1 << lg) <= m; lg++) {                                // bit position
        for (int cpx = 0; cpx < mpx; cpx++) {                               // carry of positive x
            for (int cpy = 0; cpy < mpy; cpy++) {                           // carry of positive y
                for (int cnx = 0; cnx < mnx; cnx++) {                       // carry of negative x
                    for (int cny = 0; cny < mny; cny++) {                   // carry of negative y
                        for (int sx = 0; sx < 2; sx++) {                    // is the suffix of x greater than the suffix of m
                            for (int sy = 0; sy < 2; sy++) {                // is the suffix of y greater than the suffix of m
                                for (int msk = 0; msk < (1 << n); msk++) {  // iterating over the mask of the current bit position
                                    int spx = cpx + px[msk];
                                    int spy = cpy + py[msk];
                                    int snx = cnx + nx[msk];
                                    int sny = cny + ny[msk];
                                    if (((spx ^ snx) & 1) || ((spy ^ sny) & 1)) {
                                        continue;
                                    }
                                    int bx = spx & 1, by = spy & 1;
                                    int nsx = (bx < (m >> lg & 1) ? 0 : bx > (m >> lg & 1) ? 1 : sx);
                                    int nsy = (by < (m >> lg & 1) ? 0 : by > (m >> lg & 1) ? 1 : sy);
                                    add(dp[lg + 1][spx / 2][spy / 2][snx / 2][sny / 2][nsx][nsy], dp[lg][cpx][cpy][cnx][cny][sx][sy]);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    cout << (dp[__lg(m) + 1][0][0][0][0][0][0] + MOD - 1) % MOD << '\n';
}

#include <bits/stdc++.h>
using namespace std;

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
ll mask(int i){
	return (ll(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
	static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
void myshuffle(vc<t>&a){
	rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

using uint=unsigned;
using ull=unsigned long long;

struct modinfo{uint mod,root;};
template<modinfo const&ref>
struct modular{
	static constexpr uint const &mod=ref.mod;
	static modular root(){return modular(ref.root);}
	uint v;
	//modular(initializer_list<uint>ls):v(*ls.bg){}
	modular(ll vv=0){s(vv%mod+mod);}
	modular& s(uint vv){
		v=vv<mod?vv:vv-mod;
		return *this;
	}
	modular operator-()const{return modular()-*this;}
	modular& operator+=(const modular&rhs){return s(v+rhs.v);}
	modular&operator-=(const modular&rhs){return s(v+mod-rhs.v);}
	modular&operator*=(const modular&rhs){
		v=ull(v)*rhs.v%mod;
		return *this;
	}
	modular&operator/=(const modular&rhs){return *this*=rhs.inv();}
	modular operator+(const modular&rhs)const{return modular(*this)+=rhs;}
	modular operator-(const modular&rhs)const{return modular(*this)-=rhs;}
	modular operator*(const modular&rhs)const{return modular(*this)*=rhs;}
	modular operator/(const modular&rhs)const{return modular(*this)/=rhs;}
	modular pow(int n)const{
		modular res(1),x(*this);
		while(n){
			if(n&1)res*=x;
			x*=x;
			n>>=1;
		}
		return res;
	}
	modular inv()const{return pow(mod-2);}
	/*modular inv()const{
		int x,y;
		int g=extgcd(v,mod,x,y);
		assert(g==1);
		if(x<0)x+=mod;
		return modular(x);
	}*/
	friend modular operator+(int x,const modular&y){
		return modular(x)+y;
	}
	friend modular operator-(int x,const modular&y){
		return modular(x)-y;
	}
	friend modular operator*(int x,const modular&y){
		return modular(x)*y;
	}
	friend modular operator/(int x,const modular&y){
		return modular(x)/y;
	}
	friend ostream& operator<<(ostream&os,const modular&m){
		return os<<m.v;
	}
	friend istream& operator>>(istream&is,modular&m){
		ll x;is>>x;
		m=modular(x);
		return is;
	}
	bool operator<(const modular&r)const{return v<r.v;}
	bool operator==(const modular&r)const{return v==r.v;}
	bool operator!=(const modular&r)const{return v!=r.v;}
	explicit operator bool()const{
		return v;
	}
};

extern constexpr modinfo base{998244353,3};
//extern constexpr modinfo base{1000000007,0};
//modinfo base{1,0};
using mint=modular<base>;

const int vmax=(1<<21)+10;
mint fact[vmax],finv[vmax],invs[vmax];
void initfact(){
	fact[0]=1;
	rng(i,1,vmax){
		fact[i]=fact[i-1]*i;
	}
	finv[vmax-1]=fact[vmax-1].inv();
	for(int i=vmax-2;i>=0;i--){
		finv[i]=finv[i+1]*(i+1);
	}
	for(int i=vmax-1;i>=1;i--){
		invs[i]=finv[i]*fact[i-1];
	}
}
mint choose(int n,int k){
	return fact[n]*finv[n-k]*finv[k];
}
mint binom(int a,int b){
	return fact[a+b]*finv[a]*finv[b];
}
mint catalan(int n){
	return binom(n,n)-(n-1>=0?binom(n-1,n+1):0);
}

const int S=44;
mint dp[2][S][S][S][S];

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	int n;cin>>n;
	int m;cin>>m;
	vc<tuple<int,int,int,int>> xy;
	rep(i,n){
		int x,y;cin>>x>>y;
		xy.eb(max(x,int(0)),max(-x,int(0)),max(y,int(0)),max(-y,int(0)));
	}
	xy.eb(1,1,0,0);
	xy.eb(0,0,1,1);
	int cur=0;
	dp[cur][0][0][0][0]=1;
	int len=__lg(m)+1;
	rep(lv,len){
		for(auto z:xy){
			int a,b,c,d;tie(a,b,c,d)=z;
			gnr(p,a,S)gnr(q,b,S)gnr(r,c,S)gnr(s,d,S){
				dp[cur][p][q][r][s]+=dp[cur][p-a][q-b][r-c][s-d];
			}
		}
		int nx=cur^1;

		zero(dp[nx]);
		int v=(m>>lv)&1;
		rep(p,S/2)rep(q,S/2)rep(r,S/2)rep(s,S/2){
			dp[nx][p][q][r][s]=dp[cur][p*2+v][q*2+v][r*2+v][s*2+v];
		}

		cur=nx;
	}
	cout<<dp[cur][0][0][0][0]-1<<endl;
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN = 5;
const int MOD = 998244353;
void inc(int &a, int b) { if ((a += b) >= MOD) a -= MOD; }

int n, boxsz;
int dx[MAXN], dy[MAXN];

int xpos[MAXN], xneg[MAXN], ypos[MAXN], yneg[MAXN];

// sum(f[i]*dx[i]|dx[i]>0)+sum(f[i]*dx[i]|dx[i]<0)=0	sum(f[i]*xpos[i])=sum(f[i]*xneg[i])
// sum(f[i]*dy[i]|dy[i]>0)+sum(f[i]*dy[i]|dy[i]<0)=0	sum(f[i]*ypos[i])=sum(f[i]*yneg[i])
// sum(f[i]*dx[i]|dx[i]>0)<=boxsz						sum(f[i]*xpos[i])<=boxsz
// sum(f[i]*dy[i]|dy[i]>0)<=boxsz						sum(f[i]*ypos[i])<=boxsz

int sumxpos, sumxneg, sumypos, sumyneg;
int nstate;

vector<int> ways, nways;

int encode(int xposcarry, int xnegcarry, int yposcarry, int ynegcarry, int xposgreater, int yposgreater) {
	assert(xposcarry >= 0 && (xposcarry == 0 || xposcarry < sumxpos));
	assert(xnegcarry >= 0 && (xnegcarry == 0 || xnegcarry < sumxneg));
	assert(yposcarry >= 0 && (yposcarry == 0 || yposcarry < sumypos));
	assert(ynegcarry >= 0 && (ynegcarry == 0 || ynegcarry < sumyneg));
	int ret = 0;
	if (sumxpos > 0) ret = ret*sumxpos + xposcarry;
	if (sumxneg > 0) ret = ret*sumxneg + xnegcarry;
	if (sumypos > 0) ret = ret*sumypos + yposcarry;
	if (sumyneg > 0) ret = ret*sumyneg + ynegcarry;
	ret = ret * 2 + xposgreater;
	ret = ret * 2 + yposgreater;
	return ret;
}
void decode(int key, int &xposcarry, int &xnegcarry, int &yposcarry, int &ynegcarry, int &xposgreater, int &yposgreater) {
	yposgreater = key % 2, key /= 2;
	xposgreater = key % 2, key /= 2;
	if (sumyneg > 0) ynegcarry = key%sumyneg, key /= sumyneg; else ynegcarry = 0;
	if (sumypos > 0) yposcarry = key%sumypos, key /= sumypos; else yposcarry = 0;
	if (sumxneg > 0) xnegcarry = key%sumxneg, key /= sumxneg; else xnegcarry = 0;
	if (sumxpos > 0) xposcarry = key%sumxpos, key /= sumxpos; else xposcarry = 0;
	assert(key == 0);
}

int solve() {
	REP(i, n) xpos[i] = dx[i] > 0 ? +dx[i] : 0;
	REP(i, n) xneg[i] = dx[i] < 0 ? -dx[i] : 0;
	REP(i, n) ypos[i] = dy[i] > 0 ? +dy[i] : 0;
	REP(i, n) yneg[i] = dy[i] < 0 ? -dy[i] : 0;
	sumxpos = 0; REP(i, n) sumxpos += xpos[i];
	sumxneg = 0; REP(i, n) sumxneg += xneg[i];
	sumypos = 0; REP(i, n) sumypos += ypos[i];
	sumyneg = 0; REP(i, n) sumyneg += yneg[i];
	nstate = (sumxpos == 0 ? 1 : sumxpos)*(sumxneg == 0 ? 1 : sumxneg)*(sumypos == 0 ? 1 : sumypos)*(sumyneg == 0 ? 1 : sumyneg) * 2 * 2;
	ways = nways = vector<int>(nstate, 0);
	inc(ways[encode(0, 0, 0, 0, 0, 0)], 1);
	for (int bit = 0; (1 << bit) <= boxsz; ++bit) {
		int boxszbit = (boxsz >> bit) & 1;
		REP(key, nstate) nways[key] = 0;
		REP(key, nstate) if(ways[key]>0) {
			int xposcarry, xnegcarry, yposcarry, ynegcarry, xposgreater, yposgreater; decode(key, xposcarry, xnegcarry, yposcarry, ynegcarry, xposgreater, yposgreater);
			REP(mask, 1 << n) {
				int xposval = xposcarry, xnegval = xnegcarry, yposval = yposcarry, ynegval = ynegcarry;
				REP(i, n) if (mask&(1 << i)) {
					xposval += xpos[i];
					xnegval += xneg[i];
					yposval += ypos[i];
					ynegval += yneg[i];
				}
				if (xposval % 2 != xnegval % 2) continue;
				if (yposval % 2 != ynegval % 2) continue;
				int nxposcarry = xposval / 2, nxnegcarry = xnegval / 2, nyposcarry = yposval / 2, nynegcarry = ynegval / 2;
				int xbit = xposval % 2, nxposgreater = xbit > boxszbit || xbit == boxszbit && xposgreater == 1 ? 1 : 0;
				int ybit = yposval % 2, nyposgreater = ybit > boxszbit || ybit == boxszbit && yposgreater == 1 ? 1 : 0;
				inc(nways[encode(nxposcarry, nxnegcarry, nyposcarry, nynegcarry, nxposgreater, nyposgreater)], ways[key]);
			}
		}
		swap(ways, nways);
	}
	int ret = ways[encode(0, 0, 0, 0, 0, 0)];
	inc(ret, MOD - 1);
	return ret;
}

void run() {
	scanf("%d%d", &n, &boxsz);
	REP(i, n) scanf("%d%d", &dx[i], &dy[i]);
	printf("%d\n", solve());
}

int main() {
	run();
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const ll mod = 998244353; // faster if const
ll modpow(ll a, ll e) {
	if (e == 0) return 1;
	ll x = modpow(a * a % mod, e >> 1);
	return e & 1 ? x * a % mod : x;
}

vector<ll> BerlekampMassey(vector<ll> s) {
	int n = sz(s), L = 0, m = 0;
	vector<ll> C(n), B(n), T;
	C[0] = B[0] = 1;

	ll b = 1;
	rep(i,0,n) { ++m;
		ll d = s[i] % mod;
		rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
		if (!d) continue;
		T = C; ll coef = d * modpow(b, mod-2) % mod;
		rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) % mod;
		if (2 * L > i) continue;
		L = i + 1 - L; B = T; b = d; m = 0;
	}

	C.resize(L + 1); C.erase(C.begin());
	trav(x, C) x = (mod - x) % mod;
	return C;
}

typedef vector<ll> Poly;
ll linearRec(Poly S, Poly tr, ll k) { /// start-hash
	int n = sz(S);

	auto combine = [&](Poly a, Poly b) {
		Poly res(n * 2 + 1);
		rep(i,0,n+1) rep(j,0,n+1)
			res[i + j] = (res[i + j] + a[i] * b[j]) % mod;
		for (int i = 2 * n; i > n; --i) rep(j,0,n)
			res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) % mod;
		res.resize(n + 1);
		return res;
	};

	Poly pol(n + 1), e(pol);
	pol[0] = e[1] = 1;

	for (++k; k; k /= 2) {
		if (k % 2) pol = combine(pol, e);
		e = combine(e, e);
	}

	ll res = 0;
	rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod;
	return res;
} /// end-hash

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n;
	int m;
	cin >> n >> m;
	if(n < 3){
		cout << 0 << '\n';
		return 0;
	}
	int a[5]; int b[5];
	for(int i = 0; i < n; i++) cin >> a[i] >> b[i];
	const int R = 700;
	vector<ll> vals(R+1, 0);
	int f[5];
	for(f[0] = 0; f[0] <= R; f[0]++){
		for(f[1] = 0; f[1] <= R; f[1]++){
			int r1 = -a[0] * f[0] - a[1] * f[1];
			int r2 = -b[0] * f[0] - b[1] * f[1];
			for(f[2] = 0; f[2] <= R; f[2]++){
				int cxs = r1;
				int cys = r2;
				r1 -= a[2];
				r2 -= b[2];
				if(n == 4){
					if(a[3]){
						f[3] = cxs / a[3];
					} else if(b[3]){
						f[3] = cys / b[3];
					} else assert(false);
					if(f[3] < 0) continue;
					cxs -= a[3] * f[3];
					cys -= b[3] * f[3];
				} else if(n == 5){
					int d = a[3] * b[4] - a[4] * b[3];
					f[3] = (cxs * b[4] - a[4] * cys) / d;
					if(f[3] < 0) continue;
					f[4] = (a[3] * cys - cxs * b[3]) / d;
					if(f[4] < 0) continue;
					cxs -= a[3] * f[3] + a[4] * f[4];
					cys -= b[3] * f[3] + b[4] * f[4];
				}
				if(cxs != 0 || cys != 0) continue;
				int xpsum = 0, ypsum = 0;
				for(int i = 0; i < n; i++){
					if(a[i] >= 0) xpsum += a[i] * f[i];
					if(b[i] >= 0) ypsum += b[i] * f[i];
				}
				if(xpsum > R || ypsum > R) continue;
				vals[max(xpsum, ypsum)]++;
			}
		}
	}
	for(int i = 1; i <= R; i++){
		vals[i] += vals[i-1];
	}
	vector<ll> rec = BerlekampMassey(vals);
	vals.resize(rec.size());
	ll res = linearRec(vals, rec, m);
	res = (res + mod - 1) % mod;
	cout << res << '\n';
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,n) for(int i=0;i<(n);i++)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long ll;

template<class T> void read(T &x){
	int f=0; x=0; char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
	if(f) x=-x;
}

const int N=20,mod=998244353;
int f[N][N][N][N][2][2];
int g[N][N][N][N][2][2];
int x[N],y[N],n,m;

void add(int &x,int y){
	x=(x+y>=mod?x+y-mod:x+y);
}

int main(){
	read(n),read(m);
	rep(i,1,n) read(x[i]),read(y[i]);
	f[0][0][0][0][0][0]=1;
	for(;m;m>>=1){
		memset(g,0,sizeof g);
		REP(px,N) REP(nx,N)
			REP(py,N) REP(ny,N)
				REP(fx,2) REP(fy,2){
					int t=f[px][nx][py][ny][fx][fy];
					if(!t) continue;
					REP(s,1<<n){
						int Px=px,Nx=nx,Py=py,Ny=ny;
						rep(i,1,n) if(s>>(i-1)&1){
							Px+=max(x[i],0);
							Nx-=min(x[i],0);
							Py+=max(y[i],0);
							Ny-=min(y[i],0);
						}
						if((Px&1)!=(Nx&1)||(Py&1)!=(Ny&1)) continue;
						int gx=((Px&1)<(m&1)?0:((Px&1)>(m&1)?1:fx));
						int gy=((Py&1)<(m&1)?0:((Py&1)>(m&1)?1:fy));
						Px>>=1,Nx>>=1,Py>>=1,Ny>>=1;
						add(g[Px][Nx][Py][Ny][gx][gy],t);
					}
				}
		swap(f,g);
	}
	cout<<((f[0][0][0][0][0][0]+mod-1)%mod)<<endl;
	return 0;
}

#include <bits/stdc++.h>
const int N = 32, L = 20, mod = 998244353;
int n, R, ALL;
int spx[N], snx[N], spy[N], sny[N];
int dp[2][L][L][L][L][2][2], (*cur)[L][L][L][2][2] = *dp, (*nxt)[L][L][L][2][2] = dp[1];
inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline int & reduce(int &x) {return x += x >> 31 & mod;}
inline void add(int &x, const int y) {x += y - mod, x += x >> 31 & mod;}
int main() {
	int i, c, d, x, y, v, ox, oy;
	int cpx, cnx, cpy, cny, ncpx, ncnx, ncpy, ncny;
	scanf("%d%d", &n, &R), ALL = ~(-1 << n);
	for (i = 0; i < n; ++i)
		scanf("%d%d", &x, &y),
		x >> 31 ? snx[1 << i] -= x : spx[1 << i] += x,
		y >> 31 ? sny[1 << i] -= y : spy[1 << i] += y;
	for (i = 3; i <= ALL; ++i)
		spx[i] = spx[i & (i - 1)] + spx[i & -i],
		snx[i] = snx[i & (i - 1)] + snx[i & -i],
		spy[i] = spy[i & (i - 1)] + spy[i & -i],
		sny[i] = sny[i & (i - 1)] + sny[i & -i];
	******nxt = 1;
	for (; R; R >>= 1) {
		c = R & 1, std::swap(cur, nxt), memset(nxt, 0, sizeof *dp);
		for (cpx = 0; cpx <= spx[ALL]; ++cpx) for (cnx = 0; cnx <= snx[ALL]; ++cnx)
		for (cpy = 0; cpy <= spy[ALL]; ++cpy) for (cny = 0; cny <= sny[ALL]; ++cny)
		for (ox = 0; ox < 2; ++ox) for (oy = 0; oy < 2; ++oy)
			if (v = cur[cpx][cnx][cpy][cny][ox][oy])
				for (d = 0; d <= ALL; ++d) {
					ncpx = cpx + spx[d], ncnx = cnx + snx[d];
					ncpy = cpy + spy[d], ncny = cny + sny[d];
					if (((ncpx ^ ncnx) | (ncpy ^ ncny)) & 1) continue;
					add(nxt[ncpx >> 1][ncnx >> 1][ncpy >> 1][ncny >> 1][(ncpx ^ c) & 1 ? !c : ox][(ncpy ^ c) & 1 ? !c : oy], v);
				}
	}
	printf("%d\n", reduce(--******nxt));
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

template <int MOD_> struct modnum {
	static constexpr int MOD = MOD_;
	static_assert(MOD_ > 0, "MOD must be positive");

private:
	using ll = long long;

	int v;

	static int minv(int a, int m) {
		a %= m;
		assert(a);
		return a == 1 ? 1 : int(m - ll(minv(m, a)) * ll(m) / a);
	}

public:

	modnum() : v(0) {}
	modnum(ll v_) : v(int(v_ % MOD)) { if (v < 0) v += MOD; }
	explicit operator int() const { return v; }
	friend std::ostream& operator << (std::ostream& out, const modnum& n) { return out << int(n); }
	friend std::istream& operator >> (std::istream& in, modnum& n) { ll v_; in >> v_; n = modnum(v_); return in; }

	friend bool operator == (const modnum& a, const modnum& b) { return a.v == b.v; }
	friend bool operator != (const modnum& a, const modnum& b) { return a.v != b.v; }

	modnum inv() const {
		modnum res;
		res.v = minv(v, MOD);
		return res;
	}
	friend modnum inv(const modnum& m) { return m.inv(); }
	modnum neg() const {
		modnum res;
		res.v = v ? MOD-v : 0;
		return res;
	}
	friend modnum neg(const modnum& m) { return m.neg(); }

	modnum operator- () const {
		return neg();
	}
	modnum operator+ () const {
		return modnum(*this);
	}

	modnum& operator ++ () {
		v ++;
		if (v == MOD) v = 0;
		return *this;
	}
	modnum& operator -- () {
		if (v == 0) v = MOD;
		v --;
		return *this;
	}
	modnum& operator += (const modnum& o) {
		v += o.v;
		if (v >= MOD) v -= MOD;
		return *this;
	}
	modnum& operator -= (const modnum& o) {
		v -= o.v;
		if (v < 0) v += MOD;
		return *this;
	}
	modnum& operator *= (const modnum& o) {
		v = int(ll(v) * ll(o.v) % MOD);
		return *this;
	}
	modnum& operator /= (const modnum& o) {
		return *this *= o.inv();
	}

	friend modnum operator ++ (modnum& a, int) { modnum r = a; ++a; return r; }
	friend modnum operator -- (modnum& a, int) { modnum r = a; --a; return r; }
	friend modnum operator + (const modnum& a, const modnum& b) { return modnum(a) += b; }
	friend modnum operator - (const modnum& a, const modnum& b) { return modnum(a) -= b; }
	friend modnum operator * (const modnum& a, const modnum& b) { return modnum(a) *= b; }
	friend modnum operator / (const modnum& a, const modnum& b) { return modnum(a) /= b; }
};

using num = modnum<998244353>;

struct state {
	int sx, mx;
	int sy, my;
	bool mxl, myl;
	friend bool operator < (const state& a, const state& b) {
		return tie(a.sx, a.mx, a.sy, a.my, a.mxl, a.myl) < tie(b.sx, b.mx, b.sy, b.my, b.mxl, b.myl);
	}
};

int main() {
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int N; int64_t M; cin >> N >> M;
	vector<pair<int, int>> P(N);
	for (int i = 0; i < N; i++) {
		cin >> P[i].first >> P[i].second;
	}
	map<state, num> dp;
	dp[state{0,0,0,0,false,false}] = 1;
	for (int l = 0; l < 40; l++) {
		for (int i = 0; i < N; i++) {
			map<state, num> ndp = dp; // can add nothing

			for (const auto& it : dp) {
				state s = it.first;
				num v = it.second;

				s.sx += P[i].first;
				s.mx += max(P[i].first, 0);
				s.sy += P[i].second;
				s.my += max(P[i].second, 0);

				ndp[s] += v;
			}
			dp = std::move(ndp);
		}

		{
			map<state, num> ndp;
			for (const auto& it : dp) {
				state s = it.first;
				num v = it.second;
				if (s.sx & 1) continue;
				s.sx >>= 1;
				if (s.sy & 1) continue;
				s.sy >>= 1;

				if ((s.mx & 1) != ((M >> l) & 1)) {
					s.mxl = (s.mx & 1) > ((M >> l) & 1);
				}
				s.mx >>= 1;
				if ((s.my & 1) != ((M >> l) & 1)) {
					s.myl = (s.my & 1) > ((M >> l) & 1);
				}
				s.my >>= 1;

				ndp[s] += v;
			}
			dp = std::move(ndp);
		}
	}

	cout << dp[state{0,0,0,0,false,false}] - 1 << '\n';

	return 0;
}

#include <bits/stdc++.h>

const int N = 5;
const int M = 32;
const int S = 10000;
const int MOD = 998244353;

void add(int &x, int a) {
  x += a;
  if (x >= MOD) {
    x -= MOD;
  }
}

int go(int s, int sbit, int mbit) {
  if (sbit == mbit) {
    return s;
  }
  return sbit < mbit ? 0 : 2;
}

int a[N], b[N], mbits[M], dim[4], dp[2][9][S];

void decode(int s, int *carries) {
  for (int i = 0; i < 4; ++i) {
    carries[i] = s % dim[i];
    s /= dim[i];
  }
}

int main() {
  int n, m;
  while (scanf("%d%d", &n, &m) == 2) {
    for (int i = 0; i < n; ++i) {
      scanf("%d%d", a + i, b + i);
    }
    int mlen = 0;
    for (m++; m; m >>= 1) {
      mbits[mlen++] = m & 1;
    }
    mbits[mlen] = mbits[mlen + 1] = 0;
    memset(dim, 0, sizeof(dim));
    for (int i = 0; i < n; ++i) {
      dim[a[i] > 0 ? 1 : 0] += std::abs(a[i]);
      dim[b[i] > 0 ? 3 : 2] += std::abs(b[i]);
    }
    int carrymax = dim[0] * dim[1] * dim[2] * dim[3];
    if (carrymax) {
      memset(dp, 0, sizeof(dp));
      dp[0][4][0] = 1;
      for (int i = 0; i < mlen + 2; ++i) {
        memset(dp[i + 1 & 1], 0, sizeof(dp[i + 1 & 1]));
        for (int cmpset = 0; cmpset < 9; ++cmpset) {
          for (int carryset = 0; carryset < carrymax; ++carryset) {
            int dpvalue = dp[i & 1][cmpset][carryset];
            if (dpvalue) {
              int ocarries[4], carries[4];
              decode(carryset, ocarries);
              for (int msk = 0; msk < (i < mlen ? 1 << n : 1); ++msk) {
                memcpy(carries, ocarries, sizeof(carries));
                for (int j = 0; j < n; ++j) {
                  if (msk >> j & 1) {
                    carries[a[j] > 0 ? 1 : 0] += std::abs(a[j]);
                    carries[b[j] > 0 ? 3 : 2] += std::abs(b[j]);
                  }
                }
                if ((carries[0] & 1) == (carries[1] & 1) &&
                    (carries[2] & 1) == (carries[3] & 1)) {
                  int cmp0 = go(cmpset % 3, carries[0] & 1, mbits[i]);
                  int cmp1 = go(cmpset / 3, carries[2] & 1, mbits[i]);
                  int ncarryset = 0;
                  for (int i = 4; i--;) {
                    ncarryset = ncarryset * dim[i] + (carries[i] >> 1);
                  }
                  add(dp[i + 1 & 1][cmp1 * 3 + cmp0][ncarryset], dpvalue);
                }
              }
            }
          }
        }
      }
      printf("%d\n", (dp[mlen & 1][0][0] + MOD - 1) % MOD);
    } else {
      puts("0");
    }
  }
}

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 45;
const int P = 998244353;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
int n, m, Log, a[MAXN], x[MAXN], y[MAXN], bit[MAXN];
int dp[2][MAXN][MAXN][MAXN][MAXN][2][2];
void update(int &x, int y) {
	x += y;
	if (x >= P) x -= P;
}
int main() {
	read(n), read(m);
	while (m != 0) {
		a[++Log] = m % 2;
		m >>= 1;
	}
	for (int i = 1; i <= n; i++) {
		read(x[i]), read(y[i]);
		bit[i] = 1 << (i - 1);
	}
	int lim = 41;
	dp[Log & 1][0][0][0][0][1][1] = 1;
	for (int i = Log, s = Log & 1, t = s ^ 1; i >= 1; i--, swap(s, t)) {
		memset(dp[t], 0, sizeof(dp[t]));
		for (int px = 0; px <= lim; px++)
		for (int py = 0; py <= lim; py++)
		for (int nx = 0; nx <= lim; nx++)
		for (int ny = 0; ny <= lim; ny++) {
			int vzz = dp[s][px][py][nx][ny][0][0];
			int vzo = dp[s][px][py][nx][ny][0][1];
			int voz = dp[s][px][py][nx][ny][1][0];
			int voo = dp[s][px][py][nx][ny][1][1];
			if (!(vzz || vzo || voz || voo)) continue;
			for (int s = 0; s <= (1 << n) - 1; s++) {
				int incpx = 0, incpy = 0, incnx = 0, incny = 0;
				for (int j = 1; j <= n; j++)
					if (s & bit[j]) {
						if (x[j] >= 0) incpx += x[j];
						else incnx -= x[j];
						if (y[j] >= 0) incpy += y[j];
						else incny -= y[j];
					}
				if (px >= incpx && py >= incpy && nx >= incnx && ny >= incny) {
					int tpx = (px - incpx) * 2;
					int tpy = (py - incpy) * 2;
					int tnx = (nx - incnx) * 2;
					int tny = (ny - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						update(dp[t][tpx][tpy][tnx][tny][0][a[i] == 0], vzo);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][0], voz);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][a[i] == 0], voo);
					}
				}
				if (px + 1 >= incpx && py >= incpy && nx + 1 >= incnx && ny >= incny) {
					int tpx = (px + 1 - incpx) * 2;
					int tpy = (py - incpy) * 2;
					int tnx = (nx + 1 - incnx) * 2;
					int tny = (ny - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						update(dp[t][tpx][tpy][tnx][tny][0][a[i] == 0], vzo);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][a[i] == 0], voo);
					}
				}
				if (px >= incpx && py + 1 >= incpy && nx >= incnx && ny + 1 >= incny) {
					int tpx = (px - incpx) * 2;
					int tpy = (py + 1 - incpy) * 2;
					int tnx = (nx - incnx) * 2;
					int tny = (ny + 1 - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][0][1], vzo);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][1], voo);
					}
				}
				if (px + 1 >= incpx && py + 1 >= incpy && nx + 1 >= incnx && ny + 1 >= incny) {
					int tpx = (px + 1 - incpx) * 2;
					int tpy = (py + 1 - incpy) * 2;
					int tnx = (nx + 1 - incnx) * 2;
					int tny = (ny + 1 - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][0][1], vzo);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][1], voo);
					}
				}
			}
		}
	}
	int ans = P - 1;
	for (int l1 = 0; l1 <= 1; l1++)
	for (int l2 = 0; l2 <= 1; l2++)
		update(ans, dp[0][0][0][0][0][l1][l2]);
	cout << ans << endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 45;
const int P = 998244353;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
int n, m, Log, a[MAXN], x[MAXN], y[MAXN], bit[MAXN];
int dp[2][MAXN][MAXN][MAXN][MAXN][2][2];
void update(int &x, int y) {
	x += y;
	if (x >= P) x -= P;
}
int main() {
	read(n), read(m);
	while (m != 0) {
		a[++Log] = m % 2;
		m >>= 1;
	}
	for (int i = 1; i <= n; i++) {
		read(x[i]), read(y[i]);
		bit[i] = 1 << (i - 1);
	}
	int lim = 32;
	dp[Log & 1][0][0][0][0][1][1] = 1;
	for (int i = Log, s = Log & 1, t = s ^ 1; i >= 1; i--, swap(s, t)) {
		memset(dp[t], 0, sizeof(dp[t]));
		for (int px = 0; px <= lim; px++)
		for (int py = 0; py <= lim; py++)
		for (int nx = 0; nx <= lim; nx++)
		for (int ny = 0; ny <= lim; ny++) {
			int vzz = dp[s][px][py][nx][ny][0][0];
			int vzo = dp[s][px][py][nx][ny][0][1];
			int voz = dp[s][px][py][nx][ny][1][0];
			int voo = dp[s][px][py][nx][ny][1][1];
			if (!(vzz || vzo || voz || voo)) continue;
			for (int s = 0; s <= (1 << n) - 1; s++) {
				int incpx = 0, incpy = 0, incnx = 0, incny = 0;
				for (int j = 1; j <= n; j++)
					if (s & bit[j]) {
						if (x[j] >= 0) incpx += x[j];
						else incnx -= x[j];
						if (y[j] >= 0) incpy += y[j];
						else incny -= y[j];
					}
				if (px >= incpx && py >= incpy && nx >= incnx && ny >= incny) {
					int tpx = (px - incpx) * 2;
					int tpy = (py - incpy) * 2;
					int tnx = (nx - incnx) * 2;
					int tny = (ny - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						update(dp[t][tpx][tpy][tnx][tny][0][a[i] == 0], vzo);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][0], voz);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][a[i] == 0], voo);
					}
				}
				if (px + 1 >= incpx && py >= incpy && nx + 1 >= incnx && ny >= incny) {
					int tpx = (px + 1 - incpx) * 2;
					int tpy = (py - incpy) * 2;
					int tnx = (nx + 1 - incnx) * 2;
					int tny = (ny - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						update(dp[t][tpx][tpy][tnx][tny][0][a[i] == 0], vzo);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][a[i] == 0], voo);
					}
				}
				if (px >= incpx && py + 1 >= incpy && nx >= incnx && ny + 1 >= incny) {
					int tpx = (px - incpx) * 2;
					int tpy = (py + 1 - incpy) * 2;
					int tnx = (nx - incnx) * 2;
					int tny = (ny + 1 - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][0][1], vzo);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][1], voo);
					}
				}
				if (px + 1 >= incpx && py + 1 >= incpy && nx + 1 >= incnx && ny + 1 >= incny) {
					int tpx = (px + 1 - incpx) * 2;
					int tpy = (py + 1 - incpy) * 2;
					int tnx = (nx + 1 - incnx) * 2;
					int tny = (ny + 1 - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][0][1], vzo);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][1], voo);
					}
				}
			}
		}
	}
	int ans = P - 1;
	for (int l1 = 0; l1 <= 1; l1++)
	for (int l2 = 0; l2 <= 1; l2++)
		update(ans, dp[0][0][0][0][0][l1][l2]);
	cout << ans << endl;
	return 0;
}

//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <math.h>
#include <string.h>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<double> vd;
typedef vector<string> vs;
typedef map<string, int> mpsi;
typedef map<double, int> mpdi;
typedef map<int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0},  {0, -1},
                        {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T>
inline T abs1(T a) {
  return a < 0 ? -a : a;
}

#ifndef CPPELEVEN
template <class T>
inline T max1(T a, T b) {
  return b < a ? a : b;
}
template <class T>
inline T max1(T a, T b, T c) {
  return max1(max1(a, b), c);
}
template <class T>
inline T max1(T a, T b, T c, T d) {
  return max1(max1(a, b, c), d);
}
template <class T>
inline T max1(T a, T b, T c, T d, T e) {
  return max1(max1(a, b, c, d), e);
}
template <class T>
inline T min1(T a, T b) {
  return a < b ? a : b;
}
template <class T>
inline T min1(T a, T b, T c) {
  return min1(min1(a, b), c);
}
template <class T>
inline T min1(T a, T b, T c, T d) {
  return min1(min1(a, b, c), d);
}
template <class T>
inline T min1(T a, T b, T c, T d, T e) {
  return min1(min1(a, b, c, d), e);
}
#else
template <typename t, typename t1>
t min1(t a, t1 b) {
  return a < b ? a : b;
}
template <typename t, typename... arg>
t min1(t a, arg... arr) {
  return min1(a, min1(arr...));
}
template <typename t, typename t1>
t max1(t a, t1 b) {
  return a > b ? a : b;
}
template <typename t, typename... arg>
t max1(t a, arg... arr) {
  return max1(a, max1(arr...));
}
#endif

inline int jud(double a, double b) {
  if (abs(a) < eps && abs(b) < eps)
    return 0;
  else if (abs1(a - b) / max(abs1(a), abs1(b)) < eps)
    return 0;
  if (a < b) return -1;
  return 1;
}
template <typename t>
inline int jud(t a, t b) {
  if (a < b) return -1;
  if (a == b) return 0;
  return 1;
}

template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1) {
  if (na == 0) return 0;
  int be = 0, en = na - 1;
  if (*a <= *(a + na - 1)) {
    if (f_lb == 0)
      while (be < en) {
        int mid = (be + en + 1) / 2;
        if (jud(*(a + mid), val) != 1)
          be = mid;
        else
          en = mid - 1;
      }
    else
      while (be < en) {
        int mid = (be + en) / 2;
        if (jud(*(a + mid), val) != -1)
          en = mid;
        else
          be = mid + 1;
      }
    if (f_small && jud(*(a + be), val) == 1) be--;
    if (!f_small && jud(*(a + be), val) == -1) be++;
  } else {
    if (f_lb)
      while (be < en) {
        int mid = (be + en + 1) / 2;
        if (jud(*(a + mid), val) != -1)
          be = mid;
        else
          en = mid - 1;
      }
    else
      while (be < en) {
        int mid = (be + en) / 2;
        if (jud(*(a + mid), val) != 1)
          en = mid;
        else
          be = mid + 1;
      }
    if (!f_small && jud(*(a + be), val) == -1) be--;
    if (f_small && jud(*(a + be), val) == 1) be++;
  }
  return be;
}

template <class T>
inline T lowb(T num) {
  return num & (-num);
}
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) {
  return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32);
}
inline int bitnum(ll nValue) {
  return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32);
}
inline int bitmaxl(ui a) {
  if (a == 0) return 0;
  return 32 - __builtin_clz(a);
}
inline int bitmaxl(int a) {
  if (a == 0) return 0;
  return 32 - __builtin_clz(a);
}
inline int bitmaxl(ull a) {
  int temp = a >> 32;
  if (temp) return 32 - __builtin_clz(temp) + 32;
  return bitmaxl(int(a));
}
inline int bitmaxl(ll a) {
  int temp = a >> 32;
  if (temp) return 32 - __builtin_clz(temp) + 32;
  return bitmaxl(int(a));
}
#else
#endif

long long pow(long long n, long long m, long long mod = 0) {
  if (m < 0) return 0;
  long long ans = 1;
  long long k = n;
  while (m) {
    if (m & 1) {
      ans *= k;
      if (mod) ans %= mod;
    }
    k *= k;
    if (mod) k %= mod;
    m >>= 1;
  }
  return ans;
}

#define MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
  if (mod == -1) mod = MOD;
  a += b;
  while (a >= mod) a -= mod;
  while (a < 0) a += mod;
}
template <class t>
void output1(t arr) {
  for (int i = 0; i < (int)arr.size(); i++) cerr << arr[i] << ' ';
  cerr << endl;
}
template <class t>
void output2(t arr) {
  for (int i = 0; i < (int)arr.size(); i++) output1(arr[i]);
}

//...................................................................

const int mod = 998244353;
int n, m;
pii orig[7];
// [max abs(x) delta to m][delta between neg x and pos x][..y..][..y..]
int dp[2][22][22 * 2][22][22 * 2];

int main() {
  ios_base::sync_with_stdio(0);
#ifdef DEBUG  //..................................................
  freopen("input.txt", "r", stdin);
#endif  //........................................................

  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &orig[i].first, &orig[i].second);
  }
  memset(dp, 0, sizeof(dp));
  int now = 0, nxt = 1;
  dp[now][0][21][0][21] = 1;
  for (int i = bitmaxl(m) - 1; i >= 0; i--) {
    memset(dp[nxt], 0, sizeof(dp[nxt]));
    for (int dmx = 0; dmx <= 17; dmx++) for (int dx = -16; dx <= 16; dx++) {
      for (int dmy = 0; dmy <= 17; dmy++) for (int dy = -16; dy <= 16; dy++) {
        if (dp[now][dmx][dx + 21][dmy][dy + 21]) for (int mask = 0; mask < 1 << n; mask++) {
          int px = 0, nx = 0, py = 0, ny = 0;
          for (int j = 0; j < n; j++) if (mask & (1 << j)) {
            if (orig[j].first > 0) px += orig[j].first;
            else nx -= orig[j].first;
            if (orig[j].second > 0) py += orig[j].second;
            else ny -= orig[j].second;
          }
          int dx_n = (dx * 2 + px - nx);
          if (abs(dx_n) > 16) continue;
          int dy_n = (dy * 2 + py - ny);
          if (abs(dy_n) > 16) continue;

          int a = 0, b = 0;
          int dmx_n = dmx * 2 + bool(m & (1 << i));
          a = dmx_n - px - (dx > 0 ? 0 : dx * 2);
          b = dmx_n - nx + (dx < 0 ? 0 : dx * 2);
          dmx_n = min(a, b);
          int dmy_n = dmy * 2 + bool(m & (1 << i));
          a = dmy_n - py - (dy > 0 ? 0 : dy * 2);
          b = dmy_n - ny + (dy < 0 ? 0 : dy * 2);
          dmy_n = min(a, b);
          if (dmx == 17 || dmx_n > 17) dmx_n = 17;
          if (dmy == 17 || dmy_n > 17) dmy_n = 17;
          if (dmx_n < 0 || dmy_n < 0) continue;
          add(dp[nxt][dmx_n][dx_n + 21][dmy_n][dy_n + 21],
              dp[now][dmx][dx + 21][dmy][dy + 21], mod);
        }
      }
    }
    swap(now, nxt);
  }
  int ans = 0;
  for (int i = 0; i <= 17; i++) for (int j = 0; j <= 17; j++) {
    add(ans, dp[now][i][21][j][21], mod);
  }
  cout << (ans - 1 + mod) % mod << endl;

  return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;
#define mp make_pair
#define f first
#define s second

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MOD = 998244353; // = (119<<23)+1
const int MX = 2e5+5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};

template<class T> bool ckmin(T& a, const T& b) {
	return a > b ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }
int pc(int x) { return __builtin_popcount(x); }

namespace input {
	template<class T> void re(complex<T>& x);
	template<class T1, class T2> void re(pair<T1,T2>& p);
	template<class T> void re(vector<T>& a);
	template<class T, size_t SZ> void re(array<T,SZ>& a);

	template<class T> void re(T& x) { cin >> x; }
	void re(double& x) { string t; re(t); x = stod(t); }
	void re(ld& x) { string t; re(t); x = stold(t); }
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t); re(ts...);
	}

	template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = {a,b}; }
	template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
	template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
	template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
	void pr(int x) { cout << x; }
	void pr(long x) { cout << x; }
	void pr(ll x) { cout << x; }
	void pr(unsigned x) { cout << x; }
	void pr(unsigned long x) { cout << x; }
	void pr(unsigned long long x) { cout << x; }
	void pr(float x) { cout << x; }
	void pr(double x) { cout << x; }
	void pr(ld x) { cout << x; }
	void pr(char x) { cout << x; }
	void pr(const char* x) { cout << x; }
	void pr(const string& x) { cout << x; }
	void pr(bool x) { pr(x ? "true" : "false"); }
	template<class T> void pr(const complex<T>& x) { cout << x; }

	template<class T1, class T2> void pr(const pair<T1,T2>& x);
	template<class T> void pr(const T& x);

	template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
		pr(t); pr(ts...);
	}
	template<class T1, class T2> void pr(const pair<T1,T2>& x) {
		pr("{",x.f,", ",x.s,"}");
	}
	template<class T> void pr(const T& x) {
		pr("{"); // const iterator needed for vector<bool>
		bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
		pr("}");
	}

	void ps() { pr("\n"); } // print w/ spaces
	template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
	}

	void pc() { pr("]\n"); } // debug w/ commas
	template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
	}
	#define dbg(x...) pr("[",#x,"] = ["), pc(x);
}

using namespace output;

namespace io {
	void setIn(string s) { freopen(s.c_str(),"r",stdin); }
	void setOut(string s) { freopen(s.c_str(),"w",stdout); }
	void setIO(string s = "") {
		ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
		// cin.exceptions(cin.failbit);
		// throws exception when do smth illegal
		// ex. try to read letter into int
		if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
	}
}

using namespace io;

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

/**
 * Description: modular arithmetic operations
 * Source:
	* KACTL
	* https://codeforces.com/blog/entry/63903
	* https://codeforces.com/contest/1261/submission/65632855 (tourist)
	* https://codeforces.com/contest/1264/submission/66344993 (ksun)
 * Verification:
	* https://open.kattis.com/problems/modulararithmetic
 */

// #include "../../contest/CppIO.h"

struct mi {
	typedef decay<decltype(MOD)>::type T;
 	/// don't silently convert to T
	T v; explicit operator T() const { return v; }
	mi() { v = 0; }
	mi(ll _v) {
		v = (-MOD < _v && _v < MOD) ? _v : _v % MOD;
		if (v < 0) v += MOD;
	}
	friend bool operator==(const mi& a, const mi& b) {
		return a.v == b.v; }
	friend bool operator!=(const mi& a, const mi& b) {
		return !(a == b); }
	friend bool operator<(const mi& a, const mi& b) {
		return a.v < b.v; }
	friend void re(mi& a) { ll x; re(x); a = mi(x); }
	friend void pr(const mi& a) { pr(a.v); }
	friend ostream& operator<<(ostream& os, const mi& a) {
		return os << a.v; }

	mi& operator+=(const mi& m) {
		if ((v += m.v) >= MOD) v -= MOD;
		return *this; }
	mi& operator-=(const mi& m) {
		if ((v -= m.v) < 0) v += MOD;
		return *this; }
	mi& operator*=(const mi& m) {
		v = (ll)v*m.v%MOD; return *this; }
	mi& operator/=(const mi& m) { return (*this) *= inv(m); }
	friend mi pow(mi a, ll p) {
		mi ans = 1; assert(p >= 0);
		for (; p; p /= 2, a *= a) if (p&1) ans *= a;
		return ans;
	}
	friend mi inv(const mi& a) { assert(a.v != 0);
		return pow(a,MOD-2); }

	mi operator-() const { return mi(-v); }
	mi& operator++() { return *this += 1; }
	mi& operator--() { return *this -= 1; }
	friend mi operator+(mi a, const mi& b) { return a += b; }
	friend mi operator-(mi a, const mi& b) { return a -= b; }
	friend mi operator*(mi a, const mi& b) { return a *= b; }
	friend mi operator/(mi a, const mi& b) { return a /= b; }
};
typedef vector<mi> vmi;
typedef pair<mi,mi> pmi;
typedef vector<pmi> vpmi;

vector<vmi> comb;
void genComb(int SZ) {
	comb.assign(SZ,vmi(SZ)); comb[0][0] = 1;
	FOR(i,1,SZ) F0R(j,i+1)
		comb[i][j] = comb[i-1][j]+(j?comb[i-1][j-1]:0);
}

int n,m;
mi dp[21][21][21][21][2][2], DP[21][21][21][21][2][2];

int main() {
	setIO(); re(n,m);
	vpi v(n); re(v);
	dp[0][0][0][0][0][0] = 1;
	while (m) {
		F0R(a,21) F0R(b,21) F0R(c,21) F0R(d,21) F0R(e,2) F0R(f,2)
			if (dp[a][b][c][d][e][f] != 0) {
				F0R(x,1<<n) {
					int A = a, B = b, C = c, D = d;
					F0R(y,n) if (x&(1<<y)) {
						A += max(v[y].f,0), B += max(-v[y].f,0);
						C += max(v[y].s,0), D += max(-v[y].s,0);
					}
					if ((A&1) == (B&1) && (C&1) == (D&1)) {
						int E = e; if ((A&1) != (m&1)) E = (A&1)>(m&1);
						int F = f; if ((C&1) != (m&1)) F = (C&1)>(m&1);
						DP[A/2][B/2][C/2][D/2][E][F] += dp[a][b][c][d][e][f];
					}
				}
			}
		F0R(a,21) F0R(b,21) F0R(c,21) F0R(d,21) F0R(e,2) F0R(f,2) {
			dp[a][b][c][d][e][f] = DP[a][b][c][d][e][f];
			DP[a][b][c][d][e][f] = 0;
		}
		m /= 2;
	}
	ps(dp[0][0][0][0][0][0]-1);
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
*/

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=(a);i<=(b);i++)
#define Fod(i,b,a) for (int i=(b);i>=(a);i--)
#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define outval(x) cerr<<#x" = "<<x<<endl
#define outv(x) cerr<<#x" = "<<x<<"  "
#define outtag(x) cerr<<"--------------"#x"---------------"<<endl
#define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";\
	For(_x,L,R) cerr<<a[_x]<<" ";cerr<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned uint;
typedef long double LD;
typedef vector <int> vi;
typedef pair <int,int> pii;
LL read(){
	LL x=0,f=0;
	char ch=getchar();
	while (!isdigit(ch))
		f=ch=='-',ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
const int N=5,mod=998244353;
void Add(int &x,int y){
	if ((x+=y)>=mod)
		x-=mod;
}
int n,m;
int x[N],y[N];
int dp[32][20][20][20][20][2][2];
int Px[1<<N],Py[1<<N],Nx[1<<N],Ny[1<<N];
int main(){
	n=read(),m=read();
	For(i,0,n-1)
		x[i]=read(),y[i]=read();
	For(s,0,(1<<n)-1)
		For(i,0,n-1)
			if (s>>i&1){
				(x[i]>0?Px:Nx)[s]+=abs(x[i]);
				(y[i]>0?Py:Ny)[s]+=abs(y[i]);
			}
	clr(dp);
	dp[0][0][0][0][0][0][0]=1;
	For(i,0,29){
		int bit=m>>i&1;
		For(px,0,19) For(py,0,19)
		For(nx,0,19) For(ny,0,19)
		For(kx,0,1) For(ky,0,1){
			int v=dp[i][px][py][nx][ny][kx][ky];
			if (!v)
				continue;
			For(s,0,(1<<n)-1){
				int a=px+Px[s],b=py+Py[s],c=nx+Nx[s],d=ny+Ny[s];
				if ((a&1)==(c&1)&&(b&1)==(d&1))
					Add(dp[i+1][a>>1][b>>1][c>>1][d>>1]
						[(a&1)>bit||(a&1)==bit&&kx]
						[(b&1)>bit||(b&1)==bit&&ky],v);
			}
		}
	}
	cout<<(dp[30][0][0][0][0][0][0]-1+mod)%mod<<endl;
	return 0;
}

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=(a);i<=(b);i++)
#define Fod(i,b,a) for (int i=(b);i>=(a);i--)
#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define outval(x) cerr<<#x" = "<<x<<endl
#define outv(x) cerr<<#x" = "<<x<<"  "
#define outtag(x) cerr<<"--------------"#x"---------------"<<endl
#define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";\
	For(_x,L,R) cerr<<a[_x]<<" ";cerr<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned uint;
typedef long double LD;
typedef vector <int> vi;
typedef pair <int,int> pii;
LL read(){
	LL x=0,f=0;
	char ch=getchar();
	while (!isdigit(ch))
		f=ch=='-',ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
const int N=5,mod=998244353;
void Add(int &x,int y){
	if ((x+=y)>=mod)
		x-=mod;
}
int n,m;
int x[N],y[N];
int dp[32][2][2][20][20][20][20];
int Px[1<<N],Py[1<<N],Nx[1<<N],Ny[1<<N];
int main(){
	n=read(),m=read();
	For(i,0,n-1)
		x[i]=read(),y[i]=read();
	For(s,0,(1<<n)-1)
		For(i,0,n-1)
			if (s>>i&1){
				(x[i]>0?Px:Nx)[s]+=abs(x[i]);
				(y[i]>0?Py:Ny)[s]+=abs(y[i]);
			}
	clr(dp);
	dp[0][0][0][0][0][0][0]=1;
	For(i,0,29){
		int bit=m>>i&1;
		For(kx,0,1) For(ky,0,1)
		For(px,0,19) For(py,0,19)
		For(nx,0,19) For(ny,0,19){
			int v=dp[i][kx][ky][px][py][nx][ny];
			if (!v)
				continue;
			For(s,0,(1<<n)-1){
				int a=px+Px[s],b=py+Py[s],c=nx+Nx[s],d=ny+Ny[s];
				if ((a&1)==(c&1)&&(b&1)==(d&1))
					Add(dp[i+1]
						[(a&1)>bit||(a&1)==bit&&kx]
						[(b&1)>bit||(b&1)==bit&&ky]
						[a>>1][b>>1][c>>1][d>>1],v);
			}
		}
	}
	cout<<(dp[30][0][0][0][0][0][0]-1+mod)%mod<<endl;
	return 0;
}

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=(a);i<=(b);i++)
#define Fod(i,b,a) for (int i=(b);i>=(a);i--)
#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define outval(x) cerr<<#x" = "<<x<<endl
#define outv(x) cerr<<#x" = "<<x<<"  "
#define outtag(x) cerr<<"--------------"#x"---------------"<<endl
#define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";\
	For(_x,L,R) cerr<<a[_x]<<" ";cerr<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned uint;
typedef long double LD;
typedef vector <int> vi;
typedef pair <int,int> pii;
LL read(){
	LL x=0,f=0;
	char ch=getchar();
	while (!isdigit(ch))
		f=ch=='-',ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
const int N=5,mod=998244353;
void Add(int &x,int y){
	if ((x+=y)>=mod)
		x-=mod;
}
int n,m;
int x[N],y[N];
int dp[32][20][20][20][20][2][2];
int Px[1<<N],Py[1<<N],Nx[1<<N],Ny[1<<N];
int main(){
	n=read(),m=read();
	For(i,0,n-1)
		x[i]=read(),y[i]=read();
	For(s,0,(1<<n)-1)
		For(i,0,n-1)
			if (s>>i&1){
				(x[i]>0?Px:Nx)[s]+=abs(x[i]);
				(y[i]>0?Py:Ny)[s]+=abs(y[i]);
			}
	clr(dp);
	dp[0][0][0][0][0][0][0]=1;
	For(i,0,29){
		int bit=m>>i&1;
		For(px,0,19) For(py,0,19)
		For(nx,0,19) For(ny,0,19)
		For(kx,0,1) For(ky,0,1){
			int v=dp[i][px][py][nx][ny][kx][ky];
			if (!v)
				continue;
//			printf("dp[%d][%d][%d][%d][%d][%d][%d]=%d\n"
//				,i,px,py,nx,ny,kx,ky,v);
			For(s,0,(1<<n)-1){
				int a=px+Px[s],b=py+Py[s],c=nx+Nx[s],d=ny+Ny[s];
				if ((a&1)==(c&1)&&(b&1)==(d&1))
					Add(dp[i+1][a>>1][b>>1][c>>1][d>>1]
						[(a&1)>bit||(a&1)==bit&&kx]
						[(b&1)>bit||(b&1)==bit&&ky],v);
			}
		}
	}
	cout<<(dp[30][0][0][0][0][0][0]-1+mod)%mod<<endl;
	return 0;
}
/*
ax1+bx2+cx3+dx4+ex5=0
ay1+by2+cy3+dy4+ey5=0
*/

#include <bits/stdc++.h>
#define MOD 998244353
using namespace std;
inline int add(int a,int b)
{a+=b;return a>=MOD?a-MOD:a;}
inline int sub(int a,int b)
{a-=b;return a<0?a+MOD:a;}
int f[30][21][21][17][17];
int n,m;
int lx=0,rx=0,ly=0,ry=0;
int xx1[32]={0},xx2[32]={0},yy1[32]={0},yy2[32]={0};
int G(int pos,int dx,int dy,int mx,int my)
{

	if(mx>0||my>0)return 0;
	mx=max(mx,-16),my=max(my,-16);
	if(dx<lx||dx>rx)return 0;
	if(dy<ly||dy>ry)return 0;
	if(pos<0)return dx==0&&dy==0;
	int res=f[pos][dx-lx][dy-ly][mx+16][my+16];
	if(res!=-1)return res;
	res=0;
	int dx1=dx*2,dy1=dy*2;
	int mx1=mx*2-(m>>pos&1),my1=my*2-(m>>pos&1);
	for(int i=0;i<(1<<n);i++)
		res=add(res,G(pos-1,dx1+xx1[i],dy1+yy1[i],mx1+xx2[i],my1+yy2[i]));
	return (f[pos][dx-lx][dy-ly][mx+16][my+16]=res);
}
#define lb(xx) (xx&(-xx))
void ini(int a[]){
	for(int i=0;i<(1<<n);i++)
		a[i]=a[lb(i)]+a[i^lb(i)];
}
int main()
{
	scanf("%d%d",&n,&m);
	int mnx=1e9,mny=1e9,mxx=-1e9,mxy=-1e9;
	for(int i=0,x,y;i<n;i++){
		scanf("%d%d",&x,&y);
		mnx=min(mnx,x),mny=min(mny,y);
		mxx=max(mxx,x),mxy=max(mxy,y);
		xx1[1<<i]=x,yy1[1<<i]=y;
		if(x>0){
			xx2[1<<i]=x;
			lx-=x;
		}
		else rx-=x;
		if(y>0){
			yy2[1<<i]=y;
			ly-=y;
		}
		else ry-=y;
	}
	if(mnx>0||mny>0||mxx<0||mxy<0)return puts("0")&0;
	memset(f,-1,sizeof(f));
	ini(xx1),ini(xx2),ini(yy1),ini(yy2);
	printf("%d\n",sub(G(29,0,0,0,0),1));
	return 0;
}

#include <bits/stdc++.h>
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define rep(i,N) for(long long i = 0; i < (long long)(N); i++)
#define repr(i,N) for(long long i = (long long)(N) - 1; i >= 0; i--)
#define rep1(i,N) for(long long i = 1; i <= (long long)(N) ; i++)
#define repr1(i,N) for(long long i = (N) ; (long long)(i) > 0 ; i--)
#define each(x,v) for(auto& x : v)
#define all(v) (v).begin(),(v).end()
#define sz(v) ((int)(v).size())
#define ini(...) int __VA_ARGS__; in(__VA_ARGS__)
#define inl(...) long long __VA_ARGS__; in(__VA_ARGS__)
#define ins(...) string __VA_ARGS__; in(__VA_ARGS__)
using namespace std; void solve();
using ll = long long; template<class T = ll> using V = vector<T>;
using vi = V<int>; using vl = V<>; using vvi = V< V<int> >;
constexpr int inf = 1001001001; constexpr ll infLL = (1LL << 61) - 1;
struct IoSetupNya {IoSetupNya() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); cerr << fixed << setprecision(7);} } iosetupnya;
template<typename T, typename U> inline bool amin(T &x, U y) { return (y < x) ? (x = y, true) : false; }
template<typename T, typename U> inline bool amax(T &x, U y) { return (x < y) ? (x = y, true) : false; }
template<typename T, typename U> ostream& operator <<(ostream& os, const pair<T, U> &p) { os << p.first << " " << p.second; return os; }
template<typename T, typename U> istream& operator >>(istream& is, pair<T, U> &p) { is >> p.first >> p.second; return is; }
template<typename T> ostream& operator <<(ostream& os, const vector<T> &v) { int s = (int)v.size(); rep(i,s) os << (i ? " " : "") << v[i]; return os; }
template<typename T> istream& operator >>(istream& is, vector<T> &v) { for(auto &x : v) is >> x; return is; }
void in(){} template <typename T,class... U> void in(T &t,U &...u){ cin >> t; in(u...);}
void out(){cout << "\n";} template <typename T,class... U> void out(const T &t,const U &...u){ cout << t; if(sizeof...(u)) cout << " "; out(u...);}
template<typename T>void die(T x){out(x); exit(0);}
#ifdef NyaanDebug
  #include "NyaanDebug.h"
  #define trc(...) do { cerr << #__VA_ARGS__ << " = "; dbg_out(__VA_ARGS__);} while(0)
  #define trca(v,N) do { cerr << #v << " = "; array_out(v , N);cout << endl;} while(0)
#else
  #define trc(...)
  #define trca(...)
  int main(){solve();}
#endif

#define in2(N,s,t) rep(i,N){in(s[i] , t[i]);}
#define in3(N,s,t,u) rep(i,N){in(s[i] , t[i] , u[i]);}
using vd = V<double>; using vs = V<string>; using vvl = V< V<> >;
template<typename T>using heap = priority_queue< T , V<T> , greater<T> >;

using P = pair<int,int>; using vp = V<P>;
constexpr int MOD = /** 1000000007; //*/ 998244353;
//////////////////

template< int mod >
struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }

  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }

  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }

  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }

  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

  bool operator==(const ModInt &p) const { return x == p.x; }

  bool operator!=(const ModInt &p) const { return x != p.x; }

  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }

  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }

  static int get_mod() { return mod; }
};

using modint = ModInt< MOD >;
using vm = vector<modint>;

constexpr int MAX = 21;
modint dp[MAX][MAX][MAX][MAX][2][2];
modint ep[MAX][MAX][MAX][MAX][2][2];

void solve(){
  ini(N , M);
  vp a(N); in(a);

  dp[0][0][0][0][0][0] = 1;
  while(M > 0){
    //trc(M);
    rep(acpx , MAX) rep(acnx , MAX) rep(acpy , MAX) rep(acny , MAX) rep(afx , 2) rep(afy , 2)
      ep[acpx][acnx][acpy][acny][afx][afy] = 0;

    rep(cpx , MAX) rep(cnx , MAX) rep(cpy , MAX) rep(cny , MAX) rep(fx , 2) rep(fy , 2)
    {
      modint cur = dp[cpx][cnx][cpy][cny][fx][fy];
      if(cur == 0) continue;
      //trc(cur , cpx , cnx , cpy , cny , fx , fy);
      rep(bit , 1 << N){
        int dpx = cpx;
        int dnx = cnx;
        int dpy = cpy;
        int dny = cny;
        rep(i , N){
          if( (bit >> i) & 1){
            dpx += max(0 , a[i].first);
            dnx -= min(0 , a[i].first);
            dpy += max(0 , a[i].second);
            dny -= min(0 , a[i].second);
          }
        }
        if( (dpx & 1) != (dnx & 1) ) continue;
        if( (dpy & 1) != (dny & 1) ) continue;
        int nfx = (dpx & 1) > (M & 1) ? 1 : (dpx & 1) < (M & 1) ? 0 : fx;
        int nfy = (dpy & 1) > (M & 1) ? 1 : (dpy & 1) < (M & 1) ? 0 : fy;
        dpx >>= 1; dnx >>= 1; dpy >>= 1; dny >>= 1;
        //trc(bit , dpx , dnx , dpy , dny , nfx , nfy);
        ep[dpx][dnx][dpy][dny][nfx][nfy] += cur;
      }

    }
    swap(dp , ep);
    M >>= 1;
  }
  out(dp[0][0][0][0][0][0] - 1);
}

/**
 *    author:  tourist
 *    created: 02.02.2020 17:52:33
**/
#include <bits/stdc++.h>

using namespace std;

template <typename T>
T inverse(T a, T m) {
  T u = 0, v = 1;
  while (a != 0) {
    T t = m / a;
    m -= t * a; swap(a, m);
    u -= t * v; swap(u, v);
  }
  assert(m == 1);
  return u;
}

template <typename T>
class Modular {
 public:
  using Type = typename decay<decltype(T::value)>::type;

  constexpr Modular() : value() {}
  template <typename U>
  Modular(const U& x) {
    value = normalize(x);
  }

  template <typename U>
  static Type normalize(const U& x) {
    Type v;
    if (-mod() <= x && x < mod()) v = static_cast<Type>(x);
    else v = static_cast<Type>(x % mod());
    if (v < 0) v += mod();
    return v;
  }

  const Type& operator()() const { return value; }
  template <typename U>
  explicit operator U() const { return static_cast<U>(value); }
  constexpr static Type mod() { return T::value; }

  Modular& operator+=(const Modular& other) { if ((value += other.value) >= mod()) value -= mod(); return *this; }
  Modular& operator-=(const Modular& other) { if ((value -= other.value) < 0) value += mod(); return *this; }
  template <typename U> Modular& operator+=(const U& other) { return *this += Modular(other); }
  template <typename U> Modular& operator-=(const U& other) { return *this -= Modular(other); }
  Modular& operator++() { return *this += 1; }
  Modular& operator--() { return *this -= 1; }
  Modular operator++(int) { Modular result(*this); *this += 1; return result; }
  Modular operator--(int) { Modular result(*this); *this -= 1; return result; }
  Modular operator-() const { return Modular(-value); }

  template <typename U = T>
  typename enable_if<is_same<typename Modular<U>::Type, int>::value, Modular>::type& operator*=(const Modular& rhs) {
#ifdef _WIN32
    uint64_t x = static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value);
    uint32_t xh = static_cast<uint32_t>(x >> 32), xl = static_cast<uint32_t>(x), d, m;
    asm(
      "divl %4; \n\t"
      : "=a" (d), "=d" (m)
      : "d" (xh), "a" (xl), "r" (mod())
    );
    value = m;
#else
    value = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value));
#endif
    return *this;
  }
  template <typename U = T>
  typename enable_if<is_same<typename Modular<U>::Type, int64_t>::value, Modular>::type& operator*=(const Modular& rhs) {
    int64_t q = static_cast<int64_t>(static_cast<long double>(value) * rhs.value / mod());
    value = normalize(value * rhs.value - q * mod());
    return *this;
  }
  template <typename U = T>
  typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs) {
    value = normalize(value * rhs.value);
    return *this;
  }

  Modular& operator/=(const Modular& other) { return *this *= Modular(inverse(other.value, mod())); }

  template <typename U>
  friend const Modular<U>& abs(const Modular<U>& v) { return v; }

  template <typename U>
  friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs);

  template <typename U>
  friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs);

  template <typename U>
  friend std::istream& operator>>(std::istream& stream, Modular<U>& number);

 private:
  Type value;
};

template <typename T> bool operator==(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value == rhs.value; }
template <typename T, typename U> bool operator==(const Modular<T>& lhs, U rhs) { return lhs == Modular<T>(rhs); }
template <typename T, typename U> bool operator==(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) == rhs; }

template <typename T> bool operator!=(const Modular<T>& lhs, const Modular<T>& rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator!=(const Modular<T>& lhs, U rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator!=(U lhs, const Modular<T>& rhs) { return !(lhs == rhs); }

template <typename T> bool operator<(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value < rhs.value; }

template <typename T> Modular<T> operator+(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }
template <typename T, typename U> Modular<T> operator+(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) += rhs; }
template <typename T, typename U> Modular<T> operator+(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }

template <typename T> Modular<T> operator-(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T, typename U> Modular<T> operator-(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T, typename U> Modular<T> operator-(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }

template <typename T> Modular<T> operator*(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T, typename U> Modular<T> operator*(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T, typename U> Modular<T> operator*(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }

template <typename T> Modular<T> operator/(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }
template <typename T, typename U> Modular<T> operator/(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) /= rhs; }
template <typename T, typename U> Modular<T> operator/(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }

template<typename T, typename U>
Modular<T> power(const Modular<T>& a, const U& b) {
  assert(b >= 0);
  Modular<T> x = a, res = 1;
  U p = b;
  while (p > 0) {
    if (p & 1) res *= x;
    x *= x;
    p >>= 1;
  }
  return res;
}

template <typename T>
bool IsZero(const Modular<T>& number) {
  return number() == 0;
}

template <typename T>
string to_string(const Modular<T>& number) {
  return to_string(number());
}

template <typename T>
std::ostream& operator<<(std::ostream& stream, const Modular<T>& number) {
  return stream << number();
}

template <typename T>
std::istream& operator>>(std::istream& stream, Modular<T>& number) {
  typename common_type<typename Modular<T>::Type, int64_t>::type x;
  stream >> x;
  number.value = Modular<T>::normalize(x);
  return stream;
}

/*
using ModType = int;

struct VarMod { static ModType value; };
ModType VarMod::value;
ModType& md = VarMod::value;
using Mint = Modular<VarMod>;
*/

constexpr int md = 998244353;
using Mint = Modular<std::integral_constant<decay<decltype(md)>::type, md>>;

const int MAX = 20;

Mint dp[MAX][MAX][MAX][MAX][2][2];
Mint new_dp[MAX][MAX][MAX][MAX][2][2];

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<int> x(n), y(n);
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }
  memset(dp, 0, sizeof(dp));
  dp[0][0][0][0][0][0] = 1;
  while (m > 0) {
    int bit = m & 1;
    memset(new_dp, 0, sizeof(new_dp));
    for (int cpx = 0; cpx < MAX; cpx++) {
      for (int cmx = 0; cmx < MAX; cmx++) {
        for (int cpy = 0; cpy < MAX; cpy++) {
          for (int cmy = 0; cmy < MAX; cmy++) {
            for (int fx = 0; fx < 2; fx++) {
              for (int fy = 0; fy < 2; fy++) {
                Mint ft = dp[cpx][cmx][cpy][cmy][fx][fy];
                if (ft == 0) {
                  continue;
                }
                for (int mask = 0; mask < (1 << n); mask++) {
                  int dpx = cpx;
                  int dpy = cpy;
                  int dmx = cmx;
                  int dmy = cmy;
                  for (int i = 0; i < n; i++) {
                    if (mask & (1 << i)) {
                      dpx += max(x[i], 0);
                      dmx -= min(x[i], 0);
                      dpy += max(y[i], 0);
                      dmy -= min(y[i], 0);
                    }
                  }
                  if ((dpx & 1) != (dmx & 1)) {
                    continue;
                  }
                  if ((dpy & 1) != (dmy & 1)) {
                    continue;
                  }
                  int new_fx = ((dpx & 1) > bit ? 1 : ((dpx & 1) < bit ? 0 : fx));
                  int new_fy = ((dpy & 1) > bit ? 1 : ((dpy & 1) < bit ? 0 : fy));
                  dpx >>= 1;
                  dmx >>= 1;
                  dpy >>= 1;
                  dmy >>= 1;
                //  assert(dpx < MAX && dpy < MAX && dmx < MAX && dmy < MAX);
                  new_dp[dpx][dmx][dpy][dmy][new_fx][new_fy] += ft;
                }
              }
            }
          }
        }
      }
    }
    swap(dp, new_dp);
    m >>= 1;
  }
  cout << dp[0][0][0][0][0][0] - 1 << '\n';
  return 0;
}

#include <bits/stdc++.h>

using namespace std;
const int MOD = 998244353;
const int MAX_N = 33;
const int MAX_M = 22;
int dp[MAX_N][MAX_M][MAX_M][MAX_M][MAX_M][2][2];
int cpx[50], cpy[50], cnx[50], cny[50];
int a[6], x[6], y[6];
int n, m;

int main () {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }
  for (int mask = 0; mask < (1 << n); mask++) {
    for (int i = 0; i < n; i++) {
      if ((mask & (1 << i)) > 0) {
        if (x[i] >= 0) {
          cpx[mask] += x[i];
        }
        else {
          cnx[mask] -= x[i];
        }
        if (y[i] >= 0) {
          cpy[mask] += y[i];
        }
        else {
          cny[mask] -= y[i];
        }
      }
    }
  }
  dp[0][0][0][0][0][0][0] = 1;
  for (int i = 0; i <= 31; i++) {
    for (int curpx = 0; curpx <= 20; curpx++) {
      for (int curpy = 0; curpy <= 20; curpy++) {
        for (int curnx = 0; curnx <= 20; curnx++) {
          for (int curny = 0; curny <= 20; curny++) {
            for (int stax = 0; stax <= 1; stax++) {
              for (int stay = 0; stay <= 1; stay++) {
                if (dp[i][curpx][curpy][curnx][curny][stax][stay] == 0) {
                  continue;
                }
                int cur = dp[i][curpx][curpy][curnx][curny][stax][stay];
                for (int mask = 0; mask < (1 << n); mask++) {
                  int nextpx = curpx + cpx[mask];
                  int nextpy = curpy + cpy[mask];
                  int nextnx = curnx + cnx[mask];
                  int nextny = curny + cny[mask];
                  if (((nextpx & 1) != (nextnx & 1)) || ((nextpy & 1) != (nextny & 1))) {
                    continue;
                  }
                  int bitx = nextpx & 1;
                  int bity = nextpy & 1;
                  int bitm = (m >> i) & 1;
                  int nstax = (bitx < bitm ? 0 : (bitx > bitm ? 1 : stax));
                  int nstay = (bity < bitm ? 0 : (bity > bitm ? 1 : stay));
                  (dp[i + 1][nextpx / 2][nextpy / 2][nextnx / 2][nextny / 2][nstax][nstay] += cur) %= MOD;
                }
              }
            }
          }
        }
      }
    }
  }
  cout << (dp[32][0][0][0][0][0][0] + MOD - 1) % MOD;
  return 0;
}

//CLOCKS_PER_SEC
using namespace std;
#include<bits/stdc++.h>
#define sqr(x) (x)*(x)
//#define sort stable_sort
#define ll long long
#define mk make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mk(mk(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define titose CLOCKS_PER_SEC
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt");
#define fast ios_base::sync_with_stdio(false);
inline void read(int &x){int v=0,f=1;char c=getchar();while (!isdigit(c)&&c!='-') c=getchar();if (c=='-') f=-1; else v=(c&15);while (isdigit(c=getchar())) v=(v<<1)+(v<<3)+(c&15);x=v*f;}
inline void read(ll &x){ll v=0ll,f=1ll;char c=getchar();while (!isdigit(c)&&c!='-') c=getchar();if (c=='-') f=-1; else v=(c&15);while (isdigit(c=getchar())) v=(v<<1)+(v<<3)+(c&15);x=v*f;}
inline void readc(char &x){char c;while (((c=getchar())==' ')||c=='\n');x=c;}
inline void writes(string s){puts(s.c_str());}
inline void writeln(){writes("");}
inline void writei(int x){if (x<0){putchar('-');x=abs(x);}if (!x) putchar('0');char a[25];int top=0;while (x){a[++top]=(x%10)+'0';x/=10;}while (top){putchar(a[top]);top--;}}
inline void writell(ll x){if (x<0){putchar('-');x=abs(x);}if (!x) putchar('0');char a[25];int top=0;while (x){a[++top]=(x%10)+'0';x/=10;}while (top){putchar(a[top]);top--;}}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii >
#define piipi pair<pii,int>
#define plll pair<ll,pll >
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
#define forup(i,a,b) for ((i)=(a);(i)<=(b);(i)++)
#define fordo(i,a,b) for ((i)=(a);(i)>=(b);(i)--)
#define rep(i,x) forup ((i),1,(x))
#define repd(i,x) fordo ((i),(x),1)
#define itr iterator
#define fe(itcalc,c) for(__typeof((c).begin()) itcalc=(c).begin();itcalc!=(c).end();itcalc++)
#define NO {cout<<"NO";return 0;}
#define YES {cout<<"YES";return 0;}
#define y0 y000000000000000000000000000
#define y1 y111111111111111111111111111
#define j0 j000000000000000000000000000
#define j1 j111111111111111111111111111
#define cl0(a) memset((a),(0),(sizeof((a))))
#define clz(a) memset((a),(0x16),(sizeof((a))))
#define clf(a) memset((a),(-(0x16)),(sizeof((a))))
#define inf 0x3bbbbbbb
#define lnf 0x1bbbbbbbbbbbbbbbll
#define sqrt divi
#define p2(i) (1ll<<(i))
#define readi read
#define readll read
/*************************************************/
int mod=998244353;
void add(int &x,int y)
{
	x+=y;
	if(x>=mod) x-=mod;
}
int n,m,i,j,msk,cpx,cnx,cpy,cny,bx,by,dp[31][21][21][21][21][2][2],x[15],y[15],px[1<<5],py[1<<5],nx[1<<5],ny[1<<5];
int main()
{
	read(n);read(m);
	rep(i,n){
		read(x[i]);
		read(y[i]);
	}
	forup(i,0,(1<<n)-1){
		rep(j,n){
			if((i>>(j-1))&1){
				(x[j]>0?px[i]:nx[i])+=abs(x[j]);
				(y[j]>0?py[i]:ny[i])+=abs(y[j]);
			}
		}
	}
	dp[0][0][0][0][0][0][0]=1;
	forup(i,0,29){
		forup(cpx,0,19)forup(cnx,0,19)forup(cpy,0,19)forup(cny,0,19){
			forup(bx,0,1)forup(by,0,1)if(dp[i][cpx][cnx][cpy][cny][bx][by]){
				forup(msk,0,(1<<n)-1){
					int npx=cpx+px[msk];
					int npy=cpy+py[msk];
					int nnx=cnx+nx[msk];
					int nny=cny+ny[msk];
					if((npx&1)!=(nnx&1)) continue;
					if((npy&1)!=(nny&1)) continue;
					int cx=(npx&1),cy=(npy&1);
					int mx=((m>>i)&1),my=mx;
					add(dp[i+1][npx>>1][nnx>>1][npy>>1][nny>>1][(cx==mx)?bx:(cx>mx)][(cy==my)?by:(cy>my)],dp[i][cpx][cnx][cpy][cny][bx][by]);
				}
			}
		}
	}
	cout<<(dp[30][0][0][0][0][0][0]+mod-1)%mod;
	return 0;
}

#include<bits/stdc++.h>
typedef long long ll;
#define mod 998244353
ll gi(){
	ll x=0,f=1;
	char ch=getchar();
	while(!isdigit(ch))f^=ch=='-',ch=getchar();
	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
	return f?x:-x;
}
int vx[6],vy[6],spx[66],spy[66],snx[66],sny[66];
int f[33][21][21][21][21][2][2];
void add(int&a,int b){a=a+b>=mod?a+b-mod:a+b;}
int main(){
#ifdef XZZSB
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int n=gi(),m=gi();
	for(int i=1;i<=n;++i)vx[i]=gi(),vy[i]=gi();
	for(int i=0;i<1<<n;++i)
		for(int j=1;j<=n;++j)
			if(i>>j-1&1)(vx[j]>0?spx:snx)[i]+=abs(vx[j]),(vy[j]>0?spy:sny)[i]+=abs(vy[j]);
	int lpx=spx[(1<<n)-1],lnx=snx[(1<<n)-1],lpy=spy[(1<<n)-1],lny=sny[(1<<n)-1];
	if(lpx<1)lpx=1;if(lnx<1)lnx=1;if(lpy<1)lpy=1;if(lny<1)lny=1;
	int li=32-__builtin_clz(m);
	f[0][0][0][0][0][1][1]=1;
	for(int i=0,rm;i<li;++i){
		rm=m>>i&1;
		for(int px=0;px<lpx;++px)
			for(int nx=0;nx<lnx;++nx)
				for(int py=0;py<lpy;++py)
					for(int ny=0;ny<lny;++ny)
						for(int fx=0;fx<2;++fx)
							for(int fy=0;fy<2;++fy)
								if(f[i][px][nx][py][ny][fx][fy]){
									for(int S=0;S<1<<n;++S){
										int npx=px+spx[S];
										int nnx=nx+snx[S];
										int npy=py+spy[S];
										int nny=ny+sny[S];
										if((npx^nnx)&1)continue;if((npy^nny)&1)continue;
										int rx=npx&1,ry=npy&1;
										add(f[i+1][npx/2][nnx/2][npy/2][nny/2][fx&(rx<=rm)|(rx<rm)][fy&(ry<=rm)|(ry<rm)],f[i][px][nx][py][ny][fx][fy]);
									}
								}
	}
	printf("%d\n",(mod+f[li][0][0][0][0][1][1]-1)%mod);
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 5
#define MX (4*N)
#define mo 998244353
int n,m,x[N],y[N];
int dnx[1<<N],dpx[1<<N],dny[1<<N],dpy[1<<N];
int f[31][MX+1][MX+1][MX+1][MX+1][2][2];
inline void upd(int &a,int b){a+=b;a-=(a>=mo?mo:0);}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&n,&m);
	for (int i=0;i<n;++i)
		scanf("%d%d",&x[i],&y[i]);
	for (int i=0;i<1<<n;++i)
		for (int j=0;j<n;++j)
			if (i>>j&1){
				(x[j]<0?dnx[i]:dpx[i])+=abs(x[j]);
				(y[j]<0?dny[i]:dpy[i])+=abs(y[j]);
			}
	f[0][0][0][0][0][0][0]=1;
	int i=0;
	for (;1<<i<=m;++i)
		for (int nx=0;nx<=MX;++nx)
			for (int px=0;px<=MX;++px)
				for (int ny=0;ny<=MX;++ny)
					for (int py=0;py<=MX;++py)
						for (int cx=0;cx<=1;++cx)
							for (int cy=0;cy<=1;++cy){
								int val=f[i][nx][px][ny][py][cx][cy];
								if (val==0)
									continue;
								for (int s=0;s<1<<n;++s){
									int nnx=nx+dnx[s],npx=px+dpx[s];
									int nny=ny+dny[s],npy=py+dpy[s];
									if ((nnx&1)!=(npx&1) || (nny&1)!=(npy&1))
										continue;
									int ncx=((npx&1)>(m>>i&1)?1:(npx&1)<(m>>i&1)?0:cx);
									int ncy=((npy&1)>(m>>i&1)?1:(npy&1)<(m>>i&1)?0:cy);
									upd(f[i+1][nnx>>1][npx>>1][nny>>1][npy>>1][ncx][ncy],val);
								}
							}
	printf("%d\n",(f[i][0][0][0][0][0][0]-1+mo)%mo);
	return 0;
}

#include <cstdio>

using ll = long long;
#define tl(X) static_cast<ll>(X)
#define ti(X) static_cast<int>(X)
const int MOD = 998244353;

//copied from benq
struct mint
{
public:
	int val;
	mint(int _val = 0) : val(_val)
	{
		val = (-MOD <= val && val < MOD) ? val : val%MOD;
		if(val < 0) val += MOD;
	}
	explicit operator int () const {return val;}

	mint operator -() const {return mint(-val);}
	mint& operator += (mint m) {if((val += m.val) >= MOD) val -= MOD; return *this;}
	mint& operator -= (mint m) {if((val -= m.val) < 0) val += MOD; return *this;}
	mint& operator *= (mint m) {val = ti(tl(val)*m.val%MOD); return *this;}

	friend mint pow(mint a, int p)
	{
		mint r(1);
		for(;p;p>>=1, a*=a) if(p&1) r*=a;
		return r;
	}

	friend mint operator + (mint a, mint b) {return a += b;}
	friend mint operator - (mint a, mint b) {return a -= b;}
	friend mint operator * (mint a, mint b) {return a *= b;}
};

const int MN = 5, MX = 20, LG = 30;
int N, M;
int x[MN], y[MN];
mint dp[2][MX][MX][MX][MX][2][2];
/*
conditions:
	+x = -x
	+y = -y
	+x <= M
	+y <= M
	*/

int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i = 0;i < N;++i)
		scanf("%d%d", x+i, y+i);
	dp[0][0][0][0][0][0][0] = mint(1);
	for(int i = M;i;i>>=1)
	{
		bool m = i&1;
		for(int px = 0;px < MX;++px)
			for(int nx = 0;nx < MX;++nx)
				for(int py = 0;py < MX;++py)
					for(int ny = 0;ny < MX;++ny)
						for(int xm = 0;xm < 2;++xm)
							for(int ym = 0;ym < 2;++ym)
								if(ti(dp[0][px][nx][py][ny][xm][ym]))
									for(int mask = 0;mask < 1<<N;++mask)
									{
										int px1 = px, nx1 = nx, py1 = py, ny1 = ny;
										for(int k = 0;k < mask;++k)
											if(mask>>k&1)
											{
												if(x[k]>0) px1 += x[k];
												else nx1 -= x[k];
												if(y[k]>0) py1 += y[k];
												else ny1 -= y[k];
											}
										if(1&(nx1^px1) || 1&(ny1^py1)) continue;
										bool vx1 = nx1&1, vy1 = ny1&1;
										dp[1][px1>>1][nx1>>1][py1>>1][ny1>>1][m==vx1?xm:vx1][m==vy1?ym:vy1] += dp[0][px][nx][py][ny][xm][ym];
									}
		for(int px = 0;px < MX;++px)
			for(int nx = 0;nx < MX;++nx)
				for(int py = 0;py < MX;++py)
					for(int ny = 0;ny < MX;++ny)
						for(int xm = 0;xm < 2;++xm)
							for(int ym = 0;ym < 2;++ym)
								dp[0][px][nx][py][ny][xm][ym] = dp[1][px][nx][py][ny][xm][ym], dp[1][px][nx][py][ny][xm][ym] = mint(0);
	}
	// subtract off zero vector
	printf("%d\n", ti(dp[0][0][0][0][0][0][0]-mint(1)));
	return 0;
}

#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
cs int Mod = 998244353;
void Add(int &a, int b){ a = (a + b) >= Mod ? a + b - Mod : a + b; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
cs int N = 35, M = 21;
int n, m, f[2][M][M][M][M][2][2];
int x[N], y[N];
int dx[N], dy[N], tx[N], ty[N];
int main(){
	#ifdef FSYo
	freopen("1.in", "r", stdin);
	#endif
	cin >> n >> m;
	int u = (1 << n) - 1;
	f[0][0][0][0][0][0][0] = 1;
	for(int i = 0; i < n; i++)
	scanf("%d%d", &x[i], &y[i]);
	for(int s = 0; s <= u; s++)
	for(int i = 0; i < n; i++)
	if(s >> i & 1){
		if(x[i] < 0) dx[s] += -x[i];
		else tx[s] += x[i];
		if(y[i] < 0) dy[s] += -y[i];
		else ty[s] += y[i];
	}
	int now = 0, nxt = 1;
	for(int i = 0; i < 31; i++){
	memset(f[nxt], 0, sizeof(f[nxt]));
	for(int j = 0; j <= dx[u]; j++)
	for(int k = 0; k <= tx[u]; k++)
	for(int l = 0; l <= dy[u]; l++)
	for(int r = 0; r <= ty[u]; r++)
	for(int o = 0; o < 2; o++)
	for(int e = 0, c; e < 2; e++)
	if(c = f[now][j][k][l][r][o][e])
	for(int t = 0; t <= u; t++){
		int _dx = j + dx[t];
		int _tx = k + tx[t];
		int _dy = l + dy[t];
		int _ty = r + ty[t];
		if((_dx + _tx) & 1) continue;
		if((_dy + _ty) & 1) continue;
		int a = _tx & 1, b = _ty & 1;
		_dx >>= 1, _tx >>= 1;
		_dy >>= 1, _ty >>= 1;
		int _o, _e, z = m >> i & 1;
		_o = a > z ? true : (a < z ? false : o);
		_e = b > z ? true : (b < z ? false : e);
		Add(f[nxt][_dx][_tx][_dy][_ty][_o][_e], c);
	} swap(now, nxt);
	} cout << dec(f[now][0][0][0][0][0][0], 1);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef bool boolean;

// missed charactors / ?

template <typename T>
boolean vmin(T& a, T b) {
  return (a > b) ? (a = b, true) : (false);
}
template <typename T>
boolean vmax(T& a, T b) {
  return (a < b) ? (a = b, true) : (false);
}

template <typename T>
T smax(T x) {
  return x;
}
template <typename T, typename ...K>
T smax(T a, const K &...args) {
  return max(a, smax(args...));
}

template <typename T>
T smin(T x) {
  return x;
}
template <typename T, typename ...K>
T smin(T a, const K &...args) {
  return min(a, smin(args...));
}

// debugging lib

#define VN(x) #x
#define Vmsg(x) VN(x) << " = " << (x)
#define printv(x) cerr << VN(x) << " = " << (x);
#define debug(...) fprintf(stderr, __VA_ARGS__);

template <typename A, typename B>
ostream& operator << (ostream& os, const pair<A, B>& z) {
  os << "(" << z.first << ", " << z.second << ')';
  return os;
}
template <typename T>
ostream& operator << (ostream& os, const vector<T>& a) {
  boolean isfirst = true;
  os << "{";
  for (auto z : a) {
    if (!isfirst) {
      os << ", ";
    }
    os << z;
    isfirst = false;
  }
  os << '}';
  return os;
}

#define ll long long

void exgcd(int a, int b, int& x, int& y) {
  if (!b) {
    x = 1, y = 0;
  } else {
    exgcd(b, a % b, y, x);
    y -= (a / b) * x;
  }
}

int inv(int a, int n) {
  int x, y;
  exgcd(a, n, x, y);
  return (x < 0) ? (x + n) : (x);
}

const int Mod = 998244353;

template <const int Mod = :: Mod>
class Z {
  public:
    int v;

    Z() : v(0) {	}
    Z(int x) : v(x){	}
    Z(ll x) : v(x % Mod) {	}

    friend Z operator + (const Z& a, const Z& b) {
      int x;
      return Z(((x = a.v + b.v) >= Mod) ? (x - Mod) : (x));
    }
    friend Z operator - (const Z& a, const Z& b) {
      int x;
      return Z(((x = a.v - b.v) < 0) ? (x + Mod) : (x));
    }
    friend Z operator * (const Z& a, const Z& b) {
      return Z(a.v * 1ll * b.v);
    }
    friend Z operator ~(const Z& a) {
      return inv(a.v, Mod);
    }
    friend Z operator - (const Z& a) {
      return Z(0) - a;
    }
    Z& operator += (Z b) {
      return *this = *this + b;
    }
    Z& operator -= (Z b) {
      return *this = *this - b;
    }
    Z& operator *= (Z b) {
      return *this = *this * b;
    }
    friend boolean operator == (const Z& a, const Z& b) {
      return a.v == b.v;
    }
};

Z<> qpow(Z<> a, int p) {
  Z<> rt = Z<>(1), pa = a;
  for ( ; p; p >>= 1, pa = pa * pa) {
    if (p & 1) {
      rt = rt * pa;
    }
  }
  return rt;
}

typedef Z<> Zi;

const int N = 5, N4 = N << 2, S = 1 << 5;

int abs(int x) {
  return x < 0 ? -x : x;
}

int n, m;
int x[N], y[N];
int px[S], nx[S], py[S], ny[S];
Zi f[32][N4][N4][N4][N4][2][2];

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++)
    cin >> x[i] >> y[i];
  for (int s = 0; s < (1 << n); s++) {
    for (int i = 0; i < n; i++) {
      if ((s >> i) & 1) {
        ((x[i] < 0) ? nx : px)[s] += abs(x[i]);
        ((y[i] < 0) ? ny : py)[s] += abs(y[i]);
      }
    }
  }
  int mpx = max(1, px[(1 << n) - 1]);
  int mnx = max(1, nx[(1 << n) - 1]);
  int mpy = max(1, py[(1 << n) - 1]);
  int mny = max(1, ny[(1 << n) - 1]);
  int bit = 0;
  f[0][0][0][0][0][0][0] = 1;
  for ( ; (1 << bit) <= m; bit++) {
    for (int cpx = 0; cpx < mpx; cpx++) {
      for (int cnx = 0; cnx < mnx; cnx++) {
        for (int cpy = 0; cpy < mpy; cpy++) {
          for (int cny = 0; cny < mny; cny++) {
            for (int olx = 0; olx < 2; olx++) {
              for (int oly = 0; oly < 2; oly++) {
                Zi v = f[bit][cpx][cnx][cpy][cny][olx][oly];
                if (!v.v)
                  continue;
                for (int msk = 0; msk < (1 << n); msk++) {
                  int vpx = cpx + px[msk];
                  int vnx = cnx + nx[msk];
                  int vpy = cpy + py[msk];
                  int vny = cny + ny[msk];
                  if (((vpx ^ vnx) & 1) | ((vpy ^ vny) & 1))
                    continue;
                  int vx = vpx & 1, vy = vpy & 1, bm = (m >> bit) & 1;
                  int nolx = (vx == bm) ? (olx) : (vx > bm);
                  int noly = (vy == bm) ? (oly) : (vy > bm);
                  f[bit + 1][vpx >> 1][vnx >> 1][vpy >> 1][vny >> 1][nolx][noly] += v;
                }
              }
            }
          }
        }
      }
    }
  }
  Zi ans = f[bit][0][0][0][0][0][0] - 1;
  cout << ans.v << '\n';
  return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int mo=998244353,M=16;
int n,m,a[35],x[10],y[10];
int f[31][M][M][M][M][2][2];
bool v[31][M][M][M][M][2][2];
int F(int bit,int JW1,int JW2,int JW3,int JW4,int fl1,int fl2){
	if (bit==30) return !JW1&&!JW2&&!JW3&&!JW4&&fl1&&fl2;
	if (v[bit][JW1][JW2][JW3][JW4][fl1][fl2])
		return f[bit][JW1][JW2][JW3][JW4][fl1][fl2];
	v[bit][JW1][JW2][JW3][JW4][fl1][fl2]=1;
	int &ans=f[bit][JW1][JW2][JW3][JW4][fl1][fl2];
	For(sta,0,(1<<n)-1){
		int NJW1=JW1,NJW2=JW2,NJW3=JW3,NJW4=JW4;
		For(i,1,n) if (sta&(1<<(i-1))){
			if (x[i]<=0) NJW1-=x[i];
			if (y[i]<=0) NJW2-=y[i];
			if (x[i]>=0) NJW3+=x[i];
			if (y[i]>=0) NJW4+=y[i];
		}
		if (((NJW1^NJW3)&1)||((NJW2^NJW4)&1)) continue;
		int nfl1=((NJW3&1)==a[bit]?fl1:(NJW3&1)<a[bit]);
		int nfl2=((NJW4&1)==a[bit]?fl2:(NJW4&1)<a[bit]);
		NJW1/=2; NJW2/=2; NJW3/=2; NJW4/=2;
		ans=(ans+F(bit+1,NJW1,NJW2,NJW3,NJW4,nfl1,nfl2))%mo;
	}
	return ans;
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,0,29) a[i]=(m>>i)&1;
	bool fl1=0,fl2=0,fl3=0,fl4=0;
	For(i,1,n){
		scanf("%d%d",&x[i],&y[i]);
		fl1|=(x[i]<0); fl2|=(x[i]>0);
		fl3|=(y[i]<0); fl4|=(y[i]>0);
	}
	if (!fl1||!fl2||!fl3||!fl4)	return puts("0"),0;
	printf("%d\n",(F(0,0,0,0,0,1,1)+mo-1)%mo);
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int mo=998244353,M=20;
int n,m,a[35],x[10],y[10];
int f[35][2*M][2*M][M][M][2][2];
int v[35][2*M][2*M][M][M][2][2];
int F(int bit,int JW1,int JW2,int JW3,int JW4,int fl1,int fl2){
	if (bit==30) return !JW1&&!JW2&&!JW3&&!JW4&&fl1&&fl2;
	if (v[bit][JW1+M][JW2+M][JW3][JW4][fl1][fl2])
		return f[bit][JW1+M][JW2+M][JW3][JW4][fl1][fl2];
	v[bit][JW1+M][JW2+M][JW3][JW4][fl1][fl2]=1;
	int &ans=f[bit][JW1+M][JW2+M][JW3][JW4][fl1][fl2];
	For(sta,0,(1<<n)-1){
		int NJW1=JW1,NJW2=JW2,NJW3=JW3,NJW4=JW4;
		For(i,1,n) if (sta&(1<<(i-1))){
			NJW1+=x[i]; NJW2+=y[i];
			if (x[i]>=0) NJW3+=x[i];
			if (y[i]>=0) NJW4+=y[i];
		}
		if ((NJW1&1)||(NJW2&1)) continue;
		int nfl1=((NJW3&1)==a[bit]?fl1:(NJW3&1)<a[bit]);
		int nfl2=((NJW4&1)==a[bit]?fl2:(NJW4&1)<a[bit]);
		NJW1/=2; NJW2/=2; NJW3/=2; NJW4/=2;
		ans=(ans+F(bit+1,NJW1,NJW2,NJW3,NJW4,nfl1,nfl2))%mo;
	}
	return ans;
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,0,29) a[i]=(m>>i)&1;
	bool fl1=0,fl2=0,fl3=0,fl4=0;
	For(i,1,n){
		scanf("%d%d",&x[i],&y[i]);
	    fl1|=(x[i]<0); fl2|=(x[i]>0);
		fl3|=(y[i]<0); fl4|=(y[i]>0);
	}
	if (!fl1||!fl2||!fl3||!fl4)	return puts("0"),0;
	printf("%d\n",(F(0,0,0,0,0,1,1)+mo-1)%mo);
}
/*
+ +
+ -
- -

f[i][a][b][c][d]:

前i个数字,x和的进位为a,y和的进位为b,x最大值的进位为c,y最大值的进位为d,
x最大值前缀是否合法，y最大值前缀是否合法
*/

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define Mod 998244353
using namespace std;
void add(int& x,int y)
{
	x+=y;
	if(x>=Mod)x-=Mod;
	return ;
}
int dp[32][21][21][21][21][2][2];
int x[6],y[6];
int n,m;
//a,b:x c,d:y e,f:limit
void work(int i,int a,int b,int c,int d,int e,int f,int state)
{
	int val=dp[i][a][b][c][d][e][f];
	int curbit=(m>>i)&1;
	for(int j=0;j<n;j++)
		if(state&(1<<j))
		{
			if(x[j]>=0)a+=x[j];
			else b-=x[j];
			if(y[j]>=0)c+=y[j];
			else d-=y[j];
		}
	if((a&1)!=(b&1))return ;
	if((c&1)!=(d&1))return ;
	if((a&1)&&!curbit)e=1;
	if(!(a&1)&&curbit)e=0;
	if((c&1)&&!curbit)f=1;
	if(!(c&1)&&curbit)f=0;
	a>>=1;b>>=1;c>>=1;d>>=1;
	add(dp[i+1][a][b][c][d][e][f],val);
	return ;
}
int main()
{
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
		scanf("%d %d",&x[i],&y[i]);
	dp[0][0][0][0][0][0][0]=1;
	for(int i=0;i<=30;i++)
		for(int a=0;a<=4*n;a++)
			for(int b=0;b<=4*n;b++)
				for(int c=0;c<=4*n;c++)
					for(int d=0;d<=4*n;d++)
						for(int e=0;e<2;e++)
							for(int f=0;f<2;f++)
								if(dp[i][a][b][c][d][e][f])
									for(int state=0;state<(1<<n);state++)
										work(i,a,b,c,d,e,f,state);
	printf("%d\n",(dp[31][0][0][0][0][0][0]-1+Mod)%Mod);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ref(i,x,y)for(int i=x;i<=y;++i)
#define def(i,x,y)for(int i=x;i>=y;--i)
#define pb push_back
#define SZ(x) ((int)x.size())
#define mp make_pair
#define fi first
#define se second
typedef vector<int> vint;
typedef long long LL;
const int S=22,T=9;
const int mod=998244353;
int n,m,x[6],y[6],dp[31][S+1][S+1][T+1][T+1];
void inc(int&a,int b){a+=b;if(a>=mod)a-=mod;}
int main(){
	cin>>n>>m;
	ref(i,1,n)cin>>x[i]>>y[i];
	int totx=0,toty=0;
	ref(i,1,n)if(x[i]>0)totx++;if(totx>n/2)ref(i,1,n)x[i]=-x[i];
	ref(i,1,n)if(y[i]>0)toty++;if(toty>n/2)ref(i,1,n)y[i]=-y[i];
	totx=toty=0;
	ref(i,1,n)if(x[i]>0)totx++;ref(i,1,n)if(y[i]>0)toty++;
	int bx=totx*4+1,by=toty*4+1;
	dp[30][bx][by][0][0]=1;
	def(i,29,0){
		ref(i1,0-bx,S-bx)ref(i2,0-by,S-by)ref(i3,0,T)ref(i4,0,T)
			if(dp[i+1][i1+bx][i2+by][i3][i4])
			ref(J,0,(1<<n)-1){
				int I1=i1<<1,I2=i2<<1,I3=i3<<1|(m>>i&1),I4=i4<<1|(m>>i&1);
				ref(j,1,n)if(J>>j-1&1){
					I1+=x[j];I2+=y[j];
					if(x[j]>0)I3-=x[j];if(y[j]>0)I4-=y[j];
				}
				I1+=bx;I2+=by;I3=min(I3,T);I4=min(I4,T);
				if(I1>=0&&I1<=S&&I2>=0&&I2<=S&&I3>=0&&I4>=0)
					inc(dp[i][I1][I2][I3][I4],dp[i+1][i1+bx][i2+by][i3][i4]);
			}
	}
	int ans=0;
	ref(i,0,T)ref(j,0,T)inc(ans,dp[0][bx][by][i][j]);
	cout<<(ans+mod-1)%mod<<endl;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long double ld;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

const int MOD = 998244353;
int add(int a, int b)
{
	a+=b;
	while(a>=MOD) a-=MOD;
	return a;
}
void radd(int &a, int b)
{
	a=add(a,b);
}

const int LG = 31;

int minbit(int x)
{
	if(x==0) return int(1e9);
	x=abs(x);
	for(int i=0;i<LG;i++)
	{
		if(x&(1<<i))
		{
			return i;
		}
	}
	assert(0);
}

bool cmp(const ii &a, const ii &b)
{
	return (min(minbit(a.fi),minbit(a.se))>min(minbit(b.fi),minbit(b.se)));
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n,m; cin>>n>>m;
	m*=2;
	vector<ii> vec;
	for(int i=0;i<n;i++)
	{
		int x,y; cin>>x>>y;
		ll cx=x; ll cy=y;
		while(max(abs(cx),abs(cy))<=m)
		{
			vec.pb({cx,cy});
			cx<<=1; cy<<=1;
		}
	}
	sort(vec.begin(),vec.end(),cmp);
	map<vi,int> old_dp; //state = {sum_x, sum_y, sum_abs_x, sum_abs_y} (sum_abs is -1 if I don't care about the prefix anymore)
	old_dp[{0,0,0,0}]=1;
	for(int z=0;z<vec.size();z++)
	{
		int x=vec[z].fi; int y=vec[z].se;
		ll sumabsx = 0; ll sumabsy=0;
		for(int z2=z+1;z2<vec.size();z2++)
		{
			sumabsx+=abs(vec[z2].fi);
			sumabsy+=abs(vec[z2].se);
		}
		map<vi,int> new_dp;
		for(auto X:old_dp)
		{
			vi state = X.fi; int val = X.se;
			if(val==0) continue;
			if(abs(state[0])<=sumabsx&&abs(state[1])<=sumabsy)
			{
				ii tmp = {state[2],state[3]};
				if(state[2]!=-1&&state[2]+sumabsx<=m) state[2]=-1;
				if(state[3]!=-1&&state[3]+sumabsy<=m) state[3]=-1;
				radd(new_dp[state],val); //don't take (x,y)
				state[2]=tmp.fi; state[3]=tmp.se;
			}
			//take (x,y)
			ll nwx=state[0]+1LL*x;
			ll nwy=state[1]+1LL*y;
			if(abs(nwx)>sumabsx||abs(nwy)>sumabsy) continue;
			state[0]+=x; state[1]+=y;
			if(state[2]!=-1)
			{
				ll tmp = state[2]+1LL*abs(x);
				if(tmp>m) continue;
				state[2]+=abs(x);
				if(state[2]+sumabsx<=m) state[2]=-1;
			}
			if(state[3]!=-1)
			{
				ll tmp = state[3]+1LL*abs(y);
				if(tmp>m) continue;
				state[3]+=abs(y);
				if(state[3]+sumabsy<=m) state[3]=-1;
			}
			radd(new_dp[state],val);
		}
		old_dp = new_dp;
	}
	//answer minus 1 because empty polygon
	int ans=MOD-1;
	for(auto X:old_dp)
	{
		if(X.fi[0]==0&&X.fi[1]==0) radd(ans,X.se);
	}
	cout<<ans<<'\n';
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAXN = 5, MAXL = 31, MAXC = 4*MAXN + 1;
const int MOD = 998244353;
int dp[MAXL][MAXC][MAXC][MAXC][MAXC][2][2];
/* current prefix, carry (neg/pos) (x/y), x > n, y > n */

int x[5], y[5], sum_nx[32], sum_px[32], sum_ny[32], sum_py[32];

void add(int &a, int b) {
    a += b;
    if(a >= MOD)
        a -= MOD;
}

int main() {
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < n; i++)
        cin >> x[i] >> y[i];
    for(int msk = 0; msk < (1 << n); msk++) {
        for(int i = 0; i < n; i++)
            if(msk & (1 << i)) {
                sum_px[msk] += x[i] * (x[i] > 0);
                sum_nx[msk] -= x[i] * (x[i] < 0);
                sum_py[msk] += y[i] * (y[i] > 0);
                sum_ny[msk] -= y[i] * (y[i] < 0);
            }
    }
    dp[0][0][0][0][0][0][0] = 1;
    for(int pref = 0; (1 << pref) <= m; pref++) {
        int q = (1 << pref);
        for(int cnx = 0; cnx < 4 * n; cnx++) {
            for(int cny = 0; cny < 4 * n; cny++) {
                for(int cpx = 0; cpx < 4 * n; cpx++) {
                    for(int cpy = 0; cpy < 4 * n; cpy++) {
                        for(int gex = 0; gex < 2; gex++) {
                            for(int gey = 0; gey < 2; gey++) {
                                for(int msk = 0; msk < (1 << n); msk++) {
                                    int nnx = cnx + sum_nx[msk];
                                    int npx = cpx + sum_px[msk];
                                    int nny = cny + sum_ny[msk];
                                    int npy = cpy + sum_py[msk];
                                    if(nnx % 2 != npx % 2)
                                        continue;
                                    if(nny % 2 != npy % 2)
                                        continue;
                                    int bx = nnx % 2, by = nny % 2, bm = ((m & q) >> pref), ngx, ngy;
                                    if(bx != bm)
                                        ngx = bx > bm;
                                    else
                                        ngx = gex;
                                    if(by != bm)
                                        ngy = by > bm;
                                    else
                                        ngy = gey;
                                    add(dp[pref + 1][nnx / 2][nny / 2][npx / 2][npy / 2][ngx][ngy], dp[pref][cnx][cny][cpx][cpy][gex][gey]);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    cout << (dp[32 - __builtin_clz(m)][0][0][0][0][0][0] + MOD - 1) % MOD << '\n';
}

#include <bits/stdc++.h>
using namespace std;

const int mod = 998244353;

int n, m;
int f[2][25][25][25][25][2][2];
int x[6], y[6];
int tpx[1 << 6], tqx[1 << 6], tpy[1 << 6], tqy[1 << 6];

inline void update(int &x, int y) { x = x + y >= mod ? x + y - mod : x + y; }

inline bool check(int now, int px, int qx, int py, int qy)
{
	for(int a = 0; a < 2; a++)
		for(int b = 0; b < 2; b++)
			if(f[now][px][qx][py][qy]) return true;
	return false;
}

int main()
{
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i++) scanf("%d %d", &x[i], &y[i]);

	for(int s = 0; s < (1 << n); s++)
		for(int j = 1; j <= n; j++)
			if(s >> j - 1 & 1)
			{
				if(x[j] > 0) tpx[s] += x[j];
				else tqx[s] -= x[j];
				if(y[j] > 0) tpy[s] += y[j];
				else tqy[s] -= y[j];
			}

	int now = 0, lim = (1 << n) - 1;
	f[now][0][0][0][0][1][1] = 1;
	for(int i = 31; i >= 1; i--)
	{
		now ^= 1;
		memset(f[now], 0, sizeof(f[now]));
		int v = m >> i - 1 & 1;
		for(int px = 0; px <= tpx[lim]; px++)
			for(int qx = 0; qx <= tqx[lim]; qx++)
				for(int py = 0; py <= tpy[lim]; py++)
					for(int qy = 0; qy <= tqy[lim]; qy++)
					{
						if(!check(now ^ 1, px, qx, py, qy)) continue;
						for(int s = 0; s <= lim; s++)
							for(int a = 0; a < 2; a++)
								for(int b = 0; b < 2; b++)
								{
									int res = f[now ^ 1][px][qx][py][qy][a][b], na, nb;
									if(!res) continue;

									int npx = px * 2 - tpx[s], nqx = qx * 2 - tqx[s], npy = py * 2 - tpy[s], nqy = qy * 2 - tqy[s];
									if(npx > tpx[lim] || nqx > tqx[lim] || npy > tpy[lim] || nqy > tqy[lim]) continue;

									if(npx >= 0 && nqx >= 0 && npy >= 0 && nqy >= 0)
									{
										na = a & (v == 0), nb = b & (v == 0);
										update(f[now][npx][nqx][npy][nqy][na][nb], res);
									}

									bool f1 = a & (v == 0), f2 = b & (v == 0);
									if(!f1 && npx + 1 >= 0 && nqx + 1 >= 0 && npy >= 0 && nqy >= 0)
									{
										na = a & (v == 1), nb = b & (v == 0);
										update(f[now][npx + 1][nqx + 1][npy][nqy][na][nb], res);
									}
									if(!f2 && npx >= 0 && nqx >= 0 && npy + 1 >= 0 && nqy + 1 >= 0)
									{
										na = a & (v == 0), nb = b & (v == 1);
										update(f[now][npx][nqx][npy + 1][nqy + 1][na][nb], res);
									}
									if(!f1 && !f2 && npx + 1 >= 0 && nqx + 1 >= 0 && npy + 1 >= 0 && nqy + 1 >= 0)
									{
										na = a & (v == 1), nb = b & (v == 1);
										update(f[now][npx + 1][nqx + 1][npy + 1][nqy + 1][na][nb], res);
									}
								}
					}
	}

	int ans = mod - 1;
	for(int a = 0; a < 2; a++)
		for(int b = 0; b < 2; b++)
			update(ans, f[now][0][0][0][0][a][b]);

	printf("%d\n", ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const ll mod = 998244353; // faster if const
ll modpow(ll a, ll e)
{
    if (e == 0)
        return 1;
    ll x = modpow(a * a % mod, e >> 1);
    return e & 1 ? x * a % mod : x;
}

vector<ll> BerlekampMassey(vector<ll> s)
{
    int n = sz(s), L = 0, m = 0;
    vector<ll> C(n), B(n), T;
    C[0] = B[0] = 1;

    ll b = 1;
    rep(i,0,n)
    {
        ++m;
        ll d = s[i] % mod;
        rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
        if (!d)
            continue;
        T = C;
        ll coef = d * modpow(b, mod-2) % mod;
        rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) % mod;
        if (2 * L > i)
            continue;
        L = i + 1 - L;
        B = T;
        b = d;
        m = 0;
    }

    C.resize(L + 1);
    C.erase(C.begin());
    trav(x, C) x = (mod - x) % mod;
    return C;
}

typedef vector<ll> Poly;
ll linearRec(Poly S, Poly tr, ll k)   /// start-hash
{
    int n = sz(S);

    auto combine = [&](Poly a, Poly b)
    {
        Poly res(n * 2 + 1);
        rep(i,0,n+1) rep(j,0,n+1)
        res[i + j] = (res[i + j] + a[i] * b[j]) % mod;
        for (int i = 2 * n; i > n; --i)
            rep(j,0,n)
            res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) % mod;
        res.resize(n + 1);
        return res;
    };

    Poly pol(n + 1), e(pol);
    pol[0] = e[1] = 1;

    for (++k; k; k /= 2)
    {
        if (k % 2)
            pol = combine(pol, e);
        e = combine(e, e);
    }

    ll res = 0;
    rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod;
    return res;
} /// end-hash

int main()
{
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;
    int m;
    cin >> n >> m;
    if(n < 3)
    {
        cout << 0 << '\n';
        return 0;
    }
    int a[5];
    int b[5];
    for(int i = 0; i < n; i++)
        cin >> a[i] >> b[i];
    const int R = 700;
    vector<ll> vals(R+1, 0);
    int f[5];
    for(f[0] = 0; f[0] <= R; f[0]++)
    {
        for(f[1] = 0; f[1] <= R; f[1]++)
        {
            int r1 = -a[0] * f[0] - a[1] * f[1];
            int r2 = -b[0] * f[0] - b[1] * f[1];
            for(f[2] = 0; f[2] <= R; f[2]++)
            {
                int cxs = r1;
                int cys = r2;
                r1 -= a[2];
                r2 -= b[2];
                if(n == 4)
                {
                    if(a[3])
                    {
                        f[3] = cxs / a[3];
                    }
                    else if(b[3])
                    {
                        f[3] = cys / b[3];
                    }
                    else
                        assert(false);
                    if(f[3] < 0)
                        continue;
                    cxs -= a[3] * f[3];
                    cys -= b[3] * f[3];
                }
                else if(n == 5)
                {
                    int d = a[3] * b[4] - a[4] * b[3];
                    f[3] = (cxs * b[4] - a[4] * cys) / d;
                    if(f[3] < 0)
                        continue;
                    f[4] = (a[3] * cys - cxs * b[3]) / d;
                    if(f[4] < 0)
                        continue;
                    cxs -= a[3] * f[3] + a[4] * f[4];
                    cys -= b[3] * f[3] + b[4] * f[4];
                }
                if(cxs != 0 || cys != 0)
                    continue;
                int xpsum = 0, ypsum = 0;
                for(int i = 0; i < n; i++)
                {
                    if(a[i] >= 0)
                        xpsum += a[i] * f[i];
                    if(b[i] >= 0)
                        ypsum += b[i] * f[i];
                }
                if(xpsum > R || ypsum > R)
                    continue;
                vals[max(xpsum, ypsum)]++;
            }
        }
    }
    for(int i = 1; i <= R; i++)
    {
        vals[i] += vals[i-1];
    }
    vector<ll> rec = BerlekampMassey(vals);
    vals.resize(rec.size());
    ll res = linearRec(vals, rec, m);
    res = (res + mod - 1) % mod;
    cout << res << '\n';
}

#include <bits/stdc++.h>
using namespace std;

using ll=long long;
//#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
int mask(int i){
	return (int(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static random_device rd;
    static mt19937_64 gen(rd());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

using uint=unsigned;
using ull=unsigned long long;

struct modinfo{uint mod,root;};
template<modinfo const&ref>
struct modular{
	static constexpr uint const &mod=ref.mod;
	static modular root(){return modular(ref.root);}
	uint v;
	//modular(initializer_list<uint>ls):v(*ls.bg){}
	modular(ll vv=0){s(vv%mod+mod);}
	modular& s(uint vv){
		v=vv<mod?vv:vv-mod;
		return *this;
	}
	modular operator-()const{return modular()-*this;}
	modular& operator+=(const modular&rhs){return s(v+rhs.v);}
	modular&operator-=(const modular&rhs){return s(v+mod-rhs.v);}
	modular&operator*=(const modular&rhs){
		v=ull(v)*rhs.v%mod;
		return *this;
	}
	modular&operator/=(const modular&rhs){return *this*=rhs.inv();}
	modular operator+(const modular&rhs)const{return modular(*this)+=rhs;}
	modular operator-(const modular&rhs)const{return modular(*this)-=rhs;}
	modular operator*(const modular&rhs)const{return modular(*this)*=rhs;}
	modular operator/(const modular&rhs)const{return modular(*this)/=rhs;}
	modular pow(int n)const{
		modular res(1),x(*this);
		while(n){
			if(n&1)res*=x;
			x*=x;
			n>>=1;
		}
		return res;
	}
	modular inv()const{return pow(mod-2);}
	/*modular inv()const{
		int x,y;
		int g=extgcd(v,mod,x,y);
		assert(g==1);
		if(x<0)x+=mod;
		return modular(x);
	}*/
	friend modular operator+(int x,const modular&y){
		return modular(x)+y;
	}
	friend modular operator-(int x,const modular&y){
		return modular(x)-y;
	}
	friend modular operator*(int x,const modular&y){
		return modular(x)*y;
	}
	friend modular operator/(int x,const modular&y){
		return modular(x)/y;
	}
	friend ostream& operator<<(ostream&os,const modular&m){
		return os<<m.v;
	}
	friend istream& operator>>(istream&is,modular&m){
		ll x;is>>x;
		m=modular(x);
		return is;
	}
	bool operator<(const modular&r)const{return v<r.v;}
	bool operator==(const modular&r)const{return v==r.v;}
	bool operator!=(const modular&r)const{return v!=r.v;}
	explicit operator bool()const{
		return v;
	}
};

constexpr modinfo base{998244353,3};
//constexpr modinfo base{1000000007,0};
using mint=modular<base>;

const int vmax=(1<<21)+10;
mint fact[vmax],finv[vmax],invs[vmax];
void initfact(){
	fact[0]=1;
	rng(i,1,vmax){
		fact[i]=fact[i-1]*i;
	}
	finv[vmax-1]=fact[vmax-1].inv();
	for(int i=vmax-2;i>=0;i--){
		finv[i]=finv[i+1]*(i+1);
	}
	for(int i=vmax-1;i>=1;i--){
		invs[i]=finv[i]*fact[i-1];
	}
}
mint choose(int n,int k){
	return fact[n]*finv[n-k]*finv[k];
}
mint binom(int a,int b){
	return fact[a+b]*finv[a]*finv[b];
}
mint catalan(int n){
	return binom(n,n)-(n-1>=0?binom(n-1,n+1):0);
}

vc<mint> mod_f(vc<mint> x,const vc<mint>&f){
	int k=si(f);
	gnr(i,k-1,si(x)){
		mint w=x[i]/f[k-1];
		rep(p,k-1)x[i-(k-1)+p]-=w*f[p];
	}
	x.resize(k-1);
	return x;
}

vc<mint> mult_mod_f(const vc<mint>&x,const vc<mint>&y,const vc<mint>&f){
	int n=si(x),m=si(y);
	vc<mint> res(n+m-1);
	rep(i,n)rep(j,m)res[i+j]+=x[i]*y[j];
	return mod_f(res,f);
}

vc<mint> pow_mod_f(vc<mint> x,int n,const vc<mint>&f){
	vc<mint> res{1};
	while(n){
		if(n&1)res=mult_mod_f(res,x,f);
		x=mult_mod_f(x,x,f);
		n>>=1;
	}
	return res;
}

// for all valid i, sum_j a_{i+j}*res_j = 0
// x^n % res で n 項目が求まる
// 多項式の向きに注意
vc<mint> berlekamp_massey(const vc<mint>& a){
	vc<mint> b{1},c{0};
	mint d=1;
	rep(i,a.size()){
		int n=b.size();
		mint w=0;
		rep(j,n)
			w+=a[i-(n-1)+j]*b[j];
		c.pb(0);
		if(!w.v)continue;
		int m=c.size();
		mint e=-w/d;
		if(m>n){
			auto tmp=b;
			b.insert(b.bg,m-n,0);
			rep(j,m)
				b[j]+=e*c[j];
			c=tmp;
			d=w;
		}else{
			rep(j,m)
				b[n-m+j]+=e*c[j];
		}
	}
	return b;
}

mint get_kth(const vc<mint>&a,int k){
	auto p=berlekamp_massey(a);
	if(si(p)==1)return 0;
	auto q=pow_mod_f({0,1},k,p);
	mint res=0;
	rep(i,si(q))res+=a[i]*q[i];
	return res;
}

//(-pi,0](0,pi]
int argtype(pi a){
	if(a.b==0)return a.a<0?1:0;
	return a.b<0?0:1;
}
bool argless(pi a,pi b){
	int at=argtype(a),bt=argtype(b);
	if(at!=bt)return at<bt;
	return a.a*b.b-a.b*b.a>0;
};

mint interpolate(const vc<mint>&a,mint x){
	int n=si(a);
	if(inc(0,x.v,n-1))return a[x.v];
	mint w=1;
	rep(i,n)w*=x-i;
	mint res;
	rep(i,n)res+=w/(x-i)*a[i]*finv[i]*finv[n-1-i]*((n-1-i)%2?-1:1);
	return res;
}

const int mmax=185;
//const int mmax=15;

mint dp[mmax][mmax];
mint buf[mmax][mmax];

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	initfact();

	int n,m;cin>>n>>m;
	vc<pi> xy;
	rep(i,n){
		int x,y;cin>>x>>y;
		xy.eb(x,y);
	}
	sort(all(xy),argless);
	dmp(xy);
	int L=mmax-5;
	rep(w,L)rng(h,w,w+2){
		rep(sx,w+1)rng(sy,h,h+1){
			zero(dp);
			dp[sx][sy]=1;
			for(auto z:xy){
				rep(xx,w+1)rep(yy,h+1){
					int x=z.a<0?w-xx:xx;
					int y=z.b<0?h-yy:yy;
					int p=x+z.a,q=y+z.b;
					if(inc(0,p,w)&&inc(0,q,h)){
						dp[p][q]+=dp[x][y];
					}
				}
			}
			buf[w][h]+=dp[sx][sy]-1;
		}
	}
	vc<mint> val(L);
	//rng(i,1,L)val[i]=buf[i][i]-buf[i][i-1]*2+buf[i-1][i-1];
	rng(i,1,L)val[i]=buf[i][i]-buf[i-1][i];

	cout<<get_kth(val,m)<<endl;
}

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const ll mod = 998244353; // faster if const
ll modpow(ll a, ll e) {
	if (e == 0) return 1;
	ll x = modpow(a * a % mod, e >> 1);
	return e & 1 ? x * a % mod : x;
}

vector<ll> BerlekampMassey(vector<ll> s) {
	int n = sz(s), L = 0, m = 0;
	vector<ll> C(n), B(n), T;
	C[0] = B[0] = 1;

	ll b = 1;
	rep(i,0,n) { ++m;
		ll d = s[i] % mod;
		rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
		if (!d) continue;
		T = C; ll coef = d * modpow(b, mod-2) % mod;
		rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) % mod;
		if (2 * L > i) continue;
		L = i + 1 - L; B = T; b = d; m = 0;
	}

	C.resize(L + 1); C.erase(C.begin());
	trav(x, C) x = (mod - x) % mod;
	return C;
}

typedef vector<ll> Poly;
ll linearRec(Poly S, Poly tr, ll k) { /// start-hash
	int n = sz(S);

	auto combine = [&](Poly a, Poly b) {
		Poly res(n * 2 + 1);
		rep(i,0,n+1) rep(j,0,n+1)
			res[i + j] = (res[i + j] + a[i] * b[j]) % mod;
		for (int i = 2 * n; i > n; --i) rep(j,0,n)
			res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) % mod;
		res.resize(n + 1);
		return res;
	};

	Poly pol(n + 1), e(pol);
	pol[0] = e[1] = 1;

	for (++k; k; k /= 2) {
		if (k % 2) pol = combine(pol, e);
		e = combine(e, e);
	}

	ll res = 0;
	rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod;
	return res;
} /// end-hash

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n;
	int m;
	cin >> n >> m;
	if(n < 3){
		cout << 0 << '\n';
		return 0;
	}
	int a[5]; int b[5];
	for(int i = 0; i < n; i++) cin >> a[i] >> b[i];
	const int R = 600;
	vector<ll> vals(R+1, 0);
	int f[5];
	for(f[0] = 0; f[0] <= R; f[0]++){
		for(f[1] = 0; f[1] <= R; f[1]++){
			int r1 = -a[0] * f[0] - a[1] * f[1];
			int r2 = -b[0] * f[0] - b[1] * f[1];
			for(f[2] = 0; f[2] <= R; f[2]++){
				int cxs = r1;
				int cys = r2;
				r1 -= a[2];
				r2 -= b[2];
				if(n == 4){
					if(a[3]){
						f[3] = cxs / a[3];
					} else if(b[3]){
						f[3] = cys / b[3];
					} else assert(false);
					if(f[3] < 0) continue;
					cxs -= a[3] * f[3];
					cys -= b[3] * f[3];
				} else if(n == 5){
					int d = a[3] * b[4] - a[4] * b[3];
					f[3] = (cxs * b[4] - a[4] * cys) / d;
					if(f[3] < 0) continue;
					f[4] = (a[3] * cys - cxs * b[3]) / d;
					if(f[4] < 0) continue;
					cxs -= a[3] * f[3] + a[4] * f[4];
					cys -= b[3] * f[3] + b[4] * f[4];
				}
				if(cxs != 0 || cys != 0) continue;
				int xpsum = 0, ypsum = 0;
				for(int i = 0; i < n; i++){
					if(a[i] >= 0) xpsum += a[i] * f[i];
					if(b[i] >= 0) ypsum += b[i] * f[i];
				}
				if(xpsum > R || ypsum > R) continue;
				vals[max(xpsum, ypsum)]++;
			}
		}
	}
	for(int i = 1; i <= R; i++){
		vals[i] += vals[i-1];
	}
	vector<ll> rec = BerlekampMassey(vals);
	vals.resize(rec.size());
	ll res = linearRec(vals, rec, m);
	res = (res + mod - 1) % mod;
	cout << res << '\n';
}

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 25;
const int P = 998244353;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
int n, m, Log, a[35], x[MAXN], y[MAXN], bit[MAXN];
int dp[2][MAXN][MAXN][MAXN][MAXN][2][2];
void update(int &x, int y) {
	x += y;
	if (x >= P) x -= P;
}
int main() {
	read(n), read(m);
	while (m != 0) {
		a[++Log] = m % 2;
		m >>= 1;
	}
	for (int i = 1; i <= n; i++) {
		read(x[i]), read(y[i]);
		bit[i] = 1 << (i - 1);
	}
	int lim = 20;
	dp[Log & 1][0][0][0][0][1][1] = 1;
	for (int i = Log, s = Log & 1, t = s ^ 1; i >= 1; i--, swap(s, t)) {
		memset(dp[t], 0, sizeof(dp[t]));
		for (int px = 0; px <= lim; px++)
		for (int py = 0; py <= lim; py++)
		for (int nx = 0; nx <= lim; nx++)
		for (int ny = 0; ny <= lim; ny++) {
			int vzz = dp[s][px][py][nx][ny][0][0];
			int vzo = dp[s][px][py][nx][ny][0][1];
			int voz = dp[s][px][py][nx][ny][1][0];
			int voo = dp[s][px][py][nx][ny][1][1];
			if (!(vzz || vzo || voz || voo)) continue;
			for (int s = 0; s <= (1 << n) - 1; s++) {
				int incpx = 0, incpy = 0, incnx = 0, incny = 0;
				for (int j = 1; j <= n; j++)
					if (s & bit[j]) {
						if (x[j] >= 0) incpx += x[j];
						else incnx -= x[j];
						if (y[j] >= 0) incpy += y[j];
						else incny -= y[j];
					}
				if (px >= incpx && py >= incpy && nx >= incnx && ny >= incny) {
					int tpx = (px - incpx) * 2;
					int tpy = (py - incpy) * 2;
					int tnx = (nx - incnx) * 2;
					int tny = (ny - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						update(dp[t][tpx][tpy][tnx][tny][0][a[i] == 0], vzo);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][0], voz);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][a[i] == 0], voo);
					}
				}
				if (px + 1 >= incpx && py >= incpy && nx + 1 >= incnx && ny >= incny) {
					int tpx = (px + 1 - incpx) * 2;
					int tpy = (py - incpy) * 2;
					int tnx = (nx + 1 - incnx) * 2;
					int tny = (ny - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						update(dp[t][tpx][tpy][tnx][tny][0][a[i] == 0], vzo);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][a[i] == 0], voo);
					}
				}
				if (px >= incpx && py + 1 >= incpy && nx >= incnx && ny + 1 >= incny) {
					int tpx = (px - incpx) * 2;
					int tpy = (py + 1 - incpy) * 2;
					int tnx = (nx - incnx) * 2;
					int tny = (ny + 1 - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][0][1], vzo);
						update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][1], voo);
					}
				}
				if (px + 1 >= incpx && py + 1 >= incpy && nx + 1 >= incnx && ny + 1 >= incny) {
					int tpx = (px + 1 - incpx) * 2;
					int tpy = (py + 1 - incpy) * 2;
					int tnx = (nx + 1 - incnx) * 2;
					int tny = (ny + 1 - incny) * 2;
					if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {
						update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][0][1], vzo);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][0], voz);
						if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][1], voo);
					}
				}
			}
		}
	}
	int ans = P - 1;
	for (int l1 = 0; l1 <= 1; l1++)
	for (int l2 = 0; l2 <= 1; l2++)
		update(ans, dp[0][0][0][0][0][l1][l2]);
	cout << ans << endl;
	return 0;
}

//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <math.h>
#include <string.h>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<double> vd;
typedef vector<string> vs;
typedef map<string, int> mpsi;
typedef map<double, int> mpdi;
typedef map<int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0},  {0, -1},
                        {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T>
inline T abs1(T a) {
  return a < 0 ? -a : a;
}

#ifndef CPPELEVEN
template <class T>
inline T max1(T a, T b) {
  return b < a ? a : b;
}
template <class T>
inline T max1(T a, T b, T c) {
  return max1(max1(a, b), c);
}
template <class T>
inline T max1(T a, T b, T c, T d) {
  return max1(max1(a, b, c), d);
}
template <class T>
inline T max1(T a, T b, T c, T d, T e) {
  return max1(max1(a, b, c, d), e);
}
template <class T>
inline T min1(T a, T b) {
  return a < b ? a : b;
}
template <class T>
inline T min1(T a, T b, T c) {
  return min1(min1(a, b), c);
}
template <class T>
inline T min1(T a, T b, T c, T d) {
  return min1(min1(a, b, c), d);
}
template <class T>
inline T min1(T a, T b, T c, T d, T e) {
  return min1(min1(a, b, c, d), e);
}
#else
template <typename t, typename t1>
t min1(t a, t1 b) {
  return a < b ? a : b;
}
template <typename t, typename... arg>
t min1(t a, arg... arr) {
  return min1(a, min1(arr...));
}
template <typename t, typename t1>
t max1(t a, t1 b) {
  return a > b ? a : b;
}
template <typename t, typename... arg>
t max1(t a, arg... arr) {
  return max1(a, max1(arr...));
}
#endif

inline int jud(double a, double b) {
  if (abs(a) < eps && abs(b) < eps)
    return 0;
  else if (abs1(a - b) / max(abs1(a), abs1(b)) < eps)
    return 0;
  if (a < b) return -1;
  return 1;
}
template <typename t>
inline int jud(t a, t b) {
  if (a < b) return -1;
  if (a == b) return 0;
  return 1;
}

template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1) {
  if (na == 0) return 0;
  int be = 0, en = na - 1;
  if (*a <= *(a + na - 1)) {
    if (f_lb == 0)
      while (be < en) {
        int mid = (be + en + 1) / 2;
        if (jud(*(a + mid), val) != 1)
          be = mid;
        else
          en = mid - 1;
      }
    else
      while (be < en) {
        int mid = (be + en) / 2;
        if (jud(*(a + mid), val) != -1)
          en = mid;
        else
          be = mid + 1;
      }
    if (f_small && jud(*(a + be), val) == 1) be--;
    if (!f_small && jud(*(a + be), val) == -1) be++;
  } else {
    if (f_lb)
      while (be < en) {
        int mid = (be + en + 1) / 2;
        if (jud(*(a + mid), val) != -1)
          be = mid;
        else
          en = mid - 1;
      }
    else
      while (be < en) {
        int mid = (be + en) / 2;
        if (jud(*(a + mid), val) != 1)
          en = mid;
        else
          be = mid + 1;
      }
    if (!f_small && jud(*(a + be), val) == -1) be--;
    if (f_small && jud(*(a + be), val) == 1) be++;
  }
  return be;
}

template <class T>
inline T lowb(T num) {
  return num & (-num);
}
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) {
  return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32);
}
inline int bitnum(ll nValue) {
  return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32);
}
inline int bitmaxl(ui a) {
  if (a == 0) return 0;
  return 32 - __builtin_clz(a);
}
inline int bitmaxl(int a) {
  if (a == 0) return 0;
  return 32 - __builtin_clz(a);
}
inline int bitmaxl(ull a) {
  int temp = a >> 32;
  if (temp) return 32 - __builtin_clz(temp) + 32;
  return bitmaxl(int(a));
}
inline int bitmaxl(ll a) {
  int temp = a >> 32;
  if (temp) return 32 - __builtin_clz(temp) + 32;
  return bitmaxl(int(a));
}
#else
#endif

long long pow(long long n, long long m, long long mod = 0) {
  if (m < 0) return 0;
  long long ans = 1;
  long long k = n;
  while (m) {
    if (m & 1) {
      ans *= k;
      if (mod) ans %= mod;
    }
    k *= k;
    if (mod) k %= mod;
    m >>= 1;
  }
  return ans;
}

#define MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
  if (mod == -1) mod = MOD;
  a += b;
  while (a >= mod) a -= mod;
  while (a < 0) a += mod;
}
template <class t>
void output1(t arr) {
  for (int i = 0; i < (int)arr.size(); i++) cerr << arr[i] << ' ';
  cerr << endl;
}
template <class t>
void output2(t arr) {
  for (int i = 0; i < (int)arr.size(); i++) output1(arr[i]);
}

//...................................................................

const int mod = 998244353;
int n, m;
pii orig[7];
// [max abs(x) delta to m][delta between neg x and pos x][..y..][..y..]
int dp[2][22][22 * 2][22][22 * 2];

int main() {
  ios_base::sync_with_stdio(0);
#ifdef DEBUG  //..................................................
  freopen("input.txt", "r", stdin);
#endif  //........................................................

  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &orig[i].first, &orig[i].second);
  }
  memset(dp, 0, sizeof(dp));
  int now = 0, nxt = 1;
  dp[now][0][21][0][21] = 1;
  for (int i = bitmaxl(m) - 1; i >= 0; i--) {
    memset(dp[nxt], 0, sizeof(dp[nxt]));
    for (int dmx = 0; dmx <= 17; dmx++) for (int dx = -16; dx <= 16; dx++) {
      for (int dmy = 0; dmy <= 17; dmy++) for (int dy = -16; dy <= 16; dy++) {
        if (dp[now][dmx][dx + 21][dmy][dy + 21]) for (int mask = 0; mask < 1 << n; mask++) {
          int px = 0, nx = 0, py = 0, ny = 0;
          for (int j = 0; j < n; j++) if (mask & (1 << j)) {
            if (orig[j].first > 0) px += orig[j].first;
            else nx -= orig[j].first;
            if (orig[j].second > 0) py += orig[j].second;
            else ny -= orig[j].second;
          }
          int dx_n = (dx * 2 + px - nx);
          if (abs(dx_n) > 16) continue;
          int dy_n = (dy * 2 + py - ny);
          if (abs(dy_n) > 16) continue;

          int a = 0, b = 0;
          int dmx_n = dmx * 2 + bool(m & (1 << i));
          a = dmx_n - px - (dx > 0 ? 0 : dx * 2);
          b = dmx_n - nx + (dx < 0 ? 0 : dx * 2);
          dmx_n = min(a, b);
          int dmy_n = dmy * 2 + bool(m & (1 << i));
          a = dmy_n - py - (dy > 0 ? 0 : dy * 2);
          b = dmy_n - ny + (dy < 0 ? 0 : dy * 2);
          dmy_n = min(a, b);
          if (dmx == 17 || dmx_n > 17) dmx_n = 17;
          if (dmy == 17 || dmy_n > 17) dmy_n = 17;
          if (dmx_n < 0 || dmy_n < 0) continue;
          add(dp[nxt][dmx_n][dx_n + 21][dmy_n][dy_n + 21],
              dp[now][dmx][dx + 21][dmy][dy + 21], mod);
        }
      }
    }
    swap(now, nxt);
  }
  int ans = 0;
  for (int i = 0; i <= 17; i++) for (int j = 0; j <= 17; j++) {
    add(ans, dp[now][i][21][j][21], mod);
  }
  cout << ans - 1 << endl;

  return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;
#define mp make_pair
#define f first
#define s second

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MOD = 998244353; // = (119<<23)+1
const int MX = 2e5+5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};

template<class T> bool ckmin(T& a, const T& b) {
	return a > b ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }
int pc(int x) { return __builtin_popcount(x); }

namespace input {
	template<class T> void re(complex<T>& x);
	template<class T1, class T2> void re(pair<T1,T2>& p);
	template<class T> void re(vector<T>& a);
	template<class T, size_t SZ> void re(array<T,SZ>& a);

	template<class T> void re(T& x) { cin >> x; }
	void re(double& x) { string t; re(t); x = stod(t); }
	void re(ld& x) { string t; re(t); x = stold(t); }
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t); re(ts...);
	}

	template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = {a,b}; }
	template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
	template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
	template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
	void pr(int x) { cout << x; }
	void pr(long x) { cout << x; }
	void pr(ll x) { cout << x; }
	void pr(unsigned x) { cout << x; }
	void pr(unsigned long x) { cout << x; }
	void pr(unsigned long long x) { cout << x; }
	void pr(float x) { cout << x; }
	void pr(double x) { cout << x; }
	void pr(ld x) { cout << x; }
	void pr(char x) { cout << x; }
	void pr(const char* x) { cout << x; }
	void pr(const string& x) { cout << x; }
	void pr(bool x) { pr(x ? "true" : "false"); }
	template<class T> void pr(const complex<T>& x) { cout << x; }

	template<class T1, class T2> void pr(const pair<T1,T2>& x);
	template<class T> void pr(const T& x);

	template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
		pr(t); pr(ts...);
	}
	template<class T1, class T2> void pr(const pair<T1,T2>& x) {
		pr("{",x.f,", ",x.s,"}");
	}
	template<class T> void pr(const T& x) {
		pr("{"); // const iterator needed for vector<bool>
		bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
		pr("}");
	}

	void ps() { pr("\n"); } // print w/ spaces
	template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
	}

	void pc() { pr("]\n"); } // debug w/ commas
	template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
	}
	#define dbg(x...) pr("[",#x,"] = ["), pc(x);
}

using namespace output;

namespace io {
	void setIn(string s) { freopen(s.c_str(),"r",stdin); }
	void setOut(string s) { freopen(s.c_str(),"w",stdout); }
	void setIO(string s = "") {
		ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
		// cin.exceptions(cin.failbit);
		// throws exception when do smth illegal
		// ex. try to read letter into int
		if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
	}
}

using namespace io;

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

/**
 * Description: modular arithmetic operations
 * Source:
	* KACTL
	* https://codeforces.com/blog/entry/63903
	* https://codeforces.com/contest/1261/submission/65632855 (tourist)
	* https://codeforces.com/contest/1264/submission/66344993 (ksun)
 * Verification:
	* https://open.kattis.com/problems/modulararithmetic
 */

// #include "../../contest/CppIO.h"

struct mi {
	typedef decay<decltype(MOD)>::type T;
 	/// don't silently convert to T
	T v; explicit operator T() const { return v; }
	mi() { v = 0; }
	mi(ll _v) {
		v = (-MOD < _v && _v < MOD) ? _v : _v % MOD;
		if (v < 0) v += MOD;
	}
	friend bool operator==(const mi& a, const mi& b) {
		return a.v == b.v; }
	friend bool operator!=(const mi& a, const mi& b) {
		return !(a == b); }
	friend bool operator<(const mi& a, const mi& b) {
		return a.v < b.v; }
	friend void re(mi& a) { ll x; re(x); a = mi(x); }
	friend void pr(const mi& a) { pr(a.v); }
	friend ostream& operator<<(ostream& os, const mi& a) {
		return os << a.v; }

	mi& operator+=(const mi& m) {
		if ((v += m.v) >= MOD) v -= MOD;
		return *this; }
	mi& operator-=(const mi& m) {
		if ((v -= m.v) < 0) v += MOD;
		return *this; }
	mi& operator*=(const mi& m) {
		v = (ll)v*m.v%MOD; return *this; }
	mi& operator/=(const mi& m) { return (*this) *= inv(m); }
	friend mi pow(mi a, ll p) {
		mi ans = 1; assert(p >= 0);
		for (; p; p /= 2, a *= a) if (p&1) ans *= a;
		return ans;
	}
	friend mi inv(const mi& a) { assert(a.v != 0);
		return pow(a,MOD-2); }

	mi operator-() const { return mi(-v); }
	mi& operator++() { return *this += 1; }
	mi& operator--() { return *this -= 1; }
	friend mi operator+(mi a, const mi& b) { return a += b; }
	friend mi operator-(mi a, const mi& b) { return a -= b; }
	friend mi operator*(mi a, const mi& b) { return a *= b; }
	friend mi operator/(mi a, const mi& b) { return a /= b; }
};
typedef vector<mi> vmi;
typedef pair<mi,mi> pmi;
typedef vector<pmi> vpmi;

vector<vmi> comb;
void genComb(int SZ) {
	comb.assign(SZ,vmi(SZ)); comb[0][0] = 1;
	FOR(i,1,SZ) F0R(j,i+1)
		comb[i][j] = comb[i-1][j]+(j?comb[i-1][j-1]:0);
}

/**
 * Description: Berlekamp-Massey, computes linear recurrence of
 * order $N$ for sequence of $2N$ terms
 * Time: O(N^2)
 * Source:
	* https://en.wikipedia.org/wiki/Berlekamp%E2%80%93Massey_algorithm
	* http://codeforces.com/blog/entry/61306
	* MIT ICPC notebook
 * Verification: http://codeforces.com/contest/506/problem/E
 */

/**
 * Description: Basic polynomial operations including division and interpolation.
 * Source: Own. Also see
 	* https://github.com/kth-competitive-programming/kactl/blob/master/content/numerical/PolyInterpolate.h
 	* https://github.com/ecnerwala/icpc-book/blob/master/content/numerical/fft.cpp
 * Verification: see FFT
 */

namespace VecOp {
	typedef mi T; using poly = vector<mi>;
	poly rev(poly v) { reverse(all(v)); return v; }
	poly shift(poly v, int x) { v.ins(begin(v),x,0); return v; }
	poly& remLead(poly& v) {
		while (sz(v) && v.bk == 0) v.pop_back(); return v; }
	T eval(const poly& v, T x) {
		T res = 0; R0F(i,sz(v)) res = x*res+v[i]; return res; }
	poly dif(const poly& v)	 {
		poly res; FOR(i,1,sz(v)) res.pb(i*v[i]); return res; }
	poly integ(const poly& v)  {
		poly res(sz(v)+1); F0R(i,sz(v)) res[i+1] = v[i]/(i+1);
		return res; }

	poly& operator+=(poly& l, const poly& r) {
		l.rsz(max(sz(l),sz(r))); F0R(i,sz(r)) l[i] += r[i];
		return l; }
	poly& operator-=(poly& l, const poly& r) {
		l.rsz(max(sz(l),sz(r))); F0R(i,sz(r)) l[i] -= r[i];
		return l; }
	poly& operator*=(poly& l, const T& r) {
		trav(t,l) t *= r; return l;	 }
	poly& operator/=(poly& l, const T& r) {
		trav(t,l) t /= r; return l; }

	poly operator+(poly l, const poly& r) { return l += r; }
	poly operator-(poly l, const poly& r) { return l -= r; }
	poly operator*(poly l, const T& r) { return l *= r; }
	poly operator*(const T& r, const poly& l) { return l*r; }
	poly operator/(poly l, const T& r) { return l /= r;	 }
	poly operator*(const poly& l, const poly& r) {
		if (!min(sz(l),sz(r))) return {};
		poly x(sz(l)+sz(r)-1);
		F0R(i,sz(l)) F0R(j,sz(r)) x[i+j] += l[i]*r[j];
		return x;
	}
	poly& operator*=(poly& l, const poly& r) { return l = l*r; }

	pair<poly,poly> qr(poly a, poly b) {
		assert(sz(b)); auto B = b.bk; assert(B != 0);
		B = 1/B; trav(t,b) t *= B;
		remLead(a); poly q(max(sz(a)-sz(b)+1,0));
		while (sz(a) >= sz(b)) {
			q[sz(a)-sz(b)] = a.bk;
			F0R(i,sz(b)) a[i+sz(a)-sz(b)] -= a.bk*b[i];
			remLead(a);
		}
		trav(t,q) t *= B; return {q,a};
	}
	poly quo(const poly& a, const poly& b) { return qr(a,b).f; }
	poly rem(const poly& a, const poly& b) { return qr(a,b).s; }
	poly interpolate(vector<pair<T,T>> v) {
		poly ret, prod = {1}; trav(t,v) prod *= poly({-t.f,1});
		F0R(i,sz(v)) {
			T fac = 1; F0R(j,sz(v)) if (i != j) fac *= v[i].f-v[j].f;
			ret += v[i].s/fac*quo(prod,{-v[i].f,1});
		}
		return ret;
	}
}
using namespace VecOp;

struct LinRec {
	vmi x; // original sequence
	vmi C, rC;
	void init(const vmi& _x) {
		x = _x; int n = sz(x), m = 0;
		vmi B; B = C = {1}; // B is fail vector
		mi b = 1; // B gives 0,0,0,...,b
		F0R(i,n) {
			m ++;
			mi d = x[i]; FOR(j,1,sz(C)) d += C[j]*x[i-j];
			if (d == 0) continue; // recurrence still works
			auto _B = C; C.rsz(max(sz(C),m+sz(B)));
			// subtract recurrence that gives 0,0,0,...,d
			mi coef = d/b; FOR(j,m,m+sz(B)) C[j] -= coef*B[j-m];
			if (sz(_B) < m+sz(B)) { B = _B; b = d; m = 0; }
		}
		rC = C; reverse(all(rC)); // polynomial for getPo
		C.erase(begin(C)); trav(t,C) t *= -1;
		// x[i]=sum_{j=0}^{sz(C)-1}C[j]*x[i-j-1]
	}
	vmi getPo(int n) {
		if (n == 0) return {1};
		vmi x = getPo(n/2); x = rem(x*x,rC);
		if (n&1) { vmi v = {0,1}; x = rem(x*v,rC); }
		return x;
	}
	mi eval(int n) {
		vmi t = getPo(n);
		mi ans = 0; F0R(i,sz(t)) ans += t[i]*x[i];
		return ans;
	}
};

LinRec L;

const int Z = 500;
vmi dumb(Z+1);

int n,m;

/*
mi dp[2*Z+1][2*Z+1][Z+1][Z+1];
// dp[current pos]

void ad(int a, int b, int c, int d, mi e) {
	if (0 <= a && a <= 2*Z && 0 <= b && b <= 2*Z && c <= Z && d <= Z)
		dp[a][b][c][d] += e;
}

void ad(pi p) {
	if (p > mp(0,0)) {
		F0R(a,2*Z+1) F0R(b,2*Z+1) F0R(c,Z) F0R(d,Z) if (dp[a][b][c][d] != 0)
			ad(a+p.f,b+p.s,c+max(p.f,0),d+max(p.s,0),dp[a][b][c][d]);
	} else {
		R0F(a,2*Z+1) R0F(b,2*Z+1) F0R(c,Z) F0R(d,Z) if (dp[a][b][c][d] != 0)
			ad(a+p.f,b+p.s,c+max(p.f,0),d+max(p.s,0),dp[a][b][c][d]);
	}
}*/

vpi v;

int divi(int y, int x) {
    if (y == 0) {
        if (x) return MOD;
        return 0;
    }
    if (x%y != 0 || x/y < 0) return MOD;
    return x/y;
}

pi solve(int x, int y) {
	x *= -1, y *= -1;
	int m0 = v[sz(v)-2].f, m1 = v[sz(v)-1].f;
	int n0 = v[sz(v)-2].s, n1 = v[sz(v)-1].s;
	int det = m0*n1-n0*m1;
	pi p = {x*n1-y*m1,y*m0-x*n0};
	if (p.f%det != 0 || p.s%det != 0) return {-1,-1};
	p.f /= det, p.s /= det;
	if (p.f < 0 || p.s < 0) return {-1,-1};
	// a*v[sz(v)-2].f+b*v[sz(v)-1].f == x
	// a*v[sz(v)-2].s+b*v[sz(v)-1].s == y
	return p;
}

void dfs(int ind, int x, int y, int X, int Y) {
	if (abs(x) > Z || abs(y) > Z || X > 2*Z || Y > 2*Z) return;
	if (ind == sz(v)-2) {
		pi p = solve(x,y);
		if (p.f == -1) return;
		int t = max((X+abs(p.f*v[sz(v)-2].f)+abs(p.s*v[sz(v)-1].f))/2,
					(Y+abs(p.f*v[sz(v)-2].s)+abs(p.s*v[sz(v)-1].s))/2);
		//ps("HA",ind,x,y,X,Y,p,t);
		if (t <= Z) dumb[t] += 1;
		return;
	}
	F0R(i,Z+1) dfs(ind+1,x+i*v[ind].f,y+i*v[ind].s,X+i*abs(v[ind].f),Y+i*abs(v[ind].s));
}

int main() {
	setIO(); re(n,m);
	v.rsz(n); re(v);
	if (n > 1) {
		dfs(0,0,0,0,0);
		dumb[0] -= 1;
	}
	//ps(dumb);
	FOR(i,1,Z+1) dumb[i] += dumb[i-1];
	L.init(dumb);
	ps(L.eval(m));
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
*/

#include <bits/stdc++.h>

using namespace std;
const int MOD = 998244353;
const int MAX_N = 33;
const int MAX_M = 22;
int dp[MAX_N][MAX_M][MAX_M][MAX_M][MAX_M][2][2];
int cpx[50], cpy[50], cnx[50], cny[50];
int a[6], x[6], y[6];
int n, m;

int main () {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }
  for (int mask = 0; mask < (1 << n); mask++) {
    for (int i = 0; i < n; i++) {
      if ((mask & (1 << i)) > 0) {
        if (x[i] >= 0) {
          cpx[mask] += x[i];
        }
        else {
          cnx[mask] -= x[i];
        }
        if (y[i] >= 0) {
          cpy[mask] += y[i];
        }
        else {
          cny[mask] -= y[i];
        }
      }
    }
  }
  dp[0][0][0][0][0][0][0] = 1;
  for (int i = 0; i <= 31; i++) {
    for (int curpx = 0; curpx <= 20; curpx++) {
      for (int curpy = 0; curpy <= 20; curpy++) {
        for (int curnx = 0; curnx <= 20; curnx++) {
          for (int curny = 0; curny <= 20; curny++) {
            for (int stax = 0; stax <= 1; stax++) {
              for (int stay = 0; stay <= 1; stay++) {
                if (dp[i][curpx][curpy][curnx][curny][stax][stay] == 0) {
                  continue;
                }
                int cur = dp[i][curpx][curpy][curnx][curny][stax][stay];
                for (int mask = 0; mask < (1 << n); mask++) {
                  int nextpx = curpx + cpx[mask];
                  int nextpy = curpy + cpy[mask];
                  int nextnx = curnx + cnx[mask];
                  int nextny = curny + cny[mask];
                  if (((nextpx & 1) != (nextnx & 1)) || ((nextpy & 1) != (nextny & 1))) {
                    continue;
                  }
                  int bitx = nextpx & 1;
                  int bity = nextpy & 1;
                  int bitm = (m >> i) & 1;
                  int nstax = (bitx < bitm ? 0 : (bitx > bitm ? 1 : stax));
                  int nstay = (bity < bitm ? 0 : (bity > bitm ? 1 : stay));
                  (dp[i + 1][nextpx / 2][nextpy / 2][nextnx / 2][nextny / 2][nstax][nstay] += cur) %= MOD;
                }
              }
            }
          }
        }
      }
    }
  }
  cout << dp[32][0][0][0][0][0][0] - 1;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ref(i,x,y)for(int i=x;i<=y;++i)
#define def(i,x,y)for(int i=x;i>=y;--i)
#define pb push_back
#define SZ(x) ((int)x.size())
#define mp make_pair
#define fi first
#define se second
typedef vector<int> vint;
typedef long long LL;
const int S=23,T=9;
const int mod=998244353;
int n,m,x[6],y[6],dp[31][S+1][S+1][T+1][T+1];
void inc(int&a,int b){a+=b;if(a>=mod)a-=mod;}
int main(){
	cin>>n>>m;
	ref(i,1,n)cin>>x[i]>>y[i];
	int totx=0,toty=0;
	ref(i,1,n)if(x[i]>0)totx++;if(totx>n/2)ref(i,1,n)x[i]=-x[i];
	ref(i,1,n)if(y[i]>0)toty++;if(toty>n/2)ref(i,1,n)y[i]=-y[i];
	totx=toty=0;
	ref(i,1,n)if(x[i]>0)totx++;ref(i,1,n)if(y[i]>0)toty++;
	int bx=totx*4+1,by=toty*4+1;
	dp[30][bx][by][0][0]=1;
	def(i,29,0){
		ref(i1,0-bx,S-bx)ref(i2,0-by,S-by)ref(i3,0,T)ref(i4,0,T)
			if(dp[i+1][i1+bx][i2+by][i3][i4])
			ref(J,0,(1<<n)-1){
				int I1=i1<<1,I2=i2<<1,I3=i3<<1|(m>>i&1),I4=i4<<1|(m>>i&1);
				ref(j,1,n)if(J>>j-1&1){
					I1-=x[j];I2-=y[j];
					if(x[j]>0)I3-=x[j];if(y[j]>0)I4-=y[j];
				}
				I1+=bx;I2+=by;I3=min(I3,T);I4=min(I4,T);
				if(I1>=0&&I1<=S&&I2>=0&&I2<=S&&I3>=0&&I4>=0)
					inc(dp[i][I1][I2][I3][I4],dp[i+1][i1+bx][i2+by][i3][i4]);
			}
	}
	int ans=0;
	ref(i,0,T)ref(j,0,T)inc(ans,dp[0][bx][by][i][j]);
	cout<<(ans+mod-1)%mod<<endl;
}