import std.algorithm;
import std.array;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.random;
import core.bitop;

immutable int[4] dx = [ 1, 0, -1, 0];
immutable int[4] dy = [ 0, 1, 0, -1];

class State {
  immutable int n;
  char[][] board;
  int[] srow, scol;
  int pieces;
  bool terminal () const {
    if (!pieces) return false;
    int u = int.max, v = int.min;
    foreach (x; chain (srow, scol)) {
      u = min (u, x);
      v = max (v, x);
    }
    return u == v;
  }
  int get (const int y, const int x) {
    if (y < 0 || y >= n || x < 0 || x >= n) return -1;
    return board[y][x].to!int;
  }
  void print () {
    debug stderr.writeln (srow);
    debug stderr.writeln (scol);
    foreach (i; 0 .. n) {
      foreach (j; 0 .. n) {
        char c = board[i][j];
        assert (c == 0 || (c >= 'a' && c <= 'z'));
        write (c == 0 ? '.' : c);
      }
      writeln;
    }
    //debug writeln;
  }
  void upd (const int y1, const int x1, const int y2, const int x2, const int d, const char c) {
    debug stderr.writefln ("upd %d %d %d %d %d %c", y1, x2, y2, x2, d, c);
    if (y1 == y2) {
      srow[y1] += d;
      scol[x1] += d;
      scol[x2] += d;
    } else {
      assert (x1 == x2);
      scol[x1] += d;
      srow[y1] += d;
      srow[y2] += d;
    }
    board[y1][x1] = c;
    board[y2][x2] = c;
    pieces += d;
  }
  int busy (const int y, const int x) {
    int mask = 0;
    foreach (k; 0 .. 4) {
      immutable j = y + dy[k];
      if (j < 0 || j >= n) continue;
      immutable i = x + dx[k];
      if (i < 0 || i >= n) continue;
      if (board[j][i] != 0) {
        mask |= 1 << (board[j][i].to!int - 97);
      }
    }
    return mask;
  }
  void randomMove () {
    while (true) {
      immutable y = uniform (0, n);
      immutable x = uniform (0, n);
      char c = board[y][x];
      int t = c.to!int;
      if (c != 0) {
        assert (t >= 97 && t < 97 + 26, format ("y = %d, x = %d, t = %d", x, y, t));
        foreach (k; 0 .. 4) {
          if (get (y + dy[k], x + dx[k]) == t) {
            upd (y, x, y + dy[k], x + dx[k], -1, 0);
            return;
          }
        }
      } else {
        immutable k = uniform (0, 4);
        immutable y2 = y + dy[k], x2 = x + dx[k];
        if (get (y2, x2) == 0) {
          immutable mask = busy (y, x) | busy (y2, x2);
          immutable o = bsf (~mask);
          assert (o >= 0 && o < 26);
          upd (y, x, y2, x2, 1, (97 + o).to!char);
          return;
        }
      }
    }
  }
  this (const int n) {
    this.n = n;
    board = new char[][](n,n);
    foreach (i; 0 .. n) {
      foreach (j; 0 .. n) {
        board[i][j] = 0;
      }
    }
    srow = new int[n];
    scol = new int[n];
  }
}

void main() {
  rndGen.seed (1);
  int n;
  readf (" %d", &n);
  auto a = new char[][](n, n);
  foreach (i; 0 .. n) a[i][] = '.';
  if (!(n % 3)) {
    foreach (i; 0 .. n / 3) {
      char c = (((2 * i) % 26) + 97).to!char;
      int x = 3 * i;
      foreach (j; 0 .. n / 3) {
        int y = 3 * j;
        a[x][y] = 'a';
        a[x+1][y] = 'a';
        a[x+2][y+2] = 'a';
        a[x+2][y+1] = 'a';
      }
    }
    foreach (i; 0 .. n) {
      writeln (a[i]);
    }
    return;
  }
  if (!(n % 4)) {
    foreach (i; 0 .. n / 4) {
      int t = ((8 * i) % 26);
      char f (int o) {
        return (((t + o) % 26) + 97).to!char;
      }
      char A = f (0), B = f (1), C = f (2), D = f (3); 
      int x = 4 * i;
      foreach (j; 0 .. n / 4) {
        int y = 4 * j;
        void g (int k, char c1, char c2, char c3, char c4) {
          a[x+k][y] = c1;
          a[x+k][y+1] = c2;
          a[x+k][y+2] = c3;
          a[x+k][y+3] = c4;
        }
        g (0, A, A, D, A);
        g (1, C, C, D, A);
        g (2, B, A, B, B);
        g (3, B, A, C, C);
      }
    }
    foreach (i; 0 .. n) {
      writeln (a[i]);
    }
    return;
  }
  writeln (-1);
}

