#include <bits/stdc++.h>
      
#define FOR(i,a,b) for( ll i = (a); i < (ll)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define UNIQUE(x) (x).erase( unique( ALL( (x) ) ) , (x).end() )
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())
#define SHOW(x) cout << #x << " = " << x << endl
     
#define pb emplace_back
#define fi first
#define se second
     
using namespace std;
     
typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vl> ml;
typedef vector<vd> md;
typedef vector<vi> mi;
     
const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ld EPS = 1e-12;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> inline T sq( T a ){ return a * a; }

ll in(){ ll x; scanf( "%lld" , &x ); return x; }
char yuyushiki[1000010]; string stin(){ scanf( "%s" , yuyushiki ); return yuyushiki; }

// head

template<class T>
class MinOp{
public:
  T operator () ( T a , T b ){ return min( a , b ); }
};
template<class T>
class MaxOp{
public:
  T operator () ( T a , T b ){ return max( a , b ); }
};


template<typename T, class OpFunc>
struct Segtree{
  T ID;
  vector<T> node;
  int size;
  OpFunc op;
  void init( int n , OpFunc opfunc , T identity ){
    op = opfunc;
    ID = identity;
    size = 1;
    while( size < n ) size *= 2;
    node = vector<T>( size*2-1 , ID );
  }
  void update( int k , T x ){
    k += size-1;
    node[k] = x;
    while( k > 0 ){
      k = (k-1)/2;
      node[k] = op( node[k*2+1] , node[k*2+2] );
    }
  }
  T query( int a , int b , int k , int l , int r ){
    if( a <= l && r <= b ){
      return node[k];
    } else if( b <= l || r <= a ){
      return ID;
    } else {
      T chl = query( a , b , k*2+1 , l , (l+r)/2 );
      T chr = query( a , b , k*2+2 , (l+r)/2 , r );
      return op( chl , chr );
    }
  }
  T query( int a , int b ){
    return query( a , b , 0 , 0 , size );
  }
  T get( int a ){
    return node[a+size-1];
  }
};


struct SA : public vi{
  int n, k;
  vi rank, tmp;
  
  bool compare( int i , int j ){
    if( rank[i] != rank[j] ) return rank[i] < rank[j];

    int ri = i + k <= n ? rank[i+k] : -1;
    int rj = j + k <= n ? rank[j+k] : -1;
    return ri < rj;
  }

  struct Compare_SA{
    SA *sa;
    Compare_SA( SA *s ) : sa(s) {}
    bool operator() ( const int &i , const int &j ){
      return sa->compare( i , j );
    }
  };

  void init( string S ){
    n = S.length();

    resize( n+1 );
    rank = tmp = vi( n+1 );
    REP( i , n+1 ){
      at(i) = i;
      rank[i] = i < n ? S[i] : -1;
    }

    for( k = 1; k <= n; k *= 2 ){
      sort( begin() , end() , Compare_SA(this) );

      tmp[at(0)] = 0;
      FOR( i , 1 , n+1 )
	tmp[at(i)] = tmp[at(i-1)] + (compare(at(i-1),at(i))?1:0);

      REP( i , n+1 ) rank[i] = tmp[i];
    }
  }
};

struct LCP : public vi{
  void init( string S , const SA &sa ){
    int n = S.length();

    vi rank(n+1);
    REP( i , n+1 ) rank[sa[i]] = i;

    int h = 0;
    resize( n , 0 );
    REP( i , n ){
      int j = sa[rank[i]-1];

      if( h > 0 ) h--;
      for( ; j+h < n && i+h < n; h++ ) if( S[j+h] != S[i+h] ) break;

      at(rank[i]-1) = h;
    }
  }
};

struct RangeLCP{
  SA sa;
  LCP lcp;
  Segtree<int,MinOp<int> > seg;
  void init( string s ){
    sa.init( s );
    lcp.init( s , sa );
    seg.init( SZ(s) , MinOp<int>() , INF );
    REP( i , SZ(s) ){
      seg.update( i , lcp[i] );
    }
  }
  int sa_query( int l , int r ){
    return seg.query( l , r );
  }
  int pos_query( int l , int r ){
    int a = sa.rank[l];
    int b = sa.rank[r];
    if( a > b ){
      swap( a , b );
    }
    return seg.query( a , b );
  }
};


int n, k, l;
string s;
SA sa;

vi v;

RangeLCP lcp;

bool check( int x ){
  int cur = 0;
  int cnt = 0;
  while( cur < n ){
    // cout << cur << " " << cnt << endl;
    if( cnt > k ){
      return false;
    }
    if( sa.rank[cur] > sa.rank[x] and lcp.pos_query( x , cur ) < l ){
      cur += l-1;
    } else {
      cur += l;
    }
    cnt++;
  }
  return true;
}

int main(){

  k = in();
  s = stin();
  n = SZ(s);
  
  sa.init( s );
  lcp.init( s );

  l = ( n + k ) / ( k + 1 );

  /*
  cout << check( 5 ) << endl;
  return 0;
  */
  

  
  REP( i , n+1 ){
    if( sa[i] <= n - l ){
      v.pb( sa[i] );
    }
  }

  int lb = -1, ub = SZ(v);
  while( ub - lb > 1 ){
    int md = ( lb + ub ) / 2;
    if( check( v[md] ) ){
      ub = md;
    } else {
      lb = md;
    }
  }

  /*
  SHOW( v[ub] );
  SHOW( check( v[ub] ) );
  */
  
  FOR( i , v[ub] , v[ub]+l ){
    printf( "%c" , s[i] );
  }
  printf( "\n" );
  
  return 0;
}


Measured memory_bytes: 5112