import Foundation

let main: () = {
    let MOD = 1_000_000_007
    let S = nextInt()
    var dp = IntArray(S + 1) { 0 }
    dp[0] = 1
    var sum = 0
    for n in 1 ... S {
        if n - 3 >= 0 {
            sum += dp[n - 3]
            sum %= MOD
        }
        dp[n] = sum
    }
    let ans = dp[S]
    print(ans)
}()

//----------------------------------

let dx = [1, 0, -1, 0] //[1, 0, -1, 0, -1,  1, -1, 1]
let dy = [0, 1, 0, -1] //[0, 1, 0, -1, -1, -1,  1, 1]

@inlinable func gcd(_ a: Int, _ b: Int) -> Int { (b > 0) ? gcd(b, a % b) : a }
@inlinable func lcm(_ a: Int, _ b: Int) -> Int { a / gcd(a, b) * b }

//----------------------------------

infix operator  =~ : ComparisonPrecedence
infix operator !=~ : ComparisonPrecedence
func =~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { !(right ~= left) }
func =~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { !(right ~= left) }

func =~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { right.contains(left) }
func !=~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { !right.contains(left) }

infix operator /^ : MultiplicationPrecedence
infix operator /^= : AssignmentPrecedence
func /^ <T: FixedWidthInteger>(left: T, right: T) -> T { (left + (right - 1)) / right }
func /^= <T: FixedWidthInteger>(left: inout T, right: T) { left = (left + (right - 1)) / right }

@inlinable func chmax<T: Comparable>(_ m: inout T, _ q: T) { if (m < q) { m = q } }
@inlinable func chmin<T: Comparable>(_ m: inout T, _ q: T) { if (m > q) { m = q } }
@inlinable func chRmax<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m < q) { m = q; return true } else { return false } }
@inlinable func chRmin<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m > q) { m = q; return true } else { return false } }

prefix operator *
prefix func * <T> (a: [T]) -> (T, T) { (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T) { (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T) { (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4], a[5]) }

func printErr(_ str: String, terminator: String = "\n") {
    let s = str + terminator
    FileHandle.standardError.write(s.data(using: .utf8)!)
    FileHandle.standardError.synchronizeFile()
}

@inlinable func next() -> String { readLine()! }
@inlinable func nextInt() -> Int { Int(next())! }
@inlinable func nextDouble() -> Double { Double(next())! }
@inlinable func listOfString() -> [String] { next().split(separator: " ").map(String.init) }
@inlinable func listOfInt() -> [Int] { listOfString().map { Int($0)! } }
@inlinable func listOfInt(_ offset: Int = 0) -> [Int] { listOfString().map { Int($0)! + offset } }
@inlinable func listOfInt(_ offsets: Int ...) -> [Int] { listOfString().enumerated().map { Int($0.element)! + offsets[$0.offset % offsets.count] } }
@inlinable func listOfDouble(_ offset: Double = 0.0) -> [Double] { listOfString().map { Double($0)! + offset } }
@inlinable func listOfDouble(_ offsets: Double ...) -> [Double] { listOfString().enumerated().map { Double($0.element)! + offsets[$0.offset % offsets.count] } }

extension Int {
    init(s: String) { self.init(s)! }
    var isEven: Bool { self.isMultiple(of: 2) }
    var isOdd: Bool { !self.isEven }
    var isTrue: Bool { self != 0 }
    var isFalse: Bool { !self.isTrue }
    var toString: String { String(self) }
    var toChar: Character { Character(UnicodeScalar(UInt8(self))) }
}
func + (left: Int, right: Bool) -> Int { left + (right ? 1 : 0) }
extension Character {
    var asciiCode: Int { Int(self.asciiValue!) }
    var string: String { String(self) }
}
extension String {
    @inlinable subscript (position: Int) -> Character { self[self.index(self.startIndex, offsetBy: position)] }
    @inlinable func repeate(_ times: Int) -> String { String(repeating: self, count: times) }
    //  @inlinable subscript (n: Int) -> String { String(self[self.index(self.startIndex, offsetBy: n)]) }
    //  @inlinable subscript (n: Int) -> Int { Int(self[self.index(self.startIndex, offsetBy: n)].asciiValue!) }
    var toInt: Int { Int(self)! }
}
extension String { // VB like
    @inlinable func _index(_ position: Int) -> String.Index! {
        if !(0 ..< self.count ~= position) { return nil }
        return self.index(self.startIndex, offsetBy: position)
    }
    @inlinable func mid(from index: Int, length: Int) -> String! {
        if let startPosition = self._index(index) {
            if let endPosition = self._index(index + length - 1) {
                return String(self[startPosition...endPosition])
            } else {
                let endPosition = self.index(before: self.endIndex)
                return String(self[startPosition...endPosition])
            }
        }
        return ""
    }
    @inlinable func left(_ length: Int) -> String { String(self.prefix(length)) }
    @inlinable func right(_ length: Int) -> String { String(self.suffix(length)) }
}

extension Dictionary {
    @inlinable mutating func getOrSet(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored }
        else {
            let newValue = defaultValue()
            self[key] = newValue
            return newValue
        }
    }
    @inlinable mutating func getOrElse(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored } else { return defaultValue() }
    }
    @inlinable func containsKey(_ key: Key) -> Bool { self.keys.contains(key) }
}

extension Set {
    static func += (left: inout Set<Element>, right: Element) { left.insert(right) }
    static func -= (left: inout Set<Element>, right: Element) { left.remove(right) }
}

extension Array {
    static func += (left: inout Array<Element>, right: Element) { left.append(right) }
    init(_ size: Int, _ initValue: ((Int) -> Element)) {
        self = [Element]()
        for index in 0 ..< size {
            let value = initValue(index)
            self.append(value)
        }
    }
    init(_ size: Int, _ initValue: (() -> Element)) {
        self = [Element]()
        for _ in 0 ..< size {
            let value = initValue()
            self.append(value)
        }
    }
}
typealias IntArray = Array<Int>
typealias DoubleArray = Array<Double>
typealias BoolArray = Array<Bool>
typealias StringArray = Array<String>

extension Array where Element == Int {
    init(_ size: Int) {
        self = [Element](repeating: 0, count: size)
    }
}
extension Array where Element == Double {
    init(_ size: Int) {
        self = [Element](repeating: 0.0, count: size)
    }
}
extension Array where Element == Bool {
    init(_ size: Int) {
        self = [Element](repeating: false, count: size)
    }
}
extension Array where Element == String {
    init(_ size: Int) {
        self = [Element](repeating: "", count: size)
    }
}

extension Array {
    @inlinable func count(_ predicate: ((Element) -> Bool)) -> Int {
        var cnt = 0; for e in self { if (predicate(e)) { cnt += 1 } }
        return cnt
    }
    @inlinable func groupBy<K>(_ keySelector: (Element) -> K) -> [K : [Element]] {
        var destination = [K : [Element]]()
        for element in self {
            let key = keySelector(element)
            var list = destination.getOrSet(key) { [Element]() }
            list.append(element)
            destination[key] = list
        }
        return destination
    }
    @inlinable func groupByIndexed<K>(_ keySelector: (Element) -> K) -> [K : [Int]] {
        var destination = [K : [Int]]()
        for element in self.enumerated() {
            let key = keySelector(element.element)
            var list = destination.getOrSet(key) { [Int]() }
            list.append(element.offset)
            destination[key] = list
        }
        return destination
    }
}

extension Array {
    func binarySearch(_ element: Element, by compare: (Element, Element) -> Int, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            let cmp = compare(midVal, element)
            if (cmp < 0) { low = mid + 1 }          //-1
            else if (0 < cmp) { high = mid - 1 }    // 1
            else { return mid } // key found        // 0
        }
        return -(low + 1)  // key not found
    }
}
extension Array where Element : Comparable {
    func binarySearch(_ element: Element, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            if (midVal < element) { low = mid + 1 }
            else if (midVal > element) { high = mid - 1 }
            else { return mid } // key found
        }
        return -(low + 1)  // key not found
    }
}

