#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <math.h> // sqrt
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <iomanip> // setprecision
using namespace std;
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vb = vector<bool>;
using vll = vector<long long>;
using pii = pair<int, int>;
using psi = pair<string, int>;

int N;

int f(vector<vector<pair<int, int>>> &data, vi &bit, int n) {
    if (n == 0) {
        int ans = 0;
        bool check = false;
        for (int i = 0; i < N; i++) {
            if (bit[i] == 0) {
                continue;
            }
            ans++;
            for (pair<int, int> p : data[i]) {
                if (bit[p.first - 1] != p.second) {
                    return 0;
                }
            }
        }
        return ans;
    }
    bit[N - n] = 1;
    int a = f(data, bit, n - 1);
    bit[N - n] = 0;
    int b = f(data, bit, n - 1);
    return max(a, b);
}

int main() {
    cin >> N;
    vi a(N);
    vector<vector<pair<int, int>>> data(N);
    for (int i = 0; i < N; i++) {
        cin >> a[i];
        vector<pair<int, int>> v(a[i]);
        for (int j = 0; j < a[i]; j++) {
            int x, y;
            cin >> x >> y;
            v[j] = {x, y};
        }
        data[i] = v;
    }
    vi bit(N, 0);
    int ans = f(data, bit, N);
    cout << ans << endl;
}

#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9 + 7);
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (a > b) { a = b; return true; } return false; }

#define N 8
bool row[N], col[N], dpos[2 * N - 1], dneg[2 * N - 1];
bool X[N][N];

void print_board() {
	rep(i, 0, N) {
		rep(j, 0, N) {
			if (X[i][j])cout << 'Q';
			else cout << '.';
		}
		cout << endl;
	}
}

void dfs(int i) {
	if (i == N) {
		print_board();
		return;
	}
	rep(j, 0, N) {
		if (X[i][j]) {
			dfs(i + 1);
			return;
		}
	}

	rep(j, 0, N) {
		if (row[i] || col[j] || dpos[i + j] || dneg[i - j + N - 1])continue;
		X[i][j] = true;
		row[i] = col[j] = dpos[i + j] = dneg[i - j + N - 1] = true;
		dfs(i + 1);
		X[i][j] = false;
		row[i] = col[j] = dpos[i + j] = dneg[i - j + N - 1] = false;
	}
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n; cin >> n;
	rep(i, 0, n) {
		int y, x; cin >> y >> x;
		X[y][x] = true;
		row[y] = col[x] = dpos[y + x] = dneg[y - x + N - 1] = true;
	}
	dfs(0);
	return 0;
}