Problem:
Score : 800 points

Problem Statement

Given are integers N and X. For each integer k between 0 and X (inclusive), find the answer to the following question, then compute the sum of all those answers, modulo 998244353.

Let us repeat the following operation on the integer k. Operation: if the integer is currently odd, subtract 1 from it and divide it by 2; otherwise, divide it by 2 and add 2^{N-1} to it. How many operations need to be performed until k returns to its original value? (The answer is considered to be 0 if k never returns to its original value.)

Constraints

1 \leq N \leq 2\times 10^5

0 \leq X < 2^N

X is given in binary and has exactly N digits. (In case X has less than N digits, it is given with leading zeroes.)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
X

Output

Print the sum of the answers to the questions for the integers between 0 and X (inclusive), modulo 998244353.

Sample Input 1

3
111

Sample Output 1

40

For example, for k=3, the operation changes k as follows: 1,0,4,6,7,3. Therefore the answer for k=3 is 6.

Sample Input 2

6
110101

Sample Output 2

616

Sample Input 3

30
001110011011011101010111011100

Sample Output 3

549320998

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

//#define NDEBUG
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <iterator>
#include <vector>

namespace n91 {

  using i8 = std::int_fast8_t;
  using i32 = std::int_fast32_t;
  using i64 = std::int_fast64_t;
  using u8 = std::uint_fast8_t;
  using u32 = std::uint_fast32_t;
  using u64 = std::uint_fast64_t;
  using isize = std::ptrdiff_t;
  using usize = std::size_t;

  constexpr usize operator"" _z(unsigned long long x) noexcept {
    return static_cast<usize>(x);
  }

  template <class T> class integral_iterator {
  public:
    using difference_type = T;
    using value_type = T;
    using pointer = const value_type*;
    using reference = value_type;
    using iterator_category = std::random_access_iterator_tag;

  private:
    using self_type = integral_iterator<value_type>;
    value_type i;

  public:
    constexpr integral_iterator() noexcept : i() {}
    explicit constexpr integral_iterator(const value_type i) noexcept : i(i) {}
    constexpr self_type operator++(int) noexcept { return self_type(i++); }
    constexpr self_type operator--(int) noexcept { return self_type(i--); }
    constexpr self_type operator[](const difference_type rhs) const noexcept {
      return self_type(i + rhs);
    }
    constexpr self_type& operator++() noexcept {
      ++i;
      return *this;
    }
    constexpr self_type& operator--() noexcept {
      --i;
      return *this;
    }
    constexpr reference operator*() const noexcept { return i; }
    constexpr self_type operator+(const difference_type rhs) const noexcept {
      return self_type(i + rhs);
    }
    constexpr self_type operator-(const difference_type rhs) const noexcept {
      return self_type(i - rhs);
    }
    constexpr difference_type operator-(const self_type rhs) const noexcept {
      return i - rhs.i;
    }
    constexpr bool operator<(const self_type rhs) const noexcept {
      return i < rhs.i;
    }
    constexpr bool operator<=(const self_type rhs) const noexcept {
      return i <= rhs.i;
    }
    constexpr bool operator>(const self_type rhs) const noexcept {
      return i > rhs.i;
    }
    constexpr bool operator>=(const self_type rhs) const noexcept {
      return i >= rhs.i;
    }
    constexpr bool operator==(const self_type rhs) const noexcept {
      return i == rhs.i;
    }
    constexpr bool operator!=(const self_type rhs) const noexcept {
      return i != rhs.i;
    }
    constexpr self_type& operator+=(const difference_type rhs) noexcept {
      i += rhs;
      return *this;
    }
    constexpr self_type& operator-=(const difference_type rhs) noexcept {
      i -= rhs;
      return *this;
    }
  };
  template <class T>
  constexpr integral_iterator<T> make_int_itr(const T i) noexcept {
    return integral_iterator<T>(i);
  }
  class rep {
    const usize f, l;

  public:
    constexpr rep(const usize f, const usize l) noexcept : f(f), l(l) {}
    constexpr auto begin() const noexcept { return make_int_itr(f); }
    constexpr auto end() const noexcept { return make_int_itr(l); }
  };
  class revrep {
    const usize f, l;