extension Array where Element == Int {
    @inlinable func distinct() -> [Element] {
        var set = Set<Element>(), ary = [Element]()
        for n in self.indices { if !set.contains(self[n]) { ary.append(self[n]); set.insert(self[n]) } }
        return ary
    }
    @inlinable func any(_ predicate: (Element) -> Bool) -> Bool {
        var any = false; for element in self { if predicate(element) { any = true } }
        return any
    }
    @inlinable func all(_ predicate: (Element) -> Bool) -> Bool {
        self.allSatisfy(predicate)
    }
    @inlinable func sum() -> Element { self.reduce(0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}

extension Array where Element == Double {
    @inlinable func sum() -> Element { self.reduce(0.0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0.0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}
extension Array where Element == String {
    @inlinable func toIntDouble() -> (Int, Double) { (Int(self[0])!, Double(self[1])!) }
    @inlinable func toIntString() -> (Int, String) { (Int(self[0])!, self[1]) }
    @inlinable func toIntIntString() -> (Int, Int, String) { (Int(self[0])!, Int(self[1])!, self[2]) }
}

@inlinable func block( _ action: () -> Void) {
    action()
}
@inlinable func repeate(_ times1: Int, _ action: () -> Void) {
    for _ in 0 ..< times1 { action() }
}
@inlinable func repeate(_ times1: Int, _ action: (Int) -> Void) {
    for index1 in 0 ..< times1 {
        action(index1)
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ action: (Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            action(index1, index2)
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ action: (Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                action(index1, index2, index3)
            }
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ times4: Int, _ action: (Int, Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                for index4 in 0 ..< times4 {
                    action(index1, index2, index3, index4)
                }
            }
        }
    }
}

func measureTimeSeconds(block: (() -> Void)) -> Double {
    let startTime = Date()
    block()
    let duration = -startTime.timeIntervalSinceNow
    return duration
}


let s = Int(readLine()!)!

var dp: [Int] = .init(repeating: -1, count: s + 1)
let mod = 1000000007
func backtrack(from value: Int, target: Int) -> Int {
  if value == target {
    return 1
  }
  if value > target {
    return 0
  }
  if dp[value] != -1 {
    return dp[value]
  }

  var sum = 0
  for i in 3..<2000 {
    if i + value > target {
      break
    }
    sum += backtrack(from: value + i, target: target)
    sum %= mod
  }
  dp[value] = sum
  return dp[value]
}

print(backtrack(from: 0, target: s))


let s = Int(readLine()!)!
let devider = 1000_000_000 + 7
var dpTable: [Int] = .init(repeating: 0, count: s+1)

dpTable[0] = 1
dpTable[1] = 0
dpTable[2] = 0

for i in 3...s {
    dpTable[i] = dpTable[i-3]+dpTable[i-1]
    dpTable[i] %= devider
}

print(dpTable[s])


let s = Int(readLine()!)!
let devider = 1000_000_000 + 7
var dpTable: [Int] = .init(repeating: 0, count: s+1)

dpTable[0] = 1
dpTable[1] = 0
dpTable[2] = 0

for i in 3...s {
    for j in 0...i-3 {
        dpTable[i] += dpTable[j]
        dpTable[i] %= devider
    }
}

print(dpTable[s])


var main = (input: string) => {
    const s: number = parseInt(input);

    let ans: number = distribution(s) % 1000000007;
    ans = (ans + 1000000007) % 1000000007;
    console.log(ans);
}

var memorizedDistribution = {};
function distribution(s: number) {
    if (s === 1 || s === 2) {
        return 0;
    } else if (s === 3) {
        return 1;
    }

    if (memorizedDistribution[s]) {
        return memorizedDistribution[s];
    } else {
        let d = (distribution(s - 1) + distribution(s - 3)) % 1000000007;
        memorizedDistribution[s] = d;
        return d;
    }
}

main(require("fs").readFileSync("/dev/stdin", "utf8"));


import { readFileSync } from "fs";

////////////////////////////////////////////////////////////////////////////////
// Application
////////////////////////////////////////////////////////////////////////////////
/* number */
const P = 10 ** 9 + 7;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [addP, subP, prodP, powP] = getNModCalc(P);
/* bigint */
// const P = 10n ** 9n + 7n;
// // eslint-disable-next-line @typescript-eslint/no-unused-vars
// const [addP, subP, prodP, powP] = getBModCalc(P);

const getPartitionNumber = (n: number): number => {
  type DicType = Map<number, number>;
  const dic: DicType = new Map<number, number>();
  range(4).forEach((i) => {
    dic.set(i, i < 3 ? 0 : 1);
  });
  const getValue = (n: number, dic: DicType) => {
    const rec = dic.get(n);
    return typeof rec !== "undefined"
      ? rec
      : (() => {
          const p = getPartitionNumber(n, dic);
          dic.set(n, p);
          return p;
        })();
  };
  const getPartitionNumber = (n: number, dic: DicType): number => {
    const rec = dic.get(n);
    return typeof rec !== "undefined"
      ? rec
      : addP(getValue(n - 1, dic), getValue(n - 3, dic));
  };
  return getPartitionNumber(n, dic);
};
const getAns = (S: number): string => getPartitionNumber(S).toString();

/** main */
const main = () => {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [cin, nCin, bCin] = getCin();
  const S = nCin();
  const ans = getAns(S);
  console.log(ans);
};
main();

////////////////////////////////////////////////////////////////////////////////
// Library
////////////////////////////////////////////////////////////////////////////////
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function range(n: number | bigint) {
  return Array.from(Array(Number(n)), (_, i) => i);
}

function tuple<T extends unknown[]>(...ts: T) {
  return ts;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getCin() {
  const inputs = readFileSync("/dev/stdin", "utf-8")
    .split("\n")
    .flatMap((l) => l.split(" "));
  let count = 0;
  const cin = () => inputs[count++];
  return tuple(
    cin,
    () => Number(cin()),
    () => BigInt(cin())
  );
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function isNumber(x: unknown): x is number {
  return typeof x === "number";
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function isBigint(x: unknown): x is bigint {
  return typeof x === "bigint";
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function nMax(ns: number[]) {
  return ns.reduce((acc, n) => Math.max(acc, n));
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function nMin(ns: number[]) {
  return ns.reduce((acc, n) => Math.min(acc, n));
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function bMax(bs: bigint[]) {
  return bs.reduce((acc, b) => (acc >= b ? acc : b));
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function bMin(bs: bigint[]) {
  return bs.reduce((acc, b) => (acc <= b ? acc : b));
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function nAbs(n: number) {
  return Math.abs(n);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function bAbs(b: bigint) {
  return b >= 0n ? b : -b;
}

type BinaryOperation<T> = (x: T, y: T) => T;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getNModCalc(n: number) {
  type CalcType = BinaryOperation<number>;
  const modAdd: CalcType = (x, y) => ((((x % n) + (y % n)) % n) + n) % n;
  const modSub: CalcType = (x, y) => ((((x % n) - (y % n)) % n) + n) % n;
  const modProd: CalcType = (x, y) => ((((x % n) * (y % n)) % n) + n) % n;
  const modPow: CalcType = (x, n) => {
    const isEvens = (() => {
      const isEvens: boolean[] = [];
      for (let tmpN = n; tmpN !== 1; tmpN = Math.floor(tmpN / 2))
        isEvens.push(tmpN % 2 === 0);
      return isEvens;
    })();
    return isEvens.reduceRight(
      (acc, b) => (b ? modProd(acc, acc) : modProd(x, modProd(acc, acc))),
      x
    );
  };
  return tuple(modAdd, modSub, modProd, modPow);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getBModCalc(b: bigint) {
  type CalcType = BinaryOperation<bigint>;
  const modAdd: CalcType = (x, y) => ((((x % b) + (y % b)) % b) + b) % b;
  const modSub: CalcType = (x, y) => ((((x % b) - (y % b)) % b) + b) % b;
  const modProd: CalcType = (x, y) => ((((x % b) * (y % b)) % b) + b) % b;
  const modPow: CalcType = (x, b) => {
    const isEvens = (() => {
      const isEvens: boolean[] = [];
      for (let tmpN = b; tmpN !== 1n; tmpN /= 2n)
        isEvens.push(tmpN % 2n === 0n);
      return isEvens;
    })();
    return isEvens.reduceRight(
      (acc, b) => (b ? modProd(acc, acc) : modProd(x, modProd(acc, acc))),
      x
    );
  };
  return tuple(modAdd, modSub, modProd, modPow);
}


import { readFileSync } from "fs";

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Application
//
////////////////////////////////////////////////////////////////////////////////////////////////////
const P = 10 ** 9 + 7;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [addP, subP, prodP, powP] = getModCalc(P);

const getPartitionNumber = (n: number): number => {
  const dic = new Map<number, number>();
  range(4).forEach((i) => {
    dic.set(i, i < 3 ? 0 : 1);
  });
  const getValue = (n: number) => {
    const rec = dic.get(n);
    return typeof rec !== "undefined"
      ? rec
      : (() => {
          const p = getPartitionNumber(n);
          dic.set(n, p);
          return getPartitionNumber(n);
        })();
  };
  const getPartitionNumber = (n: number): number => {
    const rec = dic.get(n);
    return typeof rec !== "undefined"
      ? rec
      : addP(getValue(n - 1), getValue(n - 3));
  };
  return getPartitionNumber(n);
};
const getAns = (S: number): string => getPartitionNumber(S).toString();
/** main */
const main = () => {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [cin, nCin, bCin] = getCin();
  const S = nCin();
  const ans = getAns(S);
  console.log(ans);
};
main();

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Library
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function range(n: number | bigint) {
  return Array.from(Array(Number(n)), (_, i) => i);
}
function tuple<T extends unknown[]>(...ts: T) {
  return ts;
}
function getCin() {
  const inputs = readFileSync("/dev/stdin", "utf-8").split(/[\n|\s]+/);
  let count = 0;
  const cin = () => inputs[count++];
  return tuple(
    cin,
    () => Number(cin()),
    () => BigInt(cin())
  );
}
function isNumber(x: unknown): x is number {
  return typeof x === "number";
}
function isBigint(x: unknown): x is bigint {
  return typeof x === "bigint";
}
type NumberOrBigintOrElse<T> = number | bigint extends T
  ? undefined
  : T extends number
  ? number
  : T extends bigint
  ? bigint
  : undefined;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function max<T extends number | bigint>(...ts: T[]) {
  return (ts.length === 0
    ? undefined
    : isNumber(ts[0])
    ? Math.max(...(ts as number[]))
    : (ts as bigint[]).reduce((acc, t) =>
        acc >= t ? acc : t
      )) as NumberOrBigintOrElse<T>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function min<T extends number | bigint>(...ts: T[]) {
  return (ts.length === 0
    ? undefined
    : isNumber(ts[0])
    ? Math.min(...(ts as number[]))
    : (ts as bigint[]).reduce((acc, t) =>
        acc <= t ? acc : t
      )) as NumberOrBigintOrElse<T>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function abs<T extends number | bigint>(t: T) {
  return (isNumber(t)
    ? Math.abs(t)
    : isBigint(t)
    ? t >= 0n
      ? t
      : -t
    : undefined) as NumberOrBigintOrElse<T>;
}
type BinaryOperation<T> = (x: T, y: T) => T;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getModCalc<T extends number | bigint>(n: T) {
  type CalcType = BinaryOperation<NumberOrBigintOrElse<T>>;
  const modAdd = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) + (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) + (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modSub = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) - (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) - (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modProd = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) * (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) * (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modPow: CalcType = (x, n) => {
    const isEvens =
      isNumber(x) && isNumber(n)
        ? ((x: number, n: number) => {
            let tmpN = n;
            const isEvens: boolean[] = [];
            while (tmpN !== 1) {
              isEvens.push(tmpN % 2 === 0);
              tmpN = Math.floor(tmpN / 2);
            }
            return isEvens;
          })(x, n)
        : isBigint(x) && isBigint(n)
        ? ((x: bigint, n: bigint) => {
            let tmpN = n;
            const isEvens: boolean[] = [];
            while (tmpN !== 1n) {
              isEvens.push(tmpN % 2n === 0n);
              tmpN /= 2n;
            }
            return isEvens;
          })(x, n)
        : undefined;
    return (typeof isEvens !== "undefined"
      ? isEvens.reduceRight((acc, b) => {
          const tmp = modProd(acc, acc);
          return b ? tmp : modProd(x, tmp);
        }, x)
      : undefined) as NumberOrBigintOrElse<T>;
  };
  return tuple(modAdd, modSub, modProd, modPow);
}


import { readFileSync } from "fs";

/**
 * Application
 */
const P = 10n ** 9n + 7n;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [addP, subP, prodP, powP] = getModCalc(P);
const getPartitionNumber = (n: bigint): bigint => {
  const dic = new Map<bigint, bigint>();
  range(3)
    .map((i) => BigInt(i))
    .forEach((i) => {
      dic.set(i, 0n);
    });

  const rec = dic.get(n);

  return typeof rec !== "undefined"
    ? rec
    : n < 3n
    ? 0n
    : 1n +
      range(max(0n, n - 2n))
        .map((i) => BigInt(i) + 3n)
        .map((i) => {
          const rec = dic.get(n - i);
          return typeof rec !== "undefined"
            ? rec
            : (() => {
                const p = getPartitionNumber(n - i);
                dic.set(n - i, p);
                return p;
              })();
        })
        .reduce((acc, p) => addP(acc, p), 0n);
};
const getAns = (S: bigint): string => getPartitionNumber(S).toString();
{
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [cin, nCin, bCin] = getCin();
  const S = bCin();
  const ans = getAns(S);
  console.log(ans);
}

/**
 * Library
 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function range(n: number | bigint) {
  return Array.from(Array(Number(n)), (_, i) => i);
}
function tuple<T extends unknown[]>(...ts: T) {
  return ts;
}
function getCin() {
  const inputs = readFileSync("/dev/stdin", "utf-8").split(/[\n|\s]+/);
  let count = 0;
  const cin = () => inputs[count++];
  return tuple(
    cin,
    () => Number(cin()),
    () => BigInt(cin())
  );
}
function isNumber(x: unknown): x is number {
  return typeof x === "number";
}
function isBigint(x: unknown): x is bigint {
  return typeof x === "bigint";
}
type NumberOrBigintOrElse<T> = number | bigint extends T
  ? undefined
  : T extends number
  ? number
  : T extends bigint
  ? bigint
  : undefined;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function max<T extends number | bigint>(...ts: T[]) {
  return (ts.length === 0
    ? undefined
    : isNumber(ts[0])
    ? Math.max(...(ts as number[]))
    : (ts as bigint[]).reduce((acc, t) =>
        acc >= t ? acc : t
      )) as NumberOrBigintOrElse<T>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function min<T extends number | bigint>(...ts: T[]) {
  return (ts.length === 0
    ? undefined
    : isNumber(ts[0])
    ? Math.min(...(ts as number[]))
    : (ts as bigint[]).reduce((acc, t) =>
        acc <= t ? acc : t
      )) as NumberOrBigintOrElse<T>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function abs<T extends number | bigint>(t: T) {
  return (isNumber(t)
    ? Math.abs(t)
    : isBigint(t)
    ? t >= 0n
      ? t
      : -t
    : undefined) as NumberOrBigintOrElse<T>;
}
type BinaryOperation<T> = (x: T, y: T) => T;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getModCalc<T extends number | bigint>(n: T) {
  type CalcType = BinaryOperation<NumberOrBigintOrElse<T>>;
  const modAdd = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) + (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) + (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modSub = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) - (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) - (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modProd = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) * (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) * (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modPow: CalcType = (x, n) => {
    const isEvens =
      isNumber(x) && isNumber(n)
        ? ((x: number, n: number) => {
            let tmpN = n;
            const isEvens: boolean[] = [];
            while (tmpN !== 1) {
              isEvens.push(tmpN % 2 === 0);
              tmpN = Math.floor(tmpN / 2);
            }
            return isEvens;
          })(x, n)
        : isBigint(x) && isBigint(n)
        ? ((x: bigint, n: bigint) => {
            let tmpN = n;
            const isEvens: boolean[] = [];
            while (tmpN !== 1n) {
              isEvens.push(tmpN % 2n === 0n);
              tmpN /= 2n;
            }
            return isEvens;
          })(x, n)
        : undefined;
    return (typeof isEvens !== "undefined"
      ? isEvens.reduceRight((acc, b) => {
          const tmp = modProd(acc, acc);
          return b ? tmp : modProd(x, tmp);
        }, x)
      : undefined) as NumberOrBigintOrElse<T>;
  };
  return tuple(modAdd, modSub, modProd, modPow);
}


import { readFileSync } from "fs";

/**
 * Application
 */
const P = 10n ** 9n + 7n;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [addP, subP, prodP, powP] = getModCalc(P);
const getPartitionNumber = (n: bigint): bigint => {
  const dic = new Map<bigint, bigint>();
  range(3)
    .map((i) => BigInt(i))
    .forEach((i) => {
      dic.set(i, 0n);
    });

  const rec = dic.get(n);

  return typeof rec !== "undefined"
    ? rec
    : n < 3n
    ? 0n
    : 1n +
      range(max(0n, n - 2n))
        .map((i) => BigInt(i) + 3n)
        .map((i) => {
          const p = getPartitionNumber(n - i);
          dic.set(n - i, p);
          return p;
        })
        .reduce((acc, p) => addP(acc, p), 0n);
};
const getAns = (S: bigint): string => getPartitionNumber(S).toString();
{
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [cin, nCin, bCin] = getCin();
  const S = bCin();
  const ans = getAns(S);
  console.log(ans);
}

/**
 * Library
 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function range(n: number | bigint) {
  return Array.from(Array(Number(n)), (_, i) => i);
}
function tuple<T extends unknown[]>(...ts: T) {
  return ts;
}
function getCin() {
  const inputs = readFileSync("/dev/stdin", "utf-8").split(/[\n|\s]+/);
  let count = 0;
  const cin = () => inputs[count++];
  return tuple(
    cin,
    () => Number(cin()),
    () => BigInt(cin())
  );
}
function isNumber(x: unknown): x is number {
  return typeof x === "number";
}
function isBigint(x: unknown): x is bigint {
  return typeof x === "bigint";
}
type NumberOrBigintOrElse<T> = number | bigint extends T
  ? undefined
  : T extends number
  ? number
  : T extends bigint
  ? bigint
  : undefined;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function max<T extends number | bigint>(...ts: T[]) {
  return (ts.length === 0
    ? undefined
    : isNumber(ts[0])
    ? Math.max(...(ts as number[]))
    : (ts as bigint[]).reduce((acc, t) =>
        acc >= t ? acc : t
      )) as NumberOrBigintOrElse<T>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function min<T extends number | bigint>(...ts: T[]) {
  return (ts.length === 0
    ? undefined
    : isNumber(ts[0])
    ? Math.min(...(ts as number[]))
    : (ts as bigint[]).reduce((acc, t) =>
        acc <= t ? acc : t
      )) as NumberOrBigintOrElse<T>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function abs<T extends number | bigint>(t: T) {
  return (isNumber(t)
    ? Math.abs(t)
    : isBigint(t)
    ? t >= 0n
      ? t
      : -t
    : undefined) as NumberOrBigintOrElse<T>;
}
type BinaryOperation<T> = (x: T, y: T) => T;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getModCalc<T extends number | bigint>(n: T) {
  type CalcType = BinaryOperation<NumberOrBigintOrElse<T>>;
  const modAdd = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) + (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) + (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modSub = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) - (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) - (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modProd = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) * (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) * (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modPow: CalcType = (x, n) => {
    const isEvens =
      isNumber(x) && isNumber(n)
        ? ((x: number, n: number) => {
            let tmpN = n;
            const isEvens: boolean[] = [];
            while (tmpN !== 1) {
              isEvens.push(tmpN % 2 === 0);
              tmpN = Math.floor(tmpN / 2);
            }
            return isEvens;
          })(x, n)
        : isBigint(x) && isBigint(n)
        ? ((x: bigint, n: bigint) => {
            let tmpN = n;
            const isEvens: boolean[] = [];
            while (tmpN !== 1n) {
              isEvens.push(tmpN % 2n === 0n);
              tmpN /= 2n;
            }
            return isEvens;
          })(x, n)
        : undefined;
    return (typeof isEvens !== "undefined"
      ? isEvens.reduceRight((acc, b) => {
          const tmp = modProd(acc, acc);
          return b ? tmp : modProd(x, tmp);
        }, x)
      : undefined) as NumberOrBigintOrElse<T>;
  };
  return tuple(modAdd, modSub, modProd, modPow);
}


import { readFileSync } from "fs";

/**
 * Application
 */
const P = 10n ** 9n + 7n;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [addP, subP, prodP, powP] = getModCalc(P);
const getPartitionNumber = (n: bigint): bigint => {
  const dic = new Map<bigint, bigint>();
  range(3)
    .map((i) => BigInt(i))
    .forEach((i) => {
      dic.set(i, 0n);
    });

  const rec = dic.get(n);

  return typeof rec !== "undefined"
    ? rec
    : n < 3n
    ? 0n
    : 1n +
      range(max(0n, n - 2n))
        .map((i) => BigInt(i) + 3n)
        .map((i) => getPartitionNumber(n - i))
        .reduce((acc, p) => addP(acc, p), 0n);
};
const getAns = (S: bigint): string => getPartitionNumber(S).toString();
{
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [cin, nCin, bCin] = getCin();
  const S = bCin();
  const ans = getAns(S);
  console.log(ans);
}

/**
 * Library
 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function range(n: number | bigint) {
  return Array.from(Array(Number(n)), (_, i) => i);
}
function tuple<T extends unknown[]>(...ts: T) {
  return ts;
}
function getCin() {
  const inputs = readFileSync("/dev/stdin", "utf-8").split(/[\n|\s]+/);
  let count = 0;
  const cin = () => inputs[count++];
  return tuple(
    cin,
    () => Number(cin()),
    () => BigInt(cin())
  );
}
function isNumber(x: unknown): x is number {
  return typeof x === "number";
}
function isBigint(x: unknown): x is bigint {
  return typeof x === "bigint";
}
type NumberOrBigintOrElse<T> = number | bigint extends T
  ? undefined
  : T extends number
  ? number
  : T extends bigint
  ? bigint
  : undefined;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function max<T extends number | bigint>(...ts: T[]) {
  return (ts.length === 0
    ? undefined
    : isNumber(ts[0])
    ? Math.max(...(ts as number[]))
    : (ts as bigint[]).reduce((acc, t) =>
        acc >= t ? acc : t
      )) as NumberOrBigintOrElse<T>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function min<T extends number | bigint>(...ts: T[]) {
  return (ts.length === 0
    ? undefined
    : isNumber(ts[0])
    ? Math.min(...(ts as number[]))
    : (ts as bigint[]).reduce((acc, t) =>
        acc <= t ? acc : t
      )) as NumberOrBigintOrElse<T>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function abs<T extends number | bigint>(t: T) {
  return (isNumber(t)
    ? Math.abs(t)
    : isBigint(t)
    ? t >= 0n
      ? t
      : -t
    : undefined) as NumberOrBigintOrElse<T>;
}
type BinaryOperation<T> = (x: T, y: T) => T;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getModCalc<T extends number | bigint>(n: T) {
  type CalcType = BinaryOperation<NumberOrBigintOrElse<T>>;
  const modAdd = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) + (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) + (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modSub = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) - (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) - (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modProd = ((x, y) =>
    isNumber(x) && isNumber(y) && isNumber(n)
      ? ((((x % n) * (y % n)) % n) + n) % n
      : isBigint(x) && isBigint(y) && isBigint(n)
      ? ((((x % n) * (y % n)) % n) + n) % n
      : undefined) as CalcType;
  const modPow: CalcType = (x, n) => {
    const isEvens =
      isNumber(x) && isNumber(n)
        ? ((x: number, n: number) => {
            let tmpN = n;
            const isEvens: boolean[] = [];
            while (tmpN !== 1) {
              isEvens.push(tmpN % 2 === 0);
              tmpN = Math.floor(tmpN / 2);
            }
            return isEvens;
          })(x, n)
        : isBigint(x) && isBigint(n)
        ? ((x: bigint, n: bigint) => {
            let tmpN = n;
            const isEvens: boolean[] = [];
            while (tmpN !== 1n) {
              isEvens.push(tmpN % 2n === 0n);
              tmpN /= 2n;
            }
            return isEvens;
          })(x, n)
        : undefined;
    return (typeof isEvens !== "undefined"
      ? isEvens.reduceRight((acc, b) => {
          const tmp = modProd(acc, acc);
          return b ? tmp : modProd(x, tmp);
        }, x)
      : undefined) as NumberOrBigintOrElse<T>;
  };
  return tuple(modAdd, modSub, modProd, modPow);
}


Cards=[input() for _ in range(3)]
start=0
while Cards[start]:
  turn=ord(Cards[start][0])-97
  Cards[start]=Cards[start][1:]
  start=turn
print(chr(turn+97).upper())


import sys
A=str(input())
B=str(input())
C=str(input())

alt="a"
while True:
  if alt == "a":
    if A=="":
      print("A")
      sys.exit()
    alt = A[0]
    A=A[1:]
  if alt == "b":
    if B=="":
      print("B")
      sys.exit()
    alt = B[0]
    B=B[1:]
  if alt == "c":
    if C=="":
      print("C")
      sys.exit()
    alt = C[0]
    C=C[1:]


s = {'a':input(),'b':input(),'c':input()}
n = 'a'
while len(s[n])!= 0:
    o = s[n][0]
    s[n] = s[n][1:]
    n = o
print(n.upper())


s_a = input()
s_b = input()
s_c = input()
turn = str()
isCalledOnce = True

turn = s_a[0]
s_a = s_a.lstrip(turn)

while len(s_a) >= 1 and len(s_b) >= 1 and len(s_c) >= 1:
    if turn == "a" and isCalledOnce:
        s_a = s_a.lstrip(s_a[0])
        if len(s_a) == 0:
            break
        turn = s_a[0]
        isCalledOnce = False
    if turn == "b" and isCalledOnce:
        s_b = s_b.lstrip(s_b[0])
        if len(s_b) == 0:
            break
        turn = s_b[0]
        isCalledOnce = False
    if turn == "c" and isCalledOnce:
        s_c = s_c.lstrip(s_c[0])
        if len(s_b) == 0:
            break
        turn = s_c[0]
        isCalledOnce = False

    isCalledOnce = True

if turn == "a":
    print("A")
if turn == "b":
    print("B")
if turn == "c":
    print("C")


s_a = input()
s_b = input()
s_c = input()
turn = str()
isCalledOnce = True

turn = s_a[0]
s_a = s_a.lstrip(turn)

while len(s_a) >= 1 and len(s_b) >= 1 and len(s_c) >= 1:
    if turn == "a" and isCalledOnce:
        turn = s_a[0]
        s_a = s_a.lstrip(turn)
        isCalledOnce = False
    if turn == "b" and isCalledOnce:
        turn = s_b[0]
        s_b = s_b.lstrip(turn)
        isCalledOnce = False
    if turn == "c":
        turn = s_c[0]
        s_c = s_c.lstrip(turn)

    isCalledOnce = True

if turn == "a":
    print("A")
if turn == "b":
    print("B")
if turn == "c":
    print("C")


s_a = input()
s_b = input()
s_c = input()
turn = str()

turn = s_a[0]
s_a = s_a.lstrip(turn)

while len(s_a) >= 1 and len(s_b) >= 1 and len(s_c) >= 1:
    if turn == "a":
        turn = s_a[0]
        s_a = s_a.lstrip(turn)
    if turn == "b":
        turn = s_b[0]
        s_b = s_b.lstrip(turn)
    if turn == "c":
        turn = s_c[0]
        s_c = s_c.lstrip(turn)

if turn == "a":
    print("A")
if turn == "b":
    print("B")
if turn == "c":
    print("C")


import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class Main {
    public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);

		// 入力
		String a = sc.next();
		String b = sc.next();
		String c = sc.next();

		// 計算
		String result = "";
		int ia = 0;
		int ib = 0;
		int ic = 0;
		char next = 'a';
		while(true){
		    if(next == 'a'){
		        if(ia == a.length()){
		            result = "A";
		            break;
		        }else{
		            next = a.charAt(ia);
		            ia++;
		        }
		    }else if(next == 'b'){
		        if(ib == b.length()){
		            result = "B";
		            break;
		        }else{
		            next = b.charAt(ib);
		            ib++;
		        }
		    }else{
		        if(ic == c.length()){
		            result = "C";
		            break;
		        }else{
		            next = c.charAt(ic);
		            ic++;
		        }
		    }
		}

		// 出力
		System.out.println(result);
	}

	public static class Scanner {
		private BufferedReader br; private StringTokenizer tok;
		public Scanner(InputStream is) throws IOException { br = new BufferedReader(new InputStreamReader(is));}
		private void getLine() throws IOException { while(!hasNext()) tok = new StringTokenizer(br.readLine());}
		private boolean hasNext() { return tok != null && tok.hasMoreTokens();}
		public String next() throws IOException { getLine(); return tok.nextToken();}
		public int nextInt() throws IOException { return Integer.parseInt(next());}
		public long nextLong() throws IOException { return Long.parseLong(next());}
		public double nextDouble() throws IOException { return Double.parseDouble(next());}
	}
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;

public final class Main {
	public static void main(String[] args) throws java.lang.Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder a = new StringBuilder(br.readLine());
		StringBuilder b = new StringBuilder(br.readLine());
		StringBuilder c = new StringBuilder(br.readLine());
		Solver s = new Solver();
		System.out.println(s.solve(a, b, c));
	}

}

class Solver {

	String solve(StringBuilder a, StringBuilder b, StringBuilder c) {
		char t = 'a';
		while (true) {
			if (t == 'a') {
				if (a.length() == 0) {
					return "A";
				}
				t = a.charAt(0);
				a.deleteCharAt(0);
			} else if (t == 'b') {

				if (b.length() == 0) {
					return "B";
				}
				t = b.charAt(0);
				b.deleteCharAt(0);
			} else if (t == 'c') {

				if (c.length() == 0) {
					return "C";
				}
				t = c.charAt(0);
				c.deleteCharAt(0);
			}
		}

	}

}


import java.io.*;
import java.util.*;

class Main {
    static char[] a, b, c;
    static int[] ids;
    static char res;

    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        ids = new int[3];
        a = br.readLine().toCharArray();
        b = br.readLine().toCharArray();
        c = br.readLine().toCharArray();
        recur(0, a);
        System.out.println(res);
    }

    static void recur(int id, char[] carr){
        if(ids[id]==carr.length){
            res = (char)(id+'A');
            return;
        }
        char curr = carr[ids[id]];
        ids[id]++;
        if(curr == 'a')
            recur(0, a);
        else if(curr == 'b')
            recur(1, b);
        else
            recur(2, c);
    }
}


import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

class AC045B {}

class Main {
    public static void main(String[] args) throws IOException {
        char[] a = rcha(), b = rcha(), c = rcha(), dmbs = {'A', 'B', 'C'};
        char[][] decks = {a, b, c};
        int[] ind = new int[3];
        if(a.length == 0) {
            prln('A');
            close();
            return;
        }
        char card = a[0];
        ind[0]++;
        while(true) {
            int n = card - 'a';
            card = decks[n][ind[n]++];
            n = card - 'a';
            if(ind[n] == decks[n].length) {
                prln(dmbs[n]);
                break;
            }
            //if(ind[1] == b.length) {
            //    prln('B');
            //    break;
            //}
            //if(ind[2] == c.length) {
            //    prln('C');
            //    break;
            //}
        }

        close();
    }

    static BufferedReader __in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __out = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;

    // references
    // IBIG = 1e9 + 7
    // IRAND ~= 3e8
    // IMAX ~= 2e10
    // LMAX ~= 9e18
    // constants
    static final int IBIG = 1000000007;
    static final int IRAND = 327859546;
    static final int IMAX = 2147483647;
    static final int IMIN = -2147483648;
    static final long LMAX = 9223372036854775807L;
    static final long LMIN = -9223372036854775808L;
    // util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {return x.length == 1 ? x[0] : x.length == 2 ? min(x[0], x[1]) : min(x[0], minstarting(1, x));}
    static int minstarting(int offset, int... x) {assert x.length > 2; return offset == x.length - 2 ? min(x[offset], x[offset + 1]) : min(x[offset], minstarting(offset + 1, x));}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {return x.length == 1 ? x[0] : x.length == 2 ? min(x[0], x[1]) : min(x[0], minstarting(1, x));}
    static long minstarting(int offset, long... x) {assert x.length > 2; return offset == x.length - 2 ? min(x[offset], x[offset + 1]) : min(x[offset], minstarting(offset + 1, x));}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {return x.length == 1 ? x[0] : x.length == 2 ? max(x[0], x[1]) : max(x[0], maxstarting(1, x));}
    static int maxstarting(int offset, int... x) {assert x.length > 2; return offset == x.length - 2 ? max(x[offset], x[offset + 1]) : max(x[offset], maxstarting(offset + 1, x));}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {return x.length == 1 ? x[0] : x.length == 2 ? max(x[0], x[1]) : max(x[0], maxstarting(1, x));}
    static long maxstarting(int offset, long... x) {assert x.length > 2; return offset == x.length - 2 ? max(x[offset], x[offset + 1]) : max(x[offset], maxstarting(offset + 1, x));}
    static int powi(int a, int b) {if(a == 0) return 0; int ans = 1; while(b > 0) {if((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if(a == 0) return 0; long ans = 1; while(b > 0) {if((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int floori(double d) {return (int)d;}
    static int ceili(double d) {return (int)ceil(d);}
    static long floorl(double d) {return (long)d;}
    static long ceill(double d) {return (long)ceil(d);}
    // input
    static void r() throws IOException {input = new StringTokenizer(__in.readLine());}
    static int ri() throws IOException {return Integer.parseInt(__in.readLine());}
    static long rl() throws IOException {return Long.parseLong(__in.readLine());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; input = new StringTokenizer(__in.readLine()); for(int i = 0; i < n; ++i) a[i] = Integer.parseInt(input.nextToken()); return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; input = new StringTokenizer(__in.readLine()); for(int i = 0; i < n; ++i) a[i] = Long.parseLong(input.nextToken()); return a;}
    static char[] rcha() throws IOException {return __in.readLine().toCharArray();}
    static String rline() throws IOException {return __in.readLine();}
    static int rni() throws IOException {input = new StringTokenizer(__in.readLine()); return Integer.parseInt(input.nextToken());}
    static int ni() {return Integer.parseInt(input.nextToken());}
    static long rnl() throws IOException {input = new StringTokenizer(__in.readLine()); return Long.parseLong(input.nextToken());}
    static long nl() {return Long.parseLong(input.nextToken());}
    // output
    static void pr(int i) {__out.print(i);}
    static void prln(int i) {__out.println(i);}
    static void pr(long l) {__out.print(l);}
    static void prln(long l) {__out.println(l);}
    static void pr(double d) {__out.print(d);}
    static void prln(double d) {__out.println(d);}
    static void pr(char c) {__out.print(c);}
    static void prln(char c) {__out.println(c);}
    static void pr(char[] s) {__out.print(new String(s));}
    static void prln(char[] s) {__out.println(new String(s));}
    static void pr(String s) {__out.print(s);}
    static void prln(String s) {__out.println(s);}
    static void pr(Object o) {__out.print(o);}
    static void prln(Object o) {__out.println(o);}
    static void prln() {__out.println();}
    static void pryes() {__out.println("yes");}
    static void pry() {__out.println("Yes");}
    static void prY() {__out.println("YES");}
    static void prno() {__out.println("no");}
    static void prn() {__out.println("No");}
    static void prN() {__out.println("NO");}
    static void pryesno(boolean b) {__out.println(b ? "yes" : "no");};
    static void pryn(boolean b) {__out.println(b ? "Yes" : "No");}
    static void prYN(boolean b) {__out.println(b ? "YES" : "NO");}
    static void prln(int... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static void prln(long... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for(int i = 0; i < n; __out.print(iter.next()), __out.print(' '), ++i); __out.println(iter.next());}
    static void flush() {__out.flush();}
    static void close() {__out.close();}}


import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

class AC045B {}

class Main {
    public static void main(String[] args) throws IOException {
        char[] a = rcha(), b = rcha(), c = rcha(), dmbs = {'A', 'B', 'C'};
        char[][] decks = {a, b, c};
        int[] ind = new int[3];
        char card = a[0];
        ind[0]++;
        while(true) {
            int n = card - 'a';
            card = decks[n][ind[n]++];
            n = card - 'a';
            if(ind[n] == decks[n].length) {
                prln(dmbs[n]);
                break;
            }
            //if(ind[1] == b.length) {
            //    prln('B');
            //    break;
            //}
            //if(ind[2] == c.length) {
            //    prln('C');
            //    break;
            //}
        }

        close();
    }

    static BufferedReader __in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __out = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;

    // references
    // IBIG = 1e9 + 7
    // IRAND ~= 3e8
    // IMAX ~= 2e10
    // LMAX ~= 9e18
    // constants
    static final int IBIG = 1000000007;
    static final int IRAND = 327859546;
    static final int IMAX = 2147483647;
    static final int IMIN = -2147483648;
    static final long LMAX = 9223372036854775807L;
    static final long LMIN = -9223372036854775808L;
    // util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {return x.length == 1 ? x[0] : x.length == 2 ? min(x[0], x[1]) : min(x[0], minstarting(1, x));}
    static int minstarting(int offset, int... x) {assert x.length > 2; return offset == x.length - 2 ? min(x[offset], x[offset + 1]) : min(x[offset], minstarting(offset + 1, x));}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {return x.length == 1 ? x[0] : x.length == 2 ? min(x[0], x[1]) : min(x[0], minstarting(1, x));}
    static long minstarting(int offset, long... x) {assert x.length > 2; return offset == x.length - 2 ? min(x[offset], x[offset + 1]) : min(x[offset], minstarting(offset + 1, x));}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {return x.length == 1 ? x[0] : x.length == 2 ? max(x[0], x[1]) : max(x[0], maxstarting(1, x));}
    static int maxstarting(int offset, int... x) {assert x.length > 2; return offset == x.length - 2 ? max(x[offset], x[offset + 1]) : max(x[offset], maxstarting(offset + 1, x));}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {return x.length == 1 ? x[0] : x.length == 2 ? max(x[0], x[1]) : max(x[0], maxstarting(1, x));}
    static long maxstarting(int offset, long... x) {assert x.length > 2; return offset == x.length - 2 ? max(x[offset], x[offset + 1]) : max(x[offset], maxstarting(offset + 1, x));}
    static int powi(int a, int b) {if(a == 0) return 0; int ans = 1; while(b > 0) {if((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if(a == 0) return 0; long ans = 1; while(b > 0) {if((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int floori(double d) {return (int)d;}
    static int ceili(double d) {return (int)ceil(d);}
    static long floorl(double d) {return (long)d;}
    static long ceill(double d) {return (long)ceil(d);}
    // input
    static void r() throws IOException {input = new StringTokenizer(__in.readLine());}
    static int ri() throws IOException {return Integer.parseInt(__in.readLine());}
    static long rl() throws IOException {return Long.parseLong(__in.readLine());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; input = new StringTokenizer(__in.readLine()); for(int i = 0; i < n; ++i) a[i] = Integer.parseInt(input.nextToken()); return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; input = new StringTokenizer(__in.readLine()); for(int i = 0; i < n; ++i) a[i] = Long.parseLong(input.nextToken()); return a;}
    static char[] rcha() throws IOException {return __in.readLine().toCharArray();}
    static String rline() throws IOException {return __in.readLine();}
    static int rni() throws IOException {input = new StringTokenizer(__in.readLine()); return Integer.parseInt(input.nextToken());}
    static int ni() {return Integer.parseInt(input.nextToken());}
    static long rnl() throws IOException {input = new StringTokenizer(__in.readLine()); return Long.parseLong(input.nextToken());}
    static long nl() {return Long.parseLong(input.nextToken());}
    // output
    static void pr(int i) {__out.print(i);}
    static void prln(int i) {__out.println(i);}
    static void pr(long l) {__out.print(l);}
    static void prln(long l) {__out.println(l);}
    static void pr(double d) {__out.print(d);}
    static void prln(double d) {__out.println(d);}
    static void pr(char c) {__out.print(c);}
    static void prln(char c) {__out.println(c);}
    static void pr(char[] s) {__out.print(new String(s));}
    static void prln(char[] s) {__out.println(new String(s));}
    static void pr(String s) {__out.print(s);}
    static void prln(String s) {__out.println(s);}
    static void pr(Object o) {__out.print(o);}
    static void prln(Object o) {__out.println(o);}
    static void prln() {__out.println();}
    static void pryes() {__out.println("yes");}
    static void pry() {__out.println("Yes");}
    static void prY() {__out.println("YES");}
    static void prno() {__out.println("no");}
    static void prn() {__out.println("No");}
    static void prN() {__out.println("NO");}
    static void pryesno(boolean b) {__out.println(b ? "yes" : "no");};
    static void pryn(boolean b) {__out.println(b ? "Yes" : "No");}
    static void prYN(boolean b) {__out.println(b ? "YES" : "NO");}
    static void prln(int... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static void prln(long... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for(int i = 0; i < n; __out.print(iter.next()), __out.print(' '), ++i); __out.println(iter.next());}
    static void flush() {__out.flush();}
    static void close() {__out.close();}}


import java.util.*;
import java.io.*;

public class Main{

     public static void main(String []args){
       Scanner scanner = new Scanner(System.in);
       String a = scanner.next();
       String b = scanner.next();
       String c = scanner.next();
       List<Character> list1 = new ArrayList<>();
       List<Character> list2= new ArrayList<>();
       List<Character> list3 = new ArrayList<>();

       int current =1;

       for(int i=0;i<a.length();i++)
       list1.add(a.charAt(i));

       for(int i=0;i<b.length();i++)
       list2.add(b.charAt(i));

       for(int i=0;i<c.length();i++)
       list3.add(c.charAt(i));

       outerloop:
       while(list1.size()!=0 || list2.size()!=0 || list3.size()!=0 )
       {

          if(current==1)
          {

              while(list1.size()!=0 &&list1.get(0)=='a' )
              {

                  list1.remove(0);
              }
              if(list1.size()!=0 && list1.get(0)=='b' )
              current =2;
               if( list1.size()!=0 && list1.get(0)=='c')
               current =3;

               if(list1.size()!=0)
              list1.remove(0);
              else break outerloop;

          }

          else if(current==2)
          {
              while(list2.size()!=0 && list2.get(0)=='b')
              {
                  list2.remove(0);
              }
              if(list2.size()!=0 && list2.get(0)=='a' )
              current =1;
               if(list2.size()!=0 && list2.get(0)=='c')
               current =3;

                if(list2.size()!=0)
                  list2.remove(0);
                else break outerloop;

          }

          else if(current==3)
          {
              while(list3.size()!=0 && list3.get(0)=='c' )
              {
                  list3.remove(0);
              }
              if(list3.size()!=0 &&list3.get(0)=='a')
              current =1;
               if(list3.size()!=0 && list3.get(0)=='b' )
               current =2;

                if(list3.size()!=0)
                  list3.remove(0);
                else break outerloop;

          }
       }

       if(list1.size()==0)
       System.out.println("A");
       else if(list2.size()==0)
       System.out.println("B");
       else if(list3.size()==0)
       System.out.println("C");

     }
}


#include <stdio.h>

int main(int argc, char **argv)
{
	int i , acnt = 0, bcnt = 0, ccnt = 0;
	char cards[3][300] = { 0 };
	char turn = 'a';

	for (i = 0; i < 3; i++) {
		scanf("%s", cards[i]);
	}
	for (;;) {
		if (turn == 'a') {
			turn = cards[0][acnt];
			if (!turn) {
				printf("A\r\n");
				break;
			}
			acnt++;
		} else if (turn == 'b') {
			turn = cards[1][bcnt];
			if (!turn) {
				printf("B\r\n");
				break;
			}
			bcnt++;
		} else {
			turn = cards[2][ccnt];
			if (!turn) {
				printf("C\r\n");
				break;
			}
			ccnt++;
		}
	}

	return 0;
}


#include<stdio.h>

#define PEOPLE_MAX 3
#define MAX_LENGTH 101
int main(int argc, char *argv[])
{
	int i, turn = 0;
	int position[PEOPLE_MAX] = {0};
	char s[PEOPLE_MAX][MAX_LENGTH];

	for (i = 0; i < PEOPLE_MAX; ++i) {
		scanf("%s", s[i]);
	}

	while(1) {
		++position[turn];
		turn = s[turn][position[turn] - 1] - 97;
		if (s[turn][position[turn]] == '\0') {
			break;
		}
	}
	printf("%c\n", turn + 65);

	return 0;
}


#include<stdio.h>
#include<string.h>
int main(void)
{
	char a[3][100];
	int x,y,i,w[3],j,p[3];
	for(i=0;i<3;i++) w[i]=0;
	for(i=0;i<3;i++){
		scanf("%s",a[i]); w[i]=strlen(a[i]); p[i]=0;
	}
	x=0;
	while(1){
		y=a[x][p[x]]-'a';
		p[x]++;
		x=y;
		if(p[x]==w[x]) break;
	}
	printf("%c\n",x+'A');
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ll long long
int main(){
  string sa,sb,sc;
  cin >> sa >> sb >> sc;
  ll la=sa.size(),lb=sb.size(),lc=sc.size();
  char ch='a';
  ll a=0,b=0,c=0;
  while(1){
    if(ch=='a'&& a>=la){
       cout << 'A';
      break;
      return 0;
    }
    if(ch=='b'&& b>=lb){
       cout << 'B';
      break;
      return 0;
    }
    if(ch=='c'&& c>=lc){
       cout << 'C';
      break;
      return 0;
    }
    if(ch=='a'){
      ch=sa.at(a);
      a++;
    }else if(c=='b'){
      ch=sb.at(b);
      b++;
    }else{
      ch=sc.at(c);
      c++;
    }

  }
}


#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Solution{

public:
    char winner(const vector<string>& s){

        char cur = 'a';
        vector<int> p(3, 0);
        while(p[cur - 'a'] < s[cur - 'a'].size()){
            cur = s[cur - 'a'][p[cur - 'a']];
            p[cur - 'a'] ++;
        }
        return cur - 'a' + 'A';
    }
};

int main() {

    vector<string> s(3);
    for(int i = 0; i < 3; i ++) cin >> s[i];
    printf("%c\n", Solution().winner(s));

    return 0;
}


#include <iostream>
#include <string>
using namespace std;
string Sa,Sb,Sc;
int a_cnt = 0;
int b_cnt = 0;
int c_cnt = 0;
string ans = "A";

void make_turn(char id){
    if(id == 'a'){
    	if(a_cnt < Sa.size()){
    	    a_cnt++;
    	    make_turn(Sa[a_cnt-1]);
    		}
    	else{
    	    ans = "A";
    		}
    	}
    else if(id == 'b' ){
    	if(b_cnt < Sb.size()){
    	    b_cnt++;
    	    make_turn(Sb[b_cnt-1]);
    	    }
    	else{
    	    ans = "B";
    		}

    	}
    else if(id == 'c'){
    	if(c_cnt < Sb.size()){
    	    c_cnt++;
        	make_turn(Sc[c_cnt-1]);
         }
    	else{
    	    ans = "C";
    		}
    	}
	}

int main(){

	cin >> Sa >> Sb >> Sc;

	make_turn('a');

	cout << ans << endl;

	return 0;
	}


short len[3], used[3], s[3][100], d, i;

void rec(t){
        if(used[t]++>=len[t]) putchar('A'+t);
        else rec(s[t][used[t]-1]);
}

main(){
        for(i=0; i<3; i++){
                while((d=getchar())!='\n'){
                        s[i][len[i]++] = d-'a';
                }
        }
        rec(0);
}


#include<stdio.h>
#include<string.h>

int main(){
int a,b,c;
char x;
  char Sa[100],Sb[100],Sc[100];
  scanf("%s",Sa);
  scanf("%s",Sb);
  scanf("%s",Sc);
  a = strlen(Sa);
  b = strlen(Sb);
  c = strlen(Sc);
  x = Sa[0];
  a--;
  while(1){
    if(a == -1 || b == -1 || c == -1){
      break;
    }
    if(x == 'a'){
      if(a > 0){
        x = Sa[strlen(Sa)-a];
      }a--;
  }
    if(x == 'b'){
      if(b > 0){
        x = Sb[strlen(Sb)-b];
      }
      b--;
  }
    if(x == 'c'){
     if(c > 0){
       x = Sc[strlen(Sc)-c];
     }
      c--;
  }
  }
  if(a == -1){
    printf("A");
  }
  if(b == -1){
    printf("B");
  }
  if(c == -1){
    printf("C");
  }
  return 0;
}


char len[3], used[3], s[3][100], d, i;

void rec(char t){
        if(used[t]++>=len[t]) putchar('A'+t);
        else rec(s[t][used[t]-1]);
}

int main(){
        for(i=0; i<3; i++){
                while((d=getchar())!='\n'){
                        s[i][len[i]++] = d-'a';
                }
        }
        rec(0);
        return 0;
}


#include<stdio.h>
#include<string.h>

int main(){
    char a[100],b[100],c[100];
    scanf("%s",a);
    scanf("%s",b);
    scanf("%s",c);
    int sa=strlen(a);
    int sb=strlen(b);
    int sc=strlen(c);

    char s[3][100];
    for(int t=0;t<100;t++){
        s[0][t]=a[t];
        s[1][t]=b[t];
        s[2][t]=c[t];
    }

    int x=0;
    int y=0;

    int i=0;
    int j=0;
    int k=0;
    for(;;){
        if(s[x][y]=='a'){
            if(x==0){
                i++;
            }else if(x==1){
                j++;
            }else if(x==2){
                k++;
            }
            x=0;
            y=i;
        }else if(s[x][y]=='b'){
            if(x==0){
                i++;
            }else if(x==1){
                j++;
            }else if(x==2){
                k++;
            }
            x=1;
            y=j;
        }else if(s[x][y]=='c'){
            if(x==0){
                i++;
            }else if(x==1){
                j++;
            }else if(x==2){
                k++;
            }
            x=2;
            y=k;
        }else{
            break;
        }
    }

    if(i==sa){
        printf("A\n");
    }else if(j==sb){
        printf("B\n");
    }else if(k==sc){
        printf("C\n");
    }
    return 0;
}


#include<stdio.h>
int main(){
    char Sa[101],Sb[101],Sc[101];
    int i=0,j=0,k=0;
    char p='a';
    scanf("%s",Sa);
    scanf("%s",Sb);
    scanf("%s",Sc);
    while(1){
        switch(p){
            case 'a':{
                if(Sa[i]=='a')p='a';
                else if(Sa[i]=='b')p='b';
                else p='c';
                i++; break;
            }
            case 'b':{
                if(Sb[j]=='a')p='a';
                else if(Sb[j]=='b')p='b';
                else p='c';
                j++; break;
            }
            case 'c':{
                if(Sc[k]=='a')p='a';
                else if(Sc[k]=='b')p='b';
                else p='c';
                k++; break;
            }
        }
        if(Sa[i]=='\0'){
            printf("A");
            break;
        }else if(Sb[j]=='\0'){
            printf("B");
            break;
        }else if(Sc[k]=='\0'){
            printf("C");
            break;
        }
    }
    return 0;
}


'use strict'

const main = input => {
	const args = input.split('\n').map(arg => arg.split(' '))

	const t = {
		a: args[0][0].split(''),
		b: args[1][0].split(''),
		c: args[2][0].split('')
	}

	let next = 'a'

	while (true) {
		if (t[next].length === 0) break
		next = t[next].shift()
	}

	console.log(next.toUpperCase())
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'))


function Main(input) {
	input = input.split("\n");
	input[0] = input[0].split("");
	input[1] = input[1].split("");
	input[2] = input[2].split("");
  input[0].push("#");
    input[1].push("#");
    input[2].push("#");
	var now = 0;
	var ans = "C";
  //console.log(input[now])
	while(input[now].length>0){
		switch(input[now][0]){
			case "a":
			input[now].shift();
			now = 0;
			break;
         	case "b":
			input[now].shift();
			now = 1;
			break;
			case "c":
			input[now].shift();
			now = 2;
			break;
          case "#":
            switch(now){
              case 0:
                console.log("A");
                break;
              case 1:
                console.log("B");
                break;
              case 2:
                console.log("C");
                break;
                      }
            input[now].shift();
            break;
		}
	}
}Main(require("fs").readFileSync("/dev/stdin", "utf8").trim());


function Main(arg)
{
  var sa = arg.split("\n")[0].split("");
  var sb = arg.split("\n")[1].split("");
  var sc = arg.split("\n")[2].split("");

  var next = 'a';
  while (1) {
    if (next === 'a') {
      if (sa.length===0) {
        console.log("A");
        return;
      }
      next = sa.shift();
    }
    else if (next === 'b') {
      if (sb.length===0) {
        console.log("B");
        return;
      }
      next = sb.shift();
    }
    else if (next === 'c') {
      if (sc.length===0) {
        console.log("C");
        return;
      }
      next = sc.shift();
    }
  }

  return;
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


"use strict"
const create = () => {
    const input = require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n");
    const res = {
        "list": input, "index": 0, "max": input.length,
        "hasNext": function() {return this.index < this.max},
        "next": function() { if (!this.hasNext()) {throw "ArrayIndexOutOfBoundsException";}else{return this.list[this.index++];}}
    };
    return res;
}
const o = create();
const next = () => o.next()
const nextInt = () => parseInt(o.next())
const nextStrArray = () => o.next().split(" ")
const nextIntArray = () => o.next().split(" ").map(el => parseInt(el))
const nextCharArray = () => o.next().split("")
const hasNext = () => o.hasNext()
const myout = (...x) => console.log(...x)
const Main = () => {
    let s = {}
    s["a"] = next()
    s['b'] = next()
    s['c'] = next()
    let p = {
        "a" : -1,
        "b" : 0,
        "c" : 0
    }
    let turn = "a"
    while(true){
        p[turn]++
        if(p[turn] > s[turn].length){
            console.log(turn.toUpperCase())
            return
        }
        turn = s[turn][p[turn]]
    }

}
Main()


"use strict"
const create = () => {
    const input = require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n");
    const res = {
        "list": input, "index": 0, "max": input.length,
        "hasNext": function() {return this.index < this.max},
        "next": function() { if (!this.hasNext()) {throw "ArrayIndexOutOfBoundsException";}else{return this.list[this.index++];}}
    };
    return res;
}
const o = create();
const next = () => o.next()
const nextInt = () => parseInt(o.next())
const nextStrArray = () => o.next().split(" ")
const nextIntArray = () => o.next().split(" ").map(el => parseInt(el))
const nextCharArray = () => o.next().split("")
const hasNext = () => o.hasNext()
const myout = (...x) => console.log(...x)
const Main = () => {
    let s = {}
    s["a"] = next()
    s['b'] = next()
    s['c'] = next()
    let p = {
        "a" : -1,
        "b" : 0,
        "c" : 0
    }
    let turn = "a"
    while(true){
        p[turn]++
        if(p[turn] >= s[turn].length){
            console.log(turn.toUpperCase())
            return
        }
        turn = s[turn][p[turn]]
    }

}
Main()


'use strict';

function Main(input) {
  const tmp = input.split('\n');
  const A = tmp[0].split('').reverse();
  const B = tmp[1].split('').reverse();
  const C = tmp[2].split('').reverse();

  let winner;
  let turn = 1;
  let next = A.pop();
  while (turn) {
    switch (next) {
      case 'a':
        next = A.pop();
        if (next == undefined) {
          winner = 'A';
          turn = 0;
        }
        break;
      case 'b':
        next = B.pop();
        if (next == undefined) {
          winner = 'B';
          turn = 0;
        }
      case 'c':
        next = C.pop();
        if (next == undefined) {
          winner = 'C';
          turn = 0;
        }
      default:
        break;
    }
  }
  console.log(winner);
}
Main(require('fs').readFileSync('/dev/stdin', 'utf8'));


package main

import "fmt"
import "strings"

func main() {
	var ia, ib, ic string
	fmt.Scan(&ia)
	fmt.Scan(&ib)
	fmt.Scan(&ic)

	sa := strings.Split(ia, "")
	sb := strings.Split(ib, "")
	sc := strings.Split(ic, "")

	turn := "a"
	for {
		switch turn {
		case "a":
			l := len(sa)
			if l > 0 {
				turn = sa[0]
				sa = sa[1:l]
			} else {
				fmt.Println("A")
				return
			}
		case "b":
			l := len(sb)
			if l > 0 {
				turn = sb[0]
				sb = sb[1:l]
			} else {
				fmt.Println("B")
				return
			}
		case "c":
			l := len(sc)
			if l > 0 {
				turn = sc[0]
				sc = sc[1:l]
			} else {
				fmt.Println("C")
				return
			}
		}
	}
}


package main

import (
	"fmt"
	"strings"
)

func main() {
	var a, b, c string
	fmt.Scan(&a, &b, &c)

	A := strings.Split(a, "")
	B := strings.Split(b, "")
	C := strings.Split(c, "")

	ans := exec(A, B, C)
	fmt.Println(ans)
}

func exec(A, B, C []string) string {
	target := "a"
	pa, pb, pc := 0, 0, 0

	for {
		if target == "a" {
			if pa == len(A) {
				return "A"
			}
			target = A[pa]
			pa++
		} else if target == "b" {
			if pb == len(B) {
				return "B"
			}
			target = B[pb]
			pb++
		} else if target == "c" {
			if pc == len(C) {
				return "C"
			}
			target = C[pc]
			pc++
		}
	}
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
	// "regexp"
)

/* sort */
type pair struct {
	index  int64
	p1, p2 interface{}
}
type pairs []pair

func (slice pairs) Len() int {
	return len(slice)
}

func (slice pairs) Less(i, j int) bool {
	return slice[i].index < slice[j].index
}

func (slice pairs) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

/* sort */
type Int64Slice []int64

func (slice Int64Slice) Len() int {
	return len(slice)
}

func (slice Int64Slice) Less(i, j int) bool {
	return slice[i] < slice[j]
}

func (slice Int64Slice) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
func Int64s(a []int64)                    { sort.Sort(Int64Slice(a)) }
func Int64sSliceAreSorted(a []int64) bool { return sort.IsSorted(Int64Slice(a)) }

const (
	initialBufSize = 1e4
	maxBufSize     = 1e8
	INF            = 1e8
)

var (
	scanner = bufio.NewScanner(os.Stdin)
	writer  = bufio.NewWriter(os.Stdout)
	di      = []int64{-1, 0, 1, 0}
	dj      = []int64{0, -1, 0, 1}
	di8     = []int64{-1, -1, 0, 1, 1, 1, 0, -1}
	dj8     = []int64{0, -1, -1, -1, 0, 1, 1, 1}
)

func main() {
	buf := make([]byte, initialBufSize)
	scanner.Buffer(buf, maxBufSize)
	scanner.Split(bufio.ScanWords)
	Sa, Sb, Sc := readStrings(), readStrings(), readStrings()
	S := [][]string{Sa, Sb, Sc}
	turn := int64(0)
	for {
		q := S[turn][0]
		S[turn] = S[turn][1:]
		// check
		if len(S[0]) == 0 && q == "a" ||
			len(S[1]) == 0 && q == "b" ||
			len(S[2]) == 0 && q == "c" {
			fmt.Println(strings.ToUpper(q))
			break
		}
		switch q {
		case "a":
			turn = 0
		case "b":
			turn = 1
		case "c":
			turn = 2
		}
	}
}

/*==========================================
 *             Library
 *==========================================*/
func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}
func doubleAry(h int64, w int64, init int64) (res [][]int64) {
	res = make([][]int64, h)
	for i := int64(0); i < h; i++ {
		res[i] = make([]int64, w)
		for j := int64(0); j < w; j++ {
			res[i][j] = init
		}
	}
	return
}

func aryEq(a []int64, b []int64) bool {
	return reflect.DeepEqual(a, b)
}

func clone(n []int64) (r []int64) {
	r = make([]int64, len(n))
	for i := 0; i < len(n); i++ {
		r[i] = n[i]
	}
	return
}
func write(s string) {
	writer.WriteString(s)
}

func print() {
	writer.Flush()
}

// scanner.Split(bufio.ScanWords) をコメントアウトしないと使用不可
func readLine() (s string) {
	if scanner.Scan() {
		s = scanner.Text()
	}
	return s
}

func readInt() (read int64) {
	scanner.Scan()
	read, err := strconv.ParseInt(scanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return
}

func readFloat() (read float64) {
	scanner.Scan()
	read, err := strconv.ParseFloat(scanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return
}

func readRunes() (read []rune) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, v)
	}
	return
}

func readString() (read string) {
	scanner.Scan()
	read = scanner.Text()
	return
}

func readStrings() (read []string) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, string(v))
	}
	return
}

func s2i(s string) int64 {
	var intVal, e = strconv.ParseInt(s, 10, 64)
	if e != nil {
		panic(e)
	}
	return intVal
}

func i2s(i int64) string {
	var strVal = strconv.FormatInt(i, 10)
	return strVal
}

func s2f(s string) float64 {
	var floatVal, e = strconv.ParseFloat(s, 64)
	if e != nil {
		panic(e)
	}
	return floatVal
}

func abs(i int64) int64 {
	return int64(math.Abs(float64(i)))
}

func max(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans < v {
			ans = v
		}
	}
	return ans
}
func min(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans > v {
			ans = v
		}
	}
	return ans
}

func sum(i []int64) int64 {
	sum := int64(0)
	for _, val := range i {
		sum += val
	}
	return sum
}

func split(s string) []string {
	return strings.Fields(s)
}

func strAry2intAry(strs []string) []int64 {
	var ret = make([]int64, 0, len(strs))
	for _, str := range strs {
		var intVal = s2i(str)
		ret = append(ret, intVal)
	}
	return ret
}

func intAry2strAry(nums []int64) []string {
	var ret = make([]string, 0, len(nums))
	for _, num := range nums {
		var strVal = i2s(num)
		ret = append(ret, strVal)
	}
	return ret
}

func ary2str(strs []string) string {
	return strings.Join(strs, " ")
}

func reverse(res []int64) []int64 {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}
func reverseStr(res []string) []string {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}

func ini(res []int, init int) {
	if len(res) == 0 {
		return
	}
	res[0] = init
	for i := 0; i < len(res); i++ {
		copy(res[i:], res[:i])
	}
}

//
// func regexpExample() {
//     // Your code here!
//     var str = "13:20"
//     r := regexp.MustCompile(`(\d+):(\d+)`)
//     fmt.Println(r.FindStringSubmatch(str))
// }

// type Country struct {
//     gold int
//     silver int
//     blonze int
// }

// // 複数ソートのサンプル
// func stableSortExample() []Country{
//     var country = []Country {
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:3, blonze:2},
//         {gold:1, silver:3, blonze:3},
//     }
//     sort.SliceStable(country, func(i, j int) bool { return country[i].blonze > country[j].blonze })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].silver > country[j].silver })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].gold > country[j].gold })
//     return country
// }


package main

import (
	"fmt"
	"strings"
)

type player struct {
	name  string
	cards []string
}

func main() {
	var a, b, c string
	fmt.Scan(&a, &b, &c)

	players := []player{
		{name: "A", cards: strings.Split(a, "")},
		{name: "B", cards: strings.Split(b, "")},
		{name: "C", cards: strings.Split(c, "")},
	}
	cardPlayerIdxMap := map[string]int{"a": 0, "b": 1, "c": 2}
	curTurn := 0
	for {
		curPlayer := players[curTurn]
		if len(curPlayer.cards) == 0 {
			fmt.Println(curPlayer.name)
			return
		}
		card := curPlayer.cards[0]
		curPlayer.cards = curPlayer.cards[1:]
		curTurn = cardPlayerIdxMap[card]
	}
}


package main

import "fmt"

func main() {
	// Code for B - Card Game for Three (ABC Edit)
	var Sa, Sb, Sc string
	fmt.Scanf("%s\n%s\n%s", &Sa, &Sb, &Sc)

	var flag string = string('a')
	for {
		if flag == string('a') {
			flag = Sa[len(Sa)-1 : len(Sa)]
			Sa = Sa[0 : len(Sa)-1]
			if len(Sa) == 0 {
				fmt.Println("A")
				break
			}
		} else if flag == string('b') {
			flag = Sb[len(Sb)-1 : len(Sb)]
			Sb = Sb[0 : len(Sb)-1]
			if len(Sb) == 0 {
				fmt.Println("B")
				break
			}
		} else {
			flag = Sc[len(Sc)-1 : len(Sc)]
			Sc = Sc[0 : len(Sc)-1]
			if len(Sc) == 0 {
				fmt.Println("C")
				break
			}
		}
	}
}


package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"sort"
	"strconv"
)

const (
	initialBufSize = 1e4
	maxBufSize     = 1e6 + 7
)

var buf []byte = make([]byte, maxBufSize)
var sc = bufio.NewScanner(os.Stdin)

func init() {
	sc.Split(bufio.ScanWords)
	sc.Buffer(buf, maxBufSize)
}

func main() {
	Sa, Sb, Sc := nextLine(), nextLine(), nextLine()
	// var a, b, c int
	// cur := Sa[a]
	// for {
	// 	switch cur {
	// 	case 'a':
	// 		a++
	// 		if a == len(Sa) {
	// 			fmt.Println("A")
	// 			return
	// 		}
	// 		cur = Sa[a]
	// 	case 'b':
	// 		b++
	// 		if b == len(Sb) {
	// 			fmt.Println("B")
	// 			return
	// 		}
	// 		cur = Sb[b]
	// 	case 'c':
	// 		c++
	// 		if c == len(Sc) {
	// 			fmt.Println("C")
	// 			return
	// 		}
	// 		cur = Sc[c]
	// 	}
	// }
	cur := Sa[0]
	// Sa = Sa[1:]
	// fmt.Println(Sa, Sb, Sc)
	first := true
	for {
		switch cur {
		case 'a':
			if !first {
				Sa = Sa[1:]
			}
			if len(Sa) == 0 {
				fmt.Println("A")
				return
			}
			cur = Sa[0]
			first = false
		case 'b':
			Sb = Sb[1:]
			if len(Sb) == 0 {
				fmt.Println("B")
				return
			}
			cur = Sb[0]
		case 'c':
			Sc = Sc[1:]
			if len(Sc) == 0 {
				fmt.Println("C")
				return
			}
			cur = Sc[0]
		}
		// fmt.Println("経過", Sa, Sb, Sc)
	}
}

func nextLine() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func abs(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func pow(p, q int) int {
	res := p
	if q == 0 {
		return 1
	}
	for i := 0; i < q-1; i++ {
		res *= p
	}
	return res
}

func MinOf(vars ...int) int {
	min := vars[0]
	for _, i := range vars {
		if min > i {
			min = i
		}
	}
	return min
}

func MaxOf(vars ...int) int {
	max := vars[0]
	for _, i := range vars {
		if max < i {
			max = i
		}
	}
	return max
}

func gcdof2numbers(a int, b int) int {
	if b == 0 {
		return a
	}
	return gcdof2numbers(b, a%b)
}

func lcmof2numbers(a int, b int) int {
	return a / gcdof2numbers(a, b) * b
}

// マイナスの場合は考慮していない
func fuctorial(a int) int {
	if a == 1 || a == 0 {
		return 1
	} else {
		return fuctorial(a-1) * a
	}
}

func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}

// 素因数分解したmapを返す
func primeFuctorize(n int) map[int]int {
	pf := map[int]int{}
	for i := 2; i*i <= n; i++ {
		for n%i == 0 {
			pf[i]++
			n /= i
		}
	}
	if n != 1 {
		pf[n]++
	}
	return pf
}

// ここから拝借
// https://shoman.hatenablog.com/entry/2020/02/25/185456
// Stackは[]intのエイリアス
type Stack []int

// Push adds an element
func (s *Stack) Push(v int) {
	*s = append(*s, v)
}

// Pop removes the top element and return it
func (s *Stack) Pop() (int, error) {
	if s.Empty() {
		return 0, fmt.Errorf("stack is empty")
	}

	v := (*s)[len(*s)-1]
	*s = (*s)[:len(*s)-1]
	return v, nil
}

// Peek returns the top value
func (s *Stack) Peek() (int, error) {
	if s.Empty() {
		return 0, fmt.Errorf("stack is empty")
	}

	return (*s)[len(*s)-1], nil
}

// Size returns the length of stack
func (s *Stack) Size() int {
	return len(*s)
}

// Empty returns true when stack is empty
func (s *Stack) Empty() bool {
	return s.Size() == 0
}

// NewStack generates stack
func NewStack() *Stack {
	s := new(Stack)
	return s
}

// golangの公式サンプルより
// https://xn--go-hh0g6u.com/pkg/container/heap/#example__intHeap
// IntHeap は，整数の最小ヒープです。
type IntHeap []int

func (h IntHeap) Len() int           { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *IntHeap) Push(x interface{}) {
	// Push と Pop はポインタレシーバを使っています。
	// なぜなら，スライスの中身だけでなく，スライスの長さも変更するからです。
	*h = append(*h, x.(int))
}

func (h *IntHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

// この例では IntHeap にいくつかの整数を挿入しています。そして，最小値をチェックしてから，
// 優先度順に取り除いています。
func Example_intHeap() {
	h := &IntHeap{2, 1, 5}
	heap.Init(h)
	heap.Push(h, 3)
	fmt.Printf("minimum: %d\n", (*h)[0])
	for h.Len() > 0 {
		fmt.Printf("%d ", heap.Pop(h))
	}
	// Output:
	// minimum: 1
	// 1 2 3 5
}

// golangの公式サンプルより
// https://xn--go-hh0g6u.com/pkg/container/heap/#example__priorityQueue

// Item は，優先キューで管理する項目です。
type Item struct {
	value    string // 値。任意です。
	priority int    // キューにおける優先度
	// index は heap.Interface メソッドで更新されます。
	index int // ヒープにおけるインデックス
}

// PriorityQueue は heap.Interface を実装し，Item のリストを保持します。
type PriorityQueue []*Item

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	// Pop が最小ではなく最大の優先度を持つ項目を返して欲しいので，ここでは > を使っています。
	return pq[i].priority > pq[j].priority
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}

func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Item)
	item.index = n
	*pq = append(*pq, item)
}

func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	old[n-1] = nil  // メモリリークを避ける
	item.index = -1 // 安全のため
	*pq = old[0 : n-1]
	return item
}

// update はキューの Item の優先度と値を更新します。
func (pq *PriorityQueue) update(item *Item, value string, priority int) {
	item.value = value
	item.priority = priority
	heap.Fix(pq, item.index)
}


a = gets.chomp.split("")
b = gets.chomp.split("")
c = gets.chomp.split("")

turn = "a"
loop do
    next_turn = nil
    case turn
    when "a" then
        next_turn = a.shift
    when "b" then
        next_turn = b.shift
    when "c" then
        next_turn = c.shift
    end
    if next_turn == nil
        puts turn.upcase
        exit
    else
        turn = next_turn
    end
end


sa=gets.chomp.chars
sb=gets.chomp.chars
sc=gets.chomp.chars
h = {
    'a' => sa,
    'b' => sb,
    'c' => sc,
}

c = 'a'
loop do
    c = h[c].shift
    if h[c].empty?
        puts c.upcase
        exit 0
    end
end


sa = gets.chomp
sb = gets.chomp
sc = gets.chomp
s = [sa,sb,sc]
t = {"a"=>0, "b"=>1, "c"=>2}
turn = 0
loop do
    x = s[turn]
    if x == "" then
        puts t.key(turn).upcase
        break
    end
    next_t = t[x[0]]
    s[turn] = x[1..-1]
    turn = next_t
end


a = gets.chomp
b = gets.chomp
c = gets.chomp

player = "a"
ind_hash = {"a" => 0, "b" => 0, "c" =>0}
hand_hash = {"a" => a, "b" => b, "c" =>c}

while true
  ind = ind_hash[player]
  card = hand_hash[player][ind]
  break if card.nil?

  player = card
  ind_hash[card] += 1
end

puts player.upcase


# 入力部
a = gets.chomp.split('')
b = gets.chomp.split('')
c = gets.chomp.split('')
arr = [a,b,c]
# p arr[0].shift
# p arr[0][0]

turn = 0
while true
  # 抜け
  if arr[turn] == []
     break
  end
  turn = case arr[turn][0]
          when "a"
            0
          when "b"
            1
          when "c"
            2
          end
  # turn 出力===================
  # if turn == 0
  #   puts "a"
  # elsif turn == 1
  #   puts "b"
  # else
  #   puts "c"
  # end
  # ===========================
  arr[turn].shift
end
if turn == 0
    puts "A"
  elsif turn == 1
    puts "B"
  else
    puts "C"
  end


alp = ['a', 'b', 'c']
a = Array.new(3) do
    gets.split('').map do |v|
        alp.index(v)
    end
end

turn = 0
while true do
    next_turn = a[turn].shift
    if a[turn].length == 0 then
        break
    end
    turn = next_turn
end

puts alp[turn]


use std::io;

fn main() {
	let mut s:Vec<Vec<char>> = Vec::new();
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let mut si = buf.trim().chars().collect::<Vec<char>>();
	let mut sj = si.clone();
	let iter = sj.iter().rev();
	let mut sa:Vec<char> = Vec::new();
	for c in iter {
		sa.push(*c);
	}
	s.push(sa);
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let mut si = buf.trim().chars().collect::<Vec<char>>();
	let mut sj = si.clone();
	let iter = sj.iter().rev();
	let mut sb:Vec<char> = Vec::new();
	for c in iter {
		sb.push(*c);
	}
	s.push(sb);
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let mut si = buf.trim().chars().collect::<Vec<char>>();
	let mut sj = si.clone();
	let iter = sj.iter().rev();
	let mut sc:Vec<char> = Vec::new();
	for c in iter {
		sc.push(*c);
	}
	s.push(sc);
	let mut n = 0;
	let mut winner = 0;
	loop {
		match s[n].pop() {
			Some(c) => {
				if c == 'a' {
					n = 0;
				}else if c == 'b' {
					n = 1;
				}else{
					n = 2;
				};
			},
			None => {
				winner = n;
				break;
			},
		}
	}
	if winner == 0 {
		println!("A");
	}else if winner == 1 {
		println!("B");
	}else{
		println!("C");
	}
}


use std::io::stdin;

fn main() {
    let mut s = String::new();
    stdin().read_line(&mut s).ok();
    let a = String::from(s.trim());
    let mut s = String::new();
    stdin().read_line(&mut s).ok();
    let b = String::from(s.trim());
    let mut s = String::new();
    stdin().read_line(&mut s).ok();
    let c = String::from(s.trim());
    let mut s = [a, b, c];

    let mut next = 0;
    while s[next].len() > 0 {
        next = match s[next].remove(0) {
            'a' => 0,
            'b' => 1,
            _ => 2,
        };
    }

    println!(
        "{}",
        match next {
            0 => 'A',
            1 => 'B',
            _ => 'C',
        },
    );
}


#![allow(unused_imports, unused_macros, dead_code)]

macro_rules! min {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        it.next().map(|z| it.fold(z, |x, y| min!(x, y)))
    }};
    ($x:expr) => ($x);
    ($x:expr, $($ys:expr),*) => {{
        let t = min!($($ys),*);
        if $x < t { $x } else { t }
    }}
}
macro_rules! max {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        it.next().map(|z| it.fold(z, |x, y| max!(x, y)))
    }};
    ($x:expr) => ($x);
    ($x:expr, $($ys:expr),*) => {{
        let t = max!($($ys),*);
        if $x > t { $x } else { t }
    }}
}
macro_rules! ewriteln {
    ($($args:expr),*) => { let _ = writeln!(&mut std::io::stderr(), $($args),*); };
}
macro_rules! trace {
    ($x:expr) => { ewriteln!(">>> {} = {:?}", stringify!($x), $x) };
    ($($xs:expr),*) => { trace!(($($xs),*)) }
}
macro_rules! put {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        if let Some(x) = it.next() { print!("{}", x); }
        for x in it { print!(" {}", x); }
        println!("");
    }};
    ($x:expr) => { println!("{}", $x) };
    ($x:expr, $($xs:expr),*) => { print!("{} ", $x); put!($($xs),*) }
}

