You are given a string s, consisting of lowercase English letters, and the integer m.

One should choose some symbols from the given string so that any contiguous subsegment of length m has at least one selected symbol. Note that here we choose positions of symbols, not the symbols themselves.

Then one uses the chosen symbols to form a new string. All symbols from the chosen position should be used, but we are allowed to rearrange them in any order.

Formally, we choose a subsequence of indices 1 ≤ i1 < i2 < ... < it ≤ |s|. The selected sequence must meet the following condition: for every j such that 1 ≤ j ≤ |s| - m + 1, there must be at least one selected index that belongs to the segment [j, j + m - 1], i.e. there should exist a k from 1 to t, such that j ≤ ik ≤ j + m - 1.

Then we take any permutation p of the selected indices and form a new string sip1sip2... sipt.

Find the lexicographically smallest string, that can be obtained using this procedure.

Input

The first line of the input contains a single integer m (1 ≤ m ≤ 100 000).

The second line contains the string s consisting of lowercase English letters. It is guaranteed that this string is non-empty and its length doesn't exceed 100 000. It is also guaranteed that the number m doesn't exceed the length of the string s.

Output

Print the single line containing the lexicographically smallest string, that can be obtained using the procedure described above.

Examples

Input

3
cbabc


Output

a


Input

2
abcab


Output

aab


Input

3
bcabcbaccba


Output

aaabb

Note

In the first sample, one can choose the subsequence {3} and form a string "a".

In the second sample, one can choose the subsequence {1, 2, 4} (symbols on this positions are 'a', 'b' and 'a') and rearrange the chosen symbols to form a string "aab".
#include <bits/stdc++.h>
template <typename T>
class IntegerIterator
    : public std::iterator<std::input_iterator_tag, T, std::ptrdiff_t, T*, T> {
 public:
  explicit IntegerIterator(T value) : value(value) {}
  IntegerIterator& operator++() {
    ++value;
    return *this;
  }
  IntegerIterator operator++(int) {
    IntegerIterator copy = *this;
    ++value;
    return copy;
  }
  IntegerIterator& operator--() {
    --value;
    return *this;
  }
  IntegerIterator operator--(int) {
    IntegerIterator copy = *this;
    --value;
    return copy;
  }
  T operator*() const { return value; }
  bool operator==(IntegerIterator rhs) const { return value == rhs.value; }
  bool operator!=(IntegerIterator rhs) const { return !(*this == rhs); }

 private:
  T value;
};
template <typename T>
class IntegerRange {
 public:
  IntegerRange(T begin, T end) : begin_(begin), end_(end) { ; }
  IntegerIterator<T> begin() const { return IntegerIterator<T>(begin_); }
  IntegerIterator<T> end() const { return IntegerIterator<T>(end_); }

 private:
  T begin_;
  T end_;
};
template <typename T>
class ReversedIntegerRange {
 public:
  ReversedIntegerRange(T begin, T end) : begin_(begin), end_(end) { ; }
  std::reverse_iterator<IntegerIterator<T>> begin() const {
    return std::reverse_iterator<IntegerIterator<T>>(
        IntegerIterator<T>(begin_));
  }
  std::reverse_iterator<IntegerIterator<T>> end() const {
    return std::reverse_iterator<IntegerIterator<T>>(IntegerIterator<T>(end_));
  }

