#include<bits/stdc++.h>
#define N 220000
int Len,n;
int len[N<<1],fa[N<<1],son[N<<1][26];
int size,last,root,pos[N<<1],rt[N*40],lc[N*40],rc[N*40];
int a[N<<1],c[N<<1],T,sum[N*40],ans[N<<1],ANS;
int f[N<<1];
char s[N];
void Init(){root=size=last=1;}
void Extend(int c,int wz){
    int end=++size,tmp=last;
    len[end]=len[tmp]+1;pos[end]=wz;
    while(tmp&&!son[tmp][c]){
        son[tmp][c]=end;
        tmp=fa[tmp];
    }
    if(!tmp) fa[end]=root;
    else{
        int ne=son[tmp][c];
        if(len[tmp]+1==len[ne]) fa[end]=ne;
        else{
            int np=++size;
            memcpy(son[np],son[ne],sizeof(son[ne]));
            len[np]=len[tmp]+1;
            fa[np]=fa[ne];
            fa[end]=fa[ne]=np;
            pos[np]=pos[ne];
            while(tmp&&son[tmp][c]==ne){
                son[tmp][c]=np;
                tmp=fa[tmp];
          	  }
       	}
     }
    last=end;
}
void Radixsort(){
    for(int i=1;i<=size;i++) c[len[i]]++;
    for(int i=1;i<=Len;i++) c[i]+=c[i-1];
    for(int i=size;i>=1;i--) a[c[len[i]]--]=i;
}
void insert(int &i, int l, int r, int x){
    if(r<l) return ;
    i = ++T;
    if(l == r) {
        sum[i]++ ;
        //num[i]=1LL*x;
        return ;
    }
    int mid = (l + r)/2 ;
    if(x<=mid) insert(lc[i], l, mid, x) ;
    if(x>mid) insert(rc[i], mid + 1, r, x) ;
    //clac(i);
    sum[i]=sum[lc[i]]+sum[rc[i]];
}
int merge(int x, int y) {
    if(!x) return y;
    if(!y) return x;
    sum[x]+=sum[y];
    lc[x] = merge(lc[x], lc[y]) ;
    rc[x] = merge(rc[x], rc[y]) ;
    return x;
}
bool query(int x,int l,int r,int ls,int rs){
	if (ls<=l&&r<=rs)return sum[x]>0;
	int mid=(l+r)/2;
	if (ls<=mid){
		if (query(lc[x],l,mid,ls,rs))return 1;
	}
	if (mid<rs){
		if (query(rc[x],mid+1,r,ls,rs))return 1;
	}
	return 0;
	//return query(lc[x],l,mid,ls,rs)|query(rc[x],mid+1,r,ls,rs);
}
int main(){
	scanf("%d",&n);
	scanf("%s",s);
	Len=n;
	Init();
	for (int i=0;i<n;i++)Extend(s[i]-'a',i+1),insert(rt[last],1,n,i+1);
	Radixsort();
	//printf("%d\n",size);
	for (int i=size;i;i--){
		int p=a[i];
		rt[fa[p]]=merge(rt[fa[p]],rt[p]);
	}
	ANS=1;
	for (int i=2;i<=size;i++){
		int p=a[i];
		if (fa[p]==1){
			ans[p]=1;
			f[p]=p;
			continue;
		}
		//printf("%d %d %d\n",fa[p],p,i);
		bool flag=query(rt[f[p]],1,n,pos[p]-len[p]+len[f[p]],pos[p]-1);
		if (flag){
			ans[p]=ans[fa[p]]+1;
			f[p]=p;
		}else{
			ans[p]=ans[fa[p]];
			f[p]=f[fa[p]];
		}
		ANS=std::max(ANS,ans[p]);
	}
	printf("%d",ANS);
	return 0;
}


#include<bits/stdc++.h>
#define N 220000
int Len,n;
int len[N<<1],fa[N<<1],son[N<<1][26];
int size,last,root,pos[N<<1],rt[N*40],lc[N*40],rc[N*40];
int a[N<<1],c[N<<1],T,sum[N*40],ans[N<<1],ANS;
int f[N<<1];
char s[N];
void Init(){root=size=last=1;}
void Extend(int c,int wz){
    int end=++size,tmp=last;
    len[end]=len[tmp]+1;pos[end]=wz;
    while(tmp&&!son[tmp][c]){
        son[tmp][c]=end;
        tmp=fa[tmp];
    }
    if(!tmp) fa[end]=root;
    else{
        int ne=son[tmp][c];
        if(len[tmp]+1==len[ne]) fa[end]=ne;
        else{
            int np=++size;
            memcpy(son[np],son[ne],sizeof(son[ne]));
            len[np]=len[tmp]+1;
            fa[np]=fa[ne];
            fa[end]=fa[ne]=np;
            pos[np]=pos[ne];
            while(tmp&&son[tmp][c]==ne){
                son[tmp][c]=np;
                tmp=fa[tmp];
          	  }
       	}
     }
    last=end;
}
void Radixsort(){
    for(int i=1;i<=size;i++) c[len[i]]++;
    for(int i=1;i<=Len;i++) c[i]+=c[i-1];
    for(int i=size;i>=1;i--) a[c[len[i]]--]=i;
}
void insert(int &i, int l, int r, int x){
    if(r<l) return ;
    i = ++T;
    if(l == r) {
        sum[i]++ ;
        //num[i]=1LL*x;
        return ;
    }
    int mid = (l + r)/2 ;
    if(x<=mid) insert(lc[i], l, mid, x) ;
    if(x>mid) insert(rc[i], mid + 1, r, x) ;
    //clac(i);
    sum[i]=sum[lc[i]]+sum[rc[i]];
}
int merge(int x, int y) {
    if(!x) return y;
    if(!y) return x;
    sum[x]+=sum[y];
    lc[x] = merge(lc[x], lc[y]) ;
    rc[x] = merge(rc[x], rc[y]) ;
    return x;
}
bool query(int x,int l,int r,int ls,int rs){
	if (ls<=l&&r<=rs)return sum[x]>0;
	int mid=(l+r)/2;
	if (ls<=mid){
		if (query(lc[x],l,mid,ls,rs))return 1;
	}
	if (mid<rs){
		if (query(rc[x],mid+1,r,ls,rs))return 1;
	}
	return 0;
	//return query(lc[x],l,mid,ls,rs)|query(rc[x],mid+1,r,ls,rs);
}
int main(){
	scanf("%d",&n);
	scanf("%s",s);
	Len=n;
	Init();
	for (int i=0;i<n;i++)Extend(s[i]-'a',i+1),insert(rt[last],1,n,i+1);
	Radixsort();
	//printf("%d\n",size);
	for (int i=size;i;i--){
		int p=a[i];
		rt[fa[p]]=merge(rt[fa[p]],rt[p]);
	}
	ANS=1;
	for (int i=2;i<=size;i++){
		int p=a[i];
		if (fa[p]==1){
			ans[p]=1;
			f[p]=p;
			continue;
		}
		//printf("%d %d %d\n",fa[p],p,i);
		bool flag=query(rt[f[fa[p]]],1,n,pos[p]-len[p]+len[f[fa[p]]],pos[p]-1);
		if (flag){
			ans[p]=ans[fa[p]]+1;
			f[p]=p;
		}else{
			ans[p]=ans[fa[p]];
			f[p]=f[fa[p]];
		}
		ANS=std::max(ANS,ans[p]);
	}
	printf("%d",ANS);
	return 0;
}


#include<bits/stdc++.h>
#define N 220000
int Len,n;
int len[N<<1],fa[N<<1],son[N<<1][26];
int size,last,root,pos[N<<1],rt[N*40],lc[N*40],rc[N*40];
int a[N<<1],c[N<<1],T,sum[N*40],ans[N<<1],ANS;
int f[N<<1];
char s[N];
void Init(){root=size=last=1;}
void Extend(int c,int wz){
    int end=++size,tmp=last;
    len[end]=len[tmp]+1;pos[end]=wz;
    while(tmp&&!son[tmp][c]){
        son[tmp][c]=end;
        tmp=fa[tmp];
    }
    if(!tmp) fa[end]=root;
    else{
        int ne=son[tmp][c];
        if(len[tmp]+1==len[ne]) fa[end]=ne;
        else{
            int np=++size;
            memcpy(son[np],son[ne],sizeof(son[ne]));
            len[np]=len[tmp]+1;
            fa[np]=fa[ne];
            fa[end]=fa[ne]=np;
            pos[np]=pos[ne];
            while(tmp&&son[tmp][c]==ne){
                son[tmp][c]=np;
                tmp=fa[tmp];
          	  }
       	}
     }
    last=end;
}
void Radixsort(){
    for(int i=1;i<=size;i++) c[len[i]]++;
    for(int i=1;i<=Len;i++) c[i]+=c[i-1];
    for(int i=size;i>=1;i--) a[c[len[i]]--]=i;
}
void insert(int &i, int l, int r, int x){
    if(r<l) return ;
    i = ++T;
    if(l == r) {
        sum[i]++ ;
        //num[i]=1LL*x;
        return ;
    }
    int mid = (l + r)/2 ;
    if(x<=mid) insert(lc[i], l, mid, x) ;
    if(x>mid) insert(rc[i], mid + 1, r, x) ;
    //clac(i);
    sum[i]=sum[lc[i]]+sum[rc[i]];
}
int merge(int x, int y) {
    if(!x) return y;
    if(!y) return x;
    sum[x]+=sum[y];
    lc[x] = merge(lc[x], lc[y]) ;
    rc[x] = merge(rc[x], rc[y]) ;
    return x;
}
bool query(int x,int l,int r,int ls,int rs){
	if (ls>rs){
		printf("%d %d\n",ls,rs);
		printf("No\n");
		return 0;
	}
	if (ls<=l&&r<=rs)return sum[x]>0;
	int mid=(l+r)/2;
	if (ls<=mid){
		if (query(lc[x],l,mid,ls,rs))return 1;
	}
	if (mid<rs){
		if (query(rc[x],mid+1,r,ls,rs))return 1;
	}
	return 0;
	//return query(lc[x],l,mid,ls,rs)|query(rc[x],mid+1,r,ls,rs);
}
int main(){
	scanf("%d",&n);
	scanf("%s",s);
	Len=n;
	Init();
	for (int i=0;i<n;i++)Extend(s[i]-'a',i+1),insert(rt[last],1,n,i+1);
	Radixsort();
	//printf("%d\n",size);
	for (int i=size;i;i--){
		int p=a[i];
		rt[fa[p]]=merge(rt[fa[p]],rt[p]);
	}
	ANS=1;
	for (int i=2;i<=size;i++){
		int p=a[i];
		if (fa[p]==1){
			ans[p]=1;
			f[p]=p;
			continue;
		}
		//printf("%d %d %d\n",fa[p],p,i);
		bool flag=query(rt[f[p]],1,n,pos[p]-len[p]+len[f[p]]+1,pos[p]-1);
		if (flag){
			ans[p]=ans[fa[p]]+1;
			f[p]=p;
		}else{
			ans[p]=ans[fa[p]];
			f[p]=f[fa[p]];
		}
		ANS=std::max(ANS,ans[p]);
	}
	printf("%d",ANS);
	return 0;
}


#include<bits/stdc++.h>
#define N 220000
int Len,n;
int len[N<<1],fa[N<<1],son[N<<1][26];
int size,last,root,pos[N<<1],rt[N*40],lc[N*40],rc[N*40];
int a[N<<1],c[N<<1],T,sum[N*40],ans[N<<1],ANS;
int f[N<<1];
char s[N];
void Init(){root=size=last=1;}
void Extend(int c,int wz){
    int end=++size,tmp=last;
    len[end]=len[tmp]+1;pos[end]=wz;
    while(tmp&&!son[tmp][c]){
        son[tmp][c]=end;
        tmp=fa[tmp];
    }
    if(!tmp) fa[end]=root;
    else{
        int ne=son[tmp][c];
        if(len[tmp]+1==len[ne]) fa[end]=ne;
        else{
            int np=++size;
            memcpy(son[np],son[ne],sizeof(son[ne]));
            len[np]=len[tmp]+1;
            fa[np]=fa[ne];
            fa[end]=fa[ne]=np;
            pos[np]=pos[ne];
            while(tmp&&son[tmp][c]==ne){
                son[tmp][c]=np;
                tmp=fa[tmp];
          	  }
       	}
     }
    last=end;
}
void Radixsort(){
    for(int i=1;i<=size;i++) c[len[i]]++;
    for(int i=1;i<=Len;i++) c[i]+=c[i-1];
    for(int i=size;i>=1;i--) a[c[len[i]]--]=i;
}
void insert(int &i, int l, int r, int x){
    if(r<l) return ;
    i = ++T;
    if(l == r) {
        sum[i]++ ;
        //num[i]=1LL*x;
        return ;
    }
    int mid = (l + r)/2 ;
    if(x<=mid) insert(lc[i], l, mid, x) ;
    if(x>mid) insert(rc[i], mid + 1, r, x) ;
    //clac(i);
    sum[i]=sum[lc[i]]+sum[rc[i]];
}
int merge(int x, int y) {
    if(!x) return y;
    if(!y) return x;
    sum[x]+=sum[y];
    lc[x] = merge(lc[x], lc[y]) ;
    rc[x] = merge(rc[x], rc[y]) ;
    return x;
}
bool query(int x,int l,int r,int ls,int rs){
	if (ls<=l&&r<=rs)return 1;
	int mid=(l+r)/2;
	if (ls<=mid){
		if (query(lc[x],l,mid,ls,rs))return 1;
	}
	if (mid<rs){
		if (query(rc[x],mid+1,r,ls,rs))return 1;
	}
	return 0;
	//return query(lc[x],l,mid,ls,rs)|query(rc[x],mid+1,r,ls,rs);
}
int main(){
	scanf("%d",&n);
	scanf("%s",s);
	Len=n;
	Init();
	for (int i=0;i<n;i++)Extend(s[i]-'a',i+1),insert(rt[last],1,n,i+1);
	Radixsort();
	//printf("%d\n",size);
	for (int i=size;i;i--){
		int p=a[i];
		rt[fa[p]]=merge(rt[fa[p]],rt[p]);
	}
	ANS=1;
	for (int i=2;i<=size;i++){
		int p=a[i];
		if (fa[p]==1){
			ans[p]=1;
			f[p]=p;
			continue;
		}
		//printf("%d %d %d\n",fa[p],p,i);
		bool flag=query(rt[f[fa[p]]],1,n,pos[p]-len[p]+len[f[fa[p]]],pos[p]-1);
		if (flag){
			ans[p]=ans[fa[p]]+1;
			f[p]=p;
		}else{
			ans[p]=ans[fa[p]];
			f[p]=f[fa[p]];
		}
		ANS=std::max(ANS,ans[p]);
	}
	printf("%d",ANS);
	return 0;
}


