using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
using System.Text;//テキストの高速出力に必要
class Program
{
static int k;
static string s;
static int n;
static int[] suffixNums;//a番目が何文字目からか
static int[] suffixArray;
static int stringLength;//最長の文字列の長さ
static int longCount;//最長の文字列の個数

	static void Main()
	{
		k = int.Parse(Console.ReadLine());
		s = Console.ReadLine();
    n = s.Length;
    suffixNums = new int[n];//a番目が何文字目からか
    stringLength = (n+k)/(k+1);//最長の文字列の長さ
    suffixArray = SuffixArray(s);
    
    longCount = n-(stringLength-1)*(k+1);//最長の文字列の個数
    long[,] suffixMemo = new long[n-stringLength+1,2];
    for(int i = 0; i < n-stringLength+1; i++)
    {
      suffixMemo[i,0] = suffixArray[i];
      suffixMemo[i,1] = i;
    }
    suffixMemo = CoordinateCompression(suffixMemo);
    for(int i = 0; i < n-stringLength+1; i++)
    {
      suffixNums[suffixMemo[i,2]] = i;
    }

    int startNum = (int)Search(0,n-stringLength,-1);
    //Console.WriteLine(n+" "+(n-stringLength)+" "+startNum);
		Console.WriteLine(s.Substring(suffixNums[startNum],stringLength));
    for(int i = 0; i <= n-stringLength; i++)
    {
      //Console.WriteLine(s.Substring(suffixNums[i],stringLength));
    }
	}

  static int[] SuffixArray(string s)
  {//a(0~n-1)文字目から最後の文字までを辞書順にした時の順番(0-index)をO(n(logn)^2)で返す
  //例えばacbなら{0,2,1}を返す
    int n = s.Length;
    int[] answers = new int[n];
    int[][] suffixes = new int[n][];
    for(int i = 0; i < n; i++)
    {
      suffixes[i] = new int[4];
      suffixes[i][0] = i;//初期位置
      suffixes[i][1] = s[i]-'1';//文字charをint(>=0)で辞書順に変換
      //Console.WriteLine(i+" "+suffixes[i][1]);
    }

    for(int i = 1; i < n; i*=2)
    {
      Array.Sort(suffixes, (a, b) => a[0].CompareTo(b[0]));
      for(int j = 0; j < n; j++)
      {
        if(j+i < n) suffixes[j][2] = suffixes[j+i][1];
        else suffixes[j][2] = -1;
        //Console.WriteLine(j+" "+suffixes[j][2]);
      }
      
      var sorted = suffixes.OrderBy(a => a[1]).ThenBy(a => a[2]).ToList();
      int numberMemo = 0;
      suffixes[sorted[0][0]][1] = numberMemo;
      for(int j = 1; j < n; j++)
      {
        if(sorted[j][1] != sorted[j-1][1] || sorted[j][2] != sorted[j-1][2])
        {
          numberMemo++;
        }
        
        suffixes[sorted[j][0]][3] = numberMemo;
        //Console.WriteLine(i+" "+j+" "+numberMemo);
      }

      for(int j = 0; j < n; j++)
      {
        suffixes[j][1] = suffixes[j][3];
      }

      /*
      Array.Sort(suffixes, (a, b) => a[1].CompareTo(b[1]));
      for(int j = 0; j < n; j++)
      {
        if(suffixes[j][0] <= n-stringLength)
          Console.WriteLine(s.Substring(suffixes[j][0],stringLength)+" "+i
            +" "+suffixes[j][1]);
      }
      */
      
    }

    Array.Sort(suffixes, (a, b) => a[0].CompareTo(b[0]));
    for(int i = 0; i < n; i++)
    {
      answers[i] = suffixes[i][1];
    }

    /*
    Array.Sort(suffixes, (a, b) => a[1].CompareTo(b[1]));
    for(int i = 0; i < n; i++)
    {
      //Console.WriteLine(suffixes[i][0] +"a"+ (n-stringLength));
      if(suffixes[i][0] <= n-stringLength)
        Console.WriteLine(s.Substring(suffixes[i][0],stringLength));
    }
    */

    return answers;
  }

  static long Search(long min, long max, int MinorMax)//二分探索法で最小値-1最大値1を求める
  {
    while (true)
    {
      long mid = min + (max - min) / 2;
      if(MinorMax == 1)
      {
        if(Check(mid)) min = mid;//さらに大きくても成り立つかも
        else max = mid;
      }else
      {
        if(Check(mid)) max = mid;//さらに小さくても成り立つかも
        else min = mid;
      }

      if(max - min <= 1)
      {
        if(MinorMax == 1)
        {
          if(Check(max)) return max;//最大値で成り立つかの確認を優先
          else return min;
        }else
        {
          if(Check(min)) return min;//最小値で成り立つかの確認を優先
          else return max;
        }

      break;
      }  
    }
  }

  static bool Check(long testNum)
  {
    int lookingNum = 0;
    //Console.WriteLine(testNum+"b");
    testNum = suffixNums[testNum];
    //Console.WriteLine(testNum+"a");

    for(int i = 0; i < k+1; i++)
    {//分ける個数
    
      bool bigger = false;
      for(int j = 0; j < stringLength; j++)
      {
        if(lookingNum+j >= n || (int)testNum+j >= n) break;

        if(s[lookingNum+j] < s[(int)testNum+j]) break;
        else if(s[lookingNum+j] > s[(int)testNum+j])
        {
          bigger = true;
          break;
        }
      }
      lookingNum += stringLength-1;
      if(!bigger) lookingNum++;
    }

    //Console.WriteLine(lookingNum+" "+n);
    if(lookingNum >= n) return true;
    return false;
  }  

  static long[,] CoordinateCompression(long[,] vertexesOriginal)
    //1次元の座標圧縮。配列は0-indexで引数[x,順番]から[x,順番,圧縮x]を返す。
    //例えば、{2,4,4,3}は{0,2,2,1}を返す。
  {
    long n = vertexesOriginal.GetLength(0);//多次元配列の長さの取得
    long xCount = 1;//圧縮後のxの個数
    long[] compressedXmemo = new long[n];
    long[][] vertexes = new long[n][];
    for(long i = 0; i < n; i++)
    {
      vertexes[i] = new long[3];
      for(long j = 0; j < 2; j++)
      {
        vertexes[i][j] = vertexesOriginal[i,j];//配列をジャグ配列に置換
      }
    }

    Array.Sort(vertexes, (a, b) => a[0].CompareTo(b[0]));//x座標でソート
    vertexes[0][2] = 0;
    compressedXmemo[0] = vertexes[0][0];
    for(long i = 1; i < n; i++)
    {
      if(vertexes[i][0] == vertexes[i-1][0])//x座標が同じ
      {
        vertexes[i][2] = xCount - 1;
      }else
      {
        xCount++;
        vertexes[i][2] = xCount - 1;
        compressedXmemo[xCount-1] = vertexes[i][0];
      }
    }
    long[] compressedX = new long[xCount];
    for(long i = 0; i < xCount; i++) compressedX[i] = compressedXmemo[i];

    Array.Sort(vertexes, (a, b) => a[1].CompareTo(b[1]));//もとの番号順でソート

    long[,] answer = new long[n,3];
    for(long i = 0; i < n; i++)
    {
      for(long j = 0; j < 3; j++)
      {
        answer[i,j] = vertexes[i][j];//ジャグ配列から戻す
      }
    }

    return answer;//[x,順番,圧縮x]を返す。
  }

  
}

Measured memory_bytes: 46188