 private:
  T begin_;
  T end_;
};
template <typename T>
IntegerRange<T> range(T to) {
  return IntegerRange<T>(0, to);
}
template <typename T>
IntegerRange<T> range(T from, T to) {
  return IntegerRange<T>(from, to);
}
template <typename T>
IntegerRange<T> inclusiveRange(T to) {
  return IntegerRange<T>(0, to + 1);
}
template <typename T>
IntegerRange<T> inclusiveRange(T from, T to) {
  return IntegerRange<T>(from, to + 1);
}
template <typename T>
ReversedIntegerRange<T> downrange(T from) {
  return ReversedIntegerRange<T>(from, 0);
}
template <typename T>
ReversedIntegerRange<T> downrange(T from, T to) {
  return ReversedIntegerRange<T>(from, to);
}
template <typename T>
ReversedIntegerRange<T> inclusiveDownrange(T from) {
  return ReversedIntegerRange<T>(from + 1, 0);
}
template <typename T>
ReversedIntegerRange<T> inclusiveDownrange(T from, T to) {
  return ReversedIntegerRange<T>(from + 1, to);
}
template <typename R>
void sort(R& range) {
  std::sort(range.begin(), range.end());
}
template <typename R, typename Comp>
void sort(R& range, Comp comp) {
  std::sort(range.begin(), range.end(), comp);
}
template <typename R>
void reverse(R& range) {
  std::reverse(range.begin(), range.end());
}
template <typename R, typename T>
auto lower_bound(const R& range, const T& value) -> decltype(range.begin()) {
  return std::lower_bound(range.begin(), range.end(), value);
}
template <typename R, typename T, typename Comp>
auto lower_bound(const R& range, const T& value, Comp comp)
    -> decltype(range.begin()) {
  return std::lower_bound(range.begin(), range.end(), value, comp);
}
template <typename R, typename T>
auto upper_bound(const R& range, const T& value) -> decltype(range.begin()) {
  return std::upper_bound(range.begin(), range.end(), value);
}
template <typename R, typename T, typename Comp>
auto upper_bound(const R& range, const T& value, Comp comp)
    -> decltype(range.begin()) {
  return std::upper_bound(range.begin(), range.end(), value, comp);
}
template <typename R>
auto min_element(const R& range) -> decltype(range.begin()) {
  return std::min_element(range.begin(), range.end());
}
template <typename R>
auto max_element(const R& range) -> decltype(range.begin()) {
  return std::max_element(range.begin(), range.end());
}
template <typename R>
bool next_permutation(R& range) {
  return std::next_permutation(range.begin(), range.end());
}
template <typename T>
void unique(std::vector<T>& range) {
  range.erase(std::unique(range.begin(), range.end()), range.end());
}
template <typename R>
R sorted(R range) {
  sort(range);
  return range;
}
template <typename R, typename Comp>
R sorted(R range, Comp comp) {
  sort(range, comp);
  return range;
}
template <typename R>
R reversed(R range) {
  reverse(range);
  return range;
}
template <typename T>
constexpr auto hasBegin(int) -> decltype(std::begin(std::declval<T>()), true) {
  return true;
}
template <typename T>
constexpr bool hasBegin(...) {
  return false;
}
template <typename T>
using IsContainer = std::integral_constant<bool, hasBegin<T>(0)>;
template <bool b, typename T = void>
using enable_if_t = typename std::enable_if<b, T>::type;
template <typename T, typename Merge>
class SegmentTreeBase {
 protected:
  SegmentTreeBase(std::size_t n, const T& defaultValue = T(),
                  const Merge& merge = Merge())
      : n(n),
        defaultValue(defaultValue),
        shift(calculateShift(n)),
        values(shift << 1, defaultValue),
        merge(merge) {}
  template <typename R, typename = enable_if_t<IsContainer<R>::value>>
  SegmentTreeBase(const R& range, const T& defaultValue = T(),
                  const Merge& merge = Merge())
      : SegmentTreeBase(static_cast<std::size_t>(
                            std::distance(std::begin(range), std::end(range))),
                        defaultValue, merge) {
    std::copy(std::begin(range), std::end(range), values.begin() + shift);
    for (std::size_t index : downrange(shift, static_cast<std::size_t>(1))) {
      recalculate(index);
    }
  }
  static std::size_t calculateShift(std::size_t n) {
    std::size_t result = 1;
    while (result < n) {
      result <<= 1;
    }
    return result;
  }
  void recalculate(std::size_t index) {
    values[index] = merge(values[2 * index], values[2 * index + 1]);
  }
  std::size_t n;
  T defaultValue;
  std::size_t shift;
  std::vector<T> values;
  Merge merge;
};
template <typename T, typename Merge>
class BottomUpSegmentTree : protected SegmentTreeBase<T, Merge> {
 public:
  template <typename R>
  BottomUpSegmentTree(const R& range, const T& defaultValue = T(),
                      const Merge& merge = Merge())
      : SegmentTreeBase<T, Merge>(range, defaultValue, merge) {}
  const T& getElement(std::size_t index) {
    ;
    return values[index + shift];
  }
  T getResult(std::size_t l, std::size_t r) const {
    ;
    return internalGetResult(l + shift, r + shift);
  }
  template <typename Updater>
  void update(std::size_t index, const Updater& updater) {
    ;
    index += shift;
    updater(values[index]);
    for (std::size_t parent = index / 2; parent > 0; parent /= 2) {
      this->recalculate(parent);
    }
  }
  void set(std::size_t index, const T& value) {
    return update(index, [&value](T& element) { element = value; });
  }

