Problem:
Score : 300 points

Problem Statement

Snuke loves puzzles.

Today, he is working on a puzzle using S- and c-shaped pieces.
In this puzzle, you can combine two c-shaped pieces into one S-shaped piece, as shown in the figure below:

Snuke decided to create as many Scc groups as possible by putting together one S-shaped piece and two c-shaped pieces.

Find the maximum number of Scc groups that can be created when Snuke has N S-shaped pieces and M c-shaped pieces.

Constraints

1 ≤ N,M ≤ 10^{12}

Input

The input is given from Standard Input in the following format:

N M

Output

Print the answer.

Sample Input 1

1 6

Sample Output 1

2

Two Scc groups can be created as follows:

Combine two c-shaped pieces into one S-shaped piece

Create two Scc groups, each from one S-shaped piece and two c-shaped pieces

Sample Input 2

12345 678901

Sample Output 2

175897

Solution in Rust (1.15.1) (judge verdict: Accepted)

use scanner::Scanner;
use std::cmp::min;
use std::io::*;
use std::str::*;

fn solve<'a, R>(sc: &mut Scanner<'a, R>, out: &mut Write)
where
    R: BufRead,
{
    let n = sc.next_signed().unwrap();
    let m = sc.next_signed().unwrap();

    let x = min(n, m / 2);
    let y = (m - x * 2) / 4;
    writeln!(out, "{}", x + y);
}

fn main() {
    let stdin = stdin();
    let mut locked = stdin.lock();
    let mut scanner = &mut Scanner::new(&mut locked);
    let mut writer = stdout();

    solve(&mut scanner, &mut writer);
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn example1() {
        let mut input: &[u8] = b"1 6";
        let output: &[u8] = b"2\n";

        let mut scanner = &mut Scanner::new(&mut input);
        let mut answer = Vec::<u8>::new();

        solve(&mut scanner, &mut answer);

        assert_eq!(output, answer.as_slice());
    }

    #[test]
    fn example2() {
        let mut input: &[u8] = b"12345 678901";
        let output: &[u8] = b"175897\n";

        let mut scanner = &mut Scanner::new(&mut input);
        let mut answer = Vec::<u8>::new();

        solve(&mut scanner, &mut answer);

        assert_eq!(output, answer.as_slice());
    }
}

mod scanner {
    use std::io::{BufRead, Error, ErrorKind, Read};
    use std::str::FromStr;

    pub struct Scanner<'a, R>
    where
        R: 'a + BufRead + ?Sized,
    {
        reader: &'a mut R,
    }

    impl<'a, R> Scanner<'a, R>
    where
        R: 'a + BufRead + ?Sized,
    {
        pub fn new(reader: &'a mut R) -> Self {
            Scanner { reader: reader }
        }

        pub fn next_byte(&mut self) -> Result<u8, Error> {
            self.reader
                .bytes()
                .skip_while(|ref c| !Self::is_printable(*c.as_ref().ok().unwrap()))
                .next()
                .unwrap()
        }

        pub fn next_bytes(&mut self) -> Result<Vec<u8>, Error> {
            self.reader
                .bytes()
                .skip_while(|ref c| !Self::is_printable(*c.as_ref().ok().unwrap()))
                .take_while(|ref c| Self::is_printable(*c.as_ref().ok().unwrap()))
                .collect()
        }

        pub fn next_unsigned(&mut self) -> Result<u64, Error> {
            self.reader
                .bytes()
                .skip_while(|ref c| !Self::is_printable(*c.as_ref().ok().unwrap()))
                .take_while(|ref c| Self::is_printable(*c.as_ref().ok().unwrap()))
                .fold(Ok(0), |s, x| {
                    s.and_then(|t| {
                        x.and_then(|y| {
                            if b'0' <= y && y <= b'9' {
                                Ok(t * 10 + (y - b'0') as u64)
                            } else {
                                Err(Error::new(ErrorKind::InvalidData, "found not a digit"))
                            }
                        })
                    })
                })
        }

        pub fn next_signed(&mut self) -> Result<i64, Error> {
            self.reader
                .bytes()
                .skip_while(|ref c| !Self::is_printable(*c.as_ref().ok().unwrap()))
                .take_while(|ref c| Self::is_printable(*c.as_ref().ok().unwrap()))
                .fold(Ok([0i64, 0]), |s, x| {
                    x.and_then(|y| {
                        s.and_then(|t| {
                            if t[0] == 0 && y == b'-' {
                                Ok([-1, 0])
                            } else if b'0' <= y && y <= b'9' {
                                Ok([
                                    if t[0] == 0 { 1 } else { t[0] },
                                    t[1] * 10 + (y - b'0') as i64,
                                ])
                            } else {
                                Err(Error::new(ErrorKind::InvalidData, "found not a digit"))
                            }
                        })
                    })
                })
                .and_then(|s| Ok(s[0] * s[1]))
        }

        pub fn next_float(&mut self) -> Result<f64, Error> {
            self.reader
                .bytes()
                .skip_while(|ref c| !Self::is_printable(*c.as_ref().ok().unwrap()))
                .take_while(|ref c| Self::is_printable(*c.as_ref().ok().unwrap()))
                .collect::<Result<Vec<u8>, Error>>()
                .and_then(|t| {
                    String::from_utf8(t).or(Err(Error::new(ErrorKind::InvalidData, "invalid data")))
                })
                .and_then(|s| {
                    f64::from_str(&s).or(Err(Error::new(ErrorKind::InvalidData, "invalid data")))
                })
        }

        fn is_printable(c: u8) -> bool {
            0x21 <= c && c <= 0x7e
        }
    }
}