extern crate core;

use std::str::FromStr;
use std::fmt;
use std::cmp::{Ordering, max};
use std::fmt::{Display, Error, Formatter};
use std::ops::{Range, Add};
use std::f64::consts::PI;

macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}

macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
#[derive(Copy, Clone, Eq, PartialEq)]
struct Fraction {
    numerator: i32,
    denominator: i32
}
impl Fraction {
    fn new(num: i32, den: i32) -> Fraction {
        Fraction{numerator: num, denominator: den}
    }
    fn to_double(&self) -> f64 {
        self.numerator as f64 / self.denominator as f64
    }
}
fn gcd(a: i32, b: i32) -> i32 {
    match b {
        0 => a,
        _ => gcd(b, a % b)
    }
}
impl Ord for Fraction {
    fn cmp(&self, other: &Self) -> Ordering {
        (self.numerator as i64 * other.denominator as i64).cmp(&(self.denominator as i64 * other.numerator as i64))
    }
}
impl PartialOrd for Fraction {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(&other))
    }
}
impl Display for Fraction {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{}/{}", self.numerator, self.denominator)
    }
}
fn lower_bound(vec: &Vec<Fraction>, target: f64) -> usize {
    let mut left = 0;
    let mut right = vec.len();
    while left < right {
        let mid = (left + right) / 2;
        if vec[mid].to_double() < target {
            left = mid + 1;
        }else {
            right = mid;
        }
    }
    right
}
fn upper_bound(vec: &Vec<Fraction>, target: f64) -> usize {
    let mut left = 0;
    let mut right = vec.len();
    while left < right {
        let mid = (left + right) / 2;
        if vec[mid].to_double() <= target {
            left = mid + 1;
        }else {
            right = mid;
        }
    }
    right
}

fn main() {
    let mut fraction = Vec::<Fraction>::new();
    let pi = PI;
    for d in 1 .. 1001000 {
        let n = (pi * d as f64) as i32;
        if gcd(n, d) == 1 {
            fraction.push(Fraction::new(n, d))
        }
        if gcd(n + 1, d) == 1 {
            fraction.push(Fraction::new(n + 1, d))
        }
    }
    fraction.sort();
    loop {
        let_all!(err: f64);
        if err == 0.0 {
            return
        }
        if err >= 0.0001 {
            for d in 1 .. 10001 {
                let n = (pi * d as f64).floor();
                if n / d as f64 + err >= pi {
                    println!("{}/{}", n as i32, d);
                    break
                }
                if (n + 1_f64) / d as f64 - err <= pi {
                    println!("{}/{}", (n + 1_f64) as i32, d);
                    break
                }
            }
        }else {
            let mut min = Fraction::new((pi * 1000000_f64) as i32, 1000000);
            for f in lower_bound(&fraction, pi - err) .. upper_bound(&fraction, pi + err) {
                if min.denominator > fraction[f].denominator {
                    min = fraction[f]
                }
            }
            println!("{}", min);
        }
    }
}



Measured memory_bytes: 20408