Problem:
Score : 700 points

Problem Statement

Given are positive integers N and K.

Determine if the 3N integers K, K+1, ..., K+3N-1 can be partitioned into N triples (a_1,b_1,c_1), ..., (a_N,b_N,c_N) so that the condition below is satisfied. Any of the integers K, K+1, ..., K+3N-1 must appear in exactly one of those triples.

For every integer i from 1 to N, a_i + b_i \leq c_i holds.

If the answer is yes, construct one such partition.

Constraints

1 \leq N \leq 10^5

1 \leq K \leq 10^9

Input

Input is given from Standard Input in the following format:

N K

Output

If it is impossible to partition the integers satisfying the condition, print -1. If it is possible, print N triples in the following format:

a_1 b_1 c_1
:
a_N b_N c_N

Sample Input 1

1 1

Sample Output 1

1 2 3

Sample Input 2

3 3

Sample Output 2

-1

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

fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());
    let n: usize = sc.read();
    let k: usize = sc.read();

    let mut prefix = vec![];
    let mut suffix = vec![];
    for i in 0..n {
        if i % 2 == 0 {
            prefix.push(k + i);
        } else {
            suffix.push(k + i);
        }
    }

    prefix.extend(suffix);
    let a = prefix;
    let mut max_b = vec![];
    for i in 0..n {
        let c = 2 * n + i + k;
        let a = a[i];
        if c < a {
            println!("-1");
            return;
        }
        let b = c - a;
        max_b.push((b, i));
    }

    max_b.sort();
    let mut ans_b = vec![0; n];
    for i in 0..n {
        let b = k + n + i;
        if max_b[i].0 < b {
            println!("-1");
            return;
        }
        ans_b[max_b[i].1] = b;
    }

    for i in 0..n {
        let a = a[i];
        let b = ans_b[i];
        let c = 2 * n + i + k;
        sc.write(format!("{} {} {}\n", a, b, c));
    }

    // k + x
    // k+2 + x-1
    // ...
    // k+2a + x-a = k+x +0..a
    // k+1 + y
    // k+1+2+y-1
    // ...
    // k+2b+1+y-b = k+y+1 +0..b

    // k, ... ,k+2n-1
    // k+x+a+1 = k+y+1
    // x+a=y

    // k + x <= k+2N
    // k+2 + x-1 <= k+2N+1
    // k+4 + x-2
    // ...
    // k+2a + x-a <= k+2N+a
    // k+1 + x+a
    // k+3 + x+a-1
    // ...
    // k+1+2b + 2N+a-b <= k+3N-1
    // k+1+2a-2 + 2N + a - (a-1)
    // 2a = N-1
    // x=2N,
    // b=a-1

    // k   + 2N
    // k+2 + 2N-1
    // k+4 + 2N-2
    // ...
}

pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> IO<R, W> {
        IO(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: std::ops::Deref<Target = str>>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}