QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#237734#7686. The Phantom Menaceucup-team635#WA 513ms10276kbRust11.9kb2023-11-04 14:50:392023-11-04 14:50:40

Judging History

你现在查看的是最新测评结果

  • [2024-10-08 14:11:03]
  • hack成功,自动添加数据
  • (/hack/941)
  • [2024-10-08 10:05:28]
  • hack成功,自动添加数据
  • (/hack/940)
  • [2024-10-07 19:51:15]
  • hack成功,自动添加数据
  • (/hack/938)
  • [2024-10-07 19:28:01]
  • hack成功,自动添加数据
  • (/hack/937)
  • [2024-10-07 17:16:32]
  • hack成功,自动添加数据
  • (/hack/936)
  • [2024-10-07 16:53:09]
  • hack成功,自动添加数据
  • (/hack/935)
  • [2024-10-07 16:22:17]
  • hack成功,自动添加数据
  • (/hack/934)
  • [2023-11-04 14:50:40]
  • 评测
  • 测评结果:WA
  • 用时:513ms
  • 内存:10276kb
  • [2023-11-04 14:50:39]
  • 提交

answer

//---------- begin union_find ----------
pub struct DSU {
    p: Vec<i32>,
}
impl DSU {
    pub fn new(n: usize) -> DSU {
        assert!(n < std::i32::MAX as usize);
        DSU { p: vec![-1; n] }
    }
    pub fn init(&mut self) {
        self.p.iter_mut().for_each(|p| *p = -1);
    }
    pub fn root(&self, mut x: usize) -> usize {
        assert!(x < self.p.len());
        while self.p[x] >= 0 {
            x = self.p[x] as usize;
        }
        x
    }
    pub fn same(&self, x: usize, y: usize) -> bool {
        assert!(x < self.p.len() && y < self.p.len());
        self.root(x) == self.root(y)
    }
    pub fn unite(&mut self, x: usize, y: usize) -> Option<(usize, usize)> {
        assert!(x < self.p.len() && y < self.p.len());
        let mut x = self.root(x);
        let mut y = self.root(y);
        if x == y {
            return None;
        }
        if self.p[x] > self.p[y] {
            std::mem::swap(&mut x, &mut y);
        }
        self.p[x] += self.p[y];
        self.p[y] = x as i32;
        Some((x, y))
    }
    pub fn parent(&self, x: usize) -> Option<usize> {
        assert!(x < self.p.len());
        let p = self.p[x];
        if p >= 0 {
            Some(p as usize)
        } else {
            None
        }
    }
    pub fn sum<F>(&self, mut x: usize, mut f: F) -> usize
    where
        F: FnMut(usize),
    {
        while let Some(p) = self.parent(x) {
            f(x);
            x = p;
        }
        x
    }
    pub fn size(&self, x: usize) -> usize {
        assert!(x < self.p.len());
        let r = self.root(x);
        (-self.p[r]) as usize
    }
}
//---------- end union_find ----------

mod util {
    pub trait Join {
        fn join(self, sep: &str) -> String;
    }

    impl<T, I> Join for I
    where
        I: Iterator<Item = T>,
        T: std::fmt::Display,
    {
        fn join(self, sep: &str) -> String {
            let mut s = String::new();
            use std::fmt::*;
            for (i, v) in self.enumerate() {
                if i > 0 {
                    write!(&mut s, "{}", sep).ok();
                }
                write!(&mut s, "{}", v).ok();
            }
            s
        }
    }
}
// ---------- begin mod vector ----------
mod modvector {
    const MOD: u64 = (1u64 << 61) - 1;

    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
    struct ModInt(u64);

    impl std::ops::Add for ModInt {
        type Output = Self;
        fn add(self, rhs: Self) -> Self::Output {
            assert!(self.0 < MOD && rhs.0 < MOD);
            let mut d = self.0 + rhs.0;
            if d >= MOD {
                d -= MOD;
            }
            ModInt(d)
        }
    }

