#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
template <class c>
struct rge {
  c b, e;
};
template <class c>
rge<c> range(c i, c j) {
  return {i, j};
}
template <class c>
auto dud(c* x) -> decltype(cerr << *x, 0);
template <class c>
char dud(...);
struct debug {
  template <class c>
  debug& operator<<(const c&) {
    return *this;
  }
};
using ld = long double;
using ll = long long;
constexpr int mod = 1000 * 1000 * 1000 + 7;
constexpr int odw2 = (mod + 1) / 2;
void OdejmijOd(int& a, int b) {
  a -= b;
  if (a < 0) a += mod;
}
int Odejmij(int a, int b) {
  OdejmijOd(a, b);
  return a;
}
void DodajDo(int& a, int b) {
  a += b;
  if (a >= mod) a -= mod;
}
int Dodaj(int a, int b) {
  DodajDo(a, b);
  return a;
}
int Mnoz(int a, int b) { return (ll)a * b % mod; }
void MnozDo(int& a, int b) { a = Mnoz(a, b); }
int Pot(int a, int b) {
  int res = 1;
  while (b) {
    if (b % 2 == 1) MnozDo(res, a);
    a = Mnoz(a, a);
    b /= 2;
  }
  return res;
}
int Odw(int a) { return Pot(a, mod - 2); }
void PodzielDo(int& a, int b) { MnozDo(a, Odw(b)); }
int Podziel(int a, int b) { return Mnoz(a, Odw(b)); }
int Moduluj(ll x) {
  x %= mod;
  if (x < 0) x += mod;
  return x;
}
template <typename T>
T Maxi(T& a, T b) {
  return a = max(a, b);
}
template <typename T>
T Mini(T& a, T b) {
  return a = min(a, b);
}
int n, k;
int tab[4][55];
vector<tuple<int, int, int>> ruchy;
void Rusz(int id, int x, int y) {
  debug() << range(tab[0], tab[0] + n);
  debug() << range(tab[1], tab[1] + n);
  debug() << range(tab[2], tab[2] + n);
  debug() << range(tab[3], tab[3] + n);
  debug() << "Rusz("
             " ["
             "id"
             ": "
          << (id)
          << "] "
             " ["
             "x"
             ": "
          << (x)
          << "] "
             " ["
             "y"
             ": "
          << (y)
          << "] "
             ")";
  ruchy.push_back(make_tuple(id, x + 1, y + 1));
  if (1 <= x and x <= 2) {
    assert(tab[x][y] == 0);
    tab[x][y] = id;
  } else {
    assert(tab[x][y] == id);
    tab[x][y] = 0;
  }
  for (int i = 1; i <= 2; i++) {
    for (int j = 0; j < n; j++) {
      if (tab[i][j] == id and (i != x or j != y)) {
        debug() << " ["
                   "i"
                   ": "
                << (i)
                << "] "
                   " ["
                   "j"
                   ": "
                << (j) << "] ";
        assert(abs(i - x) + abs(j - y) == 1);
        tab[i][j] = 0;
        return;
      }
    }
  }
  assert(false);
}
void Algos(int zx, int zy) {
  vector<pair<int, int>> kol;
  for (int i = 0; i < n; i++) {
    kol.emplace_back(1, i);
  }
  for (int i = n - 1; i >= 0; i--) {
    kol.emplace_back(2, i);
  }
  for (int i = 0; i < (int)kol.size(); i++) {
    if (kol[i] == make_pair(zx, zy)) {
      rotate(kol.begin(), kol.begin() + i, kol.end());
      break;
    }
  }
  assert(kol[0] == make_pair(zx, zy));
  debug() << " ["
             "kol"
             ": "
          << (kol) << "] ";
  while (true) {
    bool cokol = false;
    for (int i = 1; i < (int)kol.size(); i++) {
      const int x = kol[i].first;
      const int y = kol[i].second;
      if (tab[x][y]) {
        cokol = true;
        debug() << " ["
                   "x"
                   ": "
                << (x)
                << "] "
                   " ["
                   "y"
                   ": "
                << (y)
                << "] "
                   " ["
                   "kol[i - 1]"
                   ": "
                << (kol[i - 1]) << "] ";
        Rusz(tab[x][y], kol[i - 1].first, kol[i - 1].second);
      }
    }
    if (!cokol) break;
    kol.insert(kol.begin(), kol.back());
    kol.pop_back();
    for (int i = 1; i <= 2; i++) {
      for (int j = 0; j < n; j++) {
        if (tab[i][j] > 0 and tab[i][j] == tab[i ^ 1][j]) {
          Rusz(tab[i][j], i ^ 1, j);
        }
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> k;
  try {
    for (int i = 0; i < 4; i++) {
      for (int j = 0; j < n; j++) {
        cin >> tab[i][j];
      }
    }
    for (int i = 1; i <= 2; i++) {
      for (int j = 0; j < n; j++) {
        if (tab[i][j] > 0 and tab[i][j] == tab[i ^ 1][j]) {
          Rusz(tab[i][j], i ^ 1, j);
        }
      }
    }
    int zx = -1, zy = -1;
    for (int i = 1; i <= 2; i++) {
      for (int j = 0; j < n; j++) {
        if (tab[i][j] == 0) {
          zx = i;
          zy = j;
        }
      }
    }
    if (zx == -1) throw 1;
    Algos(zx, zy);
  } catch (int x) {
    cout << -1 << endl;
    return 0;
  }
  cout << ruchy.size() << endl;
  for (auto& it : ruchy) {
    cout << get<0>(it) << " " << get<1>(it) << " " << get<2>(it) << "\n";
  }
  return 0;
}
