//デバッグ用オプション：-fsanitize=undefined,address

//コンパイラ最適化
#pragma GCC optimize("Ofast")

//インクルードなど
#include <bits/stdc++.h>
// #include <atcoder/all>

using namespace std;
// using namespace atcoder;

typedef long long ll;
using vint = vector<int>;
using vll = vector<ll>;
using vs = vector<string>;
using vbool = vector<bool>;
template <class T> using arr = vector<vector<T>>;

//マクロ
// forループ
//引数は、(ループ内変数,動く範囲)か(ループ内変数,始めの数,終わりの数)、のどちらか
// Dがついてないものはループ変数は1ずつインクリメントされ、Dがついてるものはループ変数は1ずつデクリメントされる
// FORAは範囲for文(使いにくかったら消す)
#define REP(i, n) for (ll i = 0; i < ll(n); i++)
#define REPD(i, n) for (ll i = n - 1; i >= 0; i--)
#define FOR(i, a, b) for (ll i = a; i < ll(b); i++)
#define FORD(i, a, b) for (ll i = b - 1; i >= ll(a); i--)
#define FORA(i, I) for (const auto &i : I)
// xにはvectorなどのコンテナ
#define ALL(x) x.begin(), x.end()
#define SIZE(x) ll(x.size())
//定数
#define INF 1000000000000 // 10^12:∞
#define MOD 1000000007 // 10^9+7:合同式の法
#define MAXR 100000 // 10^5:配列の最大のrange

// aよりもbが大きいならばaをbで更新する
// (更新されたならばtrueを返す)
template <typename T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b; // aをbで更新
    return true;
  }
  return false;
}
// aよりもbが小さいならばaをbで更新する
// (更新されたならばtrueを返す)
template <typename T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b; // aをbで更新
    return true;
  }
  return false;
}

template <class T> void pl(T x) { cout << x << " "; }

template <class T> void pr(T x) { cout << x << endl; }

template <class T> void prvec(const vector<T> &a) {
  REP(i, a.size() - 1) { cout << a[i] << " "; }
  pr(a[a.size() - 1]);
}

template <class T> void prarr(const arr<T> &a) {
  REP(i, a.size())
  if (a[i].empty())
    pr("");
  else
    prvec(a[i]);
}

using P = pair<ll, ll>;
void prp(const P &p) { cout << p.first << " " << p.second << endl; }

struct Constants {
  ll N;
  Constants() { cin >> N; }
} C;

struct Args {
  vll a, b, p;
  vll ids;
  Args() : a(C.N), b(C.N), p(C.N), ids(C.N) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    REP(i, C.N) cin >> a.at(i);
    REP(i, C.N) cin >> b.at(i);
    REP(i, C.N) {
      cin >> p.at(i);
      --p.at(i);
    }
    REP(i, C.N) ids.at(i) = i;
    sort(ALL(ids), [&](ll l, ll r) { return a.at(l) < a.at(r); });
  }
} args;

struct Solver {
  bool ok;
  vector<P> ans;
  Solver() : ok(true), ans() {}
  //
  void solve() {
    vll cur(C.N);
    REP(i, C.N) {
      cur.at(args.p.at(i)) = i;
    }
    FORA(id, args.ids) {
      ll target = cur.at(id);
      if (target == id) {
        continue;
      }
      if (args.a.at(id) <= args.b.at(args.p.at(id))) {
        ok = false;
        return;
      }
      if (args.a.at(target) <= args.b.at(args.p.at(target))) {
        ok = false;
        return;
      }
      ans.push_back({id + 1, target + 1});
      swap(args.p.at(id), args.p.at(target));
      cur.at(args.p.at(id)) = id;
      cur.at(args.p.at(target)) = target;
    }
  }

  void output() {
    if (!ok) {
      pr(-1);
      return;
    }
    pr(ans.size());
    FORA(p, ans) prp(p);
  }
} s;

int main() {
  s.solve();
  s.output();
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define _GLIBCXX_DEBUG
#define rep(i, from, to) for (ll i = from; i < (to); ++i)
#define mp(x,y) make_pair(x,y)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define sz(x) (int)(x).size()
#define pb push_back
using ll = long long;
using ld=long double;
using vin=vector<int>;
using vvin=vector<vin>;
using vll=vector<ll>;
using vvll=vector<vll>;
using vst=vector<string>;
using P = pair<ll,ll>;
using vp=vector<P>;
using vvp=vector<vp>;
const int inf=1e9+7;
const ll INF=9e18/2;
const long double PI = acosl(-1.0); 
template <typename T> bool chmin(T &a, const T& b){if(a > b){a = b;return true;}return false;}
template <typename T> bool chmax(T &a, const T& b){if(a < b){a = b;return true;}return false;}
template<class T> inline void Yes(T condition){ if(condition) cout << "Yes" << endl; else cout << "No" << endl; }
template<class T> inline void YES(T condition){ if(condition) cout << "YES" << endl; else cout << "NO" << endl; }
bool pair_comp(const pair<long,long> &A,const pair<long,long> &B){if(A.first==B.first)return A.second>B.second;return A.first<B.first;}//F昇→S降
const int dx[4] = { 1, 0, -1, 0 };
const int dy[4] = { 0, 1, 0, -1 };

ll dp[1<<19];//dp[s]:=前からsの時、条件を満たす数

int main(){//cout<<fixed<<setprecision(20);
  ll n,m;
  cin>>n>>m;
  vll x(m),y(m),z(m);
  rep(i,0,m){
    cin>>x[i]>>y[i]>>z[i];
    y[i]--;
  }
  dp[0]=1;
  rep(i,1,1<<n){
    int t=__builtin_popcount(i);
    vin sum(n,0);//sum[j]:=j以下の総数
    rep(j,0,n)if(i&(1<<j))sum[j]++;
    rep(j,1,n)sum[j]+=sum[j-1];
    
    rep(j,0,n){
      if(!(i&(1<<j)))continue;
      bool ok=true;
      rep(k,0,m){
        if(x[k]<t)continue;
        if(sum[y[k]]>z[k]){
         ok=false;
          break;
        }
      }
      if(ok)dp[i]+=dp[i&(~(1<<j))];
    }
  }
  cout<<dp[(1<<n)-1]<<endl;
}