#include <bits/stdc++.h>   using namespace std;   int read(int &x) { return scanf( %d , &x); }   int read(long long &x) { return scanf( %lld , &x); }   int read(double &x) { return scanf( %lf , &x); }   int read(int &x, int &y) { return scanf( %d%d , &x, &y); }   int read(long long &x, long long &y) { return scanf( %lld%lld , &x, &y); }   int read(double &x, double &y) { return scanf( %lf%lf , &x, &y); }   int read(int &x, int &y, int &z) { return scanf( %d%d%d , &x, &y, &z); }   int read(long long &x, long long &y, long long &z) {     return scanf( %lld%lld%lld , &x, &y, &z);   }   int read(double &x, double &y, double &z) {     return scanf( %lf%lf%lf , &x, &y, &z);   }   long long qpow(long long a, long long b, long long mod) {     if (a == 0) return 0;     long long ans = 1;     a %= mod;     while (b) {       if (b & 1) ans = ans * a % mod;       a = a * a % mod;       b >>= 1;     }     return ans % mod;   }   long long inv(long long x, long long mod) { return qpow(x, mod - 2, mod); }   int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};   int mon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};   const int INF = 0x3f3f3f3f;   const int mod = 1e9 + 7;   const int N = 5e5 + 5;   struct DSU {     int f[N];     void init(int n) {       for (int i = 0; i <= n; i++) f[i] = i;     }     int fa(int x) { return f[x] == x ? x : f[x] = fa(f[x]); }     void join(int x, int y) {       x = fa(x);       y = fa(y);       if (x != y) f[x] = y;     }   };   struct CombMath {     long long C[2005][2005];     void init(int n) {       for (int i = 0; i <= n; i++) C[i][0] = 1;       for (int i = 1; i <= n; i++)         for (int j = 1; j <= n; j++)           C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;     }   };   struct _2sat {     vector<int> G[N << 1];     int dfn[N << 1], low[N << 1], stk[N << 1], color[N << 1];     int t, tp, scc;     bool vis[N << 1];     void init(int n) {       for (int i = 0; i <= 2 * n; i++) G[i].clear();       for (int i = 0; i <= n * 2; i++) dfn[i] = low[i] = color[i] = vis[i] = 0;       t = tp = scc = 0;     }     void add(int x, int xv, int y, int yv) {       x = x * 2 + xv;       y = y * 2 + yv;       G[x ^ 1].push_back(y);       G[y ^ 1].push_back(x);     }     void addmaodun(int x, int xv, int y, int yv) {       x = x * 2 + (xv ^ 1);       y = y * 2 + (yv ^ 1);       G[x ^ 1].push_back(y);       G[y ^ 1].push_back(x);     }     void tarjan(int x) {       dfn[x] = low[x] = ++t;       stk[++tp] = x;       vis[x] = 1;       for (auto v : G[x]) {         if (!dfn[v]) {           tarjan(v);           low[x] = min(low[x], low[v]);         } else if (vis[v])           low[x] = min(low[x], dfn[v]);       }       if (low[x] == dfn[x]) {         color[x] = ++scc;         vis[x] = 0;         while (stk[tp] != x) {           color[stk[tp]] = scc;           vis[stk[tp--]] = 0;         }         tp--;       }     }     void work(int n) {       for (int i = 0; i < 2 * n; i++)         if (!dfn[i]) tarjan(i);       for (int i = 0; i < n; i++)         if (color[i * 2] == color[i * 2 + 1]) {           puts( -1 );           return;         }       vector<int> row, col;       for (int i = 0; i < n / 2; i++) {         if (color[i * 2] < color[i * 2 + 1]) {           continue;         } else {           row.push_back(i);         }       }       for (int i = n / 2; i < n; i++) {         if (color[i * 2] < color[i * 2 + 1]) {           continue;         } else {           col.push_back(i - n / 2);         }       }       int sz = row.size() + col.size();       printf( %d n , sz);       for (auto it : row) printf( row %d n , it);       for (auto it : col) printf( col %d n , it);     }   } twosat;   char s[N];   int a[2005];   int g[2005][2005];   signed main() {     int n;     read(n);     getchar();     for (int k = 1; k <= 2; k++) {       for (int i = 1; i <= n; i++) {         gets(s + 1);         for (int j = 1; j <= n; j++) {           g[i][j] ^= (s[j] -  0 );         }       }     }     twosat.init(2 * n);     gets(s + 1);     for (int i = 1; i <= n; i++) a[i] = s[i] -  0 ;     bool ok = 1;     for (int i = 1; i <= n; i++) {       for (int j = 1; j <= n; j++) {         int n1 = a[i], n2 = a[j];         int ii = i - 1, jj = j + n - 1;         if (g[i][j] == 1) {           if (n1 == 1 and n2 == 1) {             twosat.G[ii * 2].push_back(jj * 2 + 1);             twosat.G[jj * 2].push_back(ii * 2 + 1);             twosat.G[ii * 2 + 1].push_back(jj * 2);             twosat.G[jj * 2 + 1].push_back(ii * 2);           } else if (n2 == 1) {             twosat.G[ii * 2].push_back(ii * 2 + 1);           } else if (n1 == 1) {             twosat.G[jj * 2].push_back(jj * 2 + 1);           } else {             ok = 0;           }         } else {           if (n1 == 1 and n2 == 1) {             twosat.G[ii * 2].push_back(jj * 2);             twosat.G[ii * 2 + 1].push_back(jj * 2 + 1);             twosat.G[jj * 2].push_back(ii * 2);             twosat.G[jj * 2 + 1].push_back(ii * 2 + 1);           } else if (n2 == 1) {             twosat.G[ii * 2 + 1].push_back(ii * 2);           } else if (n1 == 1) {             twosat.G[jj * 2 + 1].push_back(jj * 2);           } else {             continue;           }         }       }     }     if (!ok)       puts( -1 );     else {       twosat.work(n * 2);     }     return 0;   }