use std::ops::DivAssign;
use std::ops::MulAssign;
use std::ops::SubAssign;
use std::collections::BinaryHeap;
use std::str::FromStr;
use std::collections::HashSet;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::ops::Neg;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Add;
use std::ops::{AddAssign, Sub};
use std::cmp::max;
use std::collections::VecDeque;
use std::cmp::min;
use std::collections::{HashMap, BTreeSet};
use std::cmp::Ordering;
use std::fmt::Debug;

fn read_line() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("No Line");
    buffer
}
fn read_lines<T: std::str::FromStr>(count: usize) -> Vec<T> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(buffer.trim().parse().ok().expect("Can't Parse"));
        buffer.clear();
    }
    vec
}
fn read_tabulate<R, T: Fn(&str)->R> (count: usize, transformer: T) -> Vec<R> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(transformer(buffer.trim()));
        buffer.clear();
    }
    vec
}
fn read_value<T: std::str::FromStr>() -> T {
    read_line().trim().parse().ok().unwrap()
}
fn read_values<T: std::str::FromStr>() -> Vec<T> {
    read_line().trim().split(' ').map(|x| x.parse().ok().expect("Can't Parse")).collect::<Vec<T>>()
}
macro_rules! freeze {
    ($($id:ident), *) => {
        $(let $id = $id;)*
    };
}
macro_rules! read_map {
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
}
macro_rules! read {
    (mut $ident: ident: [$ty:ty]) => {
        let mut $ident = read_values::<$ty>();
    };
    ($ident: ident: [$ty:ty]) => {
        let $ident = read_values::<$ty>();
    };
    (mut $ident: ident: [[$ty:ty]; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    ($ident: ident: [[$ty:ty]; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$ty:ty; $size:expr]) => {
        let mut $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$ty:ty; $size:expr]) => {
        let $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    ($($token: tt)*) => {
        let mut iter = read_values::<String>().into_iter();
        read_from_iter!(iter; $($token)*);
    };
}
macro_rules! read_from_iter {
    ($iter:expr; mut $ident:ident:$ty:ty, $($rest:tt)*) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; $ident:ident:$ty:ty, $($rest:tt)*) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; mut $ident:ident:$ty:ty) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter:expr; $ident:ident:$ty:ty) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter: expr; ) => {};
}
struct KeyValue<K, V> {
    key: K,
    value: V
}
impl <K: PartialOrd, V> PartialEq for KeyValue<K, V> {
    fn eq(&self, other: &Self) -> bool {
        self.key.eq(&other.key)
    }
}
impl <K: PartialOrd, V> Eq for KeyValue<K, V> {}
impl <K: PartialOrd, V> PartialOrd for KeyValue<K, V> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.key.partial_cmp(&other.key)
    }
}
impl <K: PartialOrd, V> Ord for KeyValue<K, V> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.key.partial_cmp(&other.key).ok_or("Can't Compare").unwrap()
    }
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
struct Rational {
    num: i64, den: i64
}
fn gcd(a: i64, b: i64) -> i64 {
    match b {
        0 => a,
        _ => gcd(b, a % b)
    }
}
impl Rational {
    fn new(n: i64, d: i64) -> Rational {
        let sign = n.signum() * d.signum();
        let g = gcd(n.abs(), d.abs());
        Rational{num: n.abs() * sign / g, den: d.abs() / g}
    }
    fn from_int(value: i32) -> Rational {
        Rational{num: value as i64, den: 1}
    }
    fn abs(&self) -> Rational {
        Rational{num: self.num.abs(), den: self.den}
    } 
}
impl Add for Rational {
    type Output = Rational;
    fn add(self, rhs: Rational) -> <Self as std::ops::Add<Rational>>::Output { 
        Rational::new(self.num * rhs.den + self.den * rhs.num, self.den * rhs.den)
    }
}
impl AddAssign for Rational {
    fn add_assign(&mut self, rhs: Rational) {
        *self = *self + rhs;
    }
}
impl Sub for Rational {
    type Output = Rational;
    fn sub(self, rhs: Self) -> Self::Output {
        Rational::new(self.num * rhs.den - self.den * rhs.num, self.den * rhs.den)
    }
}
impl SubAssign for Rational {
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs;
    }
}
impl Mul for Rational {
    type Output = Rational;
    fn mul(self, rhs: Self) -> Self::Output {
        Rational::new(self.num * rhs.num, self.den * rhs.den)
    }
}
impl MulAssign for Rational {
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs;
    }
}
impl Div for Rational {
    type Output = Rational;
    fn div(self, rhs: Self) -> Self::Output {
        Rational::new(self.num * rhs.den, self.den * rhs.num)
    }
}
impl DivAssign for Rational {
    fn div_assign(&mut self, rhs: Self) {
        *self = *self / rhs;    
    }
}
impl Neg for Rational {
    type Output = Rational;
    fn neg(self) -> Self::Output {
        Rational{num: -self.num, den: self.den}
    }
}
impl Ord for Rational {
    fn cmp(&self, other: &Self) -> Ordering {
        (*self - *other).num.cmp(&0)
    }
}
impl PartialOrd for Rational {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl Display for Rational {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{} / {}", self.num, self.den)
    }
}
#[derive(Copy, Clone, Debug)]
struct Time {
    one_day_hour: usize, hour: usize, minute: usize, second: Rational
}
impl Time {
    fn new(one_day_hour: usize, mut hour: usize, mut minute: usize, mut second: Rational) -> Time {
        minute += (second.num / second.den / 60) as usize;
        second.num %= 60 * second.den;
        hour += minute / 60;
        minute %= 60;
        hour %= one_day_hour;
        Time{one_day_hour: one_day_hour, hour: hour, minute: minute, second: second}
    }
    fn needle_pos(&self) -> (Needle, Needle, Needle) {
        let one_day_second = Rational::from_int(self.one_day_hour as i32 * 3600);
        let current_second = Rational::from_int(self.hour as i32) * Rational::from_int(3600) + Rational::from_int(self.minute as i32) * Rational::from_int(60) + self.second;
        let hour_pos = Position::new(current_second / one_day_second);
        let minute_pos = Position::new((Rational::from_int(self.minute as i32) * Rational::from_int(60) + self.second) /  Rational::from_int(3600));
        let second_pos = Position::new(self.second / Rational::from_int(60));
        let hour_speed = Rational::new(1, 3600 * self.one_day_hour as i64);
        let minute_speed = Rational::new(1, 3600);
        let second_speed = Rational::new(1, 60);
        (Needle{epoc_pos: hour_pos, speed: hour_speed}, Needle{epoc_pos: minute_pos, speed: minute_speed}, Needle{epoc_pos: second_pos, speed: second_speed})
    }
    fn succeeded(&self, second: Rational) -> Time {
        Time::new(self.one_day_hour, self.hour, self.minute, self.second + second)
    }
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
struct Position {
    ratio: Rational
}
impl Position {
    fn new(ratio: Rational) -> Position {
        Position{ratio: ratio}.normalize()
    }
    fn diff_from(&self, other: &Position) -> Position {
        Position::new(self.ratio - other.ratio)
    }
    fn normalize(&self) -> Position {
        Position{ratio: if self.ratio.num < 0 {
            Rational::new(self.ratio.den + self.ratio.num % self.ratio.den, self.ratio.den)
        }else if self.ratio.num >= self.ratio.den {
            Rational::new(self.ratio.num % self.ratio.den, self.ratio.den)
        }else {
            self.ratio
        }}
    }
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
struct Needle {
    epoc_pos: Position, speed: Rational
}
fn cal_mid_needle(epoc_time: Time) -> (Needle, Needle) {
    let (hour, minute, _) = epoc_time.needle_pos();
    let mid = (hour.epoc_pos.ratio + minute.epoc_pos.ratio) / Rational::from_int(2);
    let mid2 = mid + Rational::new(1, 2);
    let speed = (minute.speed + hour.speed) / Rational::from_int(2);
    (Needle{epoc_pos: Position::new(mid), speed: speed}, Needle{epoc_pos: Position::new(mid2), speed: speed})
}

fn main() {
    loop {
        read!(one_day_hour: usize, hour: usize, minute: usize, second: usize);
        if one_day_hour == 0 { break;}
        let start_time = Time{one_day_hour: one_day_hour, hour: hour, minute: minute, second: Rational::from_int(second as i32)};
        let (Needle{epoc_pos: pos_a, speed: mid_speed}, Needle{epoc_pos: pos_b, speed: _}) = cal_mid_needle(start_time);
        let (hour, minute, second) = start_time.needle_pos();
        if let Some(time) = vec![pos_a.diff_from(&second.epoc_pos).ratio / (second.speed - mid_speed), pos_b.diff_from(&second.epoc_pos).ratio / (second.speed- mid_speed)].into_iter().filter(|&diff| {
            let (h, m, _) = start_time.succeeded(diff).needle_pos();
            h.epoc_pos != m.epoc_pos
        }).min() {
            let min_time = start_time.succeeded(time);
            println!("{} {} {} {}", min_time.hour, min_time.minute, min_time.second.num, min_time.second.den);
        }else {
            panic!();
        }
    }
}


Measured memory_bytes: 5032