use io::*;
use modular::Modular;
use std::cmp::min;

fn main() {
    let con = read_string();
    let mut sc = Scanner::new(&con);

    let s: Vec<char> = sc.next::<String>().chars().collect();
    let mut qs: Vec<usize> = vec![0; s.len() + 1];

    for i in (0..s.len()).rev() {
        qs[i] = qs[i + 1] + if s[i] == '?' { 1 } else { 0 };
    }

    let mut tbl = vec![(false, 0.into(), 0.into(), 0.into()); s.len()];
    let ans = solve(0, &s, &qs, &mut tbl);

    // println!("{:?}", tbl);

    println!("{}", ans.1);
}

fn solve(
    pos: usize,
    s: &Vec<char>,
    qs: &Vec<usize>,
    tbl: &mut Vec<(bool, Modular, Modular, Modular)>,
) -> (bool, Modular, Modular, Modular) {
    if pos == s.len() {
        return (true, 0.into(), 0.into(), 0.into());
    }

    if tbl[pos].0 {
        return tbl[pos];
    }

    let mut abc = 0.into();
    let mut bc = 0.into();
    let mut c = 0.into();

    let t = solve(pos + 1, s, qs, tbl);
    if s[pos] == 'A' || s[pos] == '?' {
        abc += t.1 + t.2;
        bc += t.2;
        c += t.3;
    }
    if s[pos] == 'B' || s[pos] == '?' {
        abc += t.1;
        bc += t.2 + t.3;
        c += t.3;
    }
    if s[pos] == 'C' || s[pos] == '?' {
        abc += t.1;
        bc += t.2;
        c += t.3 + Modular::new(3).pow(qs[pos + 1] as i64);
    }

    tbl[pos] = (true, abc, bc, c);
    tbl[pos]
}

pub mod io {
    use std;
    use std::str::FromStr;

    pub struct Scanner<'a> {
        iter: std::str::SplitWhitespace<'a>,
    }

    impl<'a> Scanner<'a> {
        pub fn new(s: &'a str) -> Scanner<'a> {
            Scanner {
                iter: s.split_whitespace(),
            }
        }

        pub fn next<T: FromStr>(&mut self) -> T {
            let s = self.iter.next().unwrap();
            if let Ok(v) = s.parse::<T>() {
                v
            } else {
                panic!("Parse error")
            }
        }

        pub fn next_vec_len<T: FromStr>(&mut self) -> Vec<T> {
            let n: usize = self.next();
            self.next_vec(n)
        }

        pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            (0..n).map(|_| self.next()).collect()
        }
    }

    pub fn read_string() -> String {
        use std::io::Read;

        let mut s = String::new();
        std::io::stdin().read_to_string(&mut s).unwrap();
        s
    }

    pub fn read_line() -> String {
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        s.trim_right().to_owned()
    }
}

pub mod modular {
    const M: i64 = 1000000007;

    #[derive(Debug, Clone, Copy, Default, PartialOrd, Ord, PartialEq, Eq)]
    pub struct Modular(i64);

    impl ::std::fmt::Display for Modular {
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
            write!(f, "{}", self.0)
        }
    }

    impl Modular {
        pub fn new(v: i64) -> Modular {
            Modular(v % M)
        }

        pub fn pow(self, mut r: i64) -> Modular {
            let mut k = self;
            let mut ret = 1.into();

            while r > 0 {
                if r % 2 != 0 {
                    ret = ret * k;
                }
                r /= 2;
                k = k * k;
            }

            ret
        }

        // This requires M is prime
        pub fn recip(self) -> Modular {
            self.pow(M - 2)
        }
    }

    use std::ops::*;

    impl<T: Into<Modular>> Add<T> for Modular {
        type Output = Modular;
        fn add(self, rhs: T) -> Self::Output {
            Modular::new(self.0 + rhs.into().0)
        }
    }
    impl<T: Into<Modular>> AddAssign<T> for Modular {
        fn add_assign(&mut self, rhs: T) {
            *self = *self + rhs;
        }
    }

    impl<T: Into<Modular>> Sub<T> for Modular {
        type Output = Modular;
        fn sub(self, rhs: T) -> Self::Output {
            Modular::new(self.0 - rhs.into().0 + M)
        }
    }
    impl<T: Into<Modular>> SubAssign<T> for Modular {
        fn sub_assign(&mut self, rhs: T) {
            *self = *self - rhs;
        }
    }

    impl<T: Into<Modular>> Mul<T> for Modular {
        type Output = Modular;
        fn mul(self, rhs: T) -> Self::Output {
            Modular::new(self.0 * rhs.into().0)
        }
    }
    impl<T: Into<Modular>> MulAssign<T> for Modular {
        fn mul_assign(&mut self, rhs: T) {
            *self = *self * rhs;
        }
    }

    impl<T: Into<Modular>> Div<T> for Modular {
        type Output = Modular;
        fn div(self, rhs: T) -> Self::Output {
            self * rhs.into().recip()
        }
    }
    impl<T: Into<Modular>> DivAssign<T> for Modular {
        fn div_assign(&mut self, rhs: T) {
            *self = *self / rhs;
        }
    }

    impl Neg for Modular {
        type Output = Modular;
        fn neg(self) -> Self::Output {
            Modular(0) - self
        }
    }

    impl<T: ::std::convert::Into<i64>> ::std::convert::From<T> for Modular {
        fn from(v: T) -> Self {
            Modular::new(v.into())
        }
    }
}


Measured memory_bytes: 21372