stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define Would

#define you

#define please



const int cm = 1 << 17;

char cn[cm], * ci = cn + cm, ct;

inline char getcha() {

	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}

inline int getint() {

	int A = 0;

	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';

	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';

	return A;

}



pair<int, int> E[100001];

int H[100001];

int memo[100001];

int sagasu(int A) {

	if (memo[A]) return memo[A];

	vector<int> kari;

	for (int i = H[A]; i; i = E[i].second) kari.pb(sagasu(E[i].first));

	sort(kari.begin(), kari.end(), greater<int>());

	int ret = 1;

	rep(i, kari.size()) ret = max(ret, i + kari[i] + 1);

	return memo[A] = ret;

}



int main() {

	cin.tie(0);

	ios::sync_with_stdio(false);





	int N = getint();



	for (int i = 2; i <= N; i++) {

		int a = getint();

		E[i] = mp(i, H[a]);

		H[a] = i;

	}



	co(sagasu(1) - 1);



	Would you please return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.387363328745437x):
#pragma GCC optimize ("O3")

//#pragma GCC target ("avx")

//#include<bits/stdc++.h>

#include<cstdio>

#include<algorithm>

#include<functional>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define chmin(x, y) x = min(x, y)

#define chmax(x, y) x = max(x, y)

#define Would

#define you

#define please



const int cm = 1 << 17;

char cn[cm], * ci = cn + cm, ct;

inline char getcha() {

	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}

inline int getint() {

	int A = 0;

	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';

	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';

	return A;

}

pair<int, int> E[100001];

int H[100001];

int n[100001], kari[100001];

int sagasu(int A) {

	if (n[A] == n[A - 1]) return 0;

	if (n[A] == n[A - 1] + 1) {

		return sagasu(E[H[A]].first) + 1;

	}

	int k = n[A - 1];

	for (int i = H[A]; i; i = E[i].second) {

		kari[k++] = sagasu(E[i].first);

	}

	sort(kari + n[A - 1], kari + n[A], greater<int>());

	int ret = 0;

	for (int i = 0; i < n[A] - n[A - 1]; i++) ret = max(ret, kari[n[A - 1] + i] + i);

	return ret + 1;

}



