Problem:
Problem A:
Rational Irrationals
Rational numbers are numbers represented by ratios of two integers. For a prime number
p
, one of the elementary theorems in the number theory is that there is no rational number equal to √
p
. Such numbers are called irrational numbers. It is also known that there are rational numbers arbitrarily close to √
p
Now, given a positive integer
n
, we define a set
Q
n
of all rational numbers whose elements are represented by ratios of two positive integers both of which are less than or equal to
n
. For example,
Q
4
is a set of 11 rational numbers {1/1, 1/2, 1/3, 1/4, 2/1, 2/3, 3/1, 3/2, 3/4, 4/1, 4/3}. 2/2, 2/4, 3/3, 4/2 and 4/4 are not included here because they are equal to 1/1, 1/2, 1/1, 2/1 and 1/1, respectively.
Your job is to write a program that reads two integers
p
and
n
and reports two rational numbers
x / y
and
u / v
, where
u / v
< √
p
<
x / y
and there are no other elements of
Q
n
between
u/v
and
x/y
. When
n
is greater than √
p
, such a pair of rational numbers always exists.
Input
The input consists of lines each of which contains two positive integers, a prime number
p
and an integer
n
in the following format.
p n
They are separated by a space character. You can assume that
p
and
n
are less than 10000, and that
n
is greater than √
p
. The end of the input is indicated by a line consisting of two zeros.
Output
For each input line, your program should output a line consisting of the two rational numbers
x / y
and
u / v
(
x / y
>
u / v
) separated by a space character in the following format.
x/y u/v
They should be irreducible. For example, 6/14 and 15/3 are not accepted. They should be reduced to 3/7 and 5/1, respectively.
Sample Input
2 5
3 10
5 100
0 0
Output for the Sample Input
3/2 4/3
7/4 5/3
85/38 38/17

Submitted solutions:

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

using namespace std;

#define overload4(_1, _2, _3, _4, name, ...) name
#define rep1(n) for(int i = 0; i < (int)(n); ++i)
#define rep2(i, n) for(int i = 0; i < (int)(n); ++i)
#define rep3(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep4(i, a, b, c) for(int i = (a); i < (int)(b); i += (c))
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)

#define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; --i)
#define ALL(a) (a).begin(), (a).end()
#define Sort(a) (sort((a).begin(), (a).end()))
#define RSort(a) (sort((a).rbegin(), (a).rend()))
#define UNIQUE(a) (a.erase(unique((a).begin(), (a).end()), (a).end()))

typedef long long int ll;
typedef unsigned long long ul;
typedef long double ld;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef vector<char> vc;
typedef vector<string> vst;
typedef vector<double> vd;
typedef vector<long double> vld;
typedef pair<long long, long long> P;

template<class T> long long sum(const T& a){ return accumulate(a.begin(), a.end(), 0LL); }
template<class T> auto min(const T& a){ return *min_element(a.begin(), a.end()); }
template<class T> auto max(const T& a){ return *max_element(a.begin(), a.end()); }

