#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define INF 1000000000
#define LINF 1000000000000000000
#define MOD 1000000007
#define mod 998244353
#define INF63 1061109567
#define INF127 9187201950435737471
#define UINF 18446744073709551615
#define F first
#define S second
#define ll long long
#define N 100010
using namespace std;
ll n,m,req[N],ans[N];
vector<pair<ll,ll> > ed,vt[N];
bool vis[N];
void dfs(ll x)
{
	vis[x]=true;
	ll i;
	for(i=0;i<vt[x].size();i++)
	{
		if(ans[vt[x][i].S]!=-1)
		{
			continue;
		}
		ans[vt[x][i].S]=(ed[vt[x][i].S].F!=x);
		if(!vis[vt[x][i].F])
		{
			dfs(vt[x][i].F);
		}
	}
	return;
}
int main(){
	ll x,y,i;
	scanf("%lld%lld",&n,&m);
	for(i=0;i<m;i++)
	{
		scanf("%lld%lld",&x,&y);
		x--;
		y--;
		ed.push_back(make_pair(x,y));
		vt[x].push_back(make_pair(y,i));
		vt[y].push_back(make_pair(x,i));
	}
	for(i=0;i<n;i++)
	{
		scanf("%lld",&req[i]);
	}
	memset(ans,-1,sizeof(ans));
	for(i=0;i<ed.size();i++)
	{
		if(req[ed[i].F]<req[ed[i].S])
		{
			ans[i]=1;
		}
		else if(req[ed[i].F]>req[ed[i].S])
		{
			ans[i]=0;
		}
	}
	for(i=0;i<n;i++)
	{
		if(!vis[i])
		{
			dfs(i);
		}
	}
	for(i=0;i<ed.size();i++)
	{
		if(ans[i]==0)
		{
			puts("->");
		}
		else
		{
			puts("<-");
		}
	}
	return 0;
}
#include <iostream>
#include <iomanip>
#include <vector>
#include <cmath>
#include <algorithm>
#include <set>
#include <utility>
#include <queue>
#include <map>
#include <assert.h>
#include <stack>
#include <string>
#include <ctime>
#include <chrono>
#include <random>
using namespace std;

//author: Legendary Grandmaster mshiladityam
//a beautiful problem

const int MAX = 1000;
bool arr[MAX + 1][MAX + 1] = { false };
vector<int> adjC[MAX + 1], adjR[MAX + 1];
bool visC[MAX + 1] = { false }, visR[MAX + 1] = { false };


void DFS(int v, bool b)
{
	if (b)
	{
		visC[v] = true;
		for (auto u : adjC[v])
		{
			if (!visC[u]) DFS(u, b);
		}
	}
	else
	{
		visR[v] = true;
		for (auto u : adjR[v])
		{
			if (!visR[u]) DFS(u, b);
		}
	}
}

void solve()
{
	int h, w;
	cin >> h >> w;

	for (int j = 1; j <= h; j++)
	{
		for (int i = 1; i <= w; i++)
		{
			char c;
			cin >> c;
			if (c == '#')	arr[j][i] = true;
			else arr[j][i] = false;
		}
	}

	arr[1][1] = true;
	arr[h][1] = true;
	arr[1][w] = true;
	arr[h][w] = true;

	for (int j = 1; j <= h; j++)
	{
		bool f = false;
		for (int i = 1; (i <= w) && (!f); i++)
		{
			if (arr[j][i])
			{
				f = true;
				for (int q = i + 1; q <= w; q++)
				{
					if (arr[j][q])
					{
						adjC[i].push_back(q);
						adjC[q].push_back(i);
					}
				}
			}
		}
	}

	for (int j = 1; j <= w; j++)
	{
		bool f = false;
		for (int i = 1; i <= h; i++)
		{
			if (f) break;
			if (arr[i][j])
			{
				f = true;
				for (int q = i + 1; q <= h; q++)
				{
					if (arr[q][j])
					{
						adjR[i].push_back(q);
						adjR[q].push_back(i);
					}
				}
			}
		}
	}

	int C = 0, R = 0;

	for (int j = 1; j <= w; j++)
	{
		if (!visC[j])
		{
			DFS(j, true);
			C++;
		}
	}

	for (int j = 1; j <= h; j++)
	{
		if (!visR[j])
		{
			DFS(j, false);
			R++;
		}
	}

	cout << min(R, C) - 1 << "\n";

	return;
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(NULL); cout.tie(NULL);
	int t;
	//cin >> t;
	t = 1;
	while (t--)
	{
		solve();
	}
	return 0;
}