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: Accepted)

// Original: https://github.com/tanakh/competitive-rs
#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };

    ($next:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, [ $t:tt ]) => {
        {
            let len = read_value!($next, usize);
            (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
        }
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, bytes) => {
        read_value!($next, String).into_bytes()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::BTreeMap;

fn main() {
    input!(n: usize, k: usize);

    // N頂点の連結グラフには、少なくともN-1の辺がある
    // 全頂点の組み:N(N-1)/2
    // 辺で繋がれた頂点の組み:N-1
    // 最短距離が2の頂点の組み:N(N-1)/2 - (N-1) = (N-1)(N-2)/2 以下になる
    // -> K > N(N-1)/2 の時、構築できない
    // else 最短距離が2の頂点の組みがK個になるまで、スターグラフの任意の頂点を繋げればいい

    // 下限 完全グラフ(全ての頂点同士が辺で繋がっている)の時:0
    // 上限 スターグラフ(N-1個の頂点が真ん中の頂点とだけ辺で繋がっている)の時:(N-1)(N-2)/2

    let lim_node = (n - 1) * (n - 2) / 2;
    if k > lim_node {
        println!("-1");
    } else {
        // スターグラフ構築
        let mut graph = vec![];
        for i in 0..n - 1 {
            graph.push((i + 1, n));
        }

        // 新たに繋げる辺の候補を列挙
        let mut edge = vec![];
        for v in 0..n - 1 {
            for u in 0..v {
                edge.push((v + 1, u + 1));
            }
        }

        // 繋げる
        let add_num = lim_node - k;
        for i in 0..add_num {
            graph.push(edge[i]);
        }

        println!("{}", graph.len());
        for &(v, u) in graph.iter() {
            println!("{} {}", v, u);
        }
    }
}