const M: i64 = 1_000_000_007;

fn main() {
    let mut sc = Scanner::new();
    let mut a = sc.chars();
    let mut b = sc.chars();
    let mut c = sc.chars();
    a.reverse();
    b.reverse();
    c.reverse();
    let mut cur = 0;
    loop {
        if cur == 0 {
            if let Some(k) = a.pop() {
                match k {
                    'a' => { cur = 0; }
                    'b' => { cur = 1; }
                    'c' => { cur = 2 }
                    _ => {}
                }
            } else {
                put!("A");
                return
            }
        }
        else if cur == 1 {
            if let Some(k) = b.pop() {
                match k {
                    'a' => { cur = 0; }
                    'b' => { cur = 1; }
                    'c' => { cur = 2 }
                    _ => {}
                }
            } else {
                put!("B");
                return
            }
        } else {
            if let Some(k) = c.pop() {
                match k {
                    'a' => { cur = 0; }
                    'b' => { cur = 1; }
                    'c' => { cur = 2 }
                    _ => {}
                }
            } else {
                put!("C");
                return
            }
        }
    }
}

use std::io::{self, Write};
use std::str::FromStr;
use std::collections::VecDeque;

struct Scanner { stdin: io::Stdin, buffer: VecDeque<String>, }
impl Scanner {
    fn new() -> Self { Scanner { stdin: io::stdin(), buffer: VecDeque::new() } }
    fn cin<T: FromStr>(&mut self) -> T {
        while self.buffer.len() == 0 {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
        self.buffer.pop_front().unwrap().parse::<T>().ok().unwrap()
    }
    fn chars(&mut self) -> Vec<char> { self.cin::<String>().chars().collect() }
    fn vec<T: FromStr>(&mut self, n: usize) -> Vec<T> { (0..n).map(|_| self.cin()).collect() }
}


use proconio::input;
use proconio::marker::{Bytes, Chars};

// use std::cmp::*;
use std::collections::HashMap;

fn main() {
    input! {
        sa:Chars,
        sb:Chars,
        sc:Chars,
    }

    let mut idx: [usize; 3] = [0, 0, 0];
    let mut map: HashMap<char, usize> = HashMap::new();
    let inputs = [sa, sb, sc];
    map.insert('a', 0);
    map.insert('b', 1);
    map.insert('c', 2);

    let mut n = 'a';
    loop {
        let i: usize = idx[map[&n]];
        let s = &inputs[map[&n]];
        if s.len() <= i {
            println!("{}", n.to_uppercase());
            return;
        }
        n = s[i];
        idx[map[&n]] += 1;
    }
}


use proconio::input;

fn main() {
	input!(s: [String; 3]);

	let name = ['A', 'B', 'C'];
	//let mut s = s;
	let mut turn: usize = 0;
	let mut v = vec![vec![]; 3];
	for i in 0..3 {
		v[i] = s[i].chars().collect();
	}
	loop {
		if v[turn].len() == 0 {
			println!("{}", name[turn]);
			return;
		}
		turn = v[turn][0] as usize - 'a' as usize;
		v[turn].remove(0);
	}
}


use std::io;

fn main() {
	let mut s:Vec<Vec<char>> = Vec::new();
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let sa = buf.trim().chars().collect::<Vec<char>>();
	s.push(sa);
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let sb = buf.trim().chars().collect::<Vec<char>>();
	s.push(sb);
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let sc = buf.trim().chars().collect::<Vec<char>>();
	s.push(sc);
	let mut n = 0;
	let mut winner = 0;
	loop {
		match s[n].pop() {
			Some(c) => {
				if c == 'a' {
					n = 0;
				}else if c == 'b' {
					n = 1;
				}else{
					n = 2;
				};
			},
			None => {
				winner = n;
				break;
			},
		};
	}
	if winner == 0 {
		println!("A");
	}else if winner == 1 {
		println!("B");
	}else{
		println!("C");
	}
}


import Foundation

#if swift(>=4.0)
extension String {
    func split(by separator: String) -> [String] {
        return self.components(separatedBy: separator)
    }
    func toArray() -> [String] {
        return self.map{String($0)}
    }
}
func exponentiate(_ lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#else
extension String {
    func split(by separator: String) -> [String] {
        return self.componentsSeparatedByString(separator)
    }
    var count: Int {
        return self.characters.count
    }
    func toArray() -> [String] {
        return self.characters.map{String($0)}
    }
    func uppercased() -> String {
        return self.uppercaseString
    }
    func lowercased() -> String {
        return self.lowercaseString
    }
}
//extension Array where Element == String {
//    func joined(separator separator: String) -> String {
//        return self.joinWithSeparator(separator)
//    }
//}
extension Array where Element: Comparable {
    func max() -> Element {
        return self.maxElement()!
    }
    func min() -> Element {
        return self.minElement()!
    }
    func sorted() -> Array {
        return self.sort()
    }
    func reversed() -> Array {
        return self.reverse()
    }
    mutating func sort() {
        self.sortInPlace()
    }
}
extension Array {
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> {
    return start.stride(to: end, by: stride)
}
func exponentiate(lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#endif
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringSplit(by separator: String) -> [String] {
    return readLine()!.split(by: separator)
}
func readIntSplit(by separator: String) -> [Int] {
    return readLine()!.split(by: separator).map{Int($0)!}
}

/*************** テストスペース ***************/

/*************** メインプログラム ***************/

let S = (0..<3).map{_ in readLine()!.toArray()}
var cnt = [Int](repeating: 0, count: 3)
var player = 0
while true {
    if cnt[player] == S[player].count {
        print(["A","B","C"][player])
        break
    } else {
        cnt[player] += 1
        player = ["a":0,"b":1,"c":2][S[player][cnt[player]-1]]!
    }
}


import Foundation

#if swift(>=4.0)
extension String {
    func split(by separator: String) -> [String] {
        return self.components(separatedBy: separator)
    }
    func toArray() -> [String] {
        return self.map{String($0)}
    }
}
func exponentiate(_ lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#else
extension String {
    func split(by separator: String) -> [String] {
        return self.componentsSeparatedByString(separator)
    }
    var count: Int {
        return self.characters.count
    }
    func toArray() -> [String] {
        return self.characters.map{String($0)}
    }
    func uppercased() -> String {
        return self.uppercaseString
    }
    func lowercased() -> String {
        return self.lowercaseString
    }
}
//extension Array where Element == String {
//    func joined(separator separator: String) -> String {
//        return self.joinWithSeparator(separator)
//    }
//}
extension Array where Element: Comparable {
    func max() -> Element {
        return self.maxElement()!
    }
    func min() -> Element {
        return self.minElement()!
    }
    func sorted() -> Array {
        return self.sort()
    }
    func reversed() -> Array {
        return self.reverse()
    }
    mutating func sort() {
        self.sortInPlace()
    }
}
extension Array {
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> {
    return start.stride(to: end, by: stride)
}
func exponentiate(lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#endif
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringSplit(by separator: String) -> [String] {
    return readLine()!.split(by: separator)
}
func readIntSplit(by separator: String) -> [Int] {
    return readLine()!.split(by: separator).map{Int($0)!}
}

/*************** テストスペース ***************/

/*************** メインプログラム ***************/

let Sa = readLine()!.toArray()
let Sb = readLine()!.toArray()
let Sc = readLine()!.toArray()
var S = ["a": Sa, "b": Sb, "c": Sc]
var turn = "a"
while S["a"]!.count > 0 && S["a"]!.count > 0 && S["a"]!.count > 0 {
    let tmp = S[turn]![0]
    S[turn]!.removeAtIndex(0)
    turn = tmp
}
if S["a"]!.count == 0 {
    print("A")
}
if S["b"]!.count == 0 {
    print("B")
}
if S["c"]!.count == 0 {
    print("C")
}


"use strict";

const Main = args => {
  const input = args.trim().split("\n").map(e => e.split(""));
  let S = { a: input[0], b: input[1], c: input[2] };
  let current = 'a';
  let winner = '';

  while (true) {
    if (S[current].length === 0) {
      winner = current;
      break;
    }
    let next = S[current][0];
    S[current].shift();
    current = next;
  }
  console.log(winner.toUpperCase());
}

Main(require('fs').readFileSync('/dev/stdin', 'utf8'));


'use strict'

const main = (input) => {
  input = input.split('\n');
  const a = input[0].split('')
  const b = input[1].split('')
  const c = input[2].split('')

  const n = 'a'
  const s = []

  while(true) {
    if (n==='a') {
      s=a
    }else if (n==='b') {
      s=b
    }else{
      s=c
    }
    if(s.length==0) {
      console.log(n.toUpperCase());
      break
    }
    n=s.shift()
  }
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));