Problem:
Score : 900 points

Problem Statement

Let us consider a grid of squares with N rows and N columns. You want to put some domino pieces on this grid.
Each domino piece covers two squares that have a common side. Each square can be covered by at most one piece.

For each row of the grid, let's define its quality as the number of domino pieces that cover at least one square in this row.
We define the quality of each column similarly.

Find a way to put at least one domino piece on the grid so that the quality of every row is equal to the quality of every column,
or determine that such a placement doesn't exist.

Constraints

2 \le N \le 1000

Input

Input is given from Standard Input in the following format:

N

Output

If the required domino placement doesn't exist, print a single integer -1.

Otherwise, output your placement as N strings of N characters each.
If a square is not covered, the corresponding character must be . (a dot).
Otherwise, it must contain a lowercase English letter.
Squares covered by the same domino piece must contain the same letter.
If two squares have a common side but belong to different pieces, they must contain different letters.

Sample Input 1

6

Sample Output 1

aabb..
b..zz.
ba....
.a..aa
..a..b
..a..b

The quality of every row and every column is 2.

Sample Input 2

2

Sample Output 2

-1

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#line 1 "base.hpp"//3
#ifndef __clang__
#pragma GCC optimize ("O3")
#endif
void solve(
#ifdef GCJ_CASE
long long case_id
#endif
);
#if defined(EBUG) && !defined(ONLINE_JUDGE)
#define debug true
#define _GLIBCXX_DEBUG
// #define _LIBCPP_DEBUG 0
#define _LIBCPP_DEBUG2 0
#else
#define NDEBUG
#define debug false
#endif
#include<algorithm>
#include<functional>
#include<iomanip>
#include<iostream>
#include<limits>
#include<map>
#include<numeric>
#include<queue>
#include<set>
#include<type_traits>
#include<vector>
#include<cassert>
#include<climits>
#include<cmath>
#include<cstdio>
#include<cstdlib>