#include<bits/stdc++.h>
#define N 220000
int Len,n;
int len[N<<1],fa[N<<1],son[N<<1][26];
int size,last,root,pos[N<<1],rt[N*40],lc[N*40],rc[N*40];
int a[N<<1],c[N<<1],T,sum[N*40],ans[N<<1],ANS;
int f[N<<1];
char s[N];
void Init(){root=size=last=1;}
void Extend(int c,int wz){
    int end=++size,tmp=last;
    len[end]=len[tmp]+1;pos[end]=wz;
    while(tmp&&!son[tmp][c]){
        son[tmp][c]=end;
        tmp=fa[tmp];
    }
    if(!tmp) fa[end]=root;
    else{
        int ne=son[tmp][c];
        if(len[tmp]+1==len[ne]) fa[end]=ne;
        else{
            int np=++size;
            memcpy(son[np],son[ne],sizeof(son[ne]));
            len[np]=len[tmp]+1;
            fa[np]=fa[ne];
            fa[end]=fa[ne]=np;
            pos[np]=pos[ne];
            while(tmp&&son[tmp][c]==ne){
                son[tmp][c]=np;
                tmp=fa[tmp];
          	  }
       	}
     }
    last=end;
}
void Radixsort(){
    for(int i=1;i<=size;i++) c[len[i]]++;
    for(int i=1;i<=Len;i++) c[i]+=c[i-1];
    for(int i=size;i>=1;i--) a[c[len[i]]--]=i;
}
void insert(int &i, int l, int r, int x){
    if(r<l) return ;
    i = ++T;
    if(l == r) {
        sum[i]++ ;
        //num[i]=1LL*x;
        return ;
    }
    int mid = (l + r)/2 ;
    if(x<=mid) insert(lc[i], l, mid, x) ;
    if(x>mid) insert(rc[i], mid + 1, r, x) ;
    //clac(i);
    sum[i]=sum[lc[i]]+sum[rc[i]];
}
int merge(int x, int y) {
    if(!x) return y;
    if(!y) return x;
    //sum[x]+=sum[y];
    lc[x] = merge(lc[x], lc[y]) ;
    rc[x] = merge(rc[x], rc[y]) ;
    sum[x]=sum[lc[x]]+sum[rc[x]];
    return x;
}
bool query(int x,int l,int r,int ls,int rs){
	if (!x)return 0;
	if (ls<=l&&r<=rs)return sum[x]>0;
	int mid=(l+r)/2;
	if (ls<=mid){
		if (query(lc[x],l,mid,ls,rs))return 1;
	}
	if (mid<rs){
		if (query(rc[x],mid+1,r,ls,rs))return 1;
	}
	return 0;
	//return query(lc[x],l,mid,ls,rs)|query(rc[x],mid+1,r,ls,rs);
}
int main(){
	scanf("%d",&n);
	scanf("%s",s);
	Len=n;
	Init();
	for (int i=0;i<n;i++)Extend(s[i]-'a',i+1),insert(rt[last],1,n,i+1);
	Radixsort();
	//printf("%d\n",size);
	for (int i=size;i;i--){
		int p=a[i];
		rt[fa[p]]=merge(rt[fa[p]],rt[p]);
	}
	ANS=1;
	for (int i=2;i<=size;i++){
		int p=a[i];
		if (fa[p]==1){
			ans[p]=1;
			f[p]=p;
			continue;
		}
		//printf("%d %d %d\n",fa[p],p,i);
		bool flag=query(rt[f[fa[p]]],1,n,pos[p]-len[p]+len[f[fa[p]]],pos[p]-1);
		if (flag){
			ans[p]=ans[fa[p]]+1;
			f[p]=p;
		}else{
			ans[p]=ans[fa[p]];
			f[p]=f[fa[p]];
		}
		ANS=std::max(ANS,ans[p]);
	}
	printf("%d",ANS);
	return 0;
}


#include<bits/stdc++.h>
#define N 220000
int Len,n;
int len[N<<1],fa[N<<1],son[N<<1][26];
int size,last,root,pos[N<<1],rt[N*40],lc[N*40],rc[N*40];
int a[N<<1],c[N<<1],T,sum[N*40],ans[N<<1],ANS;
int f[N<<1];
char s[N];
void Init(){root=size=last=1;}
void Extend(int c,int wz){
    int end=++size,tmp=last;
    len[end]=len[tmp]+1;pos[end]=wz;
    while(tmp&&!son[tmp][c]){
        son[tmp][c]=end;
        tmp=fa[tmp];
    }
    if(!tmp) fa[end]=root;
    else{
        int ne=son[tmp][c];
        if(len[tmp]+1==len[ne]) fa[end]=ne;
        else{
            int np=++size;
            memcpy(son[np],son[ne],sizeof(son[ne]));
            len[np]=len[tmp]+1;
            fa[np]=fa[ne];
            fa[end]=fa[ne]=np;
            pos[np]=pos[ne];
            while(tmp&&son[tmp][c]==ne){
                son[tmp][c]=np;
                tmp=fa[tmp];
          	  }
       	}
     }
    last=end;
}
void Radixsort(){
    for(int i=1;i<=size;i++) c[len[i]]++;
    for(int i=1;i<=Len;i++) c[i]+=c[i-1];
    for(int i=size;i>=1;i--) a[c[len[i]]--]=i;
}
void insert(int &i, int l, int r, int x){
    if(r<l) return ;
    i = ++T;
    if(l == r) {
        sum[i]++ ;
        //num[i]=1LL*x;
        return ;
    }
    int mid = (l + r)/2 ;
    if(x<=mid) insert(lc[i], l, mid, x) ;
    if(x>mid) insert(rc[i], mid + 1, r, x) ;
    //clac(i);
    sum[i]=sum[lc[i]]+sum[rc[i]];
}
int merge(int x, int y) {
    if(!x) return y;
    if(!y) return x;
    //sum[x]+=sum[y];
    lc[x] = merge(lc[x], lc[y]) ;
    rc[x] = merge(rc[x], rc[y]) ;
    sum[x]=sum[lc[x]]+sum[rc[x]];
    return x;
}
bool query(int x,int l,int r,int ls,int rs){
	if (ls<=l&&r<=rs)return 1;
	int mid=(l+r)/2;
	if (ls<=mid){
		if (query(lc[x],l,mid,ls,rs))return 1;
	}
	if (mid<rs){
		if (query(rc[x],mid+1,r,ls,rs))return 1;
	}
	return 0;
	//return query(lc[x],l,mid,ls,rs)|query(rc[x],mid+1,r,ls,rs);
}
int main(){
	scanf("%d",&n);
	scanf("%s",s);
	Len=n;
	Init();
	for (int i=0;i<n;i++)Extend(s[i]-'a',i+1),insert(rt[last],1,n,i+1);
	Radixsort();
	//printf("%d\n",size);
	for (int i=size;i;i--){
		int p=a[i];
		rt[fa[p]]=merge(rt[fa[p]],rt[p]);
	}
	ANS=1;
	for (int i=2;i<=size;i++){
		int p=a[i];
		if (fa[p]==1){
			ans[p]=1;
			f[p]=p;
			continue;
		}
		//printf("%d %d %d\n",fa[p],p,i);
		bool flag=query(rt[f[fa[p]]],1,n,pos[p]-len[p]+len[f[fa[p]]],pos[p]-1);
		if (flag){
			ans[p]=ans[fa[p]]+1;
			f[p]=p;
		}else{
			ans[p]=ans[fa[p]];
			f[p]=f[fa[p]];
		}
		ANS=std::max(ANS,ans[p]);
	}
	printf("%d",ANS);
	return 0;
}


// tzl ak IOI!

#include<bits/stdc++.h>

#define HEAP priority_queue
#define rep(i, n) for(int i = 0, _end_ = (n); i < _end_; ++i)
#define per(i, n) for(int i = (n) - 1; i >= 0 ; --i)
#define forn(i, l, r) for(int i = (l), _end_ = (r); i <= _end_; ++i)
#define nrof(i, r, l) for(int i = (r), _end_ = (l); i >= _end_; --i)
#define FOR(a, b) for(auto (a): (b))
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define X first
#define Y second
#define eps 1e-6
#define pi 3.1415926535897932384626433832795
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(), x.end()
#define FILL(a, b) memset((a), (b), sizeof((a)))
#define MCPY(a, b) memcpy((a), (b), sizeof((b)))

using namespace std;

typedef long long LL;
typedef double flt;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef pair<int,int> pii;
typedef pair<int,LL> pil;
typedef pair<LL,int> pli;
typedef pair<LL,LL> pll;
typedef vector<pil> vil;
typedef vector<pii> vii;
typedef vector<pli> vli;
typedef vector<pll> vll;

const int iinf = 1e9 + 7;
const LL linf = 1ll << 60;
const flt dinf = 1e60;

template <typename T>
inline void scf(T &x)
{
	bool f = 0; x = 0; char c = getchar();
	while((c < '0' || c > '9') && c != '-') c = getchar();
	if(c == '-') { f = 1; c = getchar(); }
	while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
	if(f) x = -x; return;
}

template <typename T1, typename T2>
void scf(T1 &x, T2 &y) { scf(x); return scf(y); }

template <typename T1, typename T2, typename T3>
void scf(T1 &x, T2 &y, T3 &z) { scf(x); scf(y); return scf(z); }

template <typename T1, typename T2, typename T3, typename T4>
void scf(T1 &x, T2 &y, T3 &z, T4 &w) { scf(x); scf(y); scf(z); return scf(w); }

inline char mygetchar(){ char c = getchar(); while(c == ' ' || c == '\n') c = getchar(); return c; }

template <typename T>
void chkmax(T &x, const T &y){ if(y > x) x = y; return; }

template <typename T>
void chkmin(T &x, const T &y){ if(y < x) x = y; return; }

#ifdef ONLINE_JUDGE
#define debug(x,c) ;
#else
#define DEBUG
#define debug(x,c) cerr<<#x<<"="<<x<<c;
#endif

void TZL();

void RANK1();

#define tzl int
#define ak main
#define IOI ()
tzl ak IOI
{
#undef tzl
#undef ak
#undef IOI

	TZL();
	RANK1();

#define tzl return
#define caisi 0
#define myy ;
	tzl caisi myy
#undef tzl
#undef caisi
#undef myy
}

//---------------------------head----------------------------

const int N = 2e5 + 100;
const int lgN = 19;

int n;
char s[N];

namespace lcp
{
	int num[N][lgN];
	int LOG[N];

	void init(int n, int *a)
	{
		forn(i, 1, N - 1)
		{
			while((1 << LOG[i]) < i) ++LOG[i];
			--LOG[i];
		}

		forn(i, 0, n) num[i][0] = a[i];
		rep(lg, lgN - 1) forn(i, 0, n - (1 << lg + 1) + 1) num[i][lg + 1] = min(num[i][lg], num[i + (1 << lg)][lg]);
		return;
	}

	int Q(int l, int r)
	{
		if(l == r) return num[l][0];
		return min(num[l][LOG[r - l + 1]], num[r - (1 << LOG[r - l + 1]) + 1][LOG[r - l + 1]]);
	}
}

namespace pos
{
	const int hN = 1 << 18;

	int num[hN << 1];

	void build(int n, int *a)
	{
		rep(i, hN << 1) num[i] = iinf;
		forn(i, 1, n) num[i | hN] = a[i];
		per(i, hN) num[i] = min(num[i << 1], num[(i << 1) | 1]);
		return;
	}

	int Q(int s, int t)
	{
		int ret = iinf;
		for(s |= hN, t |= hN, --s, ++t; s ^ t ^ 1; s >>= 1, t >>= 1)
		{
			if(~s & 1) chkmin(ret, num[s ^ 1]);
			if(t & 1) chkmin(ret, num[t ^ 1]);
		}
		return ret;
	}

	void M(int i, int x)
	{
		num[(i |= hN)] = x;
		for(i >>= 1; i; i >>= 1) num[i] = min(num[i << 1], num[(i << 1) | 1]);
		return;
	}
}

namespace SA
{
	int n;
	int rnk[N], sa[N], h[N];

	void build(int _n, char *s)
	{
		n = _n;
		vector<char> foo; foo.clear();
		rep(i, n) foo.pb(s[i]);
		sort(ALL(foo)); foo.resize(unique(ALL(foo)) - foo.begin());

		int mx = SZ(foo);
		rep(i, n) rnk[i] = lower_bound(ALL(foo), s[i]) - foo.begin() + 1;

		static pair<pii, int> p[N], q[N];
		static int freq[N];

		for(int msk = 1; mx < n; msk <<= 1)
		{
			forn(i, 0, mx) freq[i] = 0;
			rep(i, n) p[i] = mp(mp(rnk[i], i + msk < n ? rnk[i + msk] : 0), i), ++freq[p[i].X.Y + 1];
#ifdef DEBU
			puts("-------------------------------------------------");
			printf("%d\n", msk);
			rep(i, n) printf("((%d, %d), %d) ", p[i].X.X, p[i].X.Y, p[i].Y); putchar('\n');
#endif
			forn(i, 1, mx) freq[i] += freq[i - 1];
			rep(i, n) q[freq[p[i].X.Y]++] = p[i];
			forn(i, 0, mx) freq[i] = 0;
			rep(i, n) ++freq[q[i].X.X + 1];
			forn(i, 1, mx) freq[i] += freq[i - 1];
			rep(i, n) p[freq[q[i].X.X]++] = q[i];
#ifdef DEBU
			rep(i, n) printf("((%d, %d), %d) ", p[i].X.X, p[i].X.Y, p[i].Y); putchar('\n');
#endif

			mx = 0;
			rep(i, n)
			{
				if(!i || p[i].X != p[i - 1].X) ++mx;
				rnk[p[i].Y] = mx;
			}
		}

		forn(i, 0, n) sa[rnk[i]] = i;

		int height = 0;
		rep(i, n)
		{
			int j = sa[rnk[i] - 1];
			if(height) --height;
			while(i + height < n && j + height < n && s[i + height] == s[j + height]) ++height;
			h[rnk[i]] = height;
		}
		lcp::init(n, h);
		pos::build(n, sa);
		return;
	}

	int nxt_apr(int l, int r)
	{
		int i, j;
		int lb, rb;

		//left_bound
		lb = 1, rb = rnk[l] - 1;
		while(lb <= rb)
		{
			int mid = lb + rb >> 1;
			if(lcp::Q(mid + 1, rnk[l]) >= r - l + 1) rb = mid - 1;
			else lb = mid + 1;
		}
		i = lb;

		//right_bound
		lb = rnk[l] + 1, rb = n;
		while(lb <= rb)
		{
			int mid = lb + rb >> 1;
			if(lcp::Q(rnk[l] + 1, mid) >= r - l + 1) lb = mid + 1;
			else rb = mid - 1;
		}
		j = rb;

		return pos::Q(i, j);
	}

	void del(int i)
	{
		return pos::M(rnk[i], iinf);
	}
}

void TZL()
{
	scf(n);
	scanf("%s", s);
	SA::build(n, s);
	return;
}

void RANK1()
{
	int ans = 0;
	rep(i, n)
	{
		int l = i, r = i, cur = 1;
		SA::del(i);
		for(int base = 1; base <= n - i; base <<= 1)
		{
			int nxt = SA::nxt_apr(l, r);
			if(nxt > n) break;
			int nr = r - l + nxt;
			int nbase = min(n - i, (base << 1) - 1);

#ifdef DEBUG
			printf("%d %d\t%d\n", l, r, nxt);
#endif

			if(nr - l + 1 <= nbase)
			{
				r = nr; ++cur;
#ifdef DEBUG
				printf("\t%d, %d\n", l, r);
#endif
				nxt = SA::nxt_apr(l, r);
				if(nxt + r - l - l + 1 <= nbase)
				{
					int d = nxt - l, k = (nbase - (r - l + 1)) / d;
#ifdef DEBUG
					printf("\t\t%d %d\n", d, k);
#endif
					cur += k;
					r += k * d;
				}
			}
		}
		chkmax(ans, cur);
	}
	printf("%d\n", ans);
	return;
}


// tzl ak IOI!

#include<bits/stdc++.h>

#define HEAP priority_queue
#define rep(i, n) for(int i = 0, _end_ = (n); i < _end_; ++i)
#define per(i, n) for(int i = (n) - 1; i >= 0 ; --i)
#define forn(i, l, r) for(int i = (l), _end_ = (r); i <= _end_; ++i)
#define nrof(i, r, l) for(int i = (r), _end_ = (l); i >= _end_; --i)
#define FOR(a, b) for(auto (a): (b))
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define X first
#define Y second
#define eps 1e-6
#define pi 3.1415926535897932384626433832795
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(), x.end()
#define FILL(a, b) memset((a), (b), sizeof((a)))
#define MCPY(a, b) memcpy((a), (b), sizeof((b)))

using namespace std;

typedef long long LL;
typedef double flt;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef pair<int,int> pii;
typedef pair<int,LL> pil;
typedef pair<LL,int> pli;
typedef pair<LL,LL> pll;
typedef vector<pil> vil;
typedef vector<pii> vii;
typedef vector<pli> vli;
typedef vector<pll> vll;

const int iinf = 1e9 + 7;
const LL linf = 1ll << 60;
const flt dinf = 1e60;