    impl std::ops::Sub for ModInt {
        type Output = Self;
        fn sub(self, rhs: Self) -> Self::Output {
            assert!(self.0 < MOD && rhs.0 < MOD);
            let mut d = self.0 + MOD - rhs.0;
            if d >= MOD {
                d -= MOD;
            }
            ModInt(d)
        }
    }

    impl std::ops::Mul for ModInt {
        type Output = Self;
        fn mul(self, rhs: Self) -> Self::Output {
            assert!(self.0 < MOD && rhs.0 < MOD);
            const MASK31: u64 = (1u64 << 31) - 1;
            const MASK30: u64 = (1u64 << 30) - 1;
            let au = self.0 >> 31;
            let ad = self.0 & MASK31;
            let bu = rhs.0 >> 31;
            let bd = rhs.0 & MASK31;
            let mid = ad * bu + au * bd;
            let midu = mid >> 30;
            let midd = mid & MASK30;
            let sum = au * bu * 2 + midu + (midd << 31) + ad * bd;
            let mut ans = (sum >> 61) + (sum & MOD);
            if ans >= MOD {
                ans -= MOD;
            }
            ModInt(ans)
        }
    }

    impl ModInt {
        fn new(v: u64) -> Self {
            ModInt(v % MOD)
        }
        fn zero() -> Self {
            ModInt(0)
        }
        fn pow(&self, n: u64) -> Self {
            let mut t = ModInt(1);
            let mut s = *self;
            let mut n = n;
            while n > 0 {
                if n & 1 == 1 {
                    t = t * s;
                }
                s = s * s;
                n >>= 1;
            }
            t
        }
        fn inv(&self) -> Self {
            assert!(self.0 > 0);
            self.pow(MOD - 2)
        }
    }

    pub const BASE_NUM: usize = 2;

    #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct ModVector {
        val: [ModInt; BASE_NUM],
    }

    #[allow(dead_code)]
    impl ModVector {
        pub fn zero() -> Self {
            ModVector {
                val: [ModInt::zero(); BASE_NUM],
            }
        }
        pub fn new(v: &[u64]) -> Self {
            assert!(v.len() >= BASE_NUM);
            let mut ans = ModVector::zero();
            for (x, a) in ans.val.iter_mut().zip(v.iter()) {
                *x = ModInt::new(*a);
            }
            ans
        }
        pub fn single(v: u64) -> Self {
            ModVector::new(&[v; BASE_NUM])
        }
        pub fn add(&self, rhs: &Self) -> Self {
            let mut ans = ModVector::zero();
            for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
                *c = *a + *b;
            }
            ans
        }
        pub fn sub(&self, rhs: &Self) -> Self {
            let mut ans = ModVector::zero();
            for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
                *c = *a - *b;
            }
            ans
        }
        pub fn mul(&self, rhs: &Self) -> Self {
            let mut ans = ModVector::zero();
            for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
                *c = *a * *b;
            }
            ans
        }
        pub fn inv(&self) -> Self {
            let mut ans = ModVector::zero();
            for (x, a) in ans.val.iter_mut().zip(self.val.iter()) {
                *x = a.inv();
            }
            ans
        }
    }

    pub fn rand_time() -> u32 {
        static mut X: u32 = 0;
        unsafe {
            if X == 0 {
                use std::time::{SystemTime, UNIX_EPOCH};
                X = SystemTime::now()
                    .duration_since(UNIX_EPOCH)
                    .unwrap()
                    .subsec_nanos();
            }
            X ^= X << 13;
            X ^= X >> 17;
            X ^= X << 5;
            X
        }
    }

    pub fn rand_memory() -> u32 {
        static mut X: u32 = 0;
        unsafe {
            if X == 0 {
                X = Box::into_raw(Box::new("I hope this is a random number")) as u32;
            }
            X ^= X << 13;
            X ^= X >> 17;
            X ^= X << 5;
            X
        }
    }

    pub fn generate_random_rad() -> ModVector {
        let mut rad = ModVector::zero();
        for (i, v) in rad.val.iter_mut().enumerate() {
            *v = ModInt::new(if i & 1 == 0 {
                rand_time() as u64 + 2
            } else {
                rand_memory() as u64 + 2
            });
        }
        rad
    }
}
// ---------- end mod vector ----------