const long long MINF = 0x7fffffffffff;
const long long INF = 0x1fffffffffffffff;
const long long MOD = 998244353;
const long double EPS = 1e-9;
const long double PI = acos(-1);
 
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template<typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &p){ is >> p.first >> p.second; return is; }
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p){ os << "(" << p.first << ", " << p.second << ")"; return os; }
template<typename T> istream &operator>>(istream &is, vector<T> &v){ for(T &in : v) is >> in; return is; }
template<typename T> ostream &operator<<(ostream &os, const vector<T> &v){ for(int i = 0; i < (int) v.size(); ++i){ os << v[i] << (i + 1 != (int) v.size() ? " " : ""); } return os; }
template <typename T, typename S> ostream &operator<<(ostream &os, const map<T, S> &mp){ for(auto &[key, val] : mp){ os << key << ":" << val << " "; } return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &st){ auto itr = st.begin(); for(int i = 0; i < (int)st.size(); ++i){ os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &st){ auto itr = st.begin(); for(int i = 0; i < (int)st.size(); ++i){ os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; }
template <typename T> ostream &operator<<(ostream &os, queue<T> q){ while(q.size()){ os << q.front() << " "; q.pop(); } return os; }
template <typename T> ostream &operator<<(ostream &os, deque<T> q){ while(q.size()){ os << q.front() << " "; q.pop_front(); } return os; }
template <typename T> ostream &operator<<(ostream &os, stack<T> st){ while(st.size()){ os << st.top() << " "; st.pop(); } return os; }
template <class T, class Container, class Compare> ostream &operator<<(ostream &os, priority_queue<T, Container, Compare> pq){ while(pq.size()){ os << pq.top() << " "; pq.pop(); } return os; }

template<class T, class U> inline T vin(T& vec, U n) { vec.resize(n); for(int i = 0; i < (int) n; ++i) cin >> vec[i]; return vec; }
template<class T> inline void vout(T vec, string s = "\n"){ for(auto x : vec) cout << x << s; }
template<class... T> void in(T&... a){ (cin >> ... >> a); }
void out(){ cout << '\n'; }
template<class T, class... Ts> void out(const T& a, const Ts&... b){ cout << a; (cout << ... << (cout << ' ', b)); cout << '\n'; }
template<class T, class U> void inGraph(vector<vector<T>>& G, U n, U m, bool directed = false){ G.resize(n); for(int i = 0; i < m; ++i){ int a, b; cin >> a >> b; a--, b--; G[a].push_back(b); if(!directed) G[b].push_back(a); } }

template <long long base = 1000000LL, int digit = 6>
struct BigInt{
    int sign = 1;
    vector<long long> val;

    constexpr BigInt(const long long _val = 0) noexcept {
        if(_val != 0){
            val.assign(1, abs(_val));
            shift();
        }
        if(_val < 0) sign = -1;
    }
    constexpr BigInt(const vector<long long> &_val) noexcept : val(_val) {}
    constexpr BigInt(const string &s) noexcept {
        stoi(s);
    }

private:
    void normalize(){
        while(!val.empty() && val.back() == 0) val.pop_back();
        if(val.empty()) sign = 1;
    }
    vector<long long> karatsuba_algorithm(vector<long long> &a, vector<long long> &b){
        const int n = (int) a.size();
        const int h = n >> 1;
        assert(a.size() == b.size());
        assert((n & (n - 1)) == 0);
        if(n <= 64){
            vector<long long> res(2 * n - 1);
            for(int i = 0; i < n; ++i){
                for(int j = 0; j < n; ++j){
                    res[i + j] += a[i] * b[j];
                }
            }
            return res;
        }
        vector<long long> p(h), q(h), r(h), s(h), t(h), u(h);
        for(int i = 0; i < h; ++i){
            p[i] = a[i + h];
            q[i] = a[i];
            r[i] = b[i + h];
            s[i] = b[i];
            t[i] = p[i] + q[i];
            u[i] = r[i] + s[i];
        }
        p = karatsuba_algorithm(p, r);
        q = karatsuba_algorithm(q, s);
        t = karatsuba_algorithm(t, u);
        vector<long long> res(2 * n - 1, 0);
        for(int i = 0; i < n - 1; ++i){
            res[i] += q[i];
            res[i + h] += t[i] - p[i] - q[i];
            res[i + n] += p[i];
        }
        return res;
    }

    pair<BigInt, BigInt> divide_naive(const BigInt& rhs) const {
        assert(!rhs.val.empty());
        const int k = base / (rhs.val.back() + 1);
        const BigInt dividend = (sign == 1 ? *this : -(*this)) * k;
        const BigInt divisor = (rhs.sign == 1 ? rhs : -rhs) * k;
        BigInt quo, rem = 0;
        quo.val.resize(dividend.val.size());
        const int n = divisor.val.size();
        for(int i = (int) dividend.val.size() - 1; i >= 0; --i){
            rem.val.emplace(rem.val.begin(), dividend.val[i]);
            quo.val[i] = ((n < (int) rem.val.size() ? rem.val[n] * base : 0) + ((n - 1) < (int) rem.val.size() ? rem.val[n - 1] : 0)) / divisor.val.back();
            rem -= divisor * quo.val[i];
            while (rem.sign == -1) {
                rem += divisor;
                --quo.val[i];
            }
        }
        quo.sign = sign * rhs.sign;
        quo.normalize();
        rem.sign = sign;
        rem.normalize();
        return {quo, rem / k};
    }

    pair<BigInt, BigInt> divide_newton(const BigInt& rhs) const {
        assert(!rhs.val.empty());
        int preci = val.size() - rhs.val.size();
        BigInt t(1);
        BigInt two = BigInt(2) << rhs.val.size();
        BigInt pre;
        int lim = min(preci, 3);
        int rhslim = min(int(rhs.val.size()), 6);
        t <<= lim;
        while(pre != t){
            BigInt rb = rhs >> (rhs.val.size() - rhslim);
            if(rhslim != (int) rhs.val.size()) rb += BigInt(1);
            pre = t;
            t *= (BigInt(2) << (rhslim + lim)) - rb * t;
            t.val = vector<long long>(t.val.begin() + lim + rhslim, t.val.end());
        }
        if(lim != preci){
            pre = BigInt();
            while(pre != t){
                BigInt rb = rhs >> (rhs.val.size() - rhslim);
                if(rhslim != (int) rhs.val.size()) rb += BigInt(1);
                pre = t;
                t *= (BigInt(2) << (rhslim + lim)) - rb * t;
                t.val = vector<long long>(t.val.begin() + lim + rhslim, t.val.end());
                int next_lim = min(lim * 2 + 1, preci);
                if (next_lim != lim) t <<= next_lim - lim;
                int next_rhslim = min(rhslim * 2 + 1, int(rhs.val.size()));
                lim = next_lim;
                rhslim = next_rhslim;
            }
        }
        BigInt quo = (*this) * t;
        quo.val = vector<long long>(quo.val.begin() + val.size(), quo.val.end());
        BigInt mul = quo * rhs;
        while(mul + rhs <= (*this)){
            quo += BigInt(1);
            mul += rhs;
        }
        BigInt rem = *this - quo * rhs;
        return {quo, rem};
    }

public:
    void stoi(string &s){
        if(s == "0") return;
        int n = s.size(), idx = 0;
        if(s[0] == '-'){
            n -= 1;
            sign = -1;
            idx = 1;
        }
        int len = (n + digit - 1) / digit, rem = n % digit;
        if(rem == 0) rem += digit;
        val.resize(len);
        for(int i = len - 1; i >= 0; --i){
            if(i == len - 1){
                val[i] = stoll(s.substr(idx, rem));
                idx += rem;
            }else{
                val[i] = stoll(s.substr(idx, digit));
                idx += digit;
            }
        }
    }
    string itos() const {
        string res = "";
        if(sign == -1) res += "-";
        bool flag = false;
        for(int i = (int) val.size() - 1; i >= 0; --i){
            if(val[i] > 0 && !flag){
                res += to_string(val[i]);
                flag = true;
            }else if(flag){
                string rem = to_string(val[i]);
                res += string(digit - rem.size(), '0') + rem;
            }
        }
        return (res.empty() || res == "-") ? "0" : res;
    }
    pair<BigInt, BigInt> divide_mod(const BigInt& rhs){
        assert(!rhs.val.empty());
        BigInt div = *this / rhs;
        return make_pair(div, *this - div * rhs);
    }
    BigInt& shift(){
        for(int i = 0; i < (int) val.size() - 1; ++i){
            if(val[i] >= 0){
                val[i + 1] += val[i] / base;
                val[i] %= base;
            }else{
                long long x = (-val[i] + base - 1) / base;
                val[i] += x * base;
                val[i + 1] -= x;
            }
        }
        while(val.back() >= base){
            val.emplace_back(val.back() / base);
            val[val.size() - 2] %= base;
        }
        return *this;
    }
    BigInt& operator=(const BigInt& x) = default;
    inline BigInt& operator+=(const BigInt& rhs) noexcept {
        if(rhs.val.empty()) return *this;
        if(sign != rhs.sign) return *this -= -rhs;
        if(val.size() < rhs.val.size()){
            val.resize(rhs.val.size());
        }
        for(int i = 0; i < (int) rhs.val.size(); ++i){
            val[i] += rhs.val[i];
        }
        return (*this).shift();
    }
    inline BigInt& operator-=(const BigInt& rhs) noexcept {
        if(rhs.val.empty()) return *this;
        if(sign != rhs.sign) return *this += -rhs;
        if((sign == 1 ? *this : -(*this)) < (rhs.sign == 1 ? rhs : -rhs)){
            return *this = -(rhs - *this);
        }
        for(int i = 0; i < (int) rhs.val.size(); ++i){
            val[i] -= rhs.val[i];
        }
        
        shift();
        normalize();
        return *this;
    }
    // Karatsuba Algorithm (O(N^(1.58)))
    inline BigInt& operator*=(const BigInt& rhs) noexcept {
        if(val.empty() || rhs.val.empty()){
            return *this = BigInt();
        }

        sign *= rhs.sign;
        vector<long long> rhsval = rhs.val;
        int k = 1;
        while(k < (int) max(val.size(), rhsval.size())){
            k *= 2;
        }
        val.resize(k), rhsval.resize(k);
        val = karatsuba_algorithm(val, rhsval);

        shift();
        normalize();
        return *this;
    }
    // Newton method
    inline BigInt& operator/=(const BigInt& rhst) noexcept {
        assert(!rhst.val.empty());
        if(val.empty()) return *this;
        if((int) val.size() <= 32 && (int) rhst.val.size() <= 32){
            return *this = divide_naive(rhst).first;
        }

        BigInt rhs = rhst;
        int mulsign = sign * rhs.sign;
        sign = 1, rhs.sign = 1;
        if(*this < rhs){
            return *this = BigInt();
        }

        *this = divide_newton(rhs).first;
        sign = mulsign;
        normalize();
        return *this;
    }
    inline BigInt& operator%=(const BigInt& rhs) noexcept {
        assert(!rhs.val.empty());
        return *this = *this - (*this / rhs) * rhs;
    }
    inline BigInt& operator++() { return *this += 1; }
    inline BigInt operator++(int) {
        const BigInt res = *this;
        ++(*this);
        return res;
    }
    inline BigInt& operator--() { return *this -= 1; }
    inline BigInt operator--(int) {
        const BigInt res = *this;
        --(*this);
        return res;
    }
    inline BigInt operator+() const { return *this; }
    inline BigInt operator-() const {
        BigInt res = *this;
        if (!res.val.empty()) res.sign = -res.sign;
        return res;
    }
    inline BigInt& operator<<=(const unsigned int rhs){
        if(val.back() >= 1 || (int) val.size() >= 2){
            vector<long long> tmp(rhs, 0);
            val.insert(val.begin(), tmp.begin(), tmp.end());
        }
        return *this;
    }
    inline BigInt& operator>>=(const unsigned int rhs){
        if(rhs == 0) return *this;
        if(rhs > val.size()) val = {0};
        else val = vector<long long>(val.begin() + rhs, val.end()); 
        return *this;
    }
    inline bool operator<(const BigInt& rhs) const {
        if(sign != rhs.sign) return sign < rhs.sign;
        if(val.size() != rhs.val.size()) return sign * val.size() < rhs.sign * rhs.val.size();
        for(int i = (int) val.size() - 1; i >= 0; --i){
            if(val[i] != rhs.val[i]) return sign * val[i] < rhs.sign * rhs.val[i];
        }
        return false;
    }
    inline bool operator>(const BigInt& rhs) const { return rhs < (*this); }
    inline bool operator<=(const BigInt& rhs) const { return !((*this) > rhs); }
    inline bool operator>=(const BigInt& rhs) const { return !((*this) < rhs); }
    friend inline BigInt operator+(const BigInt& lhs, const BigInt& rhs) noexcept { return BigInt(lhs) += rhs; }
    friend inline BigInt operator-(const BigInt& lhs, const BigInt& rhs) noexcept { return BigInt(lhs) -= rhs; }
    friend inline BigInt operator*(const BigInt& lhs, const BigInt& rhs) noexcept { return BigInt(lhs) *= rhs; }
    friend inline BigInt operator/(const BigInt& lhs, const BigInt& rhs) noexcept { return BigInt(lhs) /= rhs; }
    friend inline BigInt operator%(const BigInt& lhs, const BigInt& rhs) noexcept { return BigInt(lhs) %= rhs; }
    friend inline BigInt operator<<(const BigInt& lhs, const unsigned int rhs) noexcept { return BigInt(lhs) <<= rhs; }
    friend inline BigInt operator>>(const BigInt& lhs, const unsigned int rhs) noexcept { return BigInt(lhs) >>= rhs; }
    friend inline bool operator==(const BigInt& lhs, const BigInt& rhs) noexcept { return lhs.val == rhs.val; }
    friend inline bool operator!=(const BigInt& lhs, const BigInt& rhs) noexcept { return lhs.val != rhs.val; }
    friend inline istream& operator>>(istream& is, BigInt& x) noexcept {
        string s;
        is >> s;
        x.stoi(s);
        return is;
    }
    friend inline ostream& operator<<(ostream& os, const BigInt& x) noexcept { return os << x.itos(); }
};

using bint = BigInt<1000000LL, 6>;

struct fraction{
    bint p, q;
    fraction(bint P = 0, bint Q = 1): p(P), q(Q){ }
    inline bool operator==(const fraction &other) const {
        return p * other.q == other.p * q;
    }
    inline bool operator!=(const fraction &other) const {
        return p * other.q != other.p * q;
    }
    inline bool operator<(const fraction &other) const {
        return p * other.q < other.p * q;
    }
    inline bool operator<=(const fraction &other) const {
        return p * other.q <= other.p * q;
    }
    inline bool operator>(const fraction &other) const {
        return p * other.q > other.p * q;
    }
    inline bool operator>=(const fraction &other) const {
        return p * other.q >= other.p * q;
    }
    inline fraction operator+(const fraction &other) const { return fraction(p * other.q + q * other.p, q * other.q); }
    inline fraction operator-(const fraction &other) const { return fraction(p * other.q - q * other.p, q * other.q); }
    inline fraction operator*(const fraction &other) const { return fraction(p * other.p, q * other.q); }
    inline fraction operator/(const fraction &other) const { return fraction(p * other.q, q * other.p); }
    inline fraction& operator+=(const fraction& rhs) noexcept {
        *this = *this + rhs;
        return *this;
    }
    inline fraction& operator-=(const fraction& rhs) noexcept {
        *this = *this - rhs;
        return *this;
    }
    inline fraction& operator*=(const fraction& rhs) noexcept {
        *this = *this * rhs;
        return *this;
    }
    inline fraction& operator/=(const fraction& rhs) noexcept {
        *this = *this / rhs;
        return *this;
    }
    friend inline istream& operator>>(istream& is, fraction& x) noexcept {
        is >> x.p;
        x.q = 1;
        return is;
    }
    friend inline ostream& operator<<(ostream& os, const fraction& x) noexcept { return os << x.p << "/" << x.q; }
};

pair<fraction, fraction> SternBrocot(bint n, fraction p){
    fraction a(0, 1), b(1, 0);
    fraction x(0, 1), y(1, 0);
    bool ok_left = true, ok_right = true;
    while(ok_left && ok_right){
        fraction m(a.p + b.p, a.q + b.q);
        if(p < m * m){
            bint ok = 0, ng = n;
            while(ng - ok > 1){
                bint mid = (ok + ng) / 2;
                fraction m2(a.p * mid + b.p, a.q * mid + b.q);
                if(p < m2 * m2 && m2.p <= n && m2.q <= n){
                    ok = mid;
                    m = m2;
                }else{
                    ng = mid;
                }
            }
            b = m;
            if(m.p <= n && m.q <= n){
                y = m;
            }else{
                ok_left = false;
            }
        }else{
            bint ok = 0, ng = n;
            while(ng - ok > 1){
                bint mid = (ok + ng) / 2;
                fraction m2(a.p + b.p * mid, a.q + b.q * mid);
                if(p >= m2 * m2 && m2.p <= n && m2.q <= n){
                    ok = mid;
                    m = m2;
                }else{
                    ng = mid;
                }
            }
            a = m;
            if(m.p <= n && m.q <= n){
                x = m;
            }else{
                ok_right = false;
            }
        }
    }
    return make_pair(x, y);
}

void input(){
}

void solve(){
    while(1){
        bint p, n; in(p, n);
        if(p == 0 && n == 0) break;
        fraction pf(p, 1);
        auto [a, b] = SternBrocot(n, pf);
        out(b, a);
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(20);
    
    input();
    solve();
}
accuracy: 1
time_ms: 40
memory_kb: 3432
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;

int gcd(int a, int b) { return b==0 ? a : gcd(b,a%b); }

struct Rational {
    int a,b;

    bool isnorm() { return gcd(a,b)==1; }

    bool operator<(const Rational& rhs) const {
        return 1.0*a*rhs.b<1.0*b*rhs.a;
    }
};

int solve() {
    int p,n;
    cin>>p>>n;
    if (p==0||n==0) return 0;

    double pp=sqrt(p);
    Rational lo={1,n}, hi={n,1};
    for (int b=1; b<=n; b++) {
        int a=(int)floor(b*pp);
        Rational l={a,b}, h={a+1,b};

        if (a<=n && l.isnorm() && lo<l) lo=l;
        if (a+1<=n && h.isnorm() && h<hi) hi=h;
    }

    cout<<hi.a<<'/'<<hi.b<<' '<<lo.a<<'/'<<lo.b<<'\n';
    return 1;
}

int main() {
    while (solve());
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3104
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long int lli;

int main(){
    while(1){
        lli p,n;
        cin >> p >> n;
        if(n == 0) break;

        lli lt=0,lb=1,ht=n,hb=1;
        for(int b=1; b<=n; b++){
            // t/b < sqrt(p)
            // t*t/b*b < p
            // t < sqrt(p*b*b)
            // この辺を雑に探索
            lli ul = n*n;
            lli a = p*b*b;
            lli tt = sqrt((long double)min(a, ul));
            for(lli i=-10; i<=10; i++){
                if(tt+i<0 or tt+i>n) continue;
                lli t = tt+i;
                if(t*t < p*b*b and 1.0l*t/b > 1.0l*lt/lb){
                    lt = t;
                    lb = b;
                }
                if(t*t > p*b*b and 1.0l*t/b < 1.0l*ht/hb){
                    ht = t;
                    hb = b;
                }
            }
        }
        cout << ht << "/" << hb << " " << lt << "/" << lb << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 3072
final_rank: 15

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <array>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <tuple>
#include <cmath>
#include <algorithm>
#include <functional>
#include <numeric>
#include <cfloat>
#include <climits>
#include <cassert>
#include <random>
#include <fstream>


int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a % b);
}
struct Rational {
	Rational(int num, int den) : numerator{ num }, denominator{ den } {
		const auto g = gcd(num, den);
		numerator /= g;
		denominator /= g;
	}
	Rational(int value) : numerator{ value }, denominator{ 1 }{}
	int numerator, denominator;
	Rational operator+(const Rational that) const {
		return Rational(numerator * that.denominator + that.numerator * denominator, denominator * that.denominator);
	}
	bool operator<(const Rational that) const {
		return numerator * that.denominator < denominator * that.numerator;
	}
};
std::ostream& operator<<(std::ostream& os, const Rational& that) {
	return os << that.numerator << '/' << that.denominator;
}
int main(){
	while (true) {
		int prime, n; std::cin >> prime >> n; if (prime == 0) break;
		Rational lower(1), upper(n);
		double sqrt = std::sqrt(prime);
		for (auto i = 1; i <= n; ++i) {
			const int l = sqrt * i;
			if (l <= n && lower < Rational(l, i)) {
				lower = Rational(l, i);
			}
			if (l + 1 <= n && Rational(l + 1, i) < upper) {
				upper = Rational(l + 1, i);
			}
		}
		std::cout << upper << ' ' << lower << '\n';
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3032
final_rank: 7

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<cfloat>
#include<cmath>
using namespace std;

int gcd(int a, int b){
    return b == 0 ? a : gcd(b, a%b);
}

int main(){
    int p, n;
    while(cin >> p >> n, p+n){
        double l = 0, r = DBL_MAX, sq = sqrt(p);
        int lc, lm, rc, rm;
        for(int m = 1; m <= n; m++){
            int ll = (int)(sq*m), rr = ceil(sq*m);
            if(ll < 1)  ll = 1;
            if(rr < 1)  rr = 1;
            if(ll > n)  ll = n;
            if(rr > n)  rr = n;
            if((double)ll/m < sq && (double)ll/m > l){
                l = (double)ll/m, lc = ll, lm = m;
            }
            if((double)rr/m > sq && (double)rr/m < r){
                r = (double)rr/m, rc = rr, rm = m;
            }
        }
        int g = gcd(lc, lm);    lc /= g, lm /= g;
        g = gcd(rc, rm);        rc /= g, rm /= g;
        printf("%d/%d %d/%d\n", rc, rm, lc, lm);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3112
final_rank: 13

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<cfloat>
#include<cmath>
using namespace std;

int gcd(int a, int b){
    return b == 0 ? a : gcd(b, a%b);
}

// 10000 * log(10000) * 2 ?
int main(){
    int p, n;
    while(cin >> p >> n, p+n){
        double l = 0, r = DBL_MAX, sq = sqrt(p);
        int lc, lm, rc, rm;
        for(int m = 1; m <= n; m++){
            int ll = (int)(sq*m), rr = ceil(sq*m);
            if(ll < 1)  ll = 1;
            if(rr < 1)  rr = 1;
            if(ll > n)  ll = n;
            if(rr > n)  rr = n;
            if((double)ll/m < sq && (double)ll/m > l){
                l = (double)ll/m, lc = ll, lm = m;
            }
            if((double)rr/m > sq && (double)rr/m < r){
                r = (double)rr/m, rc = rr, rm = m;
            }
        }
        int g = gcd(lc, lm);    lc /= g, lm /= g;
        g = gcd(rc, rm);        rc /= g, rm /= g;
        printf("%d/%d %d/%d\n", rc, rm, lc, lm);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3068
final_rank: 8

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int calc(int x,int y){
	if(y == 0){
		return x;
	}else{
		return calc(y,x%y);
	}
}

int main(){

	int p,n,x,y,u,v,common;
	int left,right,m,tmp_bunshi;
	double sqrt_p,near_small,near_big;
	double tmp,tmp_small,tmp_big;

	while(true){
		scanf("%d %d",&p,&n);
		if(p == 0 && n == 0)break;

		near_small = 0,near_big = DBL_MAX;

		sqrt_p = (double)sqrt(p);

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

			left = 1,right = n, m = (left+right)/2;
			tmp_small = 0;

			while(left <= right){
				tmp = (double)m/(double)bunbo;

				if(tmp < sqrt_p){
					tmp_small = tmp;
					tmp_bunshi = m;
					left = m+1;
				}else{
					right = m-1;
				}
				m = (left+right)/2;
			}
			if(near_small < tmp_small){
				near_small = tmp_small;
				u = tmp_bunshi;
				v = bunbo;
			}

			left = 1,right = n, m = (left+right)/2;
			tmp_big = DBL_MAX;

			while(left <= right){
				tmp = (double)m/(double)bunbo;

				if(tmp > sqrt_p){
					tmp_big = tmp;
					tmp_bunshi = m;
					right = m-1;
				}else{
					left = m+1;
				}
				m = (left+right)/2;
			}

			if(near_big > tmp_big){
				near_big = tmp_big;
				x = tmp_bunshi;
				y = bunbo;
			}
		}

		if(u >= v){
			common = calc(u,v);
		}else{
			common = calc(v,u);
		}

		u /= common;
		v /= common;

		if(x >= y){
			common = calc(x,y);
		}else{
			common = calc(y,x);
		}

		x /= common;
		y /= common;

		printf("%d/%d %d/%d\n",x,y,u,v);
	}

	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 3124
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
int main(){
  double p;
  int n;
  while(cin>>p>>n,n){
    double t=sqrt(p);
    int x=0,y=1,u=1e9,v=1;
    for(int i=1;i<n;i++){
      int l=0,r=n+1,m;
      while(l<r){
    m=(l+r)/2;
    if(t<(1.0*m/i))r=m;
    else l=m+1;
      }
      if(x*i<(r-1)*y)x=r-1,y=i;
      if(r!=n+1&&u*i>v*r)u=r,v=i;
    }
    cout<<u<<'/'<<v<<' '<<x<<'/'<<y<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3156
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef  pair<double,pair<int,int> > VP;
bool kyk(int,int);
int main(){
  vector<int> jj(10005);
  for(int i=0;i<=10004;i++){
    jj[i]=i*i;
  }
  while(1){
    int p,n;
    cin >> p >> n;
    if(p==0&&n==0)break;
    vector<VP> sm;
    vector<VP> la;
    for(int i=1;i<=n;i++){
      VP pul;
      VP pus;
      pus.second.second=i;
      pul.second.second=i;      
      int bns=lower_bound(jj.begin(),jj.end(),jj[i]*p)-jj.begin();
      if(bns-1>n)break;
      pul.second.first=jj[bns];
      pus.second.first=jj[bns-1];
      pul.first=(double)pul.second.first/(i*i);
      pus.first=(double)pus.second.first/(i*i);
      sm.push_back(pus);
      la.push_back(pul);
    }
    //cout << i*i << " "<<  pus.first << endl;
    //cout << pul.first << endl << endl;
    sort(sm.begin(),sm.end());
    sort(la.begin(),la.end());
    for(int i=0;i<la.size();i++){
      if(kyk(la[i].second.first,la[i].second.second)&&la[i].second.first<=n*n){
	cout << (int)sqrt(la[i].second.first)<<"/"<<la[i].second.second<<" ";
	break;
      }
    }
    for(int i=sm.size()-1;i>=0;i--){
      if(kyk(sm[i].second.first,sm[i].second.second)&&sm[i].second.first<=n*n){
	cout << (int)sqrt(sm[i].second.first)<<"/"<<sm[i].second.second<<endl;
	break;
      }
    }	
  }
  
  return 0;
}
bool kyk(int a,int b){
  //cout << a << b <<endl;
  if(a==0||b==0)return 0;
  if(b!=1&&a==b*b)return 0;
  if(b!=1&&a%b==0)return 0;
  for(int i=2;i*i<=b*b;i++){
    if(a%i==0&&b%i==0)return 0;
  }
  return 1;
}
accuracy: 1
time_ms: 10
memory_kb: 3176
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
  int p, n;
  while(cin >> p >> n, p || n) {
    int u = 1, v = 1, x = n, y = 1;
    for(int i = 1; i <= n; i++) {
      for(int j = u*i/v; j <= n; j++) {
	if(j*j <= p*i*i) {
	  if(__gcd(i, j) != 1) continue;
	  if(u*i - j*v < 0) u = j, v = i;
	} else {
	  if(x*i - j*y > 0) x = j, y = i;
	  break;
	}
      }
    }
    cout << x << "/" << y << " " << u << "/" << v << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3084
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
int main(){
  double p;
  int n;
  while(cin>>p>>n,n){
    double t=sqrt(p);
    int x=0,y=1,u=1e9,v=1;
    for(int i=1;i<n;i++){
      int l=0,r=n+1,m;
      while(l<r){
	m=(l+r)/2;
	if(t<(1.0*m/i))r=m;
	else l=m+1;
      }
      if(x*i<(r-1)*y)x=r-1,y=i;
      if(r!=n+1&&u*i>v*r)u=r,v=i;
    }
    cout<<u<<'/'<<v<<' '<<x<<'/'<<y<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3200
final_rank: 18

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"


int main() {
	while (1) {
		int p, n; cin >> p >> n;
		if (!p)break;
		pair<int, int>minp, maxp;
		ld minsa = 1e9, maxsa = 1e9;
		for (long long int bo = 1; bo <= n; ++bo) {
			ld num = sqrt(ld(bo*bo) * p);
			for (int si = max(1, int(num - 2)); si <= min(n, int(num + 1)); ++si) {
				if (si*si < bo*bo*p) {
					if (minsa >sqrt(p)-ld(si)/bo ) {
						minp = (make_pair(si, bo));
						minsa = sqrt(p) - ld(si) / bo;
					}
				}
				else if (si*si > bo*bo*p) {
					if (maxsa > ld(si) / bo - sqrt(p)) {
						maxp = make_pair(si, bo);
						maxsa = ld(si) / bo - sqrt(p);
					}
				}
			}
		}
		cout << maxp.first << "/" << maxp.second << " " << minp.first << '/' << minp.second << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2964
final_rank: 6

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1e8;
int gcd(int a,int b){
	return (b==0?a:gcd(b,a%b));
}
int main(){
	int a,b;
	while(cin>>a>>b,a+b){
		double q=sqrt(a);
		int c=1,d=1,e=1,f=inf;
		loop(i,1,b+1){
			int t=ceil(i/q);
			t--;
			if(q<(double)i/t&&(double)i/t<(double)f/e){
				f=i;e=t;
				int w=gcd(f,e);
				f/=w;t/=w;
			}
			t++;
			if(t!=0){
				if(q>(double)i/t&&(double)i/t>(double)d/c){
					d=i;c=t;
					int w=gcd(d,c);
					d/=w;c/=w;
				}
			}
		}
		cout<<f<<"/"<<e<<" "<<d<<"/"<<c<<endl;
	}
}
accuracy: 1
time_ms: 70
memory_kb: 1164
final_rank: 1

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define INF 1e9
 
class Fraction{
public:;
    double numerator,denominator;
    double div();
};
 
double Fraction::div(){
    return numerator/denominator;
}
 
ostream &operator << (ostream &os,const Fraction &f){
    os << f.numerator << '/' << f.denominator;
    return os;
}
 
int main(){
    double p;
    int n;
    while(cin >> p >> n, p){
	p = sqrt(p);
	Fraction a = (Fraction){-1,1};
	Fraction b = (Fraction){INF,1};
	for(int den = 1 ; den <= n ; den++){
	    int l = 0, r = n+1;
	    while(l < r){
		double mid = (l + r) / 2;
		if(mid < p*den){
		    if(mid/den > a.div()){
			a = (Fraction){mid,den};
		    }
		    l = mid+1;
		}else{
		    r = mid;
		}
	    }
	    l = 0, r = n+1;
	    while(l < r){
		double mid = (l + r) / 2;
		if(mid > p*den){
		    if(mid/den < b.div()){
			b = (Fraction){mid,den};
		    }
		    r = mid;
		}else{
		    l = mid+1;
		}
	    }
	}
	cout << b << " " << a << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 370
memory_kb: 1284
final_rank: 3

code_snippet: #include<iostream>
#include<cmath>
#include<tuple>
using namespace std;
int p, q;
int main() {
	while (true) {
		cin >> p >> q;
		if (p == 0 && q == 0)break;
		tuple<int, int, double>x, y;
		x = make_tuple(0, 0, 0);
		y = make_tuple(0, 0, 100000);
		double T = sqrt(1.0*p);
		for (int i = 1; i <= q; i++) {
			double I = T*i;
			int J = I;
			double K = 1.0*J / i;
			double L = 1.0*(J + 1) / i;
			if (K > get<2>(x) && J <= q) {
				x = make_tuple(J, i, K);
			}
			if (L < get<2>(y) && J + 1 <= q) {
				y = make_tuple(J + 1, i, L);
			}
		}
		cout << get<0>(y) << '/' << get<1>(y) << ' ';
		cout << get<0>(x) << '/' << get<1>(x) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3076
final_rank: 9

code_snippet: #include <cmath>
#include <iostream>
using namespace std;
int p, n; long double d;
int main() {
	while (cin >> p >> n, n) {
		d = sqrtl(p);
		int p1 = 999999, q1 = 1, p2 = 0, q2 = 1;
		for (int i = 1; i <= n; i++) {
			int j = i / d;
			if (0 < j && j <= n && 1.0L * i / j < 1.0L * p1 / q1) p1 = i, q1 = j;
			if (0 < (j + 1) && (j + 1) <= n && 1.0L * i / (j + 1) > 1.0L * p2 / q2) p2 = i, q2 = j + 1;
		}
		cout << p1 << '/' << q1 << ' ' << p2 << '/' << q2 << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3088
final_rank: 11

code_snippet: #include <iostream>
#include <complex>
#include <sstream>
#include <string>
#include <algorithm>
#include <deque>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <vector>
#include <set>
#include <limits>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
#define REP(i, j) for(int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for(int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
const int INF = 10001;

int gcd(int a, int b){ return (b == 0 ? a : gcd(b, a % b)); }

class R{
  public:
    double a, b;
    R(int aa, int bb) { a = aa; b = bb; int r; while((r = gcd(a, b)) != 1) { a /= r; b /= r; } }
    bool operator > (const R &r) const { return a / b > r.a / r.b; }
    bool operator < (const R &r) const { return a / b < r.a / r.b; }
};


int main() {
  double P;
  int N;
  while(cin >>P >>N && (P || N)){
    P = sqrt(P);
    R lower = R(-1, 1), upper = R(INF, 1);
    FOR(i, 1, N + 1){
      int l = 0, r = N + 1;
      while(r - l > 1){
        double m = (r + l) / 2;
        if(m / i >= P){
          r = m;
          upper = min(upper, R(r, i));
        }
        else{
          l = m;
          lower = max(lower, R(l, i));
        }
      }
    }
    cout <<upper.a <<"/" <<upper.b <<" " <<lower.a <<"/" <<lower.b <<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2630
memory_kb: 1284
final_rank: 5

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

using namespace std;

#define INF 1e9

class Fraction{
public:;
  double numerator,denominator;
  double div();
};

double Fraction::div(){
  return numerator/denominator;
}

ostream &operator << (ostream &os,const Fraction &f){
  os << f.numerator << '/' << f.denominator;
  return os;
}

int main(){
  double p;
  int n;
  while(cin >> p >> n, p){
    p = sqrt(p);
    Fraction a = (Fraction){-1,1};
    Fraction b = (Fraction){INF,1};
    for(int den = 1 ; den <= n ; den++){
      int l = 0, r = n+1;
      while(l < r){
        double mid = (l + r) / 2;
        if(mid < p*den){
          if(mid/den > a.div()){
            a = (Fraction){mid,den};
          }
          l = mid+1;
        }else{
          r = mid;
        }
      }
      l = 0, r = n+1;
      while(l < r){
        double mid = (l + r) / 2;
        if(mid > p*den){
          if(mid/den < b.div()){
            b = (Fraction){mid,den};
          }
          r = mid;
        }else{
          l = mid+1;
        }
      }
    }
    cout << b << " " << a << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 370
memory_kb: 1284
final_rank: 3

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

using namespace std;

#define INF 1e9

class Fraction{
public:;
  double numerator,denominator;
  double div();
};

double Fraction::div(){
  return numerator/denominator;
}

ostream &operator << (ostream &os,const Fraction &f){
  os << f.numerator << '/' << f.denominator;
  return os;
}

int main(){
  double p;
  int n;
  while(cin >> p >> n, p){
    p = sqrt(p);
    Fraction a = (Fraction){-1,1};
    Fraction b = (Fraction){INF,1};
    for(int den = 1 ; den <= n ; den++){
      int l = 0, r = n+1;
      for(int i = 0 ; i < 150 ; i++){
        double mid = (l + r) / 2;
        if(mid < p*den){
          if(mid/den > a.div()){
            a = (Fraction){mid,den};
          }
          l = mid;
        }else{
          r = mid;
        }
      }
      l = 0, r = n+1;
      for(int i = 0 ; i < 150 ; i++){
        double mid = (l + r) / 2;
        if(mid > p*den){
          if(mid/den < b.div()){
            b = (Fraction){mid,den};
          }
          r = mid;
        }else{
          l = mid;
        }
      }
    }
    cout << b << " " << a << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 4860
memory_kb: 1288
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define MAX 1000000007

int main() {
  double p,n;
  while(cin >> p >> n) {
    if(p==0 && n==0) break;
    p=sqrt(p);
    int x=0,y=0,u=0,v=0;
    double a2=MAX,b2=MAX;
    for(int i=1; i<=n; i++) {
      int a=(int)(p*i);
      int b=a+1;
      if(a>n) break;
      if(__gcd(a,i)==1 && p-(double)a/i<a2) {
	a2=p-(double)a/i;
	u=a;v=i;
      }
      if(b>n) continue;
      if(__gcd(b,i)==1 && (double)b/i-p<b2) {
	b2=(double)b/i-p;
	x=b;y=i;
      }
    }
    printf("%d/%d %d/%d\n",x,y,u,v);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1200
final_rank: 2