#pragma GCC target("avx2")
#pragma GCC optimize("O3")
   
#include <x86intrin.h>
#include <bits/stdc++.h>   
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
using namespace __gnu_pbds;
using namespace std;

template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
     
#define F first
#define S second           
#define lb lower_bound               
#define ub upper_bound
#define pb push_back
#define pf push_front    
#define ppb pop_back
#define mp make_pair
#define bpp __builtin_popcountll                                                                                        
#define sqr(x) ((x) * (x)) 
#define al 0x3F3F3F3F
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define in insert
#define ppf pop_front
#define endl '\n'
//#define int long long
 
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
 
const int mod = (int)1e9 + 7;
const int N = (int)3e5 + 123;
const ll inf = (ll)1e18 + 1;

const double pi = acos (-1.0);
const double eps = 1e-7;                  
const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

int n, k, dp[101][10001], p[101][100001];
vector <pii> ans;
vector <int> path;

inline void can (int has, int kol) {      
   memset (dp, 0, sizeof dp);
   dp[has][kol] = 1;
   for (int i = has; i >= 1; i --) {
      for (int j = kol; j >= 1; j --) {
         if (!dp[i][j]) continue;
         for (int k = 1; k <= i; k ++) {
            if (j < k * (k + 1) / 2) continue;
            int n_j = j - k * (k + 1) / 2;
            int n_i = i - k;
            if (!dp[n_i][n_j]) {
               dp[n_i][n_j] = 1;
               p[n_i][n_j] = k;
            }
         }
      }
   }
   if (!dp[0][0]) return;
   int x = 0, y = 0;
   while (x != has || y != kol) {
      int t = p[x][y];
      path.pb (t);
      x += t;
      y += t * (t + 1) / 2;
   }
   int sz = 1;
   for (int i = 1; i < n - has; i ++) ans.pb ({1, ++ sz});
   for (int i = 0; i < sz (path); i ++) {
      int from = sz;
      for (int j = 0; j < path[i]; j ++)
         ans.pb ({from, ++ sz});
   }
   cout << sz (ans) << endl;
   for (auto it : ans) cout << it.F << ' ' << it.S << endl;
   exit (0);
}

inline void boost () {                    
   ios_base :: sync_with_stdio (NULL);
   cin.tie (NULL), cout.tie (NULL);          
}                                                     

inline void Solve () {
   cin >> n >> k;
   if (k < n - 2) {
      for (int i = 1; i <= n; i ++)
         for (int j = i + 1; j <= n; j ++)
            ans.pb ({i, j});
      cout << sz (ans) - k << endl;
      for (int i = 0; i < sz (ans) - k; i ++)
         cout << ans[i].F << ' ' << ans[i].S << endl;
      exit (0);
   }
   if (k > (n - 1) * (n - 2) / 2) cout << -1, exit (0);
   int x = k;
   int sum = 1;          /*
   for (int i = 1; i * (i - 1) / 2 <= k; i ++) {
      if (i > n - 1) break;
      int has = n - i - 1, kol = k - i * (i - 1) / 2;
      can (has, kol);
   }                       */
   cout << n - 1 + (n - 1) * (n - 2) / 2 - k << endl;
   k = (n - 1) * (n - 2) / 2 - k;
   for (int i = 1; i < n; i ++) cout << 1 << ' ' << i + 1 << endl;
   for (int i = 2; i <= n; i ++) {
      for (int j = i + 1; j <= n; j ++) {
         if (k > 0) cout << i << ' ' << j << endl, k --;
      }
   }
   
}

main () {                                       
// freopen (".in", "r", stdin);    
// freopen (".out", "w", stdout);              
   boost ();
   int tt = 1;
   //cin >> tt;   
   while (tt --) {
      Solve ();
   }                                               
   return 0;      
}
                          

Measured memory_bytes: 384