Problem:
Score: 500 points

Problem Statement

Does there exist an undirected graph with N vertices satisfying the following conditions?

The graph is simple and connected.

The vertices are numbered 1, 2, ..., N.

Let M be the number of edges in the graph. The edges are numbered 1, 2, ..., M, the length of each edge is 1, and Edge i connects Vertex u_i and Vertex v_i.

There are exactly K pairs of vertices (i,\ j)\ (i < j) such that the shortest distance between them is 2.

If there exists such a graph, construct an example.

Constraints

All values in input are integers.

2 \leq N \leq 100

0 \leq K \leq \frac{N(N - 1)}{2}

Input

Input is given from Standard Input in the following format:

N K

Output

If there does not exist an undirected graph with N vertices satisfying the conditions, print -1.

If there exists such a graph, print an example in the following format (refer to Problem Statement for what the symbols stand for):

M
u_1 v_1
:
u_M v_M

If there exist multiple graphs satisfying the conditions, any of them will be accepted.

Sample Input 1

5 3

Sample Output 1

5
4 3
1 2
3 1
4 5
2 3

This graph has three pairs of vertices such that the shortest distance between them is 2: (1,\ 4), (2,\ 4), and (3,\ 5). Thus, the condition is satisfied.

Sample Input 2

5 8

Sample Output 2

-1

There is no graph satisfying the conditions.

Solution in Rust (1.15.1) (judge verdict: Runtime Error)

#![allow(unused_imports)]
#![allow(non_snake_case)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn print_graph(n: i64, islands: Vec<i64>) {
    let mut current_pointer = 0;
    let mut islands_obj = vec![vec![]; islands.len()];
    for (i, &island) in islands.iter().enumerate() {
        for j in 0..island {
            islands_obj[i].push(current_pointer);
            current_pointer += 1;
        }
    }
    assert!(current_pointer <= n - 1);
    while current_pointer < n {
        islands_obj.push(vec![current_pointer]);
        current_pointer += 1;
    }
    let mut edges = vec![];
    for island in islands_obj.iter() {
        for i in 0..island.len() {
            for j in i + 1..island.len() {
                edges.push((island[i], island[j]));
            }
        }
    }

    let polars = islands_obj[0].clone();
    for ref island in islands_obj.iter().skip(1) {
        for &mem in island.iter() {
            for &polar_mem in polars.iter() {
                edges.push((mem, polar_mem));
            }
        }
    }
    println!("{}", edges.len());
    for &(a, b) in edges.iter() {
        println!("{} {}", a + 1, b + 1);
    }
}

fn comb2(n: i64) -> i64 {
    n * (n - 1) / 2
}

fn main() {
    let v = read_vec::<i64>();
    let (n, k) = (v[0], v[1]);
    for polar_num in 1..n - 2 {
        let mut residual_apex = n - polar_num;
        let mut constructed = comb2(residual_apex);
        let mut islands = vec![polar_num];
        if constructed == k {
            debug!(polar_num);
            print_graph(n, islands);
            return;
        }
        while residual_apex > 0 {
            for i in 2..residual_apex + 1 {
                if constructed - comb2(i + 1) < k {
                    debug!(polar_num, constructed);
                    residual_apex -= i;
                    constructed -= comb2(i);
                    islands.push(i);
                }
                if constructed == k {
                    debug!(polar_num);
                    print_graph(n, islands);
                    return;
                }
            }
        }
    }
    println!("-1");
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}