#include <bits/stdc++.h>
using namespace std;
namespace modular {
template <typename>
struct is_modular : std::false_type {};
template <int M>
struct static_mint {
  static_assert(0 < M, "Module must be positive");
  using mint = static_mint;
  int val;
  static_mint() : val() {}
  static_mint(long long x) : val(x % M) {
    if (val < 0) val += M;
  }
  mint pow(long long n) const {
    mint ans = 1, x(*this);
    while (n) {
      if (n & 1) ans *= x;
      x *= x;
      n /= 2;
    }
    return ans;
  }
  mint inv() const { return pow(M - 2); }
  friend mint pow(const mint& m, long long n) { return m.pow(n); }
  friend mint inv(const mint& m) { return m.inv(); }
  mint operator+() const {
    mint m;
    m.val = val;
    return m;
  }
  mint operator-() const {
    mint m;
    m.val = M - val;
    return m;
  }
  mint& operator+=(const mint& m) {
    if ((val += m.val) >= M) val -= M;
    return *this;
  }
  mint& operator-=(const mint& m) {
    if ((val -= m.val) < 0) val += M;
    return *this;
  }
  mint& operator*=(const mint& m) {
    val = (long long)val * m.val % M;
    return *this;
  }
  mint& operator/=(const mint& m) {
    val = (long long)val * m.inv().val % M;
    return *this;
  }
  friend mint operator+(const mint& lhs, const mint& rhs) {
    return mint(lhs) += rhs;
  }
  friend mint operator-(const mint& lhs, const mint& rhs) {
    return mint(lhs) -= rhs;
  }
  friend mint operator*(const mint& lhs, const mint& rhs) {
    return mint(lhs) *= rhs;
  }
  friend mint operator/(const mint& lhs, const mint& rhs) {
    return mint(lhs) /= rhs;
  }
  friend bool operator==(const mint& lhs, const mint& rhs) {
    return lhs.val == rhs.val;
  }
  friend bool operator!=(const mint& lhs, const mint& rhs) {
    return lhs.val != rhs.val;
  }
  mint& operator++() { return *this += 1; }
  mint& operator--() { return *this -= 1; }
  mint operator++(int) {
    mint result(*this);
    *this += 1;
    return result;
  }
  mint operator--(int) {
    mint result(*this);
    *this -= 1;
    return result;
  }
  template <typename T>
  explicit operator T() const {
    return T(val);
  }
  friend std::ostream& operator<<(std::ostream& os, const mint& m) {
    return os << m.val;
  }
  friend std::istream& operator>>(std::istream& is, mint& m) {
    long long x;
    is >> x;
    m = x;
    return is;
  }
};
template <int M>
struct is_modular<static_mint<M>> : std::true_type {};
template <int& _M>
struct dynamic_mint {
  static constexpr int& M = _M;
  using mint = dynamic_mint;
  int val;
  dynamic_mint() : val() {}
  dynamic_mint(long long x) : val(x % M) {
    if (val < 0) {
      val += M;
    }
  }
  mint pow(long long n) const {
    mint ans = 1, x(*this);
    while (n) {
      if (n & 1) ans *= x;
      x *= x;
      n /= 2;
    }
    return ans;
  }
  mint inv() const { return pow(M - 2); }
  friend mint pow(const mint& m, long long n) { return m.pow(n); }
  friend mint inv(const mint& m) { return m.inv(); }
  mint operator+() const {
    mint m;
    m.val = val;
    return m;
  }
  mint operator-() const {
    mint m;
    m.val = M - val;
    return m;
  }
  mint& operator+=(const mint& m) {
    if ((val += m.val) >= M) val -= M;
    return *this;
  }
  mint& operator-=(const mint& m) {
    if ((val -= m.val) < 0) val += M;
    return *this;
  }
  mint& operator*=(const mint& m) {
    val = (long long)val * m.val % M;
    return *this;
  }
  mint& operator/=(const mint& m) {
    val = (long long)val * m.inv().val % M;
    return *this;
  }
  friend mint operator+(const mint& lhs, const mint& rhs) {
    return mint(lhs) += rhs;
  }
  friend mint operator-(const mint& lhs, const mint& rhs) {
    return mint(lhs) -= rhs;
  }
  friend mint operator*(const mint& lhs, const mint& rhs) {
    return mint(lhs) *= rhs;
  }
  friend mint operator/(const mint& lhs, const mint& rhs) {
    return mint(lhs) /= rhs;
  }
  friend bool operator==(const mint& lhs, const mint& rhs) {
    return lhs.val == rhs.val;
  }
  friend bool operator!=(const mint& lhs, const mint& rhs) {
    return lhs.val != rhs.val;
  }
  mint& operator++() { return *this += 1; }
  mint& operator--() { return *this -= 1; }
  mint operator++(int) {
    mint result(*this);
    *this += 1;
    return result;
  }
  mint operator--(int) {
    mint result(*this);
    *this -= 1;
    return result;
  }
  template <typename T>
  explicit operator T() const {
    return T(val);
  }
  friend std::ostream& operator<<(std::ostream& os, const mint& m) {
    return os << m.val;
  }
  friend std::istream& operator>>(std::istream& is, mint& m) {
    long long x;
    is >> x;
    m = x;
    return is;
  }
};
}  // namespace modular
using im = modular::static_mint<998244353>;
im p[2][100001];
im get(int i, int l, int r) {
  if (r < 0) return im(0);
  l = max(l, 0);
  return p[i][r] - (l == 0 ? 0 : p[i][l - 1]);
}
void solution() {
  int n, m;
  cin >> n >> m;
  vector<im> f(m + 1);
  vector<int> l(n), r(n);
  for (int i = 0; i < n; i++) {
    cin >> l[i] >> r[i];
  }
  for (int d = 1; d <= m; d++) {
    vector<int> L(n), R(n);
    bool glitch = false;
    for (int i = 0; i < n; i++) {
      L[i] = (l[i] + d - 1) / d;
      R[i] = r[i] / d;
      if (R[i] < L[i]) glitch = true;
    }
    if (glitch) continue;
    int bound = m / d;
    for (int i = 0; i <= 1; i++)
      for (int j = 0; j <= bound; j++) p[i][j] = 0;
    p[0][0] = 1;
    for (int i = 1; i <= bound; i++) p[0][i] = 1;
    int cur = 0, nxt = 1;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j <= bound; j++)
        p[nxt][j] += get(cur, j - R[i], j - L[i]);
      for (int j = 1; j <= bound; j++) p[nxt][j] += p[nxt][j - 1];
      for (int j = 0; j <= bound; j++) p[cur][j] = 0;
      swap(cur, nxt);
    }
    f[d] = p[cur][bound];
  }
  for (int i = m; i >= 1; i--) {
    for (int j = i + i; j <= m; j += i) f[i] -= f[j];
  }
  cout << f[1];
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int tc = 1;
  while (tc--) {
    solution();
    cout << "\n";
  }
}
