import java.io.*; import java.util.*; /** * Search the state space where a state consists of a pair of DFA states, * a marker to indicate if the strings are different, and a character marker * to indicate which character is blocked from being used (in order to preserve * a difference). * * @author Finn Lidbetter */ public class transparency_finn { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] s = br.readLine().split(" "); int nStates = Integer.parseInt(s[0]); int nFinal = Integer.parseInt(s[1]); int nTransitions = Integer.parseInt(s[2]); HashSet finalStates = new HashSet<>(); for (int i=0; i='a' && ch<='z') { lowerDfa[s1][ch-'a'] = s2; } else { upperDfa[s1][ch-'A'] = s2; } } State start = new State(0, 0, false, -1, -1); HashSet processed = new HashSet<>(); HashMap min = new HashMap<>(); min.put(start, 0); PriorityQueue pq = new PriorityQueue<>(); pq.offer(new QNode(start, 0)); while (pq.size()>0) { QNode currQNode = pq.poll(); State curr = currQNode.s; if (curr.isDifferent && finalStates.contains(curr.s0) && finalStates.contains(curr.s1)) { System.out.println(min.get(curr)); return; } int cost = currQNode.cost; if (processed.contains(curr)) { continue; } processed.add(curr); // Try taking uppercase transition. Preserve difference and clear blocks. for (int i=0; i<26; i++) { if (upperDfa[curr.s0][i]!=-1 && upperDfa[curr.s1][i]!=-1) { State nextState = new State(upperDfa[curr.s0][i], upperDfa[curr.s1][i], curr.isDifferent, -1, -1); int nextCost = cost + 2; if (!min.containsKey(nextState) || nextCost < min.get(nextState)) { min.put(nextState, nextCost); pq.offer(new QNode(nextState, nextCost)); } } } // Try taking a pair of lowercase transitions. for (int i=0; i<26; i++) { if (lowerDfa[curr.s0][i]==-1) { continue; } if (curr.constrainedState==0 && curr.blockedCharIndex==i) { continue; } for (int j=0; j<26; j++) { if (lowerDfa[curr.s1][j]==-1) { continue; } if (curr.constrainedState==1 && curr.blockedCharIndex==j) { continue; } State nextState = null; if (i==j) { nextState = new State(lowerDfa[curr.s0][i], lowerDfa[curr.s1][j], curr.isDifferent, -1, -1); } else { nextState = new State(lowerDfa[curr.s0][i], lowerDfa[curr.s1][j], true, -1, -1); } int nextCost = cost + 2; if (!min.containsKey(nextState) || nextCost < min.get(nextState)) { min.put(nextState, nextCost); pq.offer(new QNode(nextState, nextCost)); } } } // Try taking (lowercase, epsilon) transitions. for (int i=0; i<26; i++) { if (lowerDfa[curr.s0][i]==-1) { continue; } if (curr.constrainedState==0 && curr.blockedCharIndex==i) { continue; } State nextState = null; if (curr.constrainedState==0) { nextState = new State(lowerDfa[curr.s0][i], curr.s1, true, -1, -1); } else if (curr.constrainedState==1) { nextState = new State(lowerDfa[curr.s0][i], curr.s1, true, curr.constrainedState, curr.blockedCharIndex); } else { if (curr.isDifferent) { nextState = new State(lowerDfa[curr.s0][i], curr.s1, true, -1, -1); } else { nextState = new State(lowerDfa[curr.s0][i], curr.s1, true, 1, i); } } int nextCost = cost + 1; if (!min.containsKey(nextState) || nextCost < min.get(nextState)) { min.put(nextState, nextCost); pq.offer(new QNode(nextState, nextCost)); } } // Try taking (epsilon, lowercase) transitions. for (int i=0; i<26; i++) { if (lowerDfa[curr.s1][i]==-1) { continue; } if (curr.constrainedState==1 && curr.blockedCharIndex==i) { continue; } State nextState = null; if (curr.constrainedState==1) { nextState = new State(curr.s0, lowerDfa[curr.s1][i], true, -1, -1); } else if (curr.constrainedState==0) { nextState = new State(curr.s0, lowerDfa[curr.s1][i], true, curr.constrainedState, curr.blockedCharIndex); } else { if (curr.isDifferent) { nextState = new State(curr.s0, lowerDfa[curr.s1][i], true, -1, -1); } else { nextState = new State(curr.s0, lowerDfa[curr.s1][i], true, 0, i); } } int nextCost = cost + 1; if (!min.containsKey(nextState) || nextCost < min.get(nextState)) { min.put(nextState, nextCost); pq.offer(new QNode(nextState, nextCost)); } } } System.out.println(-1); } } class QNode implements Comparable { State s; int cost; public QNode(State ss, int costt) { s = ss; cost = costt; } public int compareTo(QNode q2) { return cost - q2.cost; } public String toString() { return String.format("(%s, %d)", s.toString(), cost); } } class State { int s0, s1, constrainedState, blockedCharIndex; boolean isDifferent; public State(int ss0, int ss1, boolean diff, int constrainedState, int blockedCharIndex) { s0 = ss0; s1 = ss1; isDifferent = diff; this.blockedCharIndex = blockedCharIndex; this.constrainedState = constrainedState; } public boolean equals(Object obj) { State s2 = (State)obj; return s0==s2.s0 && s1==s2.s1 && isDifferent==s2.isDifferent && blockedCharIndex==s2.blockedCharIndex && constrainedState==s2.constrainedState; } public int hashCode() { return blockedCharIndex+1 + 27*(constrainedState+1) + 27*3*(isDifferent?1:0) + 27*3*2*s1 + 27*3*2*50*s0; } public String toString() { return String.format("(%d, %d, %s, %d, %d)", s0, s1, isDifferent, constrainedState, blockedCharIndex); } }