// ---------- begin scannner ----------
#[allow(dead_code)]
mod scanner {
    use std::str::FromStr;
    pub struct Scanner<'a> {
        it: std::str::SplitWhitespace<'a>,
    }
    impl<'a> Scanner<'a> {
        pub fn new(s: &'a String) -> Scanner<'a> {
            Scanner {
                it: s.split_whitespace(),
            }
        }
        pub fn next<T: FromStr>(&mut self) -> T {
            self.it.next().unwrap().parse::<T>().ok().unwrap()
        }
        pub fn next_bytes(&mut self) -> Vec<u8> {
            self.it.next().unwrap().bytes().collect()
        }
        pub fn next_chars(&mut self) -> Vec<char> {
            self.it.next().unwrap().chars().collect()
        }
        pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
            (0..len).map(|_| self.next()).collect()
        }
    }
}
// ---------- end scannner ----------

use std::collections::*;
use std::io::Write;

type Map<K, V> = BTreeMap<K, V>;
type Set<T> = BTreeSet<T>;
type Deque<T> = VecDeque<T>;

fn main() {
    use std::io::Read;
    let mut s = String::new();
    std::io::stdin().read_to_string(&mut s).unwrap();
    let mut sc = scanner::Scanner::new(&s);
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());
    run(&mut sc, &mut out);
}

fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
    let t: u32 = sc.next();
    for _ in 0..t {
        let n: usize = sc.next();
        let m: usize = sc.next();
        let a = (0..n).map(|_| sc.next_bytes()).collect::<Vec<_>>();
        let b = (0..n).map(|_| sc.next_bytes()).collect::<Vec<_>>();
        if let Some((p, q)) = solve(a, b) {
            use util::*;
            writeln!(out, "{}", p.iter().join(" ")).ok();
            writeln!(out, "{}", q.iter().join(" ")).ok();
        } else {
            writeln!(out, "-1").ok();
        }
    }
}

use modvector::*;
type M = ModVector;

fn solve(a: Vec<Vec<u8>>, b: Vec<Vec<u8>>) -> Option<(Vec<usize>, Vec<usize>)> {
    let rad = generate_random_rad();
    let n = a.len();
    let m = a[0].len();
    let mut x = vec![];
    for a in a {
        let mut table = vec![M::zero(); m + 1];
        for (i, a) in a.iter().enumerate().rev() {
            table[i] = table[i + 1].mul(&rad).add(&M::single(*a as u64));
        }
        x.push(table);
    }
    let x = x;
    let mut y = vec![];
    for a in b {
        let mut table = vec![M::zero(); m + 1];
        for (i, a) in a.iter().enumerate().rev() {
            table[i] = table[i + 1].mul(&rad).add(&M::single(*a as u64));
        }
        y.push(table);
    }
    let y = y;
    let mut pow = vec![M::single(1); m + 1];
    for i in 1..=m {
        pow[i] = pow[i - 1].mul(&rad);
    }
    for d in 0..m {
        let mut map = Map::new();
        let mut get_id = |val: (M, usize)| -> usize {
            if let Some(&v) = map.get(&val) {
                return v;
            }
            let id = map.len();
            map.insert(val, id);
            id
        };
        let find = |l: usize, r: usize, x: &[M]| -> M {
            x[l].sub(&x[r].mul(&pow[r - l]))
        };
        let mut g = vec![];
        let mut deg = vec![0; 4 * n];
        for (i, x) in x.iter().enumerate() {
            let s = find(0, d, x);
            let t = find(d, m, x);
            let s = get_id((s, 0));
            let t = get_id((t, 1));
            if s >= g.len() {
                g.push(vec![]);
            }
            if t >= g.len() {
                g.push(vec![]);
            }
            g[s].push((t, i));
            deg[s] += 1;
            deg[t] -= 1;
        }
        for (i, y) in y.iter().enumerate() {
            let s = find(0, m - d, y);
            let t = find(m - d, m, y);
            let s = get_id((s, 1));
            let t = get_id((t, 0));
            if s >= g.len() {
                g.push(vec![]);
            }
            if t >= g.len() {
                g.push(vec![]);
            }
            g[s].push((t, i));
            deg[s] += 1;
            deg[t] -= 1;
        }
        let mut ans = vec![];
        dfs(0, &mut g, &mut ans);
        if ans.len() == 2 * n && deg.iter().all(|d| *d == 0) {
            let p = ans.iter().step_by(2).map(|a| *a + 1).collect();
            let q = ans[1..].iter().step_by(2).map(|a| *a + 1).collect();
            return Some((p, q));
        }
    }
    None
}