 protected:
  using SegmentTreeBase<T, Merge>::defaultValue;
  using SegmentTreeBase<T, Merge>::merge;
  using SegmentTreeBase<T, Merge>::n;
  using SegmentTreeBase<T, Merge>::shift;
  using SegmentTreeBase<T, Merge>::values;

 private:
  T internalGetResult(std::size_t l, std::size_t r) const {
    if (l == r) {
      return defaultValue;
    }
    if (l & 1) {
      return merge(values[l], internalGetResult(l + 1, r));
    }
    if (r & 1) {
      return merge(internalGetResult(l, r - 1), values[r - 1]);
    }
    return internalGetResult(l / 2, r / 2);
  }
};
struct Min {
  template <typename T>
  T operator()(const T& l, const T& r) const {
    return std::min(l, r);
  }
};
template <typename T, typename Enable = std::true_type>
struct PositiveInfinity {
  T operator()() const;
};
template <typename T>
struct PositiveInfinity<T, typename std::is_integral<T>::type> {
  T operator()() const { return std::numeric_limits<T>::max(); }
};
template <typename T>
struct PositiveInfinity<T, typename std::is_floating_point<T>::type> {
  T operator()() const { return std::numeric_limits<T>::infinity(); }
};
template <typename T>
class BottomUpMinSegmentTree : public BottomUpSegmentTree<T, Min> {
 public:
  template <typename R>
  BottomUpMinSegmentTree(const R& range,
                         const T& infinity = PositiveInfinity<T>()())
      : BottomUpSegmentTree<T, Min>(range, infinity) {}
  void updateMinimum(std::size_t index, const T& value) {
    return this->update(index, [&value, this](T& element) {
      element = this->merge(element, value);
    });
  }
};
using namespace std;
class TaskD {
 public:
  void solve(std::istream& in, std::ostream& out) {
    int m;
    in >> m;
    string s;
    in >> s;
    for (char c = 'a'; c <= 'z'; ++c) {
      vector<int> poses;
      poses.push_back(-1);
      for (int i : range(s.size())) {
        if (s[i] <= c) {
          poses.push_back(i);
        }
      }
      poses.push_back((int)s.size());
      bool can = true;
      for (int i : range(1, (int)poses.size())) {
        if (poses[i] - poses[i - 1] > m) {
          can = false;
          break;
        }
      }
      if (can) {
        vector<int> used_poses;
        BottomUpMinSegmentTree<int> tree(s.size());
        for (int i : range(m)) {
          if (s[i] < c) {
            tree.set(i, 0);
          }
          if (s[i] == c) {
            tree.set(i, 1);
          }
        }
        for (int i : range(m, (int)s.size())) {
          if (s[i] > c) {
            continue;
          }
          tree.set(i, tree.getResult(i - m, i) + (s[i] == c));
        }
        int mn = tree.getResult(s.size() - m, s.size());
        for (int z : range(mn)) {
          out << c;
        }
        return;
      }
      for (char d : s) {
        if (c == d) {
          out << c;
        }
      }
    }
  }
};
int main() {
  std::ios_base::sync_with_stdio(false);
  TaskD solver;
  std::istream& in(std::cin);
  std::ostream& out(std::cout);
  solver.solve(in, out);
  in.tie(0);
  out << std::fixed;
  out.precision(20);
  return 0;
}