  public:
    revrep(const usize f, const usize l) noexcept : f(l), l(f) {}
    auto begin() const noexcept {
      return std::make_reverse_iterator(make_int_itr(f));
    }
    auto end() const noexcept {
      return std::make_reverse_iterator(make_int_itr(l));
    }
  };
  template <class T> auto md_vec(const usize n, const T& value) {
    return std::vector<T>(n, value);
  }
  template <class... Args> auto md_vec(const usize n, Args... args) {
    return std::vector<decltype(md_vec(args...))>(n, md_vec(args...));
  }
  template <class T> constexpr T difference(const T& a, const T& b) {
    return a < b ? b - a : a - b;
  }
  template <class T> T scan() {
    T ret;
    std::cin >> ret;
    return ret;
  }

} // namespace n91
#include <cstdint>

namespace n91 {

  constexpr std::uint_fast64_t totient(std::uint_fast64_t x) noexcept {
    using u64 = std::uint_fast64_t;
    u64 ret = x;
    for (u64 i = static_cast<u64>(2); i * i <= x; ++i) {
      if (x % i == static_cast<u64>(0)) {
        ret -= ret / i;
        x /= i;
        while (x % i == static_cast<u64>(0)) {
          x /= i;
        }
      }
    }
    if (x != static_cast<u64>(1)) {
      ret -= ret / x;
    }
    return ret;
  }

  template <std::uint_fast64_t Modulus,
    std::uint_fast64_t InverseExp =
    totient(Modulus) - static_cast<std::uint_fast64_t>(1)>
    class modint {
    using u64 = std::uint_fast64_t;

    static_assert(Modulus < static_cast<u64>(1) << static_cast<u64>(32),
      "Modulus must be less than 2**32");

    u64 a;

    constexpr modint& negate() noexcept {
      if (a != static_cast<u64>(0)) {
        a = Modulus - a;
      }
      return *this;
    }

    public:
      constexpr modint(const u64 x = static_cast<u64>(0)) noexcept
        : a(x% Modulus) {}
      constexpr u64& value() noexcept { return a; }
      constexpr const u64& value() const noexcept { return a; }
      constexpr modint operator+() const noexcept { return modint(*this); }
      constexpr modint operator-() const noexcept { return modint(*this).negate(); }
      constexpr modint operator+(const modint rhs) const noexcept {
        return modint(*this) += rhs;
      }
      constexpr modint operator-(const modint rhs) const noexcept {
        return modint(*this) -= rhs;
      }
      constexpr modint operator*(const modint rhs) const noexcept {
        return modint(*this) *= rhs;
      }
      constexpr modint operator/(const modint rhs) const noexcept {
        return modint(*this) /= rhs;
      }
      constexpr modint& operator+=(const modint rhs) noexcept {
        a += rhs.a;
        if (a >= Modulus) {
          a -= Modulus;
        }
        return *this;
      }
      constexpr modint& operator-=(const modint rhs) noexcept {
        if (a < rhs.a) {
          a += Modulus;
        }
        a -= rhs.a;
        return *this;
      }
      constexpr modint& operator*=(const modint rhs) noexcept {
        a = a * rhs.a % Modulus;
        return *this;
      }
      constexpr modint& operator/=(modint rhs) noexcept {
        u64 exp = InverseExp;
        while (exp) {
          if (exp % static_cast<u64>(2) != static_cast<u64>(0)) {
            *this *= rhs;
          }
          rhs *= rhs;
          exp /= static_cast<u64>(2);
        }
        return *this;
      }
      constexpr bool operator==(const modint rhs) const noexcept {
        return a == rhs.a;
      }
      constexpr bool operator!=(const modint rhs) const noexcept {
        return a != rhs.a;
      }
  };

  template <class T, std::uint_fast64_t v> class modint_constant {
  public:
    static constexpr T value = static_cast<T>(v);

    using value_type = T;
  };

} // namespace n91
#include <cassert>
#include <cstddef>
#include <utility>
#include <vector>

namespace n91 {

  class prime_sieve {
  public:
    using size_type = std::size_t;

  private:
    std::vector<size_type> prime, factor;