int main() {

	//cin.tie(0);

	//ios::sync_with_stdio(false);





	int N = getint();



	for (int i = 2; i <= N; i++) {

		int a = getint();

		n[a]++;

		E[i] = mp(i, H[a]);

		H[a] = i;

	}

	rep1(i, N) n[i] = n[i - 1] + n[i];



	printf("%d\n", sagasu(1));



	Would you please return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define Would

#define you

#define please



const int cm = 1 << 17;

char cn[cm], * ci = cn + cm, ct;

inline char getcha() {

	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}

inline int getint() {

	int A = 0;

	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';

	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';

	return A;

}



pair<int, int> E[100001];

int H[100001];

int sagasu(int A) {

	vector<int> kari;

	for (int i = H[A]; i; i = E[i].second) kari.pb(sagasu(E[i].first));

	sort(kari.begin(), kari.end(), greater<int>());

	int ret = 0;

	rep(i, kari.size()) ret = max(ret, i + kari[i] + 1);

	return ret;

}



int main() {

	cin.tie(0);

	ios::sync_with_stdio(false);





	int N = getint();



	for (int i = 2; i <= N; i++) {

		int a = getint();

		E[i] = mp(i, H[a]);

		H[a] = i;

	}



	co(sagasu(1));



	Would you please return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.428240659631474x):
#pragma GCC optimize ("O3")

//#pragma GCC target ("avx")

//#include<bits/stdc++.h>

#include<cstdio>

#include<algorithm>

#include<functional>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define chmin(x, y) x = min(x, y)

#define chmax(x, y) x = max(x, y)

#define Would

#define you

#define please



const int cm = 1 << 17;

char cn[cm], * ci = cn + cm, ct;

inline char getcha() {

	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}

inline int getint() {

	int A = 0;

	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';

	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';

	return A;

}

pair<int, int> E[100001];

int H[100001];

int n[100001], kari[100001];

int sagasu(int A) {

	if (n[A] == n[A - 1]) return 0;

	if (n[A] == n[A - 1] + 1) {

		return sagasu(E[H[A]].first) + 1;

	}

	int k = n[A - 1];

	for (int i = H[A]; i; i = E[i].second) {

		kari[k++] = sagasu(E[i].first);

	}

	sort(kari + n[A - 1], kari + n[A], greater<int>());

	int ret = 0;

	for (int i = 0; i < n[A] - n[A - 1]; i++) ret = max(ret, kari[n[A - 1] + i] + i);

	return ret + 1;

}



int main() {

	//cin.tie(0);

	//ios::sync_with_stdio(false);





	int N = getint();



	for (int i = 2; i <= N; i++) {

		int a = getint();

		n[a]++;

		E[i] = mp(i, H[a]);

		H[a] = i;

	}

	rep1(i, N) n[i] = n[i - 1] + n[i];



	printf("%d\n", sagasu(1));



	Would you please return 0;

}
// Slower C++ solution:
#include <set>

#include <map>

#include <queue>

#include <ctime>

#include <cmath>

#include <cstdio>

#include <vector>

#include <string>

#include <cctype>

#include <bitset>

#include <cstring>

#include <cstdlib>

#include <utility>

#include <iostream>

#include <algorithm>

#define REP(i,a,b) for(int i=(a);i<=(b);i++)

#define PER(i,a,b) for(int i=(a);i>=(b);i--)

#define RVC(i,S) for(int i=0;i<(S).size();i++)

#define RAL(i,u) for(int i=fr[u];i!=-1;i=e[i].next)

using namespace std;

typedef long long LL;

typedef pair<int,int> pii;

     

template<class T> inline

void read(T& num) {

    bool start=false,neg=false;

    char c;

    num=0;

    while((c=getchar())!=EOF) {

        if(c=='-') start=neg=true;

        else if(c>='0' && c<='9') {

            start=true;

            num=num*10+c-'0';

        } else if(start) break;

    }

    if(neg) num=-num;

}

/*============ Header Template ============*/



struct edge {

    int next,to;

};



const int maxn=(int)(2e5)+5;

int fr[maxn];

int f[maxn];

vector<int> vi[maxn];

edge e[maxn<<1];

int tote=0;



inline void addone(int u,int v) {

    ++tote;

    e[tote].next=fr[u];fr[u]=tote;e[tote].to=v;

}



inline void addedge(int u,int v) {

    addone(u,v);addone(v,u);

}



void dfs(int x,int fa) {

    RAL(i,x) if(e[i].to!=fa) {

        dfs(e[i].to,x);

        vi[x].push_back(f[e[i].to]);

    }

    sort(vi[x].begin(),vi[x].end());

    for(int j=0;j<vi[x].size();j++) f[x]=max(f[x],vi[x][j])+1;

}



int main() {

    int n;

    read(n);

    memset(fr,-1,sizeof(fr));

    REP(i,2,n) {

        int x;

        read(x);

        addedge(x,i);

    }

    dfs(1,0);

    printf("%d\n",f[1]);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.15565638585251x):
#include <bits/stdc++.h>

using namespace std;



const int maxn = (int)(1e5) + 5;

vector<int> nxt[maxn], val[maxn];

int f[maxn];



void dfs(int x) {

	for (int i = 0; i < (int)nxt[x].size(); ++i) {

		dfs(nxt[x][i]); val[x].push_back(f[nxt[x][i]]);

	} f[x] = val[x].size();

	sort(val[x].begin(), val[x].end(), greater<int>()); int now = 0;

	for (int i = 0; i < (int)val[x].size(); ++i) f[x] = max(f[x], val[x][i] + now + 1), ++now;

}



int main() {

	int n;

	scanf("%d", &n);

	for (int i = 2; i <= n; ++i) {

		int x; scanf("%d", &x);

		nxt[x].push_back(i);

	}

	dfs(1);

	return printf("%d\n", f[1]), 0;

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <string>

#include <vector>

#include <math.h>

#define MOD 1000000007

typedef long long ll;

using namespace std;



vector<int> v[100010];

int n;

int h=0;



int dfs(int x){



  int ma=0;

  vector<int> d;

  for(int i=0;i<v[x].size();i++){

    int tmp=dfs(v[x][i]);

    d.push_back(tmp);

  }

  sort(d.begin(),d.end());

  reverse(d.begin(),d.end());

  for(int i=0;i<d.size();i++){

    ma=max(ma,d[i]+i+1);

  }

  //cout<<x<<" "<<ma<<endl;

  return ma;

}



int main(){

  //int n;

  cin>>n;

  //vector<int> v[n+1];



  for(int i=2;i<=n;i++){

    int a;

    cin>>a;

    v[a].push_back(i);

  }



  cout<<dfs(1)<<endl;

  return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.492049585414107x):
#include <iostream>

#include <algorithm>

#include <string>

#include <vector>

#include <cmath>

#include <map>

#include <queue>

#include <iomanip>

#include <set>

#include <tuple>

#define mkp make_pair

#define mkt make_tuple

#define rep(i,n) for(int i = 0; i < (n); ++i)

using namespace std;

typedef long long ll;

const ll MOD=1e9+7;



int N;

vector<int> A;



vector<vector<int>> lose;



int dfs(int now){

    int depth=0;

    vector<int> v;

    for(auto nex:lose[now]){

        int val=dfs(nex);

        v.push_back(val);

    }

    sort(v.begin(),v.end());

    reverse(v.begin(),v.end());

    for(int i=0;i<v.size();i++) depth=max(depth,v[i]+i+1);

    return depth;

}



int main(){

  cin>>N;

  A.resize(N+1,0);

  for(int i=2;i<=N;i++) cin>>A[i];



  lose.resize(N+1);

  for(int i=2;i<=N;i++){

      lose[A[i]].push_back(i);

  }



  cout<<dfs(1)<<endl;



  return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>



using namespace std;

using namespace __gnu_pbds;



#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define fbo find_by_order

#define ook order_of_key

#define INF 1e9



typedef long long ll;

typedef pair<ll,ll> ii;

typedef vector<int> vi;

typedef vector < pair<int, int> > vii;

typedef long double ld;

typedef tree<pair<int,int>, null_type, less<pair<int,int> >, rb_tree_tag, tree_order_statistics_node_update> pbds;

typedef set<int>::iterator sit;

typedef map<int,int>::iterator mit;

typedef vector<int>::iterator vit;



ll n, x, par[100001], siz[100001], ans, cnt, dp[100001];

priority_queue<int, vector<int> > pq[100001];

queue <int> q;



int main()

{

	ios_base::sync_with_stdio(false);

	cin.tie(NULL);

	cin >> n;

	for(int i = 2; i <= n; i++){

		cin >> par[i];

		siz[par[i]]++;

	}

	for(int i = 2; i <= n; i++){

		if(siz[i]==0){

			q.push(i);

		}

	}

	while(!q.empty()){

		x=q.front();

		q.pop();

		cnt=1;

		while(!pq[x].empty()){

			dp[x]=max(dp[x],pq[x].top()+cnt);

			cnt++;

			pq[x].pop();

		}

		pq[par[x]].push(dp[x]);

		siz[par[x]]--;

		if(siz[par[x]]==0 && x!=1){

			q.push(par[x]);

		}

	}

	cout << dp[1];

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.2675211533240465x):
#include<cstdio>

#include<map>

#include<algorithm>

#include<vector>

using namespace std;

#define MAXN 100005

int n,t[MAXN];

vector<int> G[MAXN];

void dfs(int u,int f)

{

	map<int,int> cnt;

	for(int i=0;i<G[u].size();i++)

	{

		int v=G[u][i];

		if(v==f) continue;

		dfs(v,u);

		cnt[t[v]]++;

	}

	map<int,int>::iterator it;

	for(it=cnt.begin();it!=cnt.end();it++)

	{

		if(it->second>1)

			cnt[(it->first)+1]+=it->second-1;

	}

	//父亲每个时刻只能找一个儿子打 剩下的儿子要推到后面

	if(it!=cnt.begin())//表示有儿子，进去过循环

		it--,t[u]=it->first+1;

}

int main()

{

	scanf("%d",&n);

	for(int i=2;i<=n;i++)

	{

		int x;

		scanf("%d",&x);

		G[i].push_back(x);

		G[x].push_back(i);

	}

	dfs(1,0);

	printf("%d\n",t[1]);

}
// Slower C++ solution:
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>



using namespace std;

using namespace __gnu_pbds;



#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define fbo find_by_order

#define ook order_of_key

#define INF 1e9



typedef long long ll;

typedef pair<ll,ll> ii;

typedef vector<int> vi;

typedef vector < pair<int, int> > vii;

typedef long double ld;

typedef tree<pair<int,int>, null_type, less<pair<int,int> >, rb_tree_tag, tree_order_statistics_node_update> pbds;

typedef set<int>::iterator sit;

typedef map<int,int>::iterator mit;

typedef vector<int>::iterator vit;



ll n, x, par[100001], siz[100001], ans, cnt, dp[100001];

priority_queue<int, vector<int> > pq[100001];

queue <int> q;



int main()

{

	ios_base::sync_with_stdio(false);

	cin.tie(NULL);

	cin >> n;

	for(int i = 2; i <= n; i++){

		cin >> par[i];

		siz[par[i]]++;

	}

	for(int i = 2; i <= n; i++){

		if(siz[i]==0){

			q.push(i);

		}

	}

	while(!q.empty()){

		x=q.front();

		q.pop();

		cnt=1;

		while(!pq[x].empty()){

			dp[x]=max(dp[x],pq[x].top()+cnt);

			cnt++;

			pq[x].pop();

		}

		pq[par[x]].push(dp[x]);

		siz[par[x]]--;

		if(siz[par[x]]==0 && x!=1){

			q.push(par[x]);

		}

	}

	cout << dp[1];

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.2444772832877775x):
#include <bits/stdc++.h>

using namespace std;

const int maxn=100005;

int n,dp[maxn],head[maxn],cnt;

struct edge{int to,next;

}e[maxn<<1];

vector<int>vec[maxn];

bool cmp(const int &a,const int &b)

{

	return dp[a]>dp[b];

}

void add(int x,int y)

{

	e[cnt].to=y;

	e[cnt].next=head[x];

	head[x]=cnt++;

}

void dfs(int u,int pre)

{

	for(int i=head[u];i;i=e[i].next)

	{

		if(e[i].to==pre)continue;

		dfs(e[i].to,u);

	}

	if(vec[u].size())

	{

	  int now=1;

		sort(vec[u].begin(),vec[u].end(),cmp);

		for(int i=0;i<vec[u].size();++i)

		{

			dp[u]=max(dp[u],dp[vec[u][i]]+now);now++;

		}

	}

}

int main()

{

	cnt=1;

	scanf("%d",&n);

	for(int i=2;i<=n;++i)

	{

		int x;scanf("%d",&x);

		add(x,i);add(i,x);vec[x].push_back(i);

	}

	dfs(1,0);

	printf("%d\n",dp[1]);

}
// Slower C++ solution:
#include<iostream>

#include<algorithm>

using namespace std;

#define INF (1<<24)

int N;

int t[500],sum[500];

int dp[500][500];

 

int calc(int X,int Y){

 

  int res=0,c=-1,a,b;

  for(int I=0;I<50;I++){

 

    if(c==-1||c+a+b<10)c=0;

    else c=1;

    a=X%10;

    b=Y%10;

    X/=10;

    Y/=10;

    res+=(a*b+c);

  }

 

  return res;

}

int solve(int l,int r){

 

  if(dp[l][r]!=-1)return dp[l][r];

  if(l==r)return 0;

  int res=INF;

  for(int i=l;i<r;i++){

    

    res=min(res, solve(l,i)+solve(i+1,r)+calc(sum[i]-sum[l-1],sum[r]-sum[i]));

  }

 

  return dp[l][r]=res;

}

 

void init(){

  for(int i=0;i<500;i++){

    t[i]=sum[i]=0;

    for(int j=0;j<500;j++)dp[i][j]=-1;

  }

}

 

int main(){

  init();

  cin>>N;

  for(int i=1;i<=N;i++){

    cin>>t[i];

    sum[i]=t[i]+sum[i-1];

  }

 

  cout<<solve(1,N)<<endl;

  return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.465890343189597x):
#include<bits/stdc++.h>

using namespace std;



int N;

int a[305],b[305];

int dp[305][305];

int sum[305][305];



int calc(int x,int y){

  int res=0,c=0;



  while(x>0||y>0){

    int px=x%10,py=y%10;

    res+=( px*py + c );

    if(px+py+c<10)c=0;

    else c=1;

    x/=10;

    y/=10;

  }



  return res+c;

}



int solve(int l,int r){

  if(dp[l][r]!=-1)return dp[l][r];

  if(l==r)return 0;

  

  int res=1e8;

  for(int i=l;i<r;i++){

    res=min(res,solve(l,i)+solve(i+1,r)+calc(b[i]-b[l-1],b[r]-b[i]));

  }

  

  return dp[l][r]=res;

}



int main(){

  memset(dp,-1,sizeof(dp));

  cin>>N;

  for(int i=1;i<=N;i++){

    cin>>a[i];

    b[i]=a[i]+b[i-1];

  }





  cout<<solve(1,N)<<endl;

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

using namespace std;



double mysqrt(double x){

	double l = 0 , r = x ;

	for(int i = 0 ; i < 64 ; i++){

		double m = (l+r)/2.0;

		if(m * m < x){

			l = m;

		}else{

			r = m;

		}

	}

	return l;

}





int main(){

	int p,n;

	while(cin >> p >> n , n){

		double sp = mysqrt(p);

		int a1 = 0 , b1 = 1 , a2 = p , b2 = 1;

		

		for(int i = 1 ; i <= n ; i++){

		

			int l = 0 , r = n;

			

			for(int x = 0 ; x < 50 ; x++){

				int m = (l+r+1)/2;

				if( (double)m/i < sp){

					if(__gcd(m,i)==1){

						if(m*b1 > a1*i){

							a1 = m;

							b1 = i;

						}

					}

					l = m;

				}else{

					r = m-1;

				}

			}

	

			l = 0 , r = n;

			for(int x = 0 ; x < 50 ; x++){

				int m = (l+r)/2;

				if( (double)m/i > sp){

					if(__gcd(m,i)==1){

						if(m*b2 < a2*i){

							a2 = m;

							b2 = i;

						}

					}

					r = m;

				}else{

					l = m+1;

				}

			}

			

		}



		cout << a2<< "/" << b2 << " " << a1 << "/" << b1 << endl;

	}

}

// Faster C++ solution for the same problem (measured speedup: 1.1524363464471739x):
#include <iostream>

#include <algorithm>

using namespace std;



double mysqrt(double x){

	double l = 0 , r = x ;

	for(int i = 0 ; i < 64 ; i++){

		double m = (l+r)/2.0;

		if(m * m < x){

			l = m;

		}else{

			r = m;

		}

	}

	return l;

}





int main(){

	int p,n;

	while(cin >> p >> n , n){

		double sp = mysqrt(p);

		int a1 = 0 , b1 = 1 , a2 = p , b2 = 1;

		

		for(int i = 1 ; i <= n ; i++){

		

			int l = 0 , r = n;

			

			for(int x = 0 ; x < 14 ; x++){

				int m = (l+r+1)/2;

				if( (double)m/i < sp){

					if(__gcd(m,i)==1){

						if(m*b1 > a1*i){

							a1 = m;

							b1 = i;

						}

					}

					l = m;

				}else{

					r = m-1;

				}

			}

	

			l = 0 , r = n;

			for(int x = 0 ; x < 14 ; x++){

				int m = (l+r)/2;

				if( (double)m/i > sp){

					if(__gcd(m,i)==1){

						if(m*b2 < a2*i){

							a2 = m;

							b2 = i;

						}

					}

					r = m;

				}else{

					l = m+1;

				}

			}

			

		}



		cout << a2<< "/" << b2 << " " << a1 << "/" << b1 << endl;

	}

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

using namespace std;



double mysqrt(double x){

	double l = 0 , r = x ;

	for(int i = 0 ; i < 64 ; i++){

		double m = (l+r)/2.0;

		if(m * m < x){

			l = m;

		}else{

			r = m;

		}

	}

	return l;

}





int main(){

	int p,n;

	while(cin >> p >> n , n){

		double sp = mysqrt(p);

		int a1 = 0 , b1 = 1 , a2 = p , b2 = 1;

		

		for(int i = 1 ; i <= n ; i++){

		

			int l = 0 , r = n;

			

			for(int x = 0 ; x < 50 ; x++){

				int m = (l+r+1)/2;

				if( (double)m/i < sp){

					if(__gcd(m,i)==1){

						if(m*b1 > a1*i){

							a1 = m;

							b1 = i;

						}

					}

					l = m;

				}else{

					r = m-1;

				}

			}

	

			l = 0 , r = n;

			for(int x = 0 ; x < 50 ; x++){

				int m = (l+r)/2;

				if( (double)m/i > sp){

					if(__gcd(m,i)==1){

						if(m*b2 < a2*i){

							a2 = m;

							b2 = i;

						}

					}

					r = m;

				}else{

					l = m+1;

				}

			}

			

		}



		cout << a2<< "/" << b2 << " " << a1 << "/" << b1 << endl;

	}

}

// Faster C++ solution for the same problem (measured speedup: 1.209303324741746x):
#include <iostream>

#include <algorithm>

using namespace std;



double mysqrt(double x){

	double l = 0 , r = x ;

	for(int i = 0 ; i < 64 ; i++){

		double m = (l+r)/2.0;

		if(m * m < x){

			l = m;

		}else{

			r = m;

		}

	}

	return l;

}





int main(){

	int p,n;

	while(cin >> p >> n , n){

		double sp = mysqrt(p);

		int a1 = 0 , b1 = 1 , a2 = p , b2 = 1;

		

		for(int i = 1 ; i <= n ; i++){

			int o = (int)(sp * i);

			for(int j = -2 ; j <= 2 ; j++){

				int w = o + j;

				if(__gcd(i,w) == 1 && w >= 0 && w <= n){

					if( (double)w/i < sp &&  a1*i < w*b1){

						a1 = w;

						b1 = i;

					}

					if((double)w/i > sp && a2*i > w*b2){

						a2 = w;

						b2 = i;

					}

				}

			}

		}



		cout << a2<< "/" << b2 << " " << a1 << "/" << b1 << endl;

	}

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

using namespace std;



double mysqrt(double x){

	double l = 0 , r = x ;

	for(int i = 0 ; i < 64 ; i++){

		double m = (l+r)/2.0;

		if(m * m < x){

			l = m;

		}else{

			r = m;

		}

	}

	return l;

}





int main(){

	int p,n;

	while(cin >> p >> n , n){

		double sp = mysqrt(p);

		int a1 = 0 , b1 = 1 , a2 = p , b2 = 1;

		

		for(int i = 1 ; i <= n ; i++){

		

			int l = 0 , r = n;

			

			for(int x = 0 ; x < 50 ; x++){

				int m = (l+r+1)/2;

				if( (double)m/i < sp){

					if(__gcd(m,i)==1){

						if(m*b1 > a1*i){

							a1 = m;

							b1 = i;

						}

					}

					l = m;

				}else{

					r = m-1;

				}

			}

	

			l = 0 , r = n;

			for(int x = 0 ; x < 50 ; x++){

				int m = (l+r)/2;

				if( (double)m/i > sp){

					if(__gcd(m,i)==1){

						if(m*b2 < a2*i){

							a2 = m;

							b2 = i;

						}

					}

					r = m;

				}else{

					l = m+1;

				}

			}

			

		}



		cout << a2<< "/" << b2 << " " << a1 << "/" << b1 << endl;

	}

}

// Faster C++ solution for the same problem (measured speedup: 1.225019058782376x):
#include <iostream>

#include <algorithm>

using namespace std;



double mysqrt(double x){

	double l = 0 , r = x ;

	for(int i = 0 ; i < 64 ; i++){

		double m = (l+r)/2.0;

		if(m * m < x){

			l = m;

		}else{

			r = m;

		}

	}

	return l;

}





int main(){

	int p,n;

	while(cin >> p >> n , n){

		double sp = mysqrt(p);

		int a1 = 0 , b1 = 1 , a2 = p , b2 = 1;

		

		for(int i = 1 ; i <= n ; i++){

			int o = (int)(sp * i);

			for(int j = 0 ; j <= 1 ; j++){

				int w = o + j;

				if(__gcd(i,w) == 1 && w >= 0 && w <= n){

					if( (double)w/i < sp &&  a1*i < w*b1){

						a1 = w;

						b1 = i;

					}

					if((double)w/i > sp && a2*i > w*b2){

						a2 = w;

						b2 = i;

					}

				}

			}

		}



		cout << a2<< "/" << b2 << " " << a1 << "/" << b1 << endl;

	}

}