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

using i8 = ::std::int_least8_t;
using i32 = ::std::int_least32_t;
using i64 = ::std::int_least64_t;
using u8 = ::std::uint_least8_t;
using u32 = ::std::uint_least32_t;
using u64 = ::std::uint_least64_t;
using isize = ::std::ptrdiff_t;
using usize = ::std::size_t;

template <class T = usize> class rep {
  const T f, l;

public:
  class itr {
    friend rep;
    T i;
    constexpr itr(T x) noexcept : i(x) {}

  public:
    void operator++() noexcept { ++i; }
    constexpr T operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr x) const noexcept { return i != x.i; }
  };
  constexpr rep(const T first, const T last) noexcept : f(first), l(last) {}
  constexpr itr begin() const noexcept { return itr(f); }
  constexpr itr end() const noexcept { return itr(l); }
};
template <class T = usize> class revrep {
  const T f, l;

public:
  class itr {
    friend revrep;
    T i;
    constexpr itr(T x) noexcept : i(x) {}

  public:
    void operator++() noexcept { --i; }
    constexpr T operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr x) const noexcept { return i != x.i; }
  };
  constexpr revrep(const T first, const T last) noexcept : f(first), l(last) {}
  constexpr itr begin() const noexcept { return itr(l - 1); }
  constexpr itr end() const noexcept { return itr(f - 1); }
};
template <class T> bool amax(T &a, const T &b) {
  return a <= b ? (a = b, 1) : 0;
}
template <class T> bool amin(T &a, const T &b) {
  return b <= a ? (a = b, 1) : 0;
}
template <class T> bool asmax(T &a, const T &b) {
  return b <= a ? 0 : (a = b, 1);
}
template <class T> bool asmin(T &a, const T &b) {
  return a <= b ? 0 : (a = b, 1);
}
template <class T> using vec_alias = ::std::vector<T>;
template <class T> auto md_vec(usize n, const T &value) {
  return ::std::vector<T>(n, value);
}
template <class... Args> auto md_vec(usize n, Args... args) {
  return ::std::vector<decltype(md_vec(args...))>(n, md_vec(args...));
}
template <class T> const T &as_const(const T &v) noexcept { return v; }
template <class T> constexpr T difference(const T &a, const T &b) {
  return a <= b ? b - a : a - b;
}

#include <cstdint>
#include <vector>

namespace n91 {

template <class Base> struct mersenne61_rolling_hash {
  using u64 = std::uint_fast64_t;
  using value_type = u64;
  using container_type = std::vector<value_type>;
  using size_type = typename container_type::size_type;

  static constexpr u64 pow2(const int exp) noexcept {
    return static_cast<u64>(1) << exp;
  }

  static constexpr u64 Mod = pow2(61) - static_cast<u64>(1);

  static constexpr u64 cyclic(const u64 v) noexcept {
    return v % pow2(30) * pow2(31) + v / pow2(30);
  }
  static constexpr u64 calc(u64 v) noexcept {
    if (v > Mod) {
      v = v % pow2(61) + v / pow2(61);
    }
    if (v > Mod) {
      v -= Mod;
    }
    return v;
  }
  static constexpr u64 multiplies(u64 l, u64 r) noexcept {
    const u64 lu = l / pow2(31), ru = r / pow2(31);
    l %= pow2(31);
    r %= pow2(31);
    return calc(lu * ru * static_cast<u64>(2) + l * r +
                cyclic(lu * r + ru * l));
  }
  static constexpr u64 multiplies_plus(u64 l, u64 r,
                                       const u64 c) noexcept {
    const u64 lu = l / pow2(31), ru = r / pow2(31);
    l %= pow2(31);
    r %= pow2(31);
    return calc(lu * ru * static_cast<u64>(2) + l * r +
                cyclic(lu * r + ru * l) + c);
  }

  container_type prefix, power;

public:
  template <class InputIterator>
  explicit mersenne61_rolling_hash(InputIterator first,
                                   const InputIterator last) noexcept
      : prefix(), power() {
    const size_type n = static_cast<size_type>(std::distance(first, last));
    prefix.reserve(n + static_cast<size_type>(1));
    prefix.push_back(static_cast<value_type>(0));
    for (; first != last; ++first) {
      prefix.push_back(multiplies_plus(prefix.back(), Base::value, *first));
    }
    power.reserve(n + static_cast<size_type>(1));
    power.push_back(static_cast<value_type>(1));
    for (size_type i = static_cast<size_type>(0); i != n; ++i) {
      power.push_back(multiplies(power.back(), Base::value));
    }
  }

  value_type operator()(const size_type first, const size_type last) const
      noexcept {
    return multiplies_plus(prefix[first], power[last - first],
                           Mod - prefix[last]);
  }
};

} // namespace n91

#include <algorithm>
#include <iostream>
#include <set>
#include <stack>
#include <string>
#include <utility>

int main() {
  static constexpr u64 Base = 12648246;
  usize n;
  std::cin >> n;
  std::string t;
  std::cin >> t;
  std::vector<u64> ft(n);
  for (const auto i : rep<>(0, n)) {
    ft[i] = t[i] - 'a';
  }
  auto rt = ft;
  std::reverse(rt.begin(), rt.end());

  const n91::mersenne61_rolling_hash<std::integral_constant<u64, Base>> fh(
      ft.cbegin(), ft.cend()),
      rh(rt.cbegin(), rt.cend());

  for (const auto s : rep<>(2, n + 1)) {
    const u64 f = fh(0, s), r = rh(n - s, n);

    bool flag = false;
    for (usize i = 0; (i + s) <= n; i += 2 * s - 2) {
      const u64 h = fh(i, i + s);
      if (h != f) {
        flag = true;
        break;
      }
    }
    if (flag) {
      continue;
    }
    flag = false;
    for (usize i = s - 1; (i + s) <= n; i += 2 * s - 2) {
      const u64 h = fh(i, i + s);
      if (h != r) {
        flag = true;
        break;
      }
    }
    if (flag) {
      continue;
    }

    const usize last_s = (n - 1) % (s - 1) + 1;
    const usize last_i = n - last_s;

    if (last_i / (s - 1) % 2 == 0) {
      if (fh(0, last_s) != fh(last_i, n)) {
        continue;
      }
    } else {
      if (rh(n - s, n - (s - last_s)) != fh(last_i, n)) {
        continue;
      }
    }

    std::cout << s << std::endl;
    return 0;
  }

  return 0;
}


Measured memory_bytes: 50956