fn dfs(v: usize, g: &mut [Vec<(usize, usize)>], ans: &mut Vec<usize>) {
    while let Some((t, k)) = g[v].pop() {
        dfs(t, g, ans);
        ans.push(k);
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 2108kb

input:

2
3 3
abc
ghi
def
bcd
efg
hia
1 3
abc
def

output:

3 2 1
2 3 1
-1

result:

ok 2 cases (2 test cases)

Test #2:

score: 0
Accepted
time: 513ms
memory: 10276kb

input:

1000000
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
...

output:

1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1...

result:

ok 1000000 cases (1000000 test cases)

Test #3:

score: 0
Accepted
time: 378ms
memory: 10168kb

input:

500000
1 2
dd
ba
1 2
cd
ba
1 2
bd
ba
1 2
ad
ba
1 2
dc
ba
1 2
cc
ba
1 2
bc
ba
1 2
ac
ba
1 2
db
ba
1 2
cb
ba
1 2
bb
ba
1 2
ab
ba
1 2
da
ba
1 2
ca
ba
1 2
ba
ba
1 2
aa
ba
1 2
dd
aa
1 2
cd
aa
1 2
bd
aa
1 2
ad
aa
1 2
dc
aa
1 2
cc
aa
1 2
bc
aa
1 2
ac
aa
1 2
db
aa
1 2
cb
aa
1 2
bb
aa
1 2
ab
aa
1 2
da
aa
1 2...

output:

-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
-1
-1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
-1
-1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
-1
-1
-1
-1
-1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
-1
-1
-1
-1...

result:

ok 500000 cases (500000 test cases)

Test #4:

score: 0
Accepted
time: 349ms
memory: 10132kb

input:

500000
2 1
d
d
b
a
2 1
c
d
b
a
2 1
b
d
b
a
2 1
a
d
b
a
2 1
d
c
b
a
2 1
c
c
b
a
2 1
b
c
b
a
2 1
a
c
b
a
2 1
d
b
b
a
2 1
c
b
b
a
2 1
b
b
b
a
2 1
a
b
b
a
2 1
d
a
b
a
2 1
c
a
b
a
2 1
b
a
b
a
2 1
a
a
b
a
2 1
d
d
a
a
2 1
c
d
a
a
2 1
b
d
a
a
2 1
a
d
a
a
2 1
d
c
a
a
2 1
c
c
a
a
2 1
b
c
a
a
2 1
a
c
a
a
2 1
d...

output:

-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
2 1
1 2
-1
-1
1 2
1 2
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1 2
1 2
1 2
1 2
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1 2
1 2
-1
-1
2 1
1 2
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1 2
1 2
-1
-1
-1
-1
-1
2 1
1 2
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1 2
1 2
-1
...

result:

ok 500000 cases (500000 test cases)

Test #5:

score: 0
Accepted
time: 330ms
memory: 6032kb

input:

333333
1 3
cbb
bfa
1 3
bbb
bfa
1 3
abb
bfa
1 3
fab
bfa
1 3
eab
bfa
1 3
dab
bfa
1 3
cab
bfa
1 3
bab
bfa
1 3
aab
bfa
1 3
ffa
bfa
1 3
efa
bfa
1 3
dfa
bfa
1 3
cfa
bfa
1 3
bfa
bfa
1 3
afa
bfa
1 3
fea
bfa
1 3
eea
bfa
1 3
dea
bfa
1 3
cea
bfa
1 3
bea
bfa
1 3
aea
bfa
1 3
fda
bfa
1 3
eda
bfa
1 3
dda
bfa
1 3
c...

output:

-1
-1
-1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
...

result:

ok 333333 cases (333333 test cases)

Test #6:

score: 0
Accepted
time: 323ms
memory: 10040kb

input:

333333
3 1
c
b
b
b
f
a
3 1
b
b
b
b
f
a
3 1
a
b
b
b
f
a
3 1
f
a
b
b
f
a
3 1
e
a
b
b
f
a
3 1
d
a
b
b
f
a
3 1
c
a
b
b
f
a
3 1
b
a
b
b
f
a
3 1
a
a
b
b
f
a
3 1
f
f
a
b
f
a
3 1
e
f
a
b
f
a
3 1
d
f
a
b
f
a
3 1
c
f
a
b
f
a
3 1
b
f
a
b
f
a
3 1
a
f
a
b
f
a
3 1
f
e
a
b
f
a
3 1
e
e
a
b
f
a
3 1
d
e
a
b
f
a
3 1
c...

output:

-1
-1
-1
2 3 1
1 2 3
-1
-1
-1
-1
-1
-1
-1
-1
-1
1 2 3
1 2 3
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
2 1 3
1 2 3
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1 3 2
1 2 3
-1
-1
-1
-1
-1
-1
-1
...

result:

ok 333333 cases (333333 test cases)

Test #7:

score: 0
Accepted
time: 320ms
memory: 6084kb

input:

250000
1 4
hbca
fhaa
1 4
gbca
fhaa
1 4
fbca
fhaa
1 4
ebca
fhaa
1 4
dbca
fhaa
1 4
cbca
fhaa
1 4
bbca
fhaa
1 4
abca
fhaa
1 4
haca
fhaa
1 4
gaca
fhaa
1 4
faca
fhaa
1 4
eaca
fhaa
1 4
daca
fhaa
1 4
caca
fhaa
1 4
baca
fhaa
1 4
aaca
fhaa
1 4
hhba
fhaa
1 4
ghba
fhaa
1 4
fhba
fhaa
1 4
ehba
fhaa
1 4
dhba
fhaa...

output:

-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1...

result:

ok 250000 cases (250000 test cases)

Test #8:

score: -100
Wrong Answer
time: 282ms
memory: 10228kb

input:

250000
4 1
h
b
c
a
f
h
a
a
4 1
g
b
c
a
f
h
a
a
4 1
f
b
c
a
f
h
a
a
4 1
e
b
c
a
f
h
a
a
4 1
d
b
c
a
f
h
a
a
4 1
c
b
c
a
f
h
a
a
4 1
b
b
c
a
f
h
a
a
4 1
a
b
c
a
f
h
a
a
4 1
h
a
c
a
f
h
a
a
4 1
g
a
c
a
f
h
a
a
4 1
f
a
c
a
f
h
a
a
4 1
e
a
c
a
f
h
a
a
4 1
d
a
c
a
f
h
a
a
4 1
c
a
c
a
f
h
a
a
4 1
b
a
c
a
f...

output:

-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
1 2 3 4
1 2 3 4
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1...

result:

wrong answer not cyclic isomorphism (test case 624)