template <typename T>
inline void scf(T &x)
{
	bool f = 0; x = 0; char c = getchar();
	while((c < '0' || c > '9') && c != '-') c = getchar();
	if(c == '-') { f = 1; c = getchar(); }
	while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
	if(f) x = -x; return;
}

template <typename T1, typename T2>
void scf(T1 &x, T2 &y) { scf(x); return scf(y); }

template <typename T1, typename T2, typename T3>
void scf(T1 &x, T2 &y, T3 &z) { scf(x); scf(y); return scf(z); }

template <typename T1, typename T2, typename T3, typename T4>
void scf(T1 &x, T2 &y, T3 &z, T4 &w) { scf(x); scf(y); scf(z); return scf(w); }

inline char mygetchar(){ char c = getchar(); while(c == ' ' || c == '\n') c = getchar(); return c; }

template <typename T>
void chkmax(T &x, const T &y){ if(y > x) x = y; return; }

template <typename T>
void chkmin(T &x, const T &y){ if(y < x) x = y; return; }

#ifdef ONLINE_JUDGE
#define debug(x,c) ;
#else
#define DEBUG
#define debug(x,c) cerr<<#x<<"="<<x<<c;
#endif

void TZL();

void RANK1();

#define tzl int
#define ak main
#define IOI ()
tzl ak IOI
{
#undef tzl
#undef ak
#undef IOI

	TZL();
	RANK1();

#define tzl return
#define caisi 0
#define myy ;
	tzl caisi myy
#undef tzl
#undef caisi
#undef myy
}

//---------------------------head----------------------------

const int N = 2e5 + 100;
const int lgN = 19;

int n;
char s[N];

namespace lcp
{
	int num[N][lgN];
	int LOG[N];

	void init(int n, int *a)
	{
		forn(i, 1, N - 1)
		{
			while((1 << LOG[i]) < i) ++LOG[i];
			--LOG[i];
		}

		forn(i, 0, n) num[i][0] = a[i];
		rep(lg, lgN - 1) forn(i, 0, n - (1 << lg + 1) + 1) num[i][lg + 1] = min(num[i][lg], num[i + (1 << lg)][lg]);
		return;
	}

	int Q(int l, int r)
	{
		if(l == r) return num[l][0];
		return min(num[l][LOG[r - l + 1]], num[r - (1 << LOG[r - l + 1]) + 1][LOG[r - l + 1]]);
	}
}

namespace pos
{
	const int hN = 1 << 18;

	int num[hN << 1];

	void build(int n, int *a)
	{
		rep(i, hN << 1) num[i] = iinf;
		forn(i, 1, n) num[i | hN] = a[i];
		per(i, hN) num[i] = min(num[i << 1], num[(i << 1) | 1]);
		return;
	}

	int Q(int s, int t)
	{
		int ret = iinf;
		for(s |= hN, t |= hN, --s, ++t; s ^ t ^ 1; s >>= 1, t >>= 1)
		{
			if(~s & 1) chkmin(ret, num[s ^ 1]);
			if(t & 1) chkmin(ret, num[t ^ 1]);
		}
		return ret;
	}

	void M(int i, int x)
	{
		num[(i |= hN)] = x;
		for(i >>= 1; i; i >>= 1) num[i] = min(num[i << 1], num[(i << 1) | 1]);
		return;
	}
}

namespace SA
{
	int n;
	int rnk[N], sa[N], h[N];

	void build(int _n, char *s)
	{
		n = _n;
		vector<char> foo; foo.clear();
		rep(i, n) foo.pb(s[i]);
		sort(ALL(foo)); foo.resize(unique(ALL(foo)) - foo.begin());

		int mx = SZ(foo);
		rep(i, n) rnk[i] = lower_bound(ALL(foo), s[i]) - foo.begin() + 1;

		static pair<pii, int> p[N], q[N];
		static int freq[N];

		for(int msk = 1; mx < n; msk <<= 1)
		{
			forn(i, 0, mx) freq[i] = 0;
			rep(i, n) p[i] = mp(mp(rnk[i], i + msk < n ? rnk[i + msk] : 0), i), ++freq[p[i].X.Y + 1];
			forn(i, 1, mx) freq[i] += freq[i - 1];
			rep(i, n) q[freq[p[i].X.Y]++] = p[i];
			forn(i, 0, mx) freq[i] = 0;
			rep(i, n) ++freq[q[i].X.X + 1];
			forn(i, 1, mx) freq[i] += freq[i - 1];
			rep(i, n) p[freq[q[i].X.X]++] = q[i];

			mx = 0;
			rep(i, n)
			{
				if(!i || p[i].X != p[i - 1].X) ++mx;
				rnk[p[i].Y] = mx;
			}
		}

		forn(i, 0, n) sa[rnk[i]] = i;

		int height = 0;
		rep(i, n)
		{
			int j = sa[rnk[i] - 1];
			if(height) --height;
			while(i + height < n && j + height < n && s[i + height] == s[j + height]) ++height;
			h[rnk[i]] = height;
		}
		lcp::init(n, h);
		pos::build(n, sa);
		return;
	}

	int nxt_apr(int l, int r)
	{
		int i, j;
		int lb, rb;

		//left_bound
		lb = 1, rb = rnk[l] - 1;
		while(lb <= rb)
		{
			int mid = lb + rb >> 1;
			if(lcp::Q(mid + 1, rnk[l]) >= r - l + 1) rb = mid - 1;
			else lb = mid + 1;
		}
		i = lb;

		//right_bound
		lb = rnk[l] + 1, rb = n;
		while(lb <= rb)
		{
			int mid = lb + rb >> 1;
			if(lcp::Q(rnk[l] + 1, mid) >= r - l + 1) lb = mid + 1;
			else rb = mid - 1;
		}
		j = rb;

		return pos::Q(i, j);
	}

	void del(int i)
	{
		return pos::M(rnk[i], iinf);
	}

	int lcp(int i, int j)
	{
		i = rnk[i], j = rnk[j];
		if(i > j) swap(i, j);
		return lcp::Q(i + 1, j);
	}
}

void TZL()
{
	scf(n);
	scanf("%s", s);
	SA::build(n, s);
	return;
}

bool is_border(int l1, int r1, int l2, int r2)
{
	return SA::lcp(l1, r2 - (r1 - l1 + 1) + 1) >= (r1 - l1 + 1);
}

void RANK1()
{
	int ans = 0;
	rep(i, n)
	{
		int l = i, r = i, cur = 1;
		SA::del(i);
		for(int base = 1; base <= n - i; base <<= 1)
		{
			int nxt = SA::nxt_apr(l, r);
			if(nxt > n) break;
			int nr = r - l + nxt;
			int nbase = min(n - i, (base << 1) - 1);

			if(nr - l + 1 <= nbase)
			{
				r = nr; ++cur;
				nxt = SA::nxt_apr(l, r);
				if(nxt + r - l - l + 1 <= nbase)
				{
					int d = nxt - l, lb = 1, rb = (nbase - (r - l + 1)) / d;
					while(lb <= rb)
					{
						int mid = lb + rb >> 1;
						nr = r + d * mid;
						if(is_border(l, nr - d, l, nr)) lb = mid + 1;
						else rb = mid - 1;
					}
					cur += rb;
					r += rb * d;
				}
			}
		}
		chkmax(ans, cur);
	}
	printf("%d\n", ans);
	return;
}


// tzl ak IOI!

#include<bits/stdc++.h>

#define HEAP priority_queue
#define rep(i, n) for(int i = 0, _end_ = (n); i < _end_; ++i)
#define per(i, n) for(int i = (n) - 1; i >= 0 ; --i)
#define forn(i, l, r) for(int i = (l), _end_ = (r); i <= _end_; ++i)
#define nrof(i, r, l) for(int i = (r), _end_ = (l); i >= _end_; --i)
#define FOR(a, b) for(auto (a): (b))
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define X first
#define Y second
#define eps 1e-6
#define pi 3.1415926535897932384626433832795
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(), x.end()
#define FILL(a, b) memset((a), (b), sizeof((a)))
#define MCPY(a, b) memcpy((a), (b), sizeof((b)))

using namespace std;

typedef long long LL;
typedef double flt;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef pair<int,int> pii;
typedef pair<int,LL> pil;
typedef pair<LL,int> pli;
typedef pair<LL,LL> pll;
typedef vector<pil> vil;
typedef vector<pii> vii;
typedef vector<pli> vli;
typedef vector<pll> vll;

const int iinf = 1e9 + 7;
const LL linf = 1ll << 60;
const flt dinf = 1e60;

template <typename T>
inline void scf(T &x)
{
	bool f = 0; x = 0; char c = getchar();
	while((c < '0' || c > '9') && c != '-') c = getchar();
	if(c == '-') { f = 1; c = getchar(); }
	while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
	if(f) x = -x; return;
}

template <typename T1, typename T2>
void scf(T1 &x, T2 &y) { scf(x); return scf(y); }

template <typename T1, typename T2, typename T3>
void scf(T1 &x, T2 &y, T3 &z) { scf(x); scf(y); return scf(z); }

template <typename T1, typename T2, typename T3, typename T4>
void scf(T1 &x, T2 &y, T3 &z, T4 &w) { scf(x); scf(y); scf(z); return scf(w); }

inline char mygetchar(){ char c = getchar(); while(c == ' ' || c == '\n') c = getchar(); return c; }

template <typename T>
void chkmax(T &x, const T &y){ if(y > x) x = y; return; }

template <typename T>
void chkmin(T &x, const T &y){ if(y < x) x = y; return; }

#ifdef ONLINE_JUDGE
#define debug(x,c) ;
#else
#define DEBUG
#define debug(x,c) cerr<<#x<<"="<<x<<c;
#endif

void TZL();

void RANK1();

#define tzl int
#define ak main
#define IOI ()
tzl ak IOI
{
#undef tzl
#undef ak
#undef IOI

	TZL();
	RANK1();

#define tzl return
#define caisi 0
#define myy ;
	tzl caisi myy
#undef tzl
#undef caisi
#undef myy
}

//---------------------------head----------------------------

const int N = 2e5 + 100;
const int lgN = 19;

int n;
char s[N];

namespace lcp
{
	int num[N][lgN];
	int LOG[N];

	void init(int n, int *a)
	{
		forn(i, 1, N - 1)
		{
			while((1 << LOG[i]) < i) ++LOG[i];
			--LOG[i];
		}

		forn(i, 0, n) num[i][0] = a[i];
		rep(lg, lgN - 1) forn(i, 0, n - (1 << lg + 1) + 1) num[i][lg + 1] = min(num[i][lg], num[i + (1 << lg)][lg]);
		return;
	}

	int Q(int l, int r)
	{
		if(l == r) return num[l][0];
		return min(num[l][LOG[r - l + 1]], num[r - (1 << LOG[r - l + 1]) + 1][LOG[r - l + 1]]);
	}
}

namespace pos
{
	const int hN = 1 << 18;

	int num[hN << 1];

	void build(int n, int *a)
	{
		rep(i, hN << 1) num[i] = iinf;
		forn(i, 1, n) num[i | hN] = a[i];
		per(i, hN) num[i] = min(num[i << 1], num[(i << 1) | 1]);
		return;
	}

	int Q(int s, int t)
	{
		int ret = iinf;
		for(s |= hN, t |= hN, --s, ++t; s ^ t ^ 1; s >>= 1, t >>= 1)
		{
			if(~s & 1) chkmin(ret, num[s ^ 1]);
			if(t & 1) chkmin(ret, num[t ^ 1]);
		}
		return ret;
	}

	void M(int i, int x)
	{
		num[(i |= hN)] = x;
		for(i >>= 1; i; i >>= 1) num[i] = min(num[i << 1], num[(i << 1) | 1]);
		return;
	}
}

namespace SA
{
	int n;
	int rnk[N], sa[N], h[N];

	void build(int _n, char *s)
	{
		n = _n;
		vector<char> foo; foo.clear();
		rep(i, n) foo.pb(s[i]);
		sort(ALL(foo)); foo.resize(unique(ALL(foo)) - foo.begin());

		int mx = SZ(foo);
		rep(i, n) rnk[i] = lower_bound(ALL(foo), s[i]) - foo.begin() + 1;

		static pair<pii, int> p[N], q[N];
		static int freq[N];

		for(int msk = 1; mx < n; msk <<= 1)
		{
			forn(i, 0, mx) freq[i] = 0;
			rep(i, n) p[i] = mp(mp(rnk[i], i + msk < n ? rnk[i + msk] : 0), i), ++freq[p[i].X.Y + 1];
#ifdef DEBU
			puts("-------------------------------------------------");
			printf("%d\n", msk);
			rep(i, n) printf("((%d, %d), %d) ", p[i].X.X, p[i].X.Y, p[i].Y); putchar('\n');
#endif
			forn(i, 1, mx) freq[i] += freq[i - 1];
			rep(i, n) q[freq[p[i].X.Y]++] = p[i];
			forn(i, 0, mx) freq[i] = 0;
			rep(i, n) ++freq[q[i].X.X + 1];
			forn(i, 1, mx) freq[i] += freq[i - 1];
			rep(i, n) p[freq[q[i].X.X]++] = q[i];
#ifdef DEBU
			rep(i, n) printf("((%d, %d), %d) ", p[i].X.X, p[i].X.Y, p[i].Y); putchar('\n');
#endif

			mx = 0;
			rep(i, n)
			{
				if(!i || p[i].X != p[i - 1].X) ++mx;
				rnk[p[i].Y] = mx;
			}
		}

		forn(i, 0, n) sa[rnk[i]] = i;

		int height = 0;
		rep(i, n)
		{
			int j = sa[rnk[i] - 1];
			if(height) --height;
			while(i + height < n && j + height < n && s[i + height] == s[j + height]) ++height;
			h[rnk[i]] = height;
		}
		lcp::init(n, h);
		pos::build(n, sa);
		return;
	}

	int nxt_apr(int l, int r)
	{
		int i, j;
		int lb, rb;

		//left_bound
		lb = 1, rb = rnk[l] - 1;
		while(lb <= rb)
		{
			int mid = lb + rb >> 1;
			if(lcp::Q(mid + 1, rnk[l]) >= r - l + 1) rb = mid - 1;
			else lb = mid + 1;
		}
		i = lb;

		//right_bound
		lb = rnk[l] + 1, rb = n;
		while(lb <= rb)
		{
			int mid = lb + rb >> 1;
			if(lcp::Q(rnk[l] + 1, mid) >= r - l + 1) lb = mid + 1;
			else rb = mid - 1;
		}
		j = rb;

		return pos::Q(i, j);
	}

	void del(int i)
	{
		return pos::M(rnk[i], iinf);
	}

	int lcp(int i, int j)
	{
		i = rnk[i], j = rnk[j];
		if(i > j) swap(i, j);
		return lcp::Q(i + 1, j);
	}
}

void TZL()
{
	scf(n);
	scanf("%s", s);
	SA::build(n, s);
	return;
}

bool is_border(int l1, int r1, int l2, int r2)
{
#ifdef DEBUG
	printf("is_border(%d, %d\t%d, %d)\t%d\n", l1, r1, l2, r2, SA::lcp(l1, r2 - (r1 - l1 + 1) + 1) >= (r1 - l1 + 1));
#endif
	return SA::lcp(l1, r2 - (r1 - l1 + 1) + 1) >= (r1 - l1 + 1);
}

