#include <sstream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cassert>
#include <ctime>
#include <map>
#include <math.h>
#include <cstdio>
#include <set>
#include <deque>
#include <memory.h>
#include <queue>

#pragma comment(linker, "/STACK:64000000")
typedef long long ll;

using namespace std;

const int MAXN = 1 << 18;
const int MOD = 1; // 1000 * 1000 * 1000 + 7;
const int INF = 2e9;
const double PI = acos(-1.0);

int slowsolve(vector<vector<int> > a) {
	int n = a.size();
	int m = a[0].size();
	queue<int> q;
	vector<int> d(1 << (n * m), INF);
	auto calc = [&](vector<vector<int> > a) {
		int mask0 = 0;
		for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) mask0 |= a[i][j] << (i * m + j);
		return mask0;
	};
	auto uncalc = [&](int mask) {
		vector<vector<int> > a(n, vector<int>(m));
		for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) a[i][j] = (mask & (1 << (i * m + j))) != 0;
		return a;
	};
	int mask0 = calc(a);
	q.push(mask0);
	d[mask0] = 0;
	while (!q.empty()) {
		int mask = q.front();
		q.pop();
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				a = uncalc(mask);
				vector<int> b = a[i];
				for (int k = 0; k < n; k++) a[k][j] = b[k];
				int nmask = calc(a);
				if (d[nmask] > d[mask] + 1) {
					d[nmask] = d[mask] + 1;
					q.push(nmask);
				}
			}
		}
	}
	if (d[(1 << (n * m)) - 1] == INF) return -1;
	return d[(1 << (n * m)) - 1];
}

int solve(vector<vector<int> > a) {
	int n = a.size();
	int m = a[0].size();

	bool any = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			any |= a[i][j];
		}
	}
	if (!any) return -1;

	int colsFilled = 0;
	for (int j = 0; j < m; j++) {
		bool ok = 1;
		for (int i = 0; i < n; i++) ok &= a[i][j];
		colsFilled += ok;
	}

	int ans = INF;
	for (int i = 0; i < n; i++) {
		int cnt = 0;
		for (int j = 0; j < m; j++) cnt += a[i][j];
		if (cnt == 0) continue; // ???????????
		if (cnt == m) ans = min(ans, m - colsFilled);

		bool found = 0;
		for (int j = 0; j < n; j++) if (a[j][i]) found = 1;
		if (found) {
			ans = min(ans, m - colsFilled + m - cnt);
			continue;
		}
		ans = min(ans, m - colsFilled + m - cnt + (a[i][i] != 1));
	}

	return ans;
}

int main() {
#ifdef _MSC_VER
	freopen("input.txt", "r", stdin);
#endif

	if (0) for (int n = 1; n <= 4; n++) {
		int m = n; {
			for (int mask = 0; mask < (1 << (n * m)); mask++) {
				cerr << n << " " << mask << endl;
				vector<vector<int> > a(n, vector<int>(m));
				for (int i = 0; i < n; i++) {
					for (int j = 0; j < m; j++) {
						a[i][j] = (mask & (1 << (i * m + j))) != 0;
					}
				}
				int ans1 = solve(a);
				int ans2 = slowsolve(a);
				if (ans1 != ans2) {
					cout << ans1 << " instead of " << ans2 << endl;
					cout << n << endl;
					for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) cout << a[i][j] << " \n"[j + 1 == m];
					cout << endl;
					solve(a);
					exit(0);
				}
			}
		}
	}

	int n, m;
	while (cin >> n) {
		m = n;
		vector<vector<int> > a(n, vector<int>(m));
		for (int i = 0; i < n; i++) {
			string s;
			cin >> s;
			for (int j = 0; j < m; j++) a[i][j] = s[j] == '#';
		}
		cout << solve(a) << endl;
	}

	return 0;
}

Measured memory_bytes: 2176