using namespace std;
using LL=long long;
using ULL=unsigned long long;
#define int LL
#define CS const
#define CX constexpr
#define IL inline
#define OP operator
#define RT return
#define TL template
#define TN typename
#define lambda [&]
#define rep(f,t,i,c,u)for(int Rb_=(t),i=(f);i c Rb_;u(i))
#define upto(f,t,i)rep(f,t,i,<=,++)
#define uptil(f,t,i)rep(f,t,i,<,++)
#define downto(f,t,i)rep(f,t,i,>=,--)
#define downtil(f,t,i)rep(f,t,i,>,--)
#define times(n,i)uptil(0,n,i)
#define rtimes(n,i)downto((n)-1,0,i)
#define iter(v)begin(v),end(v)
#define citer(v)cbegin(v),cend(v)
#define riter(v)rbegin(v),rend(v)
#define criter(v)crbegin(v),crend(v)
#define IF(a,b,c)((a)?(b):(c))
#if debug
#define ln <<endl
#else
#define ln <<'\n'
#endif
#define tb <<'\t'
#define sp <<' '
#line 1 "base_util.hpp"//3b
#define BINOPa(t,u,op)t OP op(CS u&o)CS{RT t(*this)op##=o;}
#define CMPOP(t,op,f1,f2,x)bool OP op(CS t&x)CS{RT f1 op f2;}
#define CMPOPS(t,f1,f2,x)CMPOP(t,==,f1,f2,x)CMPOP(t,!=,f1,f2,x)\
CMPOP(t,<,f1,f2,x)CMPOP(t,<=,f1,f2,x)CMPOP(t,>,f1,f2,x)CMPOP(t,>=,f1,f2,x)
#line 1 "mod.hpp"//3b
#ifndef MOD
#define MOD 1000000007
#endif
#if !defined(FORCE_MOD)&&MOD!=1000000007&&MOD!=1000000009&&MOD!=998244353
#error mod
#endif
#line 1 "power.hpp"//3bm
TL<TN T>IL T power(T x,int n){T r(1);for(;n;n/=2){if(n%2)r*=x;x*=x;}RT r;}IL int pow_mod(int x,int n,int m){int r=1;
for(;n;n/=2){if(n%2)r=r*x%m;x=x*x%m;}RT r;}
#line 2001 "mod.hpp"//3b
IL CX int modulo(int a,int b){a%=b;RT a&&(a>0)!=(b>0)?a+b:a;}IL CX int divide(int a,int b){RT(a-modulo(a,b))/b;}
TL<int d=MOD>struct MInt{
/*!https://ei1333.github.io/luzhiled/snippets/other/mod-int.html*/
int v;CX MInt():v(0){}explicit CX MInt(int i):v(modulo(i,d)){}MInt&OP+=(CS MInt&m){v+=m.v;if(v>=d)v-=d;RT*this;}
MInt&OP-=(CS MInt&m){v-=m.v;if(v<0)v+=d;RT*this;}MInt&OP*=(CS MInt&m){v=v*m.v%d;RT*this;}MInt&OP/=(CS MInt&m){
RT*this*=m.inv();}BINOPa(MInt,MInt,+)BINOPa(MInt,MInt,-)BINOPa(MInt,MInt,*)BINOPa(MInt,MInt,/)MInt OP-()CS{
RT MInt()-=*this;}CMPOP(MInt,==,v,m.v,m)CMPOP(MInt,!=,v,m.v,m)MInt pow(int n)CS{RT power(*this,n);}MInt inv()CS{
int a=v,b=d,x=1,y=0;while(b){swap(y,x-=a/b*y);swap(b,a%=b);}RT(MInt)x;}
friend ostream&OP<<(ostream&o,CS MInt&m){RT o<<m.v;}friend istream&OP>>(istream&i,MInt&m){i>>m.v;m.v%=d;RT i;}};
using mint=MInt<>;CX mint OP"" _m(ULL n){RT mint(n);}CX MInt<998244353>OP"" _m998244353(ULL n){RT MInt<998244353>(n);}
CX MInt<1000000007>OP"" _m1e9_7(ULL n){RT MInt<1000000007>(n);}
CX MInt<1000000009>OP"" _m1e9_9(ULL n){RT MInt<1000000009>(n);}
#line 1 "typedefs.hpp"//3b
using unit = tuple<>;using LD=long double;TL<TN T>using vec=vector<T>;
TL<TN T>using vvec=vec<vec<T>>;TL<TN T>using vvvec=vec<vvec<T>>;TL<TN T>using vvvvec=vec<vvvec<T>>;
using WI=vvec<int>;using VI=vec<int>;
#line 1 "alias.hpp"//3b
#define EB emplace_back
#define PB push_back
#define foldl accumulate
#define scanl partial_sum
#line 1 "util.hpp"//3b
TL<TN T>IL bool amax(T&v,CS T&a){RT v<a&&(v=a,1);}TL<TN T>IL bool amin(T&v,CS T&a){RT v>a&&(v=a,1);}
TL<TN T>IL int sizeRAB(T t){RT t.size();}
#define size sizeRAB
#define clamp clampRAB
TL<TN T>IL CX CS T&clamp(CS T&a,CS T&l,CS T&r){RT a<l?l:r<a?r:a;}TL<TN V>IL void uniq2(V&v){
v.erase(unique(iter(v)),v.end());}TL<TN V>IL void uniq(V&v){sort(iter(v));uniq2(v);}
#define leftmost_ge lower_bound
#define leftmost_gt upper_bound
namespace rab{TL<TN I>IL bool is_in(I x,I l,I r){RT l<=x&&x<r;}TL<TN T>IL T fetch(CS T&d,CS vec<T>&v,int i){
RT 0<=i&&i<size(v)?v[i]:d;}}
#line 1 "debug.hpp"//3b
TL<TN T>IL istream&OP>>(istream&s,vec<T>&v){for(auto&&p:v)s>>p;RT s;}TL<TN T,TN S>
IL ostream&OP<<(ostream&s,CS pair<T,S>&p){RT s<<"("<<p.first<<","<<p.second<<")";}
#define Rdebug1(sep, ...)IL ostream& OP<<(ostream&s,CS __VA_ARGS__&v){\
int i=0;for(CS auto&e:v){i++&&s<<sep;s<<e;}RT s;}
TL<TN T>Rdebug1(' ',vec<T>)TL<TN T,TN S>Rdebug1(' ',map<T,S>)TL<TN T>Rdebug1('\n',vvec<T>)
TL<TN T,TN S>Rdebug1('\n',vec<map<T,S>>)
#line 6001 "base.hpp"//3
signed main(){if(debug)cerr<<"MOD: "<<MOD ln;else cin.tie(0),cerr.tie(0),ios::sync_with_stdio(0);
auto p=setprecision(20);cout<<fixed<<p;cerr<<fixed<<p;
#ifdef GCJ_CASE
int T;cin>>T;times(T,t){cout<<"Case #"<<t+1<<": ";solve(t);}
#else
solve();
#endif
RT 0;}
#line 1001 "3.cpp"//
//#include "consts.hpp"