  public:
    prime_sieve() {}
    explicit prime_sieve(const size_type size) : prime(), factor(size, 0) {
      assert(size > 2);
      factor[0] = 1;
      for (size_type i{ 2 }; i != size; ++i) {
        if (factor[i] == 0) {
          factor[i] = i;
          prime.push_back(i);
        }
        for (size_type j{ 0 };
          j != prime.size() && prime[j] <= factor[i] && i * prime[j] < size;++j) {
          factor[i * prime[j]] = prime[j];
        }
      }
    }
    size_type len() const noexcept { return factor.size(); }
    bool is_prime(const size_type i) const noexcept {
      assert(i < len());
      return factor[i] == i;
    }
    std::vector<size_type> factorize(size_type i) const noexcept {
      assert(i != 0);
      std::vector<size_type> ret;
      while (i != 1) {
        ret.push_back(factor[i]);
        i /= factor[i];
      }
      return std::move(ret);
    }
    template <class C> void divisor_zeta(C& c) const noexcept {
      const size_type n{ c.size() };
      assert(n <= len());
      for (size_type i{ 0 }; i != prime.size() && prime[i] < n; ++i) {
        for (size_type j{ 1 }; j * prime[i] < n; ++j) {
          c[j * prime[i]] += c[j];
        }
      }
    }
    template <class C> void divisor_mobius(C& c) const noexcept {
      const size_type n{ c.size() };
      assert(n <= len());
      for (size_type i{ 0 }; i != prime.size() && prime[i] < n; ++i) {
        for (size_type j{ (n - 1) / prime[i] }; j != 0; --j) {
          c[j * prime[i]] -= c[j];
        }
      }
    }
    template <class C> void multiple_zeta(C& c) const noexcept {
      const size_type n{ c.size() };
      assert(n <=len());
      for (size_type i{ 0 }; i != prime.size() && prime[i] < n; ++i) {
        for (size_type j{ (n - 1) / prime[i] }; j != 0; --j) {
          c[j] += c[j * prime[i]];
        }
      }
    }
    template <class C> void multiple_mobius(C& c) const noexcept {
      const size_type n{ c.size() };
      assert(n <=len());
      for (size_type i{ 0 }; i != prime.size() && prime[i] < n; ++i) {
        for (size_type j{ 1 }; j * prime[i] < n; ++j) {
          c[j] -= c[j * prime[i]];
        }
      }
    }
  };

} // namespace n91

#include <algorithm>
#include <iostream>
#include <utility>

namespace n91 {

  void main_() {
    using mint = modint<static_cast<u64>(998244353)>;
    const usize n = scan<usize>();
    std::vector<int> x(n);
    for (auto& e : x) {
      e = scan<char>() - '0';
    }
    std::vector<mint> pow2(n + 1_z);
    pow2[0_z] = static_cast<mint>(1);
    for (const auto i : rep(0_z, n)) {
      pow2[i + 1_z] = pow2[i] + pow2[i];
    }

    const auto solve = [&](const usize block) -> mint {
      mint ret = static_cast<mint>(0);
      for (const auto i : rep(0_z, block)) {
        if (x[i]) {
          ret += pow2[block - i - 1_z];
        }
      }
      for (const auto i : rep(0_z, n)) {
        const int ex = x[i % block] ^ (i / block % 2_z);
        if (ex < x[i]) {
          return ret + static_cast<mint>(1);
        }
        if (ex > x[i]) {
          return ret;
        }
      }
      return ret + static_cast<mint>(1);
    };

    std::vector<mint> vec(n + 1_z);
    mint ans = static_cast<mint>(0);
    for (const auto i : rep(1_z, n + 1_z)) {
      if (n % i == 0_z && i % 2_z == 1_z) {
        vec[i] += solve(n / i);
      }
    }
    const prime_sieve s{ n + 1_z };
    s.multiple_mobius(vec);
    for (const auto i : rep(1_z, n + 1_z)) {
      ans += vec[i] * static_cast<mint>(n / i);
    }
    std::cout << (ans * static_cast<mint>(2)).value() << std::endl;
  }

} // namespace n91

int main() {
  n91::main_();
  return 0;
}