void RANK1()
{
	int ans = 0;
	rep(i, n)
	{
		int l = i, r = i, cur = 1;
		SA::del(i);
#ifdef DEBUG
		puts("\n\n---------------------------------------------");
#endif
		for(int base = 1; base <= n - i; base <<= 1)
		{
			int nxt = SA::nxt_apr(l, r);
			if(nxt > n) break;
			int nr = r - l + nxt;
			int nbase = min(n - i, (base << 1) - 1);

#ifdef DEBUG
			printf("%d %d\t%d\n", l, r, nxt);
#endif

			if(nr - l + 1 <= nbase)
			{
				r = nr; ++cur;
#ifdef DEBUG
				printf("\t%d, %d\n", l, r);
#endif
				nxt = SA::nxt_apr(l, r);
				if(nxt + r - l - l + 1 <= nbase)
				{
					int d = nxt - l, lb = 1, rb = (nbase - (r - l + 1)) / d;
					while(lb <= rb)
					{
						int mid = lb + rb >> 1;
						nr = r + d * mid;
						if(is_border(l, nr - d, l, nr)) lb = mid + 1;
						else rb = mid - 1;
					}
					cur += rb;
					r += rb * d;
				}
			}
		}
#ifdef DEBUG
		if(cur > 5)
		{
			printf("[%d]\n", i);
		}
#endif
		chkmax(ans, cur);
	}
	printf("%d\n", ans);
	return;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 2e5, maxlgn = 18;

namespace tree {
  const int maxnd = maxn * maxlgn * 2;

  struct Node {
    Node *lc, *rc;
    Node(void) : lc(NULL), rc(NULL) {}
  } node[maxnd];

  int cntnd, n;

  Node* New(void) {
    node[cntnd] = Node();
    return node + cntnd++;
  }

  void Init(int n_) {
    n = n_;
    cntnd = 0;
  }

  Node* Build(int x) {
    Node *root = New(), *u = root;
    int l = 0, r = n;
    while (r - l > 1) {
      int mid = l + r >> 1;
      if (x < mid) {
        r = mid;
        u = u->lc = New();
      } else {
        l = mid;
        u = u->rc = New();
      }
    }
    return root;
  }

  Node* Unite(Node *u, Node *v) {
    if (!u) return v;
    if (!v) return u;
    Node *w = New();
    w->lc = Unite(u->lc, v->lc);
    w->rc = Unite(u->rc, v->rc);
    return w;
  }

  bool Find(Node *u, int l, int r, int L = 0, int R = n) {
    if (l <= L && r >= R) return u;
    int mid = L + R >> 1;
    return (l < mid && Find(u->lc, l, r, L, mid) ||
            r > mid && Find(u->rc, l, r, mid, R));
  }

  int FindAny(Node *u) {
    int l = 0, r = n;
    while (r - l > 1) {
      int mid = l + r >> 1;
      if (u->rc) {
        l = mid;
        u = u->rc;
      } else {
        r = mid;
        u = u->lc;
      }
    }
    return l;
  }
}

namespace sam {
  const int sigma = 26;
  const int maxnd = maxn * 2;

  struct Node {
    Node *tr[sigma], *par, *key;
    int len, dp;
    tree::Node *pos;
    vector<Node*> g;
    Node(int len = 0) : tr(), par(NULL), len(len), pos(NULL), g() {}
  } node[maxnd], *start, *last;

  int cntnd;

  Node* New(const Node &u) {
    node[cntnd] = u;
    return node + cntnd++;
  }

  void Init(void) {
    cntnd = 0;
    start = last = New(0);
  }

  Node* Extend(int x, int pos) {
    Node *u = New(last->len + 1), *v = last;
    u->pos = tree::Build(pos);
    for (; v && !v->tr[x]; v = v->par) v->tr[x] = u;
    if (!v) {
      u->par = start;
    } else if (v->tr[x]->len == v->len + 1) {
      u->par = v->tr[x];
    } else {
      Node *s = New(*(v->tr[x])), *o = v->tr[x];
      s->len = v->len + 1;
      o->par = u->par = s;
      for (; v && v->tr[x] == o; v = v->par) v->tr[x] = s;
    }
    return last = u;
  }

  int ans;

  void Dfs1(Node *u) {
    for (int i = 0; i < u->g.size(); ++i) {
      Node *v = u->g[i];
      Dfs1(v);
      u->pos = tree::Unite(u->pos, v->pos);
    }
  }

  bool Twice(Node *u, Node *v) {
    if (u->len == 0) return true;
    int r = tree::FindAny(v->pos);
    return tree::Find(u->pos, r - v->len + u->len, r);
  }

  void Dfs2(Node *u) {
    if (u->par) {
      if (Twice(u->par->key, u)) {
        u->dp = u->par->dp + 1;
        u->key = u;
      } else {
        u->dp = u->par->dp;
        u->key = u->par->key;
      }
    } else {
      u->dp = 0;
      u->key = u;
    }
    ans = max(ans, u->dp);
    for (int i = 0; i < u->g.size(); ++i) {
      Node *v = u->g[i];
      Dfs2(v);
    }
  }

  void Main(void) {
    for (int i = 0; i < cntnd; ++i) {
      Node *u = node + i;
      if (u->par) {
        u->par->g.push_back(u);
      }
    }
    Dfs1(start);
    Dfs2(start);
  }
}

char str[maxn + 1];

int main(void) {
  int len;
  scanf("%d", &len);
  scanf("%s", str);
  tree::Init(len);
  sam::Init();
  for (int i = 0; i < len; ++i) {
    sam::Extend(str[i] - 'a', i);
  }
  sam::Main();
  printf("%d\n", sam::ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 2e5, maxlgn = 18;

namespace tree {
  const int maxnd = maxn * maxlgn * 2;

  struct Node {
    Node *lc, *rc;
    Node(void) : lc(NULL), rc(NULL) {}
  } node[maxnd];

  int cntnd, n;

  Node* New(void) {
    node[cntnd] = Node();
    return node + cntnd++;
  }

  void Init(int n_) {
    n = n_;
    cntnd = 0;
  }

  Node* Build(int x) {
    Node *root = New(), *u = root;
    int l = 0, r = n;
    while (r - l > 1) {
      int mid = l + r >> 1;
      if (x < mid) {
        r = mid;
        u = u->lc = New();
      } else {
        l = mid;
        u = u->rc = New();
      }
    }
    return root;
  }

  Node* Unite(Node *u, Node *v) {
    if (!u) return v;
    if (!v) return u;
    Node *w = New();
    w->lc = Unite(u->lc, v->lc);
    w->rc = Unite(u->rc, v->rc);
    return w;
  }

  bool Find(Node *u, int l, int r, int L = 0, int R = n) {
    if (!u) return false;
    if (l <= L && r >= R) return true;
    int mid = L + R >> 1;
    return (l < mid && Find(u->lc, l, r, L, mid) ||
            r > mid && Find(u->rc, l, r, mid, R));
  }

  int FindAny(Node *u) {
    int l = 0, r = n;
    while (r - l > 1) {
      int mid = l + r >> 1;
      if (u->rc) {
        l = mid;
        u = u->rc;
      } else {
        r = mid;
        u = u->lc;
      }
    }
    return l;
  }
}

namespace sam {
  const int sigma = 26;
  const int maxnd = maxn * 2;

  struct Node {
    Node *tr[sigma], *par, *key;
    int len, dp;
    tree::Node *pos;
    vector<Node*> g;
    Node(int len = 0) : tr(), par(NULL), len(len), pos(NULL), g() {}
  } node[maxnd], *start, *last;

  int cntnd;

  Node* New(const Node &u) {
    node[cntnd] = u;
    return node + cntnd++;
  }

  void Init(void) {
    cntnd = 0;
    start = last = New(0);
  }

  Node* Extend(int x, int pos) {
    Node *u = New(last->len + 1), *v = last;
    u->pos = tree::Build(pos);
    for (; v && !v->tr[x]; v = v->par) v->tr[x] = u;
    if (!v) {
      u->par = start;
    } else if (v->tr[x]->len == v->len + 1) {
      u->par = v->tr[x];
    } else {
      Node *s = New(*(v->tr[x])), *o = v->tr[x];
      s->len = v->len + 1;
      o->par = u->par = s;
      for (; v && v->tr[x] == o; v = v->par) v->tr[x] = s;
    }
    return last = u;
  }

  int ans;

  void Dfs1(Node *u) {
    for (int i = 0; i < u->g.size(); ++i) {
      Node *v = u->g[i];
      Dfs1(v);
      u->pos = tree::Unite(u->pos, v->pos);
    }
  }

  bool Twice(Node *u, Node *v) {
    if (u->len == 0) return true;
    int r = tree::FindAny(v->pos);
    return tree::Find(u->pos, r - v->len + u->len, r);
  }

  void Dfs2(Node *u) {
    if (u->par) {
      if (Twice(u->par->key, u)) {
        u->dp = u->par->dp + 1;
        u->key = u;
      } else {
        u->dp = u->par->dp;
        u->key = u->par->key;
      }
    } else {
      u->dp = 0;
      u->key = u;
    }
    ans = max(ans, u->dp);
    for (int i = 0; i < u->g.size(); ++i) {
      Node *v = u->g[i];
      Dfs2(v);
    }
  }

  void Main(void) {
    for (int i = 0; i < cntnd; ++i) {
      Node *u = node + i;
      if (u->par) {
        u->par->g.push_back(u);
      }
    }
    Dfs1(start);
    Dfs2(start);
  }
}

char str[maxn + 1];

int main(void) {
  int len;
  scanf("%d", &len);
  scanf("%s", str);
  tree::Init(len);
  sam::Init();
  for (int i = 0; i < len; ++i) {
    sam::Extend(str[i] - 'a', i);
  }
  sam::Main();
  printf("%d\n", sam::ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 2e5, maxlgn = 18;

namespace tree {
  const int maxnd = maxn * maxlgn * 4;

  struct Node {
    Node *lc, *rc;
    Node(void) : lc(NULL), rc(NULL) {}
  } node[maxnd];

  int cntnd, n;

  Node* New(void) {
    node[cntnd] = Node();
    return node + cntnd++;
  }

  void Init(int n_) {
    n = n_;
    cntnd = 0;
  }

  Node* Build(int x) {
    Node *root = New(), *u = root;
    int l = 0, r = n;
    while (r - l > 1) {
      int mid = l + r >> 1;
      if (x < mid) {
        r = mid;
        u = u->lc = New();
      } else {
        l = mid;
        u = u->rc = New();
      }
    }
    return root;
  }

  Node* Unite(Node *u, Node *v) {
    if (!u) return v;
    if (!v) return u;
    Node *w = New();
    w->lc = Unite(u->lc, v->lc);
    w->rc = Unite(u->rc, v->rc);
    return w;
  }

  bool Find(Node *u, int l, int r, int L = 0, int R = n) {
    if (!u) return false;
    if (l <= L && r >= R) return true;
    int mid = L + R >> 1;
    return (l < mid && Find(u->lc, l, r, L, mid) ||
            r > mid && Find(u->rc, l, r, mid, R));
  }

  int FindAny(Node *u) {
    int l = 0, r = n;
    while (r - l > 1) {
      int mid = l + r >> 1;
      if (u->rc) {
        l = mid;
        u = u->rc;
      } else {
        r = mid;
        u = u->lc;
      }
    }
    return l;
  }
}

namespace sam {
  const int sigma = 26;
  const int maxnd = maxn * 2;

  struct Node {
    Node *tr[sigma], *par, *key;
    int len, dp;
    tree::Node *pos;
    vector<Node*> g;
    Node(int len = 0) : tr(), par(NULL), len(len), pos(NULL), g() {}
  } node[maxnd], *start, *last;

  int cntnd;

  Node* New(const Node &u) {
    node[cntnd] = u;
    return node + cntnd++;
  }

  void Init(void) {
    cntnd = 0;
    start = last = New(0);
  }

  Node* Extend(int x, int pos) {
    Node *u = New(last->len + 1), *v = last;
    u->pos = tree::Build(pos);
    for (; v && !v->tr[x]; v = v->par) v->tr[x] = u;
    if (!v) {
      u->par = start;
    } else if (v->tr[x]->len == v->len + 1) {
      u->par = v->tr[x];
    } else {
      Node *s = New(*(v->tr[x])), *o = v->tr[x];
      s->len = v->len + 1;
      o->par = u->par = s;
      for (; v && v->tr[x] == o; v = v->par) v->tr[x] = s;
    }
    return last = u;
  }

  int ans;

  void Dfs1(Node *u) {
    for (int i = 0; i < u->g.size(); ++i) {
      Node *v = u->g[i];
      Dfs1(v);
      u->pos = tree::Unite(u->pos, v->pos);
    }
  }

  bool Twice(Node *u, Node *v) {
    if (u->len == 0) return true;
    int r = tree::FindAny(v->pos);
    return tree::Find(u->pos, r - v->len + u->len, r);
  }

  void Dfs2(Node *u) {
    if (u->par) {
      if (Twice(u->par->key, u)) {
        u->dp = u->par->dp + 1;
        u->key = u;
      } else {
        u->dp = u->par->dp;
        u->key = u->par->key;
      }
    } else {
      u->dp = 0;
      u->key = u;
    }
    ans = max(ans, u->dp);
    for (int i = 0; i < u->g.size(); ++i) {
      Node *v = u->g[i];
      Dfs2(v);
    }
  }

  void Main(void) {
    for (int i = 0; i < cntnd; ++i) {
      Node *u = node + i;
      if (u->par) {
        u->par->g.push_back(u);
      }
    }
    Dfs1(start);
    Dfs2(start);
  }
}

char str[maxn + 1];

int main(void) {
  int len;
  scanf("%d", &len);
  scanf("%s", str);
  tree::Init(len);
  sam::Init();
  for (int i = 0; i < len; ++i) {
    sam::Extend(str[i] - 'a', i);
  }
  sam::Main();
  printf("%d\n", sam::ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 2e5, maxlgn = 18;

namespace tree {
  const int maxnd = maxn * maxlgn * 2;

  struct Node {
    Node *lc, *rc;
    Node(void) : lc(NULL), rc(NULL) {}
  } node[maxnd];

  int cntnd, n;

  Node* New(void) {
    node[cntnd] = Node();
    return node + cntnd++;
  }

  void Init(int n_) {
    n = n_;
    cntnd = 0;
  }

  Node* Build(int x) {
    Node *root = New(), *u = root;
    int l = 0, r = n;
    while (r - l > 1) {
      int mid = l + r >> 1;
      if (x < mid) {
        r = mid;
        u = u->lc = New();
      } else {
        l = mid;
        u = u->rc = New();
      }
    }
    return root;
  }

  Node* Unite(Node *u, Node *v) {
    if (!u) return v;
    if (!v) return u;
    Node *w = New();
    w->lc = Unite(u->lc, v->lc);
    w->rc = Unite(u->rc, v->rc);
    return w;
  }

  bool Find(Node *u, int l, int r, int L = 0, int R = n) {
    if (l <= L && r >= R) return u;
    int mid = L + R >> 1;
    return (l < mid && Find(u->lc, l, r, L, mid) ||
            r > mid && Find(u->rc, l, r, mid, R));
  }

  int FindAny(Node *u) {
    int l = 0, r = n;
    while (r - l > 1) {
      int mid = l + r >> 1;
      if (u->rc) {
        l = mid;
        u = u->rc;
      } else {
        r = mid;
        u = u->lc;
      }
    }
    return l;
  }
}

namespace sam {
  const int sigma = 26;
  const int maxnd = maxn * 2;

  struct Node {
    Node *tr[sigma], *par, *key;
    int len, dp;
    tree::Node *pos;
    vector<Node*> g;
    Node(int len = 0) : tr(), par(NULL), len(len), pos(NULL), g() {}
  } node[maxnd], *start, *last;

  int cntnd;

  Node* New(const Node &u) {
    node[cntnd] = u;
    return node + cntnd++;
  }

  void Init(void) {
    cntnd = 0;
    start = last = New(0);
  }

  Node* Extend(int x, int pos) {
    Node *u = New(last->len + 1), *v = last;
    u->pos = tree::Build(pos);
    for (; v && !v->tr[x]; v = v->par) v->tr[x] = u;
    if (!v) {
      u->par = start;
    } else if (v->tr[x]->len == v->len + 1) {
      u->par = v->tr[x];
    } else {
      Node *s = New(*(v->tr[x])), *o = v->tr[x];
      s->len = v->len + 1;
      o->par = u->par = s;
      for (; v && v->tr[x] == o; v = v->par) v->tr[x] = s;
    }
    return last = u;
  }

  int ans;

  void Dfs1(Node *u) {
    for (int i = 0; i < u->g.size(); ++i) {
      Node *v = u->g[i];
      Dfs1(v);
      u->pos = tree::Unite(u->pos, v->pos);
    }
  }

  bool Twice(Node *u, Node *v) {
    int r = tree::FindAny(v->pos);
    return tree::Find(u->pos, r - v->len + u->len, r);
  }

  void Dfs2(Node *u) {
    if (u->par) {
      if (Twice(u->par->key, u)) {
        u->dp = u->par->dp + 1;
        u->key = u;
      } else {
        u->dp = u->par->dp;
        u->key = u->par->key;
      }
    } else {
      u->dp = 0;
      u->key = u;
    }
    ans = max(ans, u->dp);
    for (int i = 0; i < u->g.size(); ++i) {
      Node *v = u->g[i];
      Dfs2(v);
    }
  }

  void Main(void) {
    for (int i = 0; i < cntnd; ++i) {
      Node *u = node + i;
      if (u->par) {
        u->par->g.push_back(u);
      }
    }
    Dfs1(start);
    Dfs2(start);
  }
}

char str[maxn + 1];

int main(void) {
  int len;
  scanf("%d", &len);
  scanf("%s", str);
  tree::Init(len);
  sam::Init();
  for (int i = 0; i < len; ++i) {
    sam::Extend(str[i] - 'a', i);
  }
  sam::Main();
  printf("%d\n", sam::ans);
  return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>

int n;
char S[300000];

struct edge{int to,nxt;}E[500000];
int H[500000],tot;
inline void add_edge(int a,int b){E[++tot]=(edge){b,H[a]},H[a]=tot;}

struct SegmentTree{
	struct node{
		node *L,*R;
		node(){L=R=NULL;}
	};

	node *root;

	void insert(node *&now,int l,int r,int k){
		if (!now) now=new node;
		if (l==r) return;
		int mdl=(l+r)>>1;
		if (k<=mdl) insert(now->L,l,mdl,k);
		else insert(now->R,mdl+1,r,k);
	}

	bool query(node *now,int l,int r,int L,int R){
//		printf("query %d %d %d %d\n",l,r,L,R);
		if (l>R||r<L||!now) return false;
		if (L<=l&&r<=R) return true;
		int mdl=(l+r)>>1;
		return query(now->L,l,mdl,L,R)|query(now->R,mdl+1,r,L,R);
	}

	SegmentTree(){root=NULL;}
};

SegmentTree::node * merge(SegmentTree::node *&A,SegmentTree::node *&B){
	if (!(A&&B)) return A?A:B;
	SegmentTree::node *nw=new SegmentTree::node;
	nw->L=merge(A->L,B->L),nw->R=merge(A->R,B->R);
	return nw;
}

struct SAM{
	struct node{
		int son[26],len,link,R;
		SegmentTree S;
		node(){
			memset(son,0xff,sizeof(int)*26);
			len=link=R=0;
		}
	}T[500000];

	int tot,lst;

	void insert(char C){
		C-='a';
		int q=++tot,p=lst;
		T[q].len=T[p].len+1,T[q].S.insert(T[q].S.root,1,n,T[q].R=T[q].len);
		lst=q;
		while (~p&&!~T[p].son[C]) T[p].son[C]=q,p=T[p].link;
		if (!~p) return;
		int np=T[p].son[C];
		if (T[p].len+1==T[np].len) T[q].link=np;
		else{
			int nq=++tot;
			memcpy(T[nq].son,T[np].son,sizeof(int)*26);
			T[nq].link=T[np].link;
			T[nq].len=T[p].len+1;
			T[np].link=T[q].link=nq;
			while (~p&&T[p].son[C]==np) T[p].son[C]=nq,p=T[p].link;
		}
	}

	SAM(){tot=lst=0,T[0].link=-1;}
}G;

void pre(int now){
//	printf("pre %d\n",now);
	for (int i=H[now];i;i=E[i].nxt){
		pre(E[i].to);
		G.T[now].R=std::max(G.T[now].R,G.T[E[i].to].R);
		G.T[now].S.root=merge(G.T[now].S.root,G.T[E[i].to].S.root);
	}
}

int Ans;

void solve(int now,int ans,int top){
//	for (int i=0;i<dep;i++) putchar('.');
//	printf("solve %d %d %d\n",now,ans,top);
	Ans=std::max(Ans,ans);
	for (int i=H[now];i;i=E[i].nxt){
		if (G.T[top].S.query(G.T[top].S.root,1,n,G.T[E[i].to].R-G.T[E[i].to].len+G.T[top].len,G.T[E[i].to].R-1)) solve(E[i].to,ans+1,E[i].to);
		else solve(E[i].to,ans,top);
	}
}

int main(){
	scanf("%d%s",&n,S+1);
	if (n==1) return puts("1"),0;
	for (int i=1;i<=n;i++) G.insert(S[i]);
	for (int i=1;i<=G.tot;i++) add_edge(G.T[i].link,i);
	pre(0),solve(0,0,0);
	printf("%d\n",Ans);
}


#include<iostream>
#include<cstdio>
#include<cstring>

int n;
char S[300000];

struct edge{int to,nxt;}E[500000];
int H[500000],tot;
inline void add_edge(int a,int b){E[++tot]=(edge){b,H[a]},H[a]=tot;}

struct SegmentTree{
	struct node{
		node *L,*R;
		node(){L=R=NULL;}
	};

	node *root;

	void insert(node *&now,int l,int r,int k){
		if (!now) now=new node;
		if (l==r) return;
		int mdl=(l+r)>>1;
		if (k<=mdl) insert(now->L,l,mdl,k);
		else insert(now->R,mdl+1,r,k);
	}

	bool query(node *now,int l,int r,int L,int R){
//		printf("query %d %d %d %d\n",l,r,L,R);
		if (l>R||r<L||!now) return false;
		if (L<=l&&r<=R) return true;
		int mdl=(l+r)>>1;
		return query(now->L,l,mdl,L,R)|query(now->R,mdl+1,r,L,R);
	}

	SegmentTree(){root=NULL;}
};

SegmentTree::node * merge(SegmentTree::node *&A,SegmentTree::node *&B){
	if (!(A&&B)) return A?A:B;
	SegmentTree::node *nw=new SegmentTree::node;
	nw->L=merge(A->L,B->L),nw->R=merge(A->R,B->R);
	return nw;
}

struct SAM{
	struct node{
		int son[26],len,link,R;
		SegmentTree S;
		node(){ memset(son,0xff,sizeof(son));
			len=link=0;
		}
	}T[500000];

	int tot,lst,ff;

	void insert(char C){
		C-='a';
		int q=++tot,p=lst;
		T[q].len=T[p].len+1,T[q].S.insert(T[q].S.root,1,n,T[q].R=++ff);
		lst=q;
		while (~p&&!~T[p].son[C]) T[p].son[C]=q,p=T[p].link;
		if (!~p) return;
		int np=T[p].son[C];
		if (T[p].len+1==T[np].len) T[q].link=np;
		else{
			int nq=++tot;
			memcpy(T[nq].son,T[np].son,sizeof(int)*26);
			T[nq].link=T[np].link;
			T[nq].len=T[p].len+1;
			T[np].link=T[q].link=nq;
			while (~p&&T[p].son[C]==np) T[p].son[C]=nq,p=T[p].link;
		}
	}

	SAM(){tot=lst=0,T[0].link=-1;}
}G;

void pre(int now){
//	printf("pre %d\n",now);
	for (int i=H[now];i;i=E[i].nxt){
		pre(E[i].to);
		G.T[now].R=std::max(G.T[now].R,G.T[E[i].to].R);
		G.T[now].S.root=merge(G.T[now].S.root,G.T[E[i].to].S.root);
	}
}

int Ans;

void solve(int now,int ans,int top){
//	printf("solve %d %d %d\n",now,ans,top);
	Ans=std::max(Ans,ans);
	for (int i=H[now];i;i=E[i].nxt){
		if (G.T[top].S.query(G.T[top].S.root,1,n,G.T[E[i].to].R-G.T[E[i].to].len+G.T[now].len,G.T[E[i].to].R-1)) solve(E[i].to,ans+1,E[i].to);
		else solve(E[i].to,ans,now);
	}
}

int main(){
	scanf("%d%s",&n,S+1);
	if (n==1) return puts("1"),0;
	for (int i=1;i<=n;i++) G.insert(S[i]);
	for (int i=1;i<=G.tot;i++) add_edge(G.T[i].link,i);
	pre(0),solve(0,0,0);
	printf("%d\n",Ans);
}


//#include <cstdio>
//#include <cstring>
//#include <algorithm>
//using namespace std;
//int n,p,k;
//int main()
//{
//   scanf("%d%d%d",&n,&p,&k);
//   if(p==1)
//   {
//
//       if(k<n)
//       for(int i=1;i<=k+1;i++)
//       {
//           if(i==1)printf("(1) ");
//           else
//           printf("%d ",i);
//       }
//       else
//       {
//           for(int i=1;i<=n;i++)
//           {
//               printf("%d ",i);
//           }
//       }
//       printf(">>\n");
//   }
//   else if(p==n)
//   {
//       if(k<n)
//           for(int i=(n-k);i<=n;i++)
//           {
//               if(i==n)printf("(%d) >>\n",n);
//               else
//                   printf("%d ",i);
//           }
//       else
//       {
//           for(int i=1;i<=n;i++)
//           {
//               if(i==n)printf("(%d) >>\n",n);
//               else
//                   printf("%d ",i);
//           }
//       }
//
//   }
//   else
//   {
//
//       int tt=p-k;
//       if(tt<1)tt=1;
//       int kk=p+k;
//       if(kk>n)kk=n;
//       if(tt!=1)printf("<< ");
//       for(int i=tt;i<=kk;i++)
//       {
//           if(i==p)printf("(%d) ",i);
//           else
//           printf("%d ",i);
//       }
//       if(kk!=n)printf(">>\n");
//       else printf("\n");
//   }
//}
//#include <cstdio>
//#include <cstring>
//#include <algorithm>
//#include <cmath>
//using namespace std;
//int main()
//{
//    int n;
//    char str[55];
//    scanf("%d",&n);
//    scanf("%s",&str);
//    __int64 result=0;
//    for(int i=0;i<n;i++)
//    {
//        if(str[i]=='B')
//        {
//            result+=pow(2.0,i);
//        }
//    }
//    printf("%lld\n",result);
//}
#include <cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{

    __int64 a,b;
    scanf("%lld%lld",&a,&b);
    __int64 result,temp;
    __int64 cnt=1;
    if(a==0)
    {
        result=-b*b;
        printf("%lld\n",result);
        for(int i=1;i<=b;i++)
        {
            printf("x");
        }
        printf("\n");
        return 0;

    }

    for(int i=1;i<=a;i++)
    {
        temp=(a-i+1)*(a-i+1)+(i-1);
        __int64 pp=b/(i+1);
        __int64 tt=(i+1)-b%(i+1);
        temp+=-b%(i+1)*(pp+1)*(pp+1)-tt*(pp)*(pp);
        if(i==1)result=temp;
        else
        {
            if(result<temp)
            {
                cnt=i;
                result=temp;
            }
        }
    }
    printf("%lld\n",result);
    for(int i=1;i<=2*cnt+1;i++)
    {
    if(i%2)
    {
        if(i<2*(b%(cnt+1)))
        {
            for(int j=1;j<=b/(cnt+1)+1;j++)
            {
                printf("x");
            }
        }
        else
        {
            for(int j=1;j<=b/(cnt+1);j++)
            {
                printf("x");
            }
        }
    }
    else
    {
        if(i==2)
        {
            for(int j=1;j<=a-cnt+1;j++)
            {
                printf("o");
            }
        }
        else printf("o");
    }
    }
     printf("\n");
    /*if(b==0)
    {
        result=a*a;
        printf("%lld\n",result);
        for(int i=1;i<=a;i++)
        {
            printf("o");
        }
        printf("\n");
        return 0;

    }
    if(a>b/2)
    {
        if(b%2==0)
        {
            result=a*a-2*(b/2)*(b/2);
            printf("%lld\n",result);
            for(int i=1;i<=b/2;i++)
            {
                printf("x");
            }
            for(int i=1;i<=a;i++)
                printf("o");
            for(int i=1;i<=b/2;i++)
            {
                printf("x");
            }
            printf("\n");
        }

        else
        {
            result=a*a-(b/2)*(b/2)-(b/2+1)*(b/2+1);
            printf("%lld\n",result);
            for(int i=1;i<=b/2;i++)
            {
                printf("x");
            }
            for(int i=1;i<=a;i++)
                printf("o");
            for(int i=1;i<=b/2+1;i++)
            {
                printf("x");
            }
            printf("\n");
        }
    }
    else
    {

             result=-tt*(pp+1)*(pp+1)-(a+1-tt)*pp*pp+a;
             printf("%lld\n",result);
             for(int i=1;i<=tt;i++)
             {
                 for(int j=1;j<=pp+1;j++)
                 {
                     printf("x");
                 }
                 printf("o");
             }
             for(int i=1;i<=(a+1-tt);i++)
             {
                 for(int j=1;j<=pp;j++)
                 {
                     printf("x");
                 }
                if(i!=a+1-tt) printf("o");
             }
             printf("\n");

    }*/
}


//#include <cstdio>
//#include <cstring>
//#include <algorithm>
//using namespace std;
//int n,p,k;
//int main()
//{
//   scanf("%d%d%d",&n,&p,&k);
//   if(p==1)
//   {
//
//       if(k<n)
//       for(int i=1;i<=k+1;i++)
//       {
//           if(i==1)printf("(1) ");
//           else
//           printf("%d ",i);
//       }
//       else
//       {
//           for(int i=1;i<=n;i++)
//           {
//               printf("%d ",i);
//           }
//       }
//       printf(">>\n");
//   }
//   else if(p==n)
//   {
//       if(k<n)
//           for(int i=(n-k);i<=n;i++)
//           {
//               if(i==n)printf("(%d) >>\n",n);
//               else
//                   printf("%d ",i);
//           }
//       else
//       {
//           for(int i=1;i<=n;i++)
//           {
//               if(i==n)printf("(%d) >>\n",n);
//               else
//                   printf("%d ",i);
//           }
//       }
//
//   }
//   else
//   {
//
//       int tt=p-k;
//       if(tt<1)tt=1;
//       int kk=p+k;
//       if(kk>n)kk=n;
//       if(tt!=1)printf("<< ");
//       for(int i=tt;i<=kk;i++)
//       {
//           if(i==p)printf("(%d) ",i);
//           else
//           printf("%d ",i);
//       }
//       if(kk!=n)printf(">>\n");
//       else printf("\n");
//   }
//}
//#include <cstdio>
//#include <cstring>
//#include <algorithm>
//#include <cmath>
//using namespace std;
//int main()
//{
//    int n;
//    char str[55];
//    scanf("%d",&n);
//    scanf("%s",&str);
//    __int64 result=0;
//    for(int i=0;i<n;i++)
//    {
//        if(str[i]=='B')
//        {
//            result+=pow(2.0,i);
//        }
//    }
//    printf("%lld\n",result);
//}
#include <cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{

    __int64 a,b;
    scanf("%lld%lld",&a,&b);
    __int64 result;
    __int64 pp=b/(a+1);
    __int64 tt=b-pp*(a+1);
    if(a==0)
    {
        result=-b*b;
        printf("%lld\n",result);
        for(int i=1;i<=b;i++)
        {
            printf("x");
        }
        printf("\n");
        return 0;

    }
    if(b==0)
    {
        result=a*a;
        printf("%lld\n",result);
        for(int i=1;i<=a;i++)
        {
            printf("o");
        }
        printf("\n");
        return 0;

    }
    if(a>b/2)
    {
        if(b%2==0)
        {
            result=a*a-2*(b/2)*(b/2);
            printf("%lld\n",result);
            for(int i=1;i<=b/2;i++)
            {
                printf("x");
            }
            for(int i=1;i<=a;i++)
                printf("o");
            for(int i=1;i<=b/2;i++)
            {
                printf("x");
            }
            printf("\n");
        }

        else
        {
            result=a*a-(b/2)*(b/2)-(b/2+1)*(b/2+1);
            printf("%lld\n",result);
            for(int i=1;i<=b/2;i++)
            {
                printf("x");
            }
            for(int i=1;i<=a;i++)
                printf("o");
            for(int i=1;i<=b/2+1;i++)
            {
                printf("x");
            }
            printf("\n");
        }
    }
    else
    {

             result=-tt*(pp+1)*(pp+1)-(a+1-tt)*pp*pp+a;
             printf("%lld\n",result);
             for(int i=1;i<=tt;i++)
             {
                 for(int j=1;j<=pp+1;j++)
                 {
                     printf("x");
                 }
                 printf("o");
             }
             for(int i=1;i<=(a+1-tt);i++)
             {
                 for(int j=1;j<=pp;j++)
                 {
                     printf("x");
                 }
                if(i!=a+1-tt) printf("o");
             }
             printf("\n");

    }
}


#include <iostream>

using namespace std;
int main() {
	int a, b;
	cin >> a >> b;
	int ans = 0;
	if (a > b) {
		if (b % 2 == 0) {
			ans = a*a - 2 * (b / 2)*(b / 2);
			cout <<ans<< endl;
			for (int i = 0; i < b/2; i++) {
				cout << 'x';
			}
			for (int i = 0; i < a; i++) {
				cout << 'o';
			}
			for (int i = 0; i < b/2; i++) {
				cout << 'x';
			}
			cout << endl;
		}
		else {
			ans = a*a - (b / 2)*(b / 2) - (b / 2 + 1)*(b / 2 + 1);
			cout << ans << endl;
			for (int i = 0; i < b / 2; i++) {
				cout << 'x';
			}
			for (int i = 0; i < a; i++) {
				cout << 'o';
			}
			for (int i = 0; i < b / 2+1; i++) {
				cout << 'x';
			}
			cout << endl;
		}
	}
	else if(a==b){
		ans = 0;
		cout << ans << endl;
		for (int i = 0; i < a; i++) {
			cout << 'xo';
		}
		cout << endl;
	}
	else {
		int aa = a, bb = b;
		while (aa--) {
			if (bb % 2 == 0) {
				bb /= 2;
				ans += -(bb*bb);
				ans++;
			}
			else {
				bb /= 2;
				ans += -(bb*bb);
				ans++;
				bb++;
			}
		}
		ans += -(bb*bb);
		cout << ans << endl;
		while (a--) {
			if (b % 2 == 0) {
				b /= 2;
				for (int i = 0; i < b; i++) {
					cout << 'x';
				}
				cout << 'o';
			}
			else {
				b /= 2;
				for (int i = 0; i < b; i++) {
					cout << 'x';
				}
				cout << 'o';
				b++;
			}
		}
		for (int i = 0; i < b; i++) {
			cout << 'x';
		}
		cout << endl;
	}

	return 0;
}


#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    long long a,b;
    cin>>a>>b;
    long long ans=-10000000000000,k;
    for(long long i=0;i<max(a,(long long)1)&&i<=max(b-2,(long long)0);i++)
    {
        long long temp,t,r;
        temp=(a-i)*(a-i)+i;
        t=b/(i+2);
        r=b%(i+2);
        if(r==0)
        {
            temp-=t*t*(i+2);
        }
        else
        {
            temp-=t*t*(i+2-r)+(t+1)*(t+1)*r;
        }
        if(temp<=ans) {}//break;
         else
         {
             ans=temp;
             k=i;
         }
    }
    if(a==0) ans=-b*b;
    cout<<ans<<endl;
    long long t,r,Count1,Count2;
    t=b/(k+2);
    r=b%(k+2);
    Count1=r;
    Count2=k+2-r;
    //cout<<Count1<<" "<<Count2<<endl;
    for(int i=0;i<=k;i++)
    {
        if(Count1>0)
        {
            Count1--;
            for(int j=0;j<t+1;j++) printf("x");
        }
        else if(Count2>0)
        {
            Count2--;
            for(int j=0;j<t;j++) printf("x");
        }
        if(i!=k)printf("o");
    }
    for(int i=0;i<a-k;i++) printf("o");
    for(int j=0;j<t;j++) printf("x");
    //cout << "Hello world!" << endl;
    return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline long long sq(long long x)
{
    return x*x;
}
int main()
{
    long long a, b;
    while(scanf("%I64d %I64d",&a, &b)!=-1)
    {
        long long ans = 0;
        if(a==0 || b==0 || a==b)
        {
            ans = sq(a) - sq(b);
            printf("%I64d\n",ans);
            while(a--) printf("o");
            while(b--) printf("x");
            printf("\n");
        }else{
            ans = -sq(a+b);
            int ans_w,ans_l;
            long long ans_tmp;
            for(int w = 1; w <= a; ++w)
            for(int l = w-1; l <= w+1; ++l)
            if(l >= 1 && l <= b){
                ans_tmp = sq(a-w+1) + (w-1);
                ans_tmp -= sq(b/l+1)*(b%l) + sq(b/l)*(l-b%l);
                if(ans < ans_tmp){
                    ans = ans_tmp;
                    ans_w = w, ans_l = l;
                }
            }
            printf("%I64d\n",ans);
            if(ans_w >= ans_l){
                for(int i = 0; i < ans_w; ++i){
                    int w = (i>0)?1:(a-ans_w+1);
                    //cout << w <<endl;
                    while(w--)putchar('o');
                    if(i < ans_l){
                        int l = (i<(b%ans_l))?(b/ans_l+1):(b/ans_l);
                        while(l--) putchar('x');
                    }
                }
                printf("\n");
            }else{
                for(int i = 0; i < ans_l; ++i){
                    int l = (i<(b%ans_l))?(b/ans_l+1):(b/ans_l);
                    while(l--) putchar('x');
                    if(i < ans_w){
                       int w = (i>0)?1:(a-ans_w+1);
                        while(w--)putchar('o');
                    }
                }
                printf("\n");
            }
        }
    }
    return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline long long sq(long long x)
{
    return x*x;
}
int main()
{
    long long a, b;
    while(scanf("%I64d %I64d",&a, &b)!=-1)
    {
        long long ans = 0;
        if(a==0 || b<=1)
        {
            ans = sq(a) - sq(b);
            printf("%I64d\n",ans);
            while(a--) printf("o");
            while(b--) printf("x");
            printf("\n");
        }else{
            ans = -sq(a+b);
            int ans_w,ans_l;
            long long ans_tmp;
            for(int w = 1; w <= a; ++w)
            for(int l = w-1; l <= w+1; ++l)
            if(l >= 1 && l <= b){
                ans_tmp = sq(a-w+1) + (w-1);
                ans_tmp -= sq(b/l+1)*(b%l) + sq(b/l)*(l-b%l);
                if(ans < ans_tmp){
                    ans = ans_tmp;
                    ans_w = w, ans_l = l;
                }
            }
            printf("%I64d\n",ans);
            if(ans_w >= ans_l){
                for(int i = 0; i < ans_w; ++i){
                    int w = (i>0)?1:(a-ans_w+1);
                    //cout << w <<endl;
                    while(w--)putchar('o');
                    if(i < ans_l){
                        int l = (i<(b%ans_l))?(b/ans_l+1):(b/ans_l);
                        while(l--) putchar('x');
                    }
                }
                printf("\n");
            }else{
                for(int i = 0; i < ans_l; ++i){
                    int l = (i<(b%ans_l))?(b/ans_l+1):(b/ans_l);
                    while(l--) putchar('x');
                    if(i < ans_w){
                       int w = (i>0)?1:(a-ans_w+1);
                        while(w--)putchar('o');
                    }
                }
                printf("\n");
            }
        }
    }
    return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;

int main()
{
    int a, b;
    while(scanf("%d %d",&a, &b)!=-1)
    {
        if(a >= b){
            printf("%I64d\n",((long long)(a-b))*(a+b));
            while(a--) printf("o");
            while(b--) printf("x");
            printf("\n");
        }else if(a == 0){
            long long ans = -(long long)b*b;
            printf("%I64d\n",ans);
            while(b--) printf("x");
            printf("\n");
        }else{
            int n = (b-1)/a;
            int m = b - a*n;
            long long ans = ((long long)n*n - 1)*a;
            ans -= m*m;
            printf("%I64d\n",ans);
            for(int i = 0; i < a; ++i)
            {
                int tmp = n;
                while(tmp--) printf("x");
                printf("o");
            }
            while(m--) printf("x");
            printf("\n");
        }
    }
    return 0;
}


/**********************************************
			Author : smiley007
***********************************************/

//Data Structure Includes
#include <vector>
#include <queue>
#include <deque>
#include <bitset>
#include <stack>
#include <list>
#include <set>
#include <map>

//Other Includes
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cctype>
#include <cassert>
#include <numeric>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <climits>

using namespace std ;

//Defines
#define FOR(i,a,b)         	for(int i = (a); i <  (b) ; i++)
#define FOE(i,a,b)         	for(int i = (a); i <= (b) ; i++)
#define FOED(i,a,b)			for(int i = (a); i >= (b) ; i--)
#define ITR(v,it) 			for( typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define REP(i,n)			FOR(i,0,n)
#define ALL(a) 				a.begin(),a.end()
#define SORT(a) 			sort(ALL(a))
#define SZ(a)				((int)a.size())
#define SQR(x)				((x)*(x))
#define BS(i) 				__builtin_popcount(i)
#define LZ(i)				__clz
#define RE 					return
#define FI 					first
#define SD 					second
#define PB					push_back
#define MP(x,y)				make_pair(x,y)
#define SET(a,v)			memset(&a[0],v, sizeof(a[0])*SZ(a) )
#define POW2(i)				( 1LL << (i) )
//#define SET(a,i)			a |= POW2(i)
#define CLR(a,i)			a &= ~ POW2(i)
#define TOGGLE(a,i)			a ^= POW2(i)
#define TEST(a,i)			((a) & POW2(i))
#define EPS					1e-9
#define INF					1e9
#define PI 					3.141592653589793
#define MOD 				1000000007

//Typedefs
typedef long long ll ;
typedef pair<int,int> pii ;
typedef pair<string,string> pss ;
typedef vector<int> vi ;
typedef vector<ll> vl ;
typedef vector<vi> vvi ;
typedef vector<vl> vvl ;
typedef vector<bool> vb ;
typedef vector<vb> vvb ;
typedef vector<string> vs ;
typedef vector<pii> vpii ;

//Templates
//<< ----- Number Theory --- >>
template<class T> bool isPrime(T x){if(x<=1)RE false;T i;for(i=2;i*i<=x;i++)if(x%i==0)RE false;RE true;} //isPrime
template<class T> class Prime{public:vector<T> z ;Prime(){z.resize(1e5+7);REP(i,SZ(z)) z[i]=1;
z[0]=0;z[1]=0;T j;FOR(i,2,SZ(z)){if(z[i]){j=i+i;while(j<SZ(z)){ z[j]=0;j += i ;} } }} }; //Prime

//<< ----- Geometry -------- >>
template<class T> double dist(T x1,T y1,T x2,T y2){RE sqrt( 1.*(x2-x1)*(x2-x1) + 1.*(y2-y1)*(y2-y1) ) ;} //dist
template<class T> class Point{
    public :
    T x, y;
    Point(){}
    Point(T a,T b):x(a),y(b){}
    bool operator ==(const Point& tmp)const{ RE(x==tmp.x && y==tmp.y);}
    Point operator-(const Point& tmp) const{ RE Point<T> (x-tmp.x,y-tmp.y);}
};

//<<---- Conversions ------- >>
char toLowerCase(char x){RE(x+32);}
char toUpperCase(char x){RE(x-32);}
bool isUpperCase(char x){RE (65<=x && x<=90)? 1 : 0 ;}
bool isLowerCase(char x){RE (97<=x && x<=122)? 1 : 0 ;}
bool isAlpha(char x){RE (isUpperCase(x) || isLowerCase(x))? 1 : 0 ;}
bool isDigit(char x){RE('0'<=x && x<='9')? 1 : 0 ;}
template<class T> T toDec(string s){stringstream is(s);T res;is>>res;RE res;} //toDec
template<class T> string toStr(T n){string s;stringstream is;is<<n;is>>s;RE s;} //toStr

template<class T> void checkmin(T& a,T b){if(a>b)a=b;}
template<class T> void checkmax(T& a,T b){if(a<b)a=b;}

//Code Begins Here ------ >>>

// Grab your asses fella's , because this code is gonna go deep into you :)

int main(){
	#ifdef LocalHost
		freopen("input.txt","r",stdin);
	#endif

	int a,b,i,pos,neg,lol,wl,val;
	ll res;
	cin >> a >> b;
	int n = min(a,b);
	if (!a) {
		cout << -SQR(b) << "\n";
		for (i = 0; i < b; i++) cout << "x";
		cout << "\n";
	}
	else if (!b) {
		cout << SQR(a) << "\n";
		for (i = 0; i < a; i++) cout << "o";
		cout << "\n";
	}
	else {
		res = -SQR(a+b);
		for (int ap = 1; ap <= n; ap++) {
			for (int bp = ap-1; bp <= ap+1; bp++) {
				if (1 <= bp && bp <= b) {
					pos = SQR(a - (ap-1)) + (ap - 1);
					neg = SQR((b/bp) + 1)*(b%bp) + SQR(b/bp)*(bp- (b%bp));
					if (res < (pos-neg) ) {
						res = pos-neg;
						wl = ap, lol = bp;
					}
				}
			}
		}
		cout << res << "\n";
		if (wl >= lol) {
			for (int c = 0; c < wl; c++) {
				int val = (c > 0 ? 1 : (a - (wl-1)));
				for (i = 0; i < val; i++) cout << "o";
				val = (c >= (b%lol) ? (b/lol) : (b/lol + 1));
				if (c < lol) for (i = 0; i < val; i++) cout << "x";
			}
			cout << "\n";
		}
		else {
			for (int c = 0; c < lol; c++) {
				val = (c >= (b%lol) ? (b/lol) : (b/lol + 1));
				for (i = 0; i < val; i++) cout << "x";
				int val = (c > 0 ? 1 : (a - (wl-1)));
				if (c < wl) for (i = 0; i < val; i++) cout << "o";
			}
			cout << "\n";
		}
	}

	#ifdef LocalHost
    cout<<endl<<"Execution time = "<<(float)clock()/CLOCKS_PER_SEC <<" s"<<endl;
	#endif

	RE 0;
}


/**********************************************
			Author : smiley007
***********************************************/

//Data Structure Includes
#include <vector>
#include <queue>
#include <deque>
#include <bitset>
#include <stack>
#include <list>
#include <set>
#include <map>

//Other Includes
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cctype>
#include <cassert>
#include <numeric>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <climits>

using namespace std ;

//Defines
#define FOR(i,a,b)         	for(int i = (a); i <  (b) ; i++)
#define FOE(i,a,b)         	for(int i = (a); i <= (b) ; i++)
#define FOED(i,a,b)			for(int i = (a); i >= (b) ; i--)
#define ITR(v,it) 			for( typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define REP(i,n)			FOR(i,0,n)
#define ALL(a) 				a.begin(),a.end()
#define SORT(a) 			sort(ALL(a))
#define SZ(a)				((int)a.size())
#define SQR(x)				((x)*(x))
#define BS(i) 				__builtin_popcount(i)
#define LZ(i)				__clz
#define RE 					return
#define FI 					first
#define SD 					second
#define PB					push_back
#define MP(x,y)				make_pair(x,y)
#define SET(a,v)			memset(&a[0],v, sizeof(a[0])*SZ(a) )
#define POW2(i)				( 1LL << (i) )
//#define SET(a,i)			a |= POW2(i)
#define CLR(a,i)			a &= ~ POW2(i)
#define TOGGLE(a,i)			a ^= POW2(i)
#define TEST(a,i)			((a) & POW2(i))
#define EPS					1e-9
#define INF					1e9
#define PI 					3.141592653589793
#define MOD 				1000000007

//Typedefs
typedef long long ll ;
typedef pair<int,int> pii ;
typedef pair<string,string> pss ;
typedef vector<int> vi ;
typedef vector<ll> vl ;
typedef vector<vi> vvi ;
typedef vector<vl> vvl ;
typedef vector<bool> vb ;
typedef vector<vb> vvb ;
typedef vector<string> vs ;
typedef vector<pii> vpii ;

//Templates
//<< ----- Number Theory --- >>
template<class T> bool isPrime(T x){if(x<=1)RE false;T i;for(i=2;i*i<=x;i++)if(x%i==0)RE false;RE true;} //isPrime
template<class T> class Prime{public:vector<T> z ;Prime(){z.resize(1e5+7);REP(i,SZ(z)) z[i]=1;
z[0]=0;z[1]=0;T j;FOR(i,2,SZ(z)){if(z[i]){j=i+i;while(j<SZ(z)){ z[j]=0;j += i ;} } }} }; //Prime

//<< ----- Geometry -------- >>
template<class T> double dist(T x1,T y1,T x2,T y2){RE sqrt( 1.*(x2-x1)*(x2-x1) + 1.*(y2-y1)*(y2-y1) ) ;} //dist
template<class T> class Point{
    public :
    T x, y;
    Point(){}
    Point(T a,T b):x(a),y(b){}
    bool operator ==(const Point& tmp)const{ RE(x==tmp.x && y==tmp.y);}
    Point operator-(const Point& tmp) const{ RE Point<T> (x-tmp.x,y-tmp.y);}
};

//<<---- Conversions ------- >>
char toLowerCase(char x){RE(x+32);}
char toUpperCase(char x){RE(x-32);}
bool isUpperCase(char x){RE (65<=x && x<=90)? 1 : 0 ;}
bool isLowerCase(char x){RE (97<=x && x<=122)? 1 : 0 ;}
bool isAlpha(char x){RE (isUpperCase(x) || isLowerCase(x))? 1 : 0 ;}
bool isDigit(char x){RE('0'<=x && x<='9')? 1 : 0 ;}
template<class T> T toDec(string s){stringstream is(s);T res;is>>res;RE res;} //toDec
template<class T> string toStr(T n){string s;stringstream is;is<<n;is>>s;RE s;} //toStr

template<class T> void checkmin(T& a,T b){if(a>b)a=b;}
template<class T> void checkmax(T& a,T b){if(a<b)a=b;}

//Code Begins Here ------ >>>

// Grab your asses fella's , because this code is gonna go deep into you :)

int main(){
	#ifdef LocalHost
		freopen("input.txt","r",stdin);
	#endif

	int a,b,i;
	cin >> a >> b;
	ll ans = 0;
	if (a >= b) {
		ans = SQR(a) - SQR(b);
		cout << ans << "\n";
		for (i = 0; i < a; i++) cout << "o";
		for (i = 0; i < b; i++) cout << "x";
		cout << "\n";
	}
	else {
		int tot = 0;
		int len = b/(a+1);
		int rem = b - a*len;
		ans  = -a*SQR(len) - SQR(rem) + a;
		cout << ans << "\n";
		int it = a*(len+1);
		while (it--) {
			if (tot < len) {
				cout << "x";
				tot++;
			}
			else {
				cout << "o";
				tot = 0;
			}
		}
		while(rem--) cout << "x";
		cout << "\n";
	}

	#ifdef LocalHost
    cout<<endl<<"Execution time = "<<(float)clock()/CLOCKS_PER_SEC <<" s"<<endl;
	#endif

	RE 0;
}


/**********************************************
			Author : smiley007
***********************************************/

//Data Structure Includes
#include <vector>
#include <queue>
#include <deque>
#include <bitset>
#include <stack>
#include <list>
#include <set>
#include <map>

//Other Includes
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cctype>
#include <cassert>
#include <numeric>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <climits>

using namespace std ;

//Defines
#define FOR(i,a,b)         	for(int i = (a); i <  (b) ; i++)
#define FOE(i,a,b)         	for(int i = (a); i <= (b) ; i++)
#define FOED(i,a,b)			for(int i = (a); i >= (b) ; i--)
#define ITR(v,it) 			for( typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define REP(i,n)			FOR(i,0,n)
#define ALL(a) 				a.begin(),a.end()
#define SORT(a) 			sort(ALL(a))
#define SZ(a)				((int)a.size())
#define SQR(x)				(1LL*(x)*(x))
#define BS(i) 				__builtin_popcount(i)
#define LZ(i)				__clz
#define RE 					return
#define FI 					first
#define SD 					second
#define PB					push_back
#define MP(x,y)				make_pair(x,y)
#define SET(a,v)			memset(&a[0],v, sizeof(a[0])*SZ(a) )
#define POW2(i)				( 1LL << (i) )
//#define SET(a,i)			a |= POW2(i)
#define CLR(a,i)			a &= ~ POW2(i)
#define TOGGLE(a,i)			a ^= POW2(i)
#define TEST(a,i)			((a) & POW2(i))
#define EPS					1e-9
#define INF					1e9
#define PI 					3.141592653589793
#define MOD 				1000000007

//Typedefs
typedef long long ll ;
typedef pair<int,int> pii ;
typedef pair<string,string> pss ;
typedef vector<int> vi ;
typedef vector<ll> vl ;
typedef vector<vi> vvi ;
typedef vector<vl> vvl ;
typedef vector<bool> vb ;
typedef vector<vb> vvb ;
typedef vector<string> vs ;
typedef vector<pii> vpii ;

//Templates
//<< ----- Number Theory --- >>
template<class T> bool isPrime(T x){if(x<=1)RE false;T i;for(i=2;i*i<=x;i++)if(x%i==0)RE false;RE true;} //isPrime
template<class T> class Prime{public:vector<T> z ;Prime(){z.resize(1e5+7);REP(i,SZ(z)) z[i]=1;
z[0]=0;z[1]=0;T j;FOR(i,2,SZ(z)){if(z[i]){j=i+i;while(j<SZ(z)){ z[j]=0;j += i ;} } }} }; //Prime

//<< ----- Geometry -------- >>
template<class T> double dist(T x1,T y1,T x2,T y2){RE sqrt( 1.*(x2-x1)*(x2-x1) + 1.*(y2-y1)*(y2-y1) ) ;} //dist
template<class T> class Point{
    public :
    T x, y;
    Point(){}
    Point(T a,T b):x(a),y(b){}
    bool operator ==(const Point& tmp)const{ RE(x==tmp.x && y==tmp.y);}
    Point operator-(const Point& tmp) const{ RE Point<T> (x-tmp.x,y-tmp.y);}
};

//<<---- Conversions ------- >>
char toLowerCase(char x){RE(x+32);}
char toUpperCase(char x){RE(x-32);}
bool isUpperCase(char x){RE (65<=x && x<=90)? 1 : 0 ;}
bool isLowerCase(char x){RE (97<=x && x<=122)? 1 : 0 ;}
bool isAlpha(char x){RE (isUpperCase(x) || isLowerCase(x))? 1 : 0 ;}
bool isDigit(char x){RE('0'<=x && x<='9')? 1 : 0 ;}
template<class T> T toDec(string s){stringstream is(s);T res;is>>res;RE res;} //toDec
template<class T> string toStr(T n){string s;stringstream is;is<<n;is>>s;RE s;} //toStr

template<class T> void checkmin(T& a,T b){if(a>b)a=b;}
template<class T> void checkmax(T& a,T b){if(a<b)a=b;}

//Code Begins Here ------ >>>

// Grab your asses fella's , because this code is gonna go deep into you :)
ll sq(int x) {
	return 1LL*x*x;
}

int main(){
	#ifdef LocalHost
		freopen("input.txt","r",stdin);
	#endif

	int a,b,i,lol,wl,val;
	ll res,pos,neg;
	cin >> a >> b;
	int n = min(a,b);
	if (!a) {
		cout << -SQR(b) << "\n";
		for (i = 0; i < b; i++) cout << "x";
		cout << "\n";
	}
	else if (!b) {
		cout << SQR(a) << "\n";
		for (i = 0; i < a; i++) cout << "o";
		cout << "\n";
	}

	else {
		wl = lol = 0;
		res = -sq(a+b);
		for (int ap = 1; ap <= n; ap++) {
			for (int bp = ap; bp <= ap+1; bp++) {
				if (1 <= bp && bp <= b) {
					pos = sq(a - (ap-1)) + (ap - 1);
					neg = sq((b/bp) + 1)*(b%bp) + sq(b/bp)*(bp- (b%bp));
					if (res < (pos-neg) ) {
						res = pos-neg;
						wl = ap, lol = bp;
					}
				}
			}
		}
		cout << res << "\n";
		//cout << wl << " " << lol << "\n";
			for (int c = 0; c < lol; c++) {
				val = (c >= (b%lol) ? (b/lol) : (b/lol + 1));
				for (i = 0; i < val; i++) cout << "x";
				int val = (c > 0 ? 1 : (a - (wl-1)));
				if (c < wl) for (i = 0; i < val; i++) cout << "o";
			}
			cout << "\n";
	}

	#ifdef LocalHost
    cout<<endl<<"Execution time = "<<(float)clock()/CLOCKS_PER_SEC <<" s"<<endl;
	#endif

	RE 0;
}


/**********************************************
            Author : smiley007
***********************************************/

//Data Structure Includes
#include <vector>
#include <queue>
#include <deque>
#include <bitset>
#include <stack>
#include <list>
#include <set>
#include <map>

//Other Includes
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cctype>
#include <cassert>
#include <numeric>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <climits>

using namespace std ;

//Defines
#define FOR(i,a,b)          for(int i = (a); i <  (b) ; i++)
#define FOE(i,a,b)          for(int i = (a); i <= (b) ; i++)
#define FOED(i,a,b)         for(int i = (a); i >= (b) ; i--)
#define ITR(v,it)           for( typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define REP(i,n)            FOR(i,0,n)
#define ALL(a)              a.begin(),a.end()
#define SORT(a)             sort(ALL(a))
#define SZ(a)               ((int)a.size())
#define SQR(x)              (1LL*(x)*(x))
#define BS(i)               __builtin_popcount(i)
#define LZ(i)               __clz
#define RE                  return
#define FI                  first
#define SD                  second
#define PB                  push_back
#define MP(x,y)             make_pair(x,y)
#define SET(a,v)            memset(&a[0],v, sizeof(a[0])*SZ(a) )
#define POW2(i)             ( 1LL << (i) )
//#define SET(a,i)          a |= POW2(i)
#define CLR(a,i)            a &= ~ POW2(i)
#define TOGGLE(a,i)         a ^= POW2(i)
#define TEST(a,i)           ((a) & POW2(i))
#define EPS                 1e-9
#define INF                 1e9
#define PI                  3.141592653589793
#define MOD                 1000000007

//Typedefs
typedef long long ll ;
typedef pair<int,int> pii ;
typedef pair<string,string> pss ;
typedef vector<int> vi ;
typedef vector<ll> vl ;
typedef vector<vi> vvi ;
typedef vector<vl> vvl ;
typedef vector<bool> vb ;
typedef vector<vb> vvb ;
typedef vector<string> vs ;
typedef vector<pii> vpii ;

//Templates
//<< ----- Number Theory --- >>
template<class T> bool isPrime(T x){if(x<=1)RE false;T i;for(i=2;i*i<=x;i++)if(x%i==0)RE false;RE true;} //isPrime
template<class T> class Prime{public:vector<T> z ;Prime(){z.resize(1e5+7);REP(i,SZ(z)) z[i]=1;
z[0]=0;z[1]=0;T j;FOR(i,2,SZ(z)){if(z[i]){j=i+i;while(j<SZ(z)){ z[j]=0;j += i ;} } }} }; //Prime

//<< ----- Geometry -------- >>
template<class T> double dist(T x1,T y1,T x2,T y2){RE sqrt( 1.*(x2-x1)*(x2-x1) + 1.*(y2-y1)*(y2-y1) ) ;} //dist
template<class T> class Point{
    public :
    T x, y;
    Point(){}
    Point(T a,T b):x(a),y(b){}
    bool operator ==(const Point& tmp)const{ RE(x==tmp.x && y==tmp.y);}
    Point operator-(const Point& tmp) const{ RE Point<T> (x-tmp.x,y-tmp.y);}
};

//<<---- Conversions ------- >>
char toLowerCase(char x){RE(x+32);}
char toUpperCase(char x){RE(x-32);}
bool isUpperCase(char x){RE (65<=x && x<=90)? 1 : 0 ;}
bool isLowerCase(char x){RE (97<=x && x<=122)? 1 : 0 ;}
bool isAlpha(char x){RE (isUpperCase(x) || isLowerCase(x))? 1 : 0 ;}
bool isDigit(char x){RE('0'<=x && x<='9')? 1 : 0 ;}
template<class T> T toDec(string s){stringstream is(s);T res;is>>res;RE res;} //toDec
template<class T> string toStr(T n){string s;stringstream is;is<<n;is>>s;RE s;} //toStr

template<class T> void checkmin(T& a,T b){if(a>b)a=b;}
template<class T> void checkmax(T& a,T b){if(a<b)a=b;}

//Code Begins Here ------ >>>

// Grab your asses fella's , because this code is gonna go deep into you :)
ll sq(int x) {
    return 1LL*x*x;
}

int main(){
    #ifdef LocalHost
        freopen("input.txt","r",stdin);
    #endif

    int a,b,i,lol,wl,val;
    ll res,pos,neg;
    cin >> a >> b;
    int n = min(a,b);
    if (!a) {
        cout << -SQR(b) << "\n";
        for (i = 0; i < b; i++) cout << "x";
        cout << "\n";
    }
    else if (!b) {
        cout << SQR(a) << "\n";
        for (i = 0; i < a; i++) cout << "o";
        cout << "\n";
    }

    else {
        wl = lol = 0;
        res = -sq(a+b);
        for (int ap = 1; ap <= n; ap++) {
            for (int bp = ap-1; bp <= ap+1; bp++) {
                if (1 <= bp && bp <= b) {
                    pos = sq(a - (ap-1)) + (ap - 1);
                    neg = sq((b/bp) + 1)*(b%bp) + sq(b/bp)*(bp- (b%bp));
                    if (res < (pos-neg) ) {
                        res = pos-neg;
                        wl = ap, lol = bp;
                    }
                }
            }
        }
        cout << res << "\n";
        //cout << wl << " " << lol << "\n";
            for (int c = 0; c < lol; c++) {
                val = (c >= (b%lol) ? (b/lol) : (b/lol + 1));
                for (i = 0; i < val; i++) cout << "x";
                int val = (c > 0 ? 1 : (a - (wl-1)));
                if (c < wl) for (i = 0; i < val; i++) cout << "o";
            }
            cout << "\n";
    }

    #ifdef LocalHost
    cout<<endl<<"Execution time = "<<(float)clock()/CLOCKS_PER_SEC <<" s"<<endl;
    #endif

    RE 0;
}


/**********************************************
			Author : smiley007
***********************************************/

//Data Structure Includes
#include <vector>
#include <queue>
#include <deque>
#include <bitset>
#include <stack>
#include <list>
#include <set>
#include <map>

//Other Includes
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cctype>
#include <cassert>
#include <numeric>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <climits>

using namespace std ;

//Defines
#define FOR(i,a,b)         	for(int i = (a); i <  (b) ; i++)
#define FOE(i,a,b)         	for(int i = (a); i <= (b) ; i++)
#define FOED(i,a,b)			for(int i = (a); i >= (b) ; i--)
#define ITR(v,it) 			for( typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define REP(i,n)			FOR(i,0,n)
#define ALL(a) 				a.begin(),a.end()
#define SORT(a) 			sort(ALL(a))
#define SZ(a)				((int)a.size())
#define SQR(x)				((x)*(x))
#define BS(i) 				__builtin_popcount(i)
#define LZ(i)				__clz
#define RE 					return
#define FI 					first
#define SD 					second
#define PB					push_back
#define MP(x,y)				make_pair(x,y)
#define SET(a,v)			memset(&a[0],v, sizeof(a[0])*SZ(a) )
#define POW2(i)				( 1LL << (i) )
//#define SET(a,i)			a |= POW2(i)
#define CLR(a,i)			a &= ~ POW2(i)
#define TOGGLE(a,i)			a ^= POW2(i)
#define TEST(a,i)			((a) & POW2(i))
#define EPS					1e-9
#define INF					1e9
#define PI 					3.141592653589793
#define MOD 				1000000007

//Typedefs
typedef long long ll ;
typedef pair<int,int> pii ;
typedef pair<string,string> pss ;
typedef vector<int> vi ;
typedef vector<ll> vl ;
typedef vector<vi> vvi ;
typedef vector<vl> vvl ;
typedef vector<bool> vb ;
typedef vector<vb> vvb ;
typedef vector<string> vs ;
typedef vector<pii> vpii ;

//Templates
//<< ----- Number Theory --- >>
template<class T> bool isPrime(T x){if(x<=1)RE false;T i;for(i=2;i*i<=x;i++)if(x%i==0)RE false;RE true;} //isPrime
template<class T> class Prime{public:vector<T> z ;Prime(){z.resize(1e5+7);REP(i,SZ(z)) z[i]=1;
z[0]=0;z[1]=0;T j;FOR(i,2,SZ(z)){if(z[i]){j=i+i;while(j<SZ(z)){ z[j]=0;j += i ;} } }} }; //Prime

//<< ----- Geometry -------- >>
template<class T> double dist(T x1,T y1,T x2,T y2){RE sqrt( 1.*(x2-x1)*(x2-x1) + 1.*(y2-y1)*(y2-y1) ) ;} //dist
template<class T> class Point{
    public :
    T x, y;
    Point(){}
    Point(T a,T b):x(a),y(b){}
    bool operator ==(const Point& tmp)const{ RE(x==tmp.x && y==tmp.y);}
    Point operator-(const Point& tmp) const{ RE Point<T> (x-tmp.x,y-tmp.y);}
};

//<<---- Conversions ------- >>
char toLowerCase(char x){RE(x+32);}
char toUpperCase(char x){RE(x-32);}
bool isUpperCase(char x){RE (65<=x && x<=90)? 1 : 0 ;}
bool isLowerCase(char x){RE (97<=x && x<=122)? 1 : 0 ;}
bool isAlpha(char x){RE (isUpperCase(x) || isLowerCase(x))? 1 : 0 ;}
bool isDigit(char x){RE('0'<=x && x<='9')? 1 : 0 ;}
template<class T> T toDec(string s){stringstream is(s);T res;is>>res;RE res;} //toDec
template<class T> string toStr(T n){string s;stringstream is;is<<n;is>>s;RE s;} //toStr

template<class T> void checkmin(T& a,T b){if(a>b)a=b;}
template<class T> void checkmax(T& a,T b){if(a<b)a=b;}

//Code Begins Here ------ >>>

// Grab your asses fella's , because this code is gonna go deep into you :)

int main(){
	#ifdef LocalHost
		freopen("input.txt","r",stdin);
	#endif

	int a,b,i,pos,neg,ll,wl,val;
	long long res;
	cin >> a >> b;
	int n = min(a,b);
	if (!a) {
		cout << -SQR(b) << "\n";
		for (i = 0; i < b; i++) cout << "x";
		cout << "\n";
	}
	else if (!b) {
		cout << SQR(a) << "\n";
		for (i = 0; i < a; i++) cout << "o";
		cout << "\n";
	}
	else {
		res = -SQR(a+b);
		for (int ap = 1; ap <= n; ap++) {
			for (int bp = ap-1; bp <= ap+1; bp++) {
				if (1 <= bp && bp <= b) {
					pos = SQR(a - (ap-1)) + (ap - 1);
					neg = SQR(b/bp + 1)*(b%bp) + SQR(b/bp)*(b- (b%bp));
					if (res < pos-neg) {
						res = pos-neg;
						wl = ap, ll = bp;
					}
				}
			}
		}
		cout << res << "\n";
		if (wl >= ll) {
			for (int c = 0; c < wl; c++) {
				int val = (c > 0 ? 1 : (a - (wl-1)));
				for (i = 0; i < val; i++) cout << "o";
				val = (c >= (b%ll) ? (b/ll) : (b/ll + 1));
				if (c < ll) for (i = 0; i < val; i++) cout << "x";
				cout << "\n";
			}
		}
		else {
			for (int c = 0; c < ll; c++) {
				val = (c >= (b%ll) ? (b/ll) : (b/ll + 1));
				for (i = 0; i < val; i++) cout << "x";
				int val = (c > 0 ? 1 : (a - (wl-1)));
				if (c < wl) for (i = 0; i < val; i++) cout << "o";
				cout << "\n";
			}
		}
	}

	#ifdef LocalHost
    cout<<endl<<"Execution time = "<<(float)clock()/CLOCKS_PER_SEC <<" s"<<endl;
	#endif

	RE 0;
}


/**********************************************
			Author : smiley007
***********************************************/

//Data Structure Includes
#include <vector>
#include <queue>
#include <deque>
#include <bitset>
#include <stack>
#include <list>
#include <set>
#include <map>

//Other Includes
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cctype>
#include <cassert>
#include <numeric>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <climits>

using namespace std ;

//Defines
#define FOR(i,a,b)         	for(int i = (a); i <  (b) ; i++)
#define FOE(i,a,b)         	for(int i = (a); i <= (b) ; i++)
#define FOED(i,a,b)			for(int i = (a); i >= (b) ; i--)
#define ITR(v,it) 			for( typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define REP(i,n)			FOR(i,0,n)
#define ALL(a) 				a.begin(),a.end()
#define SORT(a) 			sort(ALL(a))
#define SZ(a)				((int)a.size())
#define SQR(x)				((x)*(x))
#define BS(i) 				__builtin_popcount(i)
#define LZ(i)				__clz
#define RE 					return
#define FI 					first
#define SD 					second
#define PB					push_back
#define MP(x,y)				make_pair(x,y)
#define SET(a,v)			memset(&a[0],v, sizeof(a[0])*SZ(a) )
#define POW2(i)				( 1LL << (i) )
//#define SET(a,i)			a |= POW2(i)
#define CLR(a,i)			a &= ~ POW2(i)
#define TOGGLE(a,i)			a ^= POW2(i)
#define TEST(a,i)			((a) & POW2(i))
#define EPS					1e-9
#define INF					1e9
#define PI 					3.141592653589793
#define MOD 				1000000007

//Typedefs
typedef long long ll ;
typedef pair<int,int> pii ;
typedef pair<string,string> pss ;
typedef vector<int> vi ;
typedef vector<ll> vl ;
typedef vector<vi> vvi ;
typedef vector<vl> vvl ;
typedef vector<bool> vb ;
typedef vector<vb> vvb ;
typedef vector<string> vs ;
typedef vector<pii> vpii ;

//Templates
//<< ----- Number Theory --- >>
template<class T> bool isPrime(T x){if(x<=1)RE false;T i;for(i=2;i*i<=x;i++)if(x%i==0)RE false;RE true;} //isPrime
template<class T> class Prime{public:vector<T> z ;Prime(){z.resize(1e5+7);REP(i,SZ(z)) z[i]=1;
z[0]=0;z[1]=0;T j;FOR(i,2,SZ(z)){if(z[i]){j=i+i;while(j<SZ(z)){ z[j]=0;j += i ;} } }} }; //Prime

//<< ----- Geometry -------- >>
template<class T> double dist(T x1,T y1,T x2,T y2){RE sqrt( 1.*(x2-x1)*(x2-x1) + 1.*(y2-y1)*(y2-y1) ) ;} //dist
template<class T> class Point{
    public :
    T x, y;
    Point(){}
    Point(T a,T b):x(a),y(b){}
    bool operator ==(const Point& tmp)const{ RE(x==tmp.x && y==tmp.y);}
    Point operator-(const Point& tmp) const{ RE Point<T> (x-tmp.x,y-tmp.y);}
};

//<<---- Conversions ------- >>
char toLowerCase(char x){RE(x+32);}
char toUpperCase(char x){RE(x-32);}
bool isUpperCase(char x){RE (65<=x && x<=90)? 1 : 0 ;}
bool isLowerCase(char x){RE (97<=x && x<=122)? 1 : 0 ;}
bool isAlpha(char x){RE (isUpperCase(x) || isLowerCase(x))? 1 : 0 ;}
bool isDigit(char x){RE('0'<=x && x<='9')? 1 : 0 ;}
template<class T> T toDec(string s){stringstream is(s);T res;is>>res;RE res;} //toDec
template<class T> string toStr(T n){string s;stringstream is;is<<n;is>>s;RE s;} //toStr

template<class T> void checkmin(T& a,T b){if(a>b)a=b;}
template<class T> void checkmax(T& a,T b){if(a<b)a=b;}

//Code Begins Here ------ >>>

// Grab your asses fella's , because this code is gonna go deep into you :)

int main(){
	#ifdef LocalHost
		freopen("input.txt","r",stdin);
	#endif

	int a,b;
	cin >> a >> b;
	ll ans = 0;
	if (a >= b) {
		ans = SQR(a) - SQR(b);
		cout << ans << "\n";
		for (i = 0; i < a; i++) cout << "o";
		for (i = 0; i < b; i++) cout << "x";
		cout << "\n";
	}
	else {
		int tot = 0;
		int len = b/(a+1);
		int rem = b - a*len;
		ans  = -a*SQR(len) - SQR(rem) + a;
		cout << ans << "\n";
		int it = a*(len+1);
		while (it--) {
			if (tot < len) {
				cout << "x";
				tot++;
			}
			else {
				cout << "o";
				tot = 0;
			}
		}
		while(rem--) cout << "x";
		cout << "\n";
	}

	#ifdef LocalHost
    cout<<endl<<"Execution time = "<<(float)clock()/CLOCKS_PER_SEC <<" s"<<endl;
	#endif

	RE 0;
}


/**********************************************
			Author : smiley007
***********************************************/

//Data Structure Includes
#include <vector>
#include <queue>
#include <deque>
#include <bitset>
#include <stack>
#include <list>
#include <set>
#include <map>

//Other Includes
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cctype>
#include <cassert>
#include <numeric>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <climits>

using namespace std ;

//Defines
#define FOR(i,a,b)         	for(int i = (a); i <  (b) ; i++)
#define FOE(i,a,b)         	for(int i = (a); i <= (b) ; i++)
#define FOED(i,a,b)			for(int i = (a); i >= (b) ; i--)
#define ITR(v,it) 			for( typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define REP(i,n)			FOR(i,0,n)
#define ALL(a) 				a.begin(),a.end()
#define SORT(a) 			sort(ALL(a))
#define SZ(a)				((int)a.size())
#define SQR(x)				((x)*(x))
#define BS(i) 				__builtin_popcount(i)
#define LZ(i)				__clz
#define RE 					return
#define FI 					first
#define SD 					second
#define PB					push_back
#define MP(x,y)				make_pair(x,y)
#define SET(a,v)			memset(&a[0],v, sizeof(a[0])*SZ(a) )
#define POW2(i)				( 1LL << (i) )
//#define SET(a,i)			a |= POW2(i)
#define CLR(a,i)			a &= ~ POW2(i)
#define TOGGLE(a,i)			a ^= POW2(i)
#define TEST(a,i)			((a) & POW2(i))
#define EPS					1e-9
#define INF					1e9
#define PI 					3.141592653589793
#define MOD 				1000000007

//Typedefs
typedef long long ll ;
typedef pair<int,int> pii ;
typedef pair<string,string> pss ;
typedef vector<int> vi ;
typedef vector<ll> vl ;
typedef vector<vi> vvi ;
typedef vector<vl> vvl ;
typedef vector<bool> vb ;
typedef vector<vb> vvb ;
typedef vector<string> vs ;
typedef vector<pii> vpii ;

//Templates
//<< ----- Number Theory --- >>
template<class T> bool isPrime(T x){if(x<=1)RE false;T i;for(i=2;i*i<=x;i++)if(x%i==0)RE false;RE true;} //isPrime
template<class T> class Prime{public:vector<T> z ;Prime(){z.resize(1e5+7);REP(i,SZ(z)) z[i]=1;
z[0]=0;z[1]=0;T j;FOR(i,2,SZ(z)){if(z[i]){j=i+i;while(j<SZ(z)){ z[j]=0;j += i ;} } }} }; //Prime

//<< ----- Geometry -------- >>
template<class T> double dist(T x1,T y1,T x2,T y2){RE sqrt( 1.*(x2-x1)*(x2-x1) + 1.*(y2-y1)*(y2-y1) ) ;} //dist
template<class T> class Point{
    public :
    T x, y;
    Point(){}
    Point(T a,T b):x(a),y(b){}
    bool operator ==(const Point& tmp)const{ RE(x==tmp.x && y==tmp.y);}
    Point operator-(const Point& tmp) const{ RE Point<T> (x-tmp.x,y-tmp.y);}
};

//<<---- Conversions ------- >>
char toLowerCase(char x){RE(x+32);}
char toUpperCase(char x){RE(x-32);}
bool isUpperCase(char x){RE (65<=x && x<=90)? 1 : 0 ;}
bool isLowerCase(char x){RE (97<=x && x<=122)? 1 : 0 ;}
bool isAlpha(char x){RE (isUpperCase(x) || isLowerCase(x))? 1 : 0 ;}
bool isDigit(char x){RE('0'<=x && x<='9')? 1 : 0 ;}
template<class T> T toDec(string s){stringstream is(s);T res;is>>res;RE res;} //toDec
template<class T> string toStr(T n){string s;stringstream is;is<<n;is>>s;RE s;} //toStr

template<class T> void checkmin(T& a,T b){if(a>b)a=b;}
template<class T> void checkmax(T& a,T b){if(a<b)a=b;}

//Code Begins Here ------ >>>

// Grab your asses fella's , because this code is gonna go deep into you :)

int main(){
	#ifdef LocalHost
		freopen("input.txt","r",stdin);
	#endif

	int a,b,i,pos,neg,ll,wl,val;
	long long res;
	cin >> a >> b;
	int n = min(a,b);
	if (!a) {
		cout << -SQR(b) << "\n";
		for (i = 0; i < b; i++) cout << "x";
		cout << "\n";
	}
	else if (!b) {
		cout << SQR(a) << "\n";
		for (i = 0; i < a; i++) cout << "o";
		cout << "\n";
	}
	else {
		res = -SQR(a+b);
		for (int ap = 1; ap <= n; ap++) {
			for (int bp = ap-1; bp <= ap+1; bp++) {
				if (1 <= bp && bp <= b) {
					pos = SQR(a - (ap-1)) + (ap - 1);
					neg = SQR(b/bp + 1)*(b%bp) + SQR(b/bp)*(b- (b%bp));
					if (res < pos-neg) {
						res = pos-neg;
						wl = ap, ll = bp;
					}
				}
			}
		}
		cout << res << "\n";
		if (wl >= ll) {
			for (int c = 0; c < wl; c++) {
				int val = (c > 0 ? 1 : (a - (wl-1)));
				for (i = 0; i < val; i++) cout << "o";
				val = (c >= (b%ll) ? (b/ll) : (b/ll + 1));
				if (c < ll) for (i = 0; i < val; i++) cout << "x";
			}
			cout << "\n";
		}
		else {
			for (int c = 0; c < ll; c++) {
				val = (c >= (b%ll) ? (b/ll) : (b/ll + 1));
				for (i = 0; i < val; i++) cout << "x";
				int val = (c > 0 ? 1 : (a - (wl-1)));
				if (c < wl) for (i = 0; i < val; i++) cout << "o";
			}
			cout << "\n";
		}
	}

	#ifdef LocalHost
    cout<<endl<<"Execution time = "<<(float)clock()/CLOCKS_PER_SEC <<" s"<<endl;
	#endif

	RE 0;
}