WI A;

void drawV(int i, int j) {
  A[i][j] = A[i+1][j] = i % 4 * 4 + j % 4 + 1;
}

void drawH(int i, int j) {
  A[i][j] = A[i][j+1] = i % 4 * 4 + j % 4 + 1;
}

void draw3q1(int i, int j) {
  drawV(i, j);
  drawH(i+2, j+1);
}

void draw3q2(int i, int j) {
  drawV(i, j);
  drawH(i+2, j);
  drawV(i+1, j+2);
  drawH(i, j+1);
}

void draw4q3(int i, int j) {
  drawV(i, j);
  drawV(i, j+1);
  drawH(i, j+2);
  drawH(i+1, j+2);
  drawV(i+2, j+2);
  drawV(i+2, j+3);
  drawH(i+2, j);
  drawH(i+3, j);
}

void draw7q3(int i, int j) {
  drawH(i, j);
  drawH(i, j+2);
  drawH(i, j+4);
  drawH(i+5, j);
  drawH(i+5, j+4);
  drawH(i+6, j+2);
  drawH(i+6, j+4);
  drawV(i+1, j+2);
  drawV(i+1, j+3);
  drawV(i+1, j+6);
  drawV(i+3, j);
  drawV(i+3, j+1);
  drawV(i+3, j+6);
  drawV(i+5, j+6);
}

void draw3Mq3(int i, int j, int M) {
  times(M, p) {
    // dd i; j; A;
    draw3q2(i + 3 * p, j + 3 * p);
    // dd i; j; A;
    draw3q1(i + 3 * ((p + 1) % M), j + 3 * p);
  }
}

void solve() {
  int N; cin >> N;

  if(N == 1 || N == 2) {
    cout << -1 ln;
    return;
  }

  A = WI(N, VI(N));

  if(N == 3) {
    draw3q1(0, 0);
  } else if(N % 3 == 0) {
    draw3Mq3(0, 0, N / 3);
  } else if(N == 4) {
    draw4q3(0, 0);
  } else if(N == 7) {
    draw7q3(0, 0);
  } else if(N % 3 == 1) {
    draw4q3(0, 0);
    draw3Mq3(4, 4, N / 3 - 1);
  } else if(N == 5) {
    drawV(0, 0);
    drawV(2, 0);
    drawV(1, 4);
    drawV(3, 4);
    drawH(0, 1);
    drawH(0, 3);
    drawH(4, 0);
    drawH(4, 2);
    draw3q1(1, 1);
  } else if(N == 8) {
    draw4q3(0, 0);
    draw4q3(4, 4);
  } else if(N == 11) {
    draw4q3(0, 0);
    draw7q3(4, 4);
  } else if(N == 14) {
    draw7q3(0, 0);
    draw7q3(7, 7);
  } else {
    assert(N % 3 == 2);
    draw4q3(0, 0);
    draw7q3(4, 4);
    draw3Mq3(11, 11, N / 3 - 3);
  }

  times(N, i) {
    times(N, j) {
      cout << (A[i][j] == 0 ? '.' : (char)('a' + A[i][j] - 1));
    }
    cout ln;
  }
}