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 (Python):
import sys
input = sys.stdin.buffer.readline




def RD(): return sys.stdin.read()
def II(): return int(input())
def MI(): return map(int,input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int,input().split()))
def LF(): return list(map(float,input().split()))
def TI(): return tuple(map(int,input().split()))


def main():
	n,k=MI()

	kk=(n-1)*(n-2)//2-k

	if kk<0:
		print(-1)
		exit()

	ans=[]
	
	for i in range(1,n):
		ans.append([i,n])
	

	for i in range(1,n):
		for j in range(i+1,n):
			if kk>0:
				kk-=1
				ans.append([i,j])

	print(len(ans))
	for i,j in ans:
		print(i,j)













if __name__ == "__main__":
	main()

Solution (Python):
from collections import deque
n , k = map(int,input().split())
kouho = []
for i in range(n-1):
    for j in range(i+1,n):
        kouho.append((i,j))
s = len(kouho)
now = 0
ke = []
for i in range(n-2):
    for j in range(i+1,n-1):
        ke.append((i,j))
if len(ke) < k:
    print(-1)
    exit()
kesu = set()    
for i in range(k):
    kesu.add(ke[i])

route = [[] for i in range(n)]
m = 0
for i in range(s):
    if not kouho[i] in kesu:
        m += 1
        u , v = kouho[i]
        route[u].append(v)
        route[v].append(u)

d = deque()
d.append(0)
cou = 1
visit = [False for i in range(n)]
visit[0] = True
while d:
    now = d.popleft()
    for i in route[now]:
        if not visit[i]:
            cou += 1
            visit[i] = True
            d.append(i)

if cou != n:
    print(-1)
    exit()

print(m)
for i in range(s):
    if not kouho[i] in kesu:
        x , y = kouho[i]
        print(str(x+1) + " " + str(y+1))

Solution (Python):
import sys
from collections import deque

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

in_n = lambda: int(readline())
in_nn = lambda: map(int, readline().split())
in_s = lambda: readline().rstrip().decode('utf-8')
in_nl = lambda: list(map(int, readline().split()))
in_nl2 = lambda H: [in_nl() for _ in range(H)]
in_map = lambda: [s == ord('.') for s in readline() if s != ord('\n')]
in_map2 = lambda H: [in_map() for _ in range(H)]
in_all = lambda: map(int, read().split())


INF = 10 * 5


def warshall_floyd(V, cost):
    for k in range(V):
        for i in range(V):
            for j in range(V):
                if cost[i][k] != INF and cost[k][j] != INF:
                    cost[i][j] = min(cost[i][j], cost[i][k] + cost[k][j])


def main():

    N, K = in_nn()

    G = [[INF] * N for _ in range(N)]
    ans = []

    for i in range(1, N):
        G[0][i] = 1
        G[i][0] = 1
        ans.append((1, i + 1))

    warshall_floyd(N, G)

    comb = []
    for i in range(N):
        for j in range(i + 1, N):
            if G[i][j] == 2:
                comb.append((i + 1, j + 1))

    comb = deque(comb)
    max_k = len(comb)

    if max_k < K:
        print(-1)
        exit()

    while max_k > K:
        max_k -= 1
        ans.append(comb.popleft())

    print(len(ans))
    for i, j in ans:
        print(i, j)


if __name__ == '__main__':
    main()

Solution (Python):
N, K = map(int,input().split())

if K > (N-1) * (N-2) // 2:
    print(-1)
    exit()

M = N-1 + (N-1)*(N-2)//2 - K
print(M)

for i in range(2,N+1):
    print("{0} {1}".format(1,i))
    
cnt = N-1
for i in range(2,N+1):
    for j in range(i+1,N+1):
        if cnt == M: exit()
        
        print("{0} {1}".format(i,j))
        cnt += 1

Solution (Python):
n, k = map(int, input().split())
if (n - 2) * (n - 1) // 2 >= k:
    m = (n - 1) * n // 2 - k
    print(m)
    cnt = 0
    for i in range(1, n + 1):
        for j in range(i + 1, n + 1):
            print(i, j)
            cnt += 1
            if cnt == m:
                exit()
else:
    print(-1)

Solution (Python):
import sys
sys.setrecursionlimit(10**8)
stdin = sys.stdin


def ni(): return int(ns())


def na(): return list(map(int, stdin.readline().split()))


def naa(N): return [na() for _ in range(N)]


def ns(): return stdin.readline().rstrip()  


N, K = na()

if K > ((N-1) * (N-2) / 2):
    print(-1)
else:
    M = (N-1) + (N-1) * (N-2) // 2 - K
    print(M)
    for i in range(N-1):
        print(1, (i+2))
    cnt = M - (N-1)
    if cnt == 0:
        exit()
    for i in range(2, N+1):
        for j in range(i+1, N+1):
            cnt -= 1
            print(i, j)
            if cnt == 0:
                break
        if cnt == 0:
            break

Solution (Python):
import sys
import re
import math
import collections
import bisect
import itertools
import fractions
import functools
import copy
import heapq
import decimal
import statistics
import queue



sys.setrecursionlimit(10 ** 9)
INF = 10 ** 16
MOD = 10 ** 9 + 7


ni = lambda: int(sys.stdin.readline())
ns = lambda: map(int, sys.stdin.readline().split())
na = lambda: list(map(int, sys.stdin.readline().split()))
nb = lambda: list(map(lambda x: int(x) - 1, sys.stdin.readline().split()))





def main():
    n, k = ns()
    ans = []

    tmp = (n - 1) * (n - 2) // 2
    if k > tmp:
        print(-1)
        exit(0)

    for i in range(n - 1):
        ans.append([i, n - 1])

    breakflg = False
    for i in range(n - 1):
        for j in range(i + 1, n - 1):
            if tmp == k:
                breakflg = True
                break

            tmp -= 1
            ans.append([i, j])

        if breakflg:
            break

    print(len(ans))
    for a, b in ans:
        print(a + 1, b + 1)


if __name__ == '__main__':
    main()

Solution (Python):
import sys
import re
import math
import collections
import bisect
import itertools
import fractions
import functools
import copy
import heapq
import decimal
import statistics
import queue



sys.setrecursionlimit(10 ** 9)
INF = 10 ** 16
MOD = 10 ** 9 + 7


ni = lambda: int(sys.stdin.readline())
ns = lambda: map(int, sys.stdin.readline().split())
na = lambda: list(map(int, sys.stdin.readline().split()))
nb = lambda: list(map(lambda x: int(x) - 1, sys.stdin.readline().split()))





def main():
    n, k = ns()
    ans = []

    tmp = (n - 1) * (n - 2) // 2
    if k > tmp:
        print(-1)
        exit(0)

    for i in range(n - 1):
        ans.append([i, n - 1])

    breakflg = False
    for i in range(n - 1):
        for j in range(i + 1, n - 1):
            if tmp == k:
                breakflg = True
                break

            tmp -= 1
            ans.append([i, j])

        if breakflg:
            break

    print(len(ans))
    for a, b in ans:
        print(a + 1, b + 1)


if __name__ == '__main__':
    main()

Solution (Python):

N, K = map(int, input().split())
res = (N - 1) * (N - 2) // 2 - K

if res < 0:
    print(-1)
else:
    ans = []
    for i in range(2, N + 1):
        ans.append([1, i])

    cnt = 0
    for i in range(2, N):
        if cnt == res:
            break

        for j in range(i + 1, N + 1):
            if cnt == res:
                break
            ans.append([i, j])
            cnt += 1

    print(len(ans))
    for v in ans:
        print(*v)

Solution (Python):
import itertools
n, k = map(int, input().split())
max_val = (n - 1) * (n - 2) // 2
if max_val < k:
    print(-1)
    quit()
m = max_val - k

print (n - 1 + m)
for i in range(2, n + 1):
    print("{} {}".format(1, i))

for i, j in itertools.combinations(range(2, n + 1), 2):
    if m == 0:
        break
    print("{} {}".format(i, j))
    m -= 1

Solution (Python):
from itertools import combinations

N,K=map(int,input().split())

MAX=(N-1)*(N-2)//2

if K>MAX:
  print(-1)
  exit()

n_add=MAX-K
M=N-1+n_add
e_comb = list(combinations(range(2,N+1),r=2))

print(M)
for i in range(M):
  if i < N-1:
    print(*(1,2+i))
  else:
    print(*e_comb[i-(N-1)])

Solution (Python):






import sys
input = sys.stdin.readline

import math

import bisect
import heapq
from collections import defaultdict
from collections import deque
from collections import Counter
from functools import lru_cache





MOD = 10**9+7
INF = float('inf')
AZ = "abcdefghijklmnopqrstuvwxyz"






def I(): return int(input().strip())
def S(): return input().strip()
def IL(): return list(map(int,input().split()))
def SL(): return list(map(str,input().split()))
def ILs(n): return list(int(input()) for _ in range(n))
def SLs(n): return list(input().strip() for _ in range(n))
def ILL(n): return [list(map(int, input().split())) for _ in range(n)]
def SLL(n): return [list(map(str, input().split())) for _ in range(n)]


def P(arg): print(arg); return
def Y(): print("Yes"); return
def N(): print("No"); return
def E(): exit()
def PE(arg): print(arg); exit()
def YE(): print("Yes"); exit()
def NE(): print("No"); exit()


def DD(arg): return defaultdict(arg)


def inv(n): return pow(n, MOD-2, MOD)


kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n): return kaijo_memo[n]
  if(len(kaijo_memo) == 0): kaijo_memo.append(1)
  while(len(kaijo_memo) <= n): kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]

gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n): return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0): gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n): gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]

def nCr(n,r):
  if n == r: return 1
  if n < r or r < 0: return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret


def factorization(n):
  arr = []
  temp = n
  for i in range(2, int(-(-n**0.5//1))+1):
    if temp%i==0:
      cnt=0
      while temp%i==0: 
        cnt+=1 
        temp //= i
      arr.append([i, cnt])
  if temp!=1: arr.append([temp, 1])
  if arr==[]: arr.append([n, 1])
  return arr


def make_divisors(n):
  divisors = []
  for i in range(1, int(n**0.5)+1):
    if n % i == 0:
      divisors.append(i)
      if i != n // i: 
        divisors.append(n//i)
  return divisors


def make_primes(N):
  max = int(math.sqrt(N))
  seachList = [i for i in range(2,N+1)]
  primeNum = []
  while seachList[0] <= max:
    primeNum.append(seachList[0])
    tmp = seachList[0]
    seachList = [i for i in seachList if i % tmp != 0]
  primeNum.extend(seachList)
  return primeNum


def gcd(a, b):
    while b: a, b = b, a % b
    return a


def lcm(a, b):
    return a * b // gcd (a, b)


def count_bit(n):
  count = 0
  while n:
    n &= n-1
    count += 1
  return count


def base_10_to_n(X, n):
  if X//n: return base_10_to_n(X//n, n)+[X%n]
  return [X%n]

def base_n_to_10(X, n):
  return sum(int(str(X)[-i-1])*n**i for i in range(len(str(X))))

def base_10_to_n_without_0(X, n):
  X -= 1
  if X//n: return base_10_to_n_without_0(X//n, n)+[X%n]
  return [X%n]


def int_log(n, a):
  count = 0
  while n>=a:
    n //= a
    count += 1
  return count




  
N,K = IL()
M = (N-1)*(N-2)//2
if K > M:
  print(-1)
  exit()
print(N-1+(M-K))
for i in range(N-1):
  print(i+1,N)
from itertools import combinations
ans = list(combinations(range(1,N), 2))
for i in range(M-K):
  b,c = ans.pop()
  print(b,c)

Solution (Python):
import sys
def MI(): return map(int,sys.stdin.readline().rstrip().split())

N,K = MI()

if K > ((N-1)*(N-2))//2:
    print(-1)
    exit()

print(N-1+((N-1)*(N-2))//2-K)

for i in range(2,N+1):
    print(1,i)

a = 0
for i in range(2,N):
    for j in range(i+1,N+1):
        if a < ((N-1)*(N-2))//2-K:
            print(i,j)
            a += 1

Solution (Python):
n,k = map(int,input().split())

if k == 0:
    G = []
    for i in range(1,n):
        for j in range(i+1,n+1):
            G.append((i,j))
    print(len(G))
    for u,v in G:
        print(u,v)
    exit(0)

if k-(n-1)*(n-2)//2 > 0:
    print(-1)
    exit(0)

G = []
for i in range(1,n):
    G.append((i,n))

count = (n-1)*(n-2)//2-k
for i in range(1,n-1):
    for j in range(i+1,n):
        if count == 0:
            print(len(G))
            for u,v in G:
                print(u,v)
            exit(0)
        G.append((i,j))
        count -= 1

Solution (Python):

import sys

def solve(N: int, K: int):
    k = (N - 1) * (N - 2) // 2
    if k < K:
        return None
    edges = [(1, i) for i in range(2, N+1)]
    def f():
        for i in range(2, N+1):
            for j in range(i+1, N+1):
                yield i, j
    it = f()
    while k > K:
        edges.append(next(it))
        k -= 1
    return edges


def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    K = int(next(tokens))  
    edges = solve(N, K)
    if edges:
        print(len(edges))
        for e in edges:
            print(*e)
    else:
        print(-1)

def test():
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    test()
    main()

Solution (Python):
import sys, math
from collections import defaultdict, deque, Counter
from bisect import bisect_left, bisect_right
from itertools import combinations, permutations, product
from heapq import heappush, heappop
from functools import lru_cache
input = sys.stdin.readline
rs = lambda: input().strip()
ri = lambda: int(input())
rl = lambda: list(map(int, input().split()))
mod = 1000000007
sys.setrecursionlimit(1000000)

N, K = rl()

m = (N-1)*(N-2)//2
if K > m:
	print(-1)
	exit()

ans = []
for i in range(1, N):
	ans.append((1, i+1))
remains = []
for i in range(1, N):
	for j in range(i+1, N):
		remains.append((i+1, j+1))
k = m-K
for i in range(k):
	ans.append(remains[i])
print(len(ans))
for p in ans:
	print(*p)

Solution (Python):
from itertools import combinations
n, k = map(int, input().split())
if k>(n-1)*(n-2)//2:
    print(-1)
    exit(0)
edges = []
for i in range(2, n+1):
    edges.append((1, i))
k = (n-1)*(n-2)//2-k
for i, j in combinations(range(2, n+1), 2):
    if k==0:
        break
    edges.append((i, j))
    k -= 1
print(len(edges))
for i, j in edges:
    print(i, j)

Solution (Python):
import sys
sys.setrecursionlimit(10**7) 
import math
from copy import copy, deepcopy
from copy import deepcopy as dcp
from operator import itemgetter
from bisect import bisect_left, bisect, bisect_right

from collections import deque, defaultdict


from collections import Counter

from itertools import accumulate,combinations,permutations,product

from heapq import heapify,heappop,heappush


from functools import reduce,lru_cache

from decimal import Decimal

def input(): 
    x=sys.stdin.readline()
    return x[:-1] if x[-1]=="\n" else x
def printe(*x):print("
def printl(li): _=print(*li, sep="\n") if li else None
def argsort(s, return_sorted=False): 
    inds=sorted(range(len(s)), key=lambda k: s[k])
    if return_sorted: return inds, [s[i] for i in inds]
    return inds
def alp2num(c,cap=False): return ord(c)-97 if not cap else ord(c)-65
def num2alp(i,cap=False): return chr(i+97) if not cap else chr(i+65)
def matmat(A,B):
    K,N,M=len(B),len(A),len(B[0])
    return [[sum([(A[i][k]*B[k][j]) for k in range(K)]) for j in range(M)] for i in range(N)]
def matvec(M,v):
    N,size=len(v),len(M)
    return [sum([M[i][j]*v[j] for j in range(N)]) for i in range(size)]
def T(M):
    n,m=len(M),len(M[0])
    return [[M[j][i] for j in range(n)] for i in range(m)]
def main():
    mod = 1000000007
    

    
    N, K = map(int, input().split())
    
    
    
    if K>(N-2)*(N-1)//2:
        print(-1)
        return 
    s=set()
    cur=0
    f=0
    for i in range(1,N):
        for j in range(i+1,N):
            if cur<K:
                s.add((i,j))
                cur+=1
            else:
                f=1
            if f:
                break
        if f:
            break
    print(N*(N-1)//2-K)
    for i in range(0,N):
        for j in range(i+1,N):
            if (i,j) not in s:
                print(i+1,j+1)





if __name__ == "__main__":
    main()

Solution (Python):
N, K = map(int,input().split())
max_edge = (N-1)*(N-2)//2
all_edges = [[i,j] for i in range(N) for j in range(i+1,N)]

if 0 <= K <= max_edge:
    minus = max_edge - K
    count = 0
    answer = []
    for edge in all_edges:
        if edge[0] == 0:
            answer.append(edge)
        elif count < minus:
            answer.append(edge)
            count+=1
    print(len(answer))
    for i in range(len(answer)):
        print((" ").join(str(j+1) for j in answer[i]))
else:
    print(-1)

Solution (Python):
n,k=map(int,input().split())
if k>((n-1)*(n-2))//2:
  print(-1)
else:
  m=((n-1)*(n-2))//2
  d=m-k
  print(n-1+d)
  for i in range(n-1):
    print(1,i+2)
  if d==0:exit()
  for i in range(2,n):
    for j in range(i+1,n+1):
      print(i,j)
      d-=1
      if d==0:
        exit()

Solution (Python):
N,K = map(int, input().split())
if K > (N-1)*(N-2)//2:
  print(-1)
  exit(0)
ANS = []
for i in range(2,N+1):
  ANS.append((1,i))
  
cnt = (N-1)*(N-2)//2
for i in range(2,N+1):
  if cnt == K:
    break
  for j in range(i+1,N+1):
    ANS.append((i,j))
    cnt -= 1
    if cnt == K:
      break
      
print(len(ANS))
for i,j in ANS:
  print(i,j)

Solution (Python):


import sys
sys.setrecursionlimit(10 ** 5 + 10)


def input(): return sys.stdin.readline().strip()


def resolve():

    n, k = map(int, input().split())
    val = (n-1)*(n-2)//2
    if k > val:
        print(-1)
    else:
        rem = val-k
        print(n-1+rem)
        for i in range(2,n+1):
            print(1,i)
        a, b = 2, 3
        cnt = 0
        for i in range(rem):
            print(a,b)
            if b < n:
                b+=1
            else:
                a += 1
                b = a+1



resolve()

Solution (Python):
from itertools import combinations

N,K=list(map(int,input().split()))

node=(N-1)*(N-2)//2

if K>node:
    print(-1)
    exit(0)

g=[[] for _ in range(N+1)]
M=0

for i in range(2,N+1):
    g[1].append(i)
    M+=1

cnt=node-K

for u,v in combinations(range(2,N+1),2):
    if cnt==0:
        break
    g[u].append(v)
    
    M+=1
    cnt-=1


print(M)
for i in range(1,N+1):
    for j in g[i]:
        print('{} {}'.format(i,j))

Solution (Python):
import math

N, K = map(int, input().split())

upper = (N-1)*(N-2) // 2
if upper < K:
    print(-1)
else:
    diff = upper - K
    edges = []
    for i in range(2, N+1):
        edges.append((1, i))
    j = 2
    while diff > 0:
        k = j + 1
        while k <= N and diff > 0:
            edges.append((j, k))
            k += 1
            diff -= 1
        j += 1
    print(len(edges))
    for e in edges:
        print(*e)

Solution (Python):
def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
import heapq
import math
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7






N, K = getNM()

def cmb_1(n, r):
    if n < r:
        return 0
    r = min(n - r, r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1, r + 1))
    return over // under

cnt = cmb_1(N - 1, 2) - K

if cnt < 0:
    print(-1)
    exit()

dist = [[float('inf')] * N for i in range(N)]
for i in range(N):
    dist[i][i] = 0
query = [[1, i] for i in range(2, N + 1)]

for a, b in combinations([i for i in range(2, N + 1)], 2):
    if cnt == 0:
        break
    query.append([a, b])
    cnt -= 1

print(len(query))
for i in query:
    print(*i)

"""
for a,b in query:
    dist[a - 1][b - 1] = 1
    dist[b - 1][a - 1] = 1

def warshall_floyd(dist):
    for k in range(N):
        
        for i in range(N):
            for j in range(N):
                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
    return dist

warshall_floyd(dist)

for i in dist:
    print(i)
"""

Solution (Python):
import sys

N, K = map(int, sys.stdin.readline().split())

comb = (N-1) * (N-2) // 2

if K > comb:
    print(-1)
else:
    
    res = comb - K
    print(N-1 + res)
    for i in range(2, N+1):
        print(1, i)
    for i in range(2, N):
        for j in range(i, N):
            if res == 0:
                sys.exit()
            print(i, j+1)
            res -= 1

Solution (Python):
import sys

sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, k = map(int, input().split())
    edge = []
    for i in range(1, n):
        edge.append([1, i + 1])

    total = ((n - 1) * (n - 2)) // 2
    if k > total:
        print(-1)
        exit()

    diff = total - k
    while diff:
        for i in range(1, n):
            for j in range(i + 1, n):
                edge.append([i + 1, j + 1])
                diff -= 1
                if diff == 0:
                    break
            else:
                continue
            break

    print(len(edge))
    for res in edge:
        print(*res)


if __name__ == '__main__':
    resolve()

Solution (Python):
n,k=map(int,input().split())
if k>(n-1)*n//2-(n-1):
    print(-1)
else:
    ans=[(1,i) for i in range(2,n+1)]
    lestnum=(n-1)*n//2-(n-1)-k
    for i in range(2,n):
        for j in range(i+1,n+1):
            if lestnum!=0:
                ans.append((i,j))
                lestnum-=1
    print(len(ans))
    for i in ans:
        print(" ".join(map(str,i)))

Solution (Python):
n, k = map(int,input().split())
x = (n-2)*(n-1)//2

if k > x:
    print(-1)
    exit()

ans = []
for i in range(2, n+1):
    ans.append([1, i])
i = 2
j = 3
while k < x:
    ans.append([i, j])
    if j < n:
        j += 1
    else :
        i += 1
        j = i+1
    x -= 1 

print(len(ans))
for i in range(len(ans)):
    b = [str(i) for i in ans[i]]
    print(' '.join(b))

Solution (Python):
n, k = map(int, input().split())
if (n - 2) * (n-1) // 2 < k:
    print(-1)
else:
    
    ans = []
    for i in range(2,n+1):
        ans.append([1, i])
    num = (n-2) * (n-1) // 2
    for i in range(2,n+1):
        for j in range(i+1,n+1):
            if num == k:
                print(len(ans))
                for ans_array in ans:
                    print("{} {}".format(*ans_array))
                exit()
            num -= 1
            ans.append([i,j])
    print(len(ans))
    for ans_array in ans:
        print("{} {}".format(*ans_array))

Solution (Python):
def main():
    n, k = map(int, input().split())
    lim = (n-2)*(n-1)//2
    if lim < k:
        print(-1)
    else:
        ans = []
        for i in range(2, n+1):
            ans.append([1, i])
        x = lim
        for i in range(2, n):
            for j in range(i+1, n+1):
                if x == k:
                    break
                ans.append([i, j])
                x -= 1
            if x == k:
                break
        print(len(ans))
        for u, v in ans:
            print(u, v)

if __name__ == "__main__":
    main()

Solution (Python):
N, K = map(int, input().split())

total = (N - 1) * (N - 2) // 2
if K > total:
    print(-1)
else:
    edges = []
    for k in range(2, N + 1):
        edges.append([1, k])

    res = total - K
    cnt = 0
    for u in range(2, N + 1):
        if cnt == res:
            break
    
        for v in range(u + 1, N + 1):
            edges.append([u, v])
            cnt += 1

            if cnt == res:
                break

    print(len(edges))
    for v in edges:
        print(*v)

Solution (Python):
N, K = map(int,input().split())


node = [[] for _ in range(N)]
node[0] = [i for i in range(1,N)]

if K > N*(N-1)//2 - (N-1):
    print(-1)
else:
    cnt = 0
    for i in range(1,N):
        if cnt >= N*(N-1)//2-(N-1)-K:
            break
        for j in range(i+1,N):
            if cnt >= N*(N-1)//2-(N-1)-K:
                break
            node[i].append(j)
            cnt += 1
    
    print(N-1+cnt)
    for n in range(N):
        for t in node[n]:
            print(n+1,t+1)

Solution (Python):
from itertools import combinations


def main():
    N, K = list(map(int, input().split(' ')))
    if K > (N - 1) * (N - 2) // 2:
        print(-1)
        return
    
    adj_nodes = [[] for _ in range(N)]
    adj_nodes[0] = [n for n in range(1, N)]
    C = (N - 1) * (N - 2) // 2 - K
    c = 0
    for comb in combinations(range(1, N), 2):
        if c >= C:
            break
        u, v = comb
        adj_nodes[u].append(v)
        c += 1
    print(N - 1 + C)
    for u in range(N):
        for v in adj_nodes[u]:
            print('{} {}'.format(u + 1, v + 1))


if __name__ == '__main__':
    main()

Solution (Python):
n, k = map(int, input().split())
if k > (n - 1) * (n - 2) // 2:print(-1)
else:
    m = (n - 1) * (n - 2)  // 2 - k
    print(n + m - 1)
    for i in range(2, n + 1):
        print(1, i)
    cnt = 0
    for i in range(2, n + 1):
        if cnt >= m:
            break
        for j in range(2, i):
            if cnt >= m:
                break
            print(i, j)
            cnt += 1

Solution (Python):
import sys
sys.setrecursionlimit(10**9)

def mi(): return map(int,input().split())
def ii(): return int(input())
def isp(): return input().split()

def main():
    N,K=mi()

    if not K <= (N-1)*(N-2)//2:
        print(-1)
        exit()


    k = (N-1)*(N-2)//2
    v = set([(1,x+1) for x in range(1,N)])


    

    for i in range(2,N+1):
        for j in range(1,N+1):
            if k <= K: continue

            if i+j <= N and not v in (i,i+j):
                v.add((i,i+j))
                
                k -= 1
            if k <= K:
                break
        if k <= K:
            break



    if k != K:
        print(-1)
        exit()

    print(len(v))
    for x,y in v:
        print(x,y)



if __name__ == "__main__":
  main()

Solution (Python):
import sys

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007


def main():
    N, K = map(int, readline().split())

    if K > (N - 1) * (N - 2) // 2:
        print('-1')
        return
        
    m = (N - 1) * (N - 2) // 2 - K
    M = N - 1 + m
    
    print(M)
    for i in range(2, N+1):
        print(1, i)
    
    i, j = 2, 3
    for _ in range(m):
        print(i, j)
        if j == N:
            i += 1
            j = i + 1
        else:
            j += 1

    return


if __name__ == '__main__':
    main()

Solution (Python):
def main():
  N, K  = map(int, input().split())
  max_pair = (N-1)*(N-2)//2
  if max_pair < K:
    print(-1)
  else:
    edge = []
    for i in range(N-1):
      edge.append([1, 2+i])
    from_ = 2
    to_ = 3
    for i in range(max_pair-K):
      edge.append([from_, to_])
      to_ += 1
      if to_ > N:
        from_ += 1
        to_ = from_ + 1
    num = len(edge)
    print(num)
    [print(*edge[i]) for i in range(num)]
    
if __name__ == "__main__":
  main()

Solution (Python):
import itertools

n, k = map(int, input().split())
if k > (n - 1) * (n - 2) // 2:
    print(-1)
else:
    tmp = (n - 1) * (n - 2) // 2
    tmp -= k
    print(n - 1 + tmp)
    for i in range(1, n):
        print(i, n)
    if tmp == 0:
        exit()
    for lst in itertools.combinations(range(1, n), 2):
        print(lst[0], lst[1])
        tmp -= 1
        if tmp == 0:
            break

Solution (Python):
N, K = map(int, input().split())
if K > (N-1)*(N-2)//2:
    print(-1)
else:
    s = (N-1)*(N-2)//2
    ans = []
    for i in range(2, N+1):
        ans.append([1, i])
    for i in range(2, N):
        if s == K:
            break
        for j in range(i+1, N+1):
            if s == K:
                break
            ans.append([i, j])
            s -= 1
    print(len(ans))
    for i, j in ans:
        print(i, j)

Solution (Python):
def solve():
  N, K = map(int, input().split())
  if K > (N - 1) * (N - 2) // 2:
    print(-1)
    return
  else:
    root = [[False for _ in range(N + 10)] for _ in range(N + 10)]
    M = (N - 1) * (N - 2) // 2 - K
    i = 1
    j = 2
    print(M + N - 1)
    for k in range(N - 1):
      print('1 {}'.format(k + 2))
    for _ in range(M):
      print('{0} {1}'.format(i + 1, j + 1))
      j += 1
      if j == N:
        i += 1
        j = i + 1
    return
solve()

Solution (Python):
n,k=map(int,input().split())



if k>((n-1)*(n-2))//2:
    print(-1)
    exit()

ans=set([])

cnt=((n-1)*(n-2))//2
for i in range(2,n+1):
    ans.add((1,i))

for i in range(2,n):
    for j in range(i+1,n+1):
        if cnt>k:
            ans.add((i,j))
            cnt-=1
        else:
            break

print(len(ans))

for item in ans:
    print(item[0],item[1])

Solution (Python):
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

from itertools import combinations
def main():
    N, K = map(int, readline().split())    
    
    
    
    
    
    if K > (N-2)*(N-1)//2:
        print(-1) 
        return 

    
    
    
    
    
    
    M = (N-1)*(N-2)//2 - K
    
    
    print(M + N-1) 

    
    for i in range(2, N+1):
        print(1, i)

    
    
    cnt = 0
    
    p = [int(i) for i in range(2, N+1)] 
    for i, j in combinations(p, 2):
        if cnt == M:
            return
        print(i, j)
        cnt += 1
if __name__ == '__main__':
    main()

Solution (Python):
import sys
sys.setrecursionlimit(10000000)
input=sys.stdin.readline

n,k = map(int,input().split())

mx=(n-1)*(n-2)//2

if mx < k:print(-1);exit()

ans=[]
for i in range(n-1):
    ans.append((i+1,n))


add=mx-k

edge=[]
for i in range(n-1):
    for j in range(i):
        edge.append((i+1,j+1))
for i in range(add):
    ans.append(edge[i])

print(len(ans))
for i in ans:
    print(*i)