Language: C++

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

template<class T> inline void chmax(T& a, T b) { if(b > a) a = b; }

const int A = 0, M = 1, INF = 0xfffffff;

int num[2], n[2], m[2];
vector<int> cmp[2];
vector<string> characters[2];
vector<string> c(2);
vector<vector<int> > G[2], rG[2], cG[2];

void add_edge(int id, int from, int to) {
	G[id][from].push_back(to);
	rG[id][to].push_back(from);
}

void dfs(int id, int v, vector<int>& vs, vector<bool>& used) {
	used[v] = true;
	for(int i = 0; i < G[id][v].size(); ++i)
		if(!used[G[id][v][i]])
			dfs(id, G[id][v][i], vs, used);

	vs.push_back(v);
}

void rdfs(int id, int v, int k, vector<bool>& used) {
	used[v] = true;
	cmp[id][v] = k;
	characters[id][k] += c[id][v];
	for(int i = 0; i < rG[id][v].size(); ++i)
		if(!used[rG[id][v][i]])
			rdfs(id, rG[id][v][i], k, used);
}

int scc(int id) {
	vector<bool> used(n[id], false);
	vector<int> vs;
	vs.reserve(n[id]);
	for(int v = 0; v < n[id]; ++v)
		if(!used[v])
			dfs(id, v, vs, used);

	characters[id].resize(n[id]);
	fill(used.begin(), used.end(), false);
	int k = 0;
	for(int i = vs.size() - 1; i >= 0; --i)
		if(!used[vs[i]])
			rdfs(id, vs[i], k++, used);

	return k;
}

bool match(const string& a, const string& b) {
	for(int i = 0; i < a.size(); ++i)
		for(int j = 0; j < b.size(); ++j)
			if(a[i] == a[j])
				return true;

	return false;
}

bool infinite() {
	for(int i = 0; i < num[A] && characters[A][i].size() > 1; ++i)
		for(int j = 0; j < num[M] && characters[M][j].size() > 1; ++j)
			if(match(characters[A][i], characters[M][j]))
				return true;

	return false;			
}

vector<vector<int> > memo;
int search(int a_pos, int m_pos) {
	if(memo[a_pos][m_pos] != -1)
		return memo[a_pos][m_pos];

	bool point = match(characters[A][a_pos], characters[M][m_pos]);
	int res = 0;

	for(int i = 0; i < cG[A][a_pos].size(); ++i)
		for(int j = 0; j < cG[M][m_pos].size(); ++j)
			chmax(res, search(cG[A][a_pos][i], cG[M][m_pos][j]));

	if(!point || characters[M][m_pos].size() > 1)
		for(int i = 0; i < cG[A][a_pos].size(); ++i)
			chmax(res, search(cG[A][a_pos][i], m_pos));

	if(!point || characters[A][a_pos].size() > 1)
		for(int i = 0; i < cG[M][m_pos].size(); ++i)
			chmax(res, search(a_pos, cG[M][m_pos][i]));

	res += point;

	return memo[a_pos][m_pos] = res;
}

int main() {
	cin.tie(false);
	ios::sync_with_stdio(false);

	for(int i = A; i <= M; ++i) {
		cin >> n[i] >> m[i];

		G[i].resize(n[i]);
		rG[i].resize(n[i]);
		cmp[i].resize(n[i]);

		for(int j = 0; j < n[i]; ++j) {
			char in;
			cin >> in;
			c[i] += in;
		}

		for(int j = 0; j < m[i]; ++j) {
			int a, b;
			cin >> a >> b;
			--a; --b;

			add_edge(i, a, b);
		}

		num[i] = scc(i);

		cG[i].resize(num[i]);
		
		for(int j = 0; j < n[i]; ++j)
			for(int k = 0; k < G[i][j].size(); ++k)
				if(cmp[i][j] != cmp[i][G[i][j][k]])
					cG[i][cmp[i][j]].push_back(cmp[i][G[i][j][k]]);

		for(int j = 0; j < num[i]; ++j) {
			sort(cG[i][j].begin(), cG[i][j].end());
			cG[i][j].erase(unique(cG[i][j].begin(), cG[i][j].end()), cG[i][j].end());
		}
	}

	if(infinite()) {
		cout << -1 << endl;
		return EXIT_SUCCESS;
	}

	memo.resize(num[A], vector<int>(num[M], -1));
	int ans = 0;
	for(int i = 0; i < num[A]; ++i)
		for(int j = 0; j < num[M]; ++j)
			chmax(ans, search(i, j));

	cout << ans << endl;

	return EXIT_SUCCESS;
}

Compiler output:
a.cc: In function 'int main()':
a.cc:102:16: error: no matching function for call to 'std::basic_istream<char>::tie(bool)'
  102 |         cin.tie(false);
      |         ~~~~~~~^~~~~~~
In file included from /usr/include/c++/14/ios:46,
                 from /usr/include/c++/14/ostream:40,
                 from /usr/include/c++/14/iostream:41,
                 from a.cc:2:
/usr/include/c++/14/bits/basic_ios.h:299:7: note: candidate: 'std::basic_ostream<_CharT, _Traits>* std::basic_ios<_CharT, _Traits>::tie() const [with _CharT = char; _Traits = std::char_traits<char>]'
  299 |       tie() const
      |       ^~~
/usr/include/c++/14/bits/basic_ios.h:299:7: note:   candidate expects 0 arguments, 1 provided
/usr/include/c++/14/bits/basic_ios.h:311:7: note: candidate: 'std::basic_ostream<_CharT, _Traits>* std::basic_ios<_CharT, _Traits>::tie(std::basic_ostream<_CharT, _Traits>*) [with _CharT = char; _Traits = std::char_traits<char>]'
  311 |       tie(basic_ostream<_CharT, _Traits>* __tiestr)
      |       ^~~
/usr/include/c++/14/bits/basic_ios.h:311:43: note:   no known conversion for argument 1 from 'bool' to 'std::basic_ostream<char>*'
  311 |       tie(basic_ostream<_CharT, _Traits>* __tiestr)
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
a.cc:136:25: error: 'sort' was not declared in this scope; did you mean 'short'?
  136 |                         sort(cG[i][j].begin(), cG[i][j].end());
      |                         ^~~~
      |                         short
a.cc:137:40: error: 'unique' was not declared in this scope
  137 |                         cG[i][j].erase(unique(cG[i][j].begin(), cG[i][j].end()), cG[i][j].end());
      |                                        ^~~~~~