[Question]
  [
# Challenge
This challenge will have you write a program that takes in two integers `n` and `m` and outputs the number non-intersecting loops on the `n` by `m` torus made by starting at `(0,0)` and only taking steps up and to the right. You can think of torus as the grid with [wraparound](https://en.wikipedia.org/wiki/Wraparound_(video_games)) both at the top and the bottom and on the sides. 
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so fewest bytes wins.
# Example
For example, if the input is `n=m=5`, one valid walk is 
```
(0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (2,3) -> (2,4) -> 
(2,0) -> (3,0) -> (4,0) -> (4,1) -> (4,2) -> (4,3) -> 
(0,3) -> (1,3) -> (1,4) -> 
(1,0) -> (1,1) -> (2,1) -> (3,1) -> (3,2) -> (3,3) -> (3,4) -> (4,4) -> 
(0,4) -> (0,0)
```
as shown in the graphic.
[![A loop on the torus.](https://i.stack.imgur.com/okBgBm.png)](https://i.stack.imgur.com/okBgBm.png)
Some example input/outputs 
```
f(1,1) = 2 (up or right)
f(1,2) = 2 (up or right-right)
f(2,2) = 4 (up-up, up-right-up-right, right-right, right-up-right-up)
f(2,3) = 7
f(3,3) = 22
f(2,4) = 13
f(3,4) = 66
f(4,4) = 258
```
  
[Answer]
# [Python 2](https://docs.python.org/2/), 87 bytes
```
f=lambda m,n,z=0,l=[]:z==0if z in l else sum(f(m,n,(z+d)%m%(n*1j),l+[z])for d in(1,1j))
```
[Try it online!](https://tio.run/##VcqxDoMgFIXhvU9xFxOod1B0asKTGAcbJNLA1agdel@e4gSO3zn/9juXlVSMVvspvM0EAQlZN@j1ML5Y68ZZYHAEHmZ/zHB8g7DiqgTXRlahEvRsPxJ9PfAo7bqDSbloMY0ybrujE@xF@chQGeqOLqMrobAvnwJ9QvwD "Python 2 – Try It Online")
The interesting thing here is using a complex number `z` to store the coordinate of the current position. We can move up by adding `1` and move right by adding `1j`. To my surprise, modulo works on complex numbers in a way that lets us handle the wrapping for each dimension separately: doing `%m` acts on the real part, and `%(n*1j)` acts on the imaginary part.
[Answer]
# JavaScript (ES6), 67 bytes
This shorter version is derived from a Python 3.8 alternate version found by [@xnor](https://codegolf.stackexchange.com/users/20260/xnor). However, this works only for \$m\times n<32\$ in JS.
Takes input as `(m)(n)`.
```
m=>n=>(g=(k,l)=>l>>k&1?!k:g((k+m)%(m*n),l|=1<<k)+g(k-~k%m-k%m,l))``
```
[Try it online!](https://tio.run/##bczNCoJAFAXgfU9hC@Pe1GRGswhnehXFdKg7P5HRKnr1STBcaHDO6uOcW/2q@@ZxvT8T6y6t74Q3QlohQQmgWKOQWkrasPOaTgqAIoMhmK3FWL8FK0vCSAElHwpNMnRYYFX5xtne6XannYIOGA7BIE0DvloI/y98knwp2SiHmWST8D93@UgsW65@VBQzyifi@6P/Ag "JavaScript (Node.js) – Try It Online")
To have it work for any input, we could use BigInts for **73 bytes**:
```
m=>n=>(g=(k,l=k)=>l&(b=1n<<k)?!k:g((k+m)%(m*n),l|=b)+g(k-~k%m-k%m,l))(0n)
```
[Try it online!](https://tio.run/##dczNCoJAGIXhfVdhC@P7UlNnbJRw7FrUVGr@IqNVdOuTgYGYLd7VwzmX8lH29e18vQfanBrbcqt4oXkBHQfhSy6QF3IDFY91ngs8rsWhAxCeQhfUVqMvn7xCrwMRvISrgiFfIkKk0dZG90Y2O2k6aCHW@AmdMHTI6tfIHyMTSxaMjpbOjE6MLJ0mI8Z0YflFxmaYTJDss5myQdmoWZrRyL4B "JavaScript (Node.js) – Try It Online")
---
# JavaScript (ES6), ~~76 73~~ 72 bytes
Takes input as `(m)(n)`.
```
m=>n=>(g=(x,y)=>g[x+=y*m]?!x:g(-~x%m,y,g[x]=1)+g(x%m,-~y%n)+--g[x])(0,0)
```
[Try it online!](https://tio.run/##bcxBDoIwEAXQvafABcmMtAIF0ZgUD2JYEIQGA60RY9oNV68QDAsg@Zv5L/Of@Tfvinf9@lCpHqWtuG15KnkKgoMmBnkq7trj5tBmt72@CqC9dltiyFBnPERPwHjT3rgSPUrHGiEgAdpCyU415bFRAioIcQg6vu@w3UrYtrBZ4rVEk5wXEs3CNubiicJo/fWnJFlQPBM7XewP "JavaScript (Node.js) – Try It Online")
### Commented
```
m => n => (         // m = width; n = height
  g = (             // g is a recursive function taking:
        x, y        //   the current coordinates (x, y) on the torus
      ) =>          //
    g[              // the surrounding object of g is also used for storage
      x += y * m    // turn x into a key for the current coordinates
    ] ?             // if this cell was already visited:
      !x            //   return 1 if we're back to (0, 0), or 0 otherwise
    :               // else:
      g(            //   first recursive call:
        -~x % m,    //     move to the right
        y,          //     leave y unchanged
        g[x] = 1    //     mark the current cell as visited by setting the flag g[x]
      ) +           //   add the result of
      g(            //   a second recursive call:
        x % m,      //     restore x in [0...m-1]
        -~y % n     //     move up
      ) +           //
      --g[x]        //   clear the flag on the current cell
)(0, 0)             // initial call to g with (x, y) = (0, 0)
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 28 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
ạƝ§=1Ȧ
²‘p/’ŒPÇƇḢÐṂ%⁸QƑƇṪÐṂL
```
A monadic Link accepting a list, `[m,n]`, which yields the count.
**[TIO-jt1qe1v9](https://tio.run/##y0rNyan8///hroXH5h5abmt4YhnXoU2PGmYU6D9qmHl0UsDh9mPtD3csOjzh4c4m1UeNOwKPTQQK7FwFFvD5//@/oY4hAA "Jelly – Try It Online")** ...although there is little point, it's way too inefficient.  
(I can't even run `[2,3]` locally with 16GB ram)!
### How?
Brute force - creates coordinates of a tiled version big enough then filters the power-set of these points to those paths with neighbours only increasing by one in a single direction, then filters to those starting at a minimal coordinate (i.e. the origin) and, at the same time, removes this start coordinate from each. Then uses modulo arithmetic to wrap back to a torus and filters out any containing duplicate coordinates (i.e. those containing intersections) and, finally, filters to those with minimal ending coordinates (i.e. ending back at the origin) and yields the result's length.
```
ạƝ§=1Ȧ - Link 1: all neighbours differ by 1 in exactly one direction
 Ɲ     - for neighbours:
ạ      -   absolute difference
  §    - sum each
   =1  - equal to one (vectorises)
     Ȧ - any and all? (falsey if empty or contains a falsey value when flattened)
²‘p/’ŒPÇƇḢÐṂ%⁸QƑƇṪÐṂL - Main Link: list of integers, [m,n]
²                     - square (vectorises) -> [m*m, n*n]
 ‘                    - increment (vectorises) -> [m*m+1, n*n+1]
   /                  - reduce with:
  p                   -   Cartesian product
    ’                 - decrement (vectorises) -> all the coordinates of an m*m by n*n grid
                      -                           including [0, 0] and [m*m, n*n] 
     ŒP               - power-set -> all paths going either up OR right at each step, but not
                      -              necessarily by only 1, and
                      -              necessarily both up and right (e.g. [...[1,3],[5,7],[6,2],...])
        Ƈ             - filter keep those for which:
       Ç              -   call last Link (1) as a monad
                      -              ...now all remaining paths do only go in steps
                      -              of one up or one right
          ÐṂ          - filter keep those minimal under:
         Ḣ            -   head - removes the 1st coordinate from each and yields them for the filter
                      -          ...so only those which started at [0,0] but without it
            %⁸        - modulo by the left argument ([m,n]) (vectorises)
                Ƈ     - filter keep those for which:
               Ƒ      -   is invariant when:
              Q       -     de-duplicated
                      -          ...so no repetitions of torus coordinates (and we already removed
                      -          the first [0,0] which must be present exactly twice)
                  ÐṂ  - filter keep those minimal under:
                 Ṫ    -   tail
                      -          ...so only those which ended at [0,0] 
                    L - length
```
[Answer]
## Haskell, ~~88~~ 80 bytes
```
n#m|let(x!y)a|elem(x,y)a=0^(x+y)|b<-(x,y):a=(mod(x+1)n!y)b+(x!mod(y+1)m)b=0!0$[]
```
[Try it online!](https://tio.run/##bctBC8IgGMbxe5/iHdtBWYE6T5GfJAqUCY183agdFPzuZh2128OP//PQ76d1LmffY3J2J6GLVCfrLJJwLFOxOwljpMlcTj85a0VwnQty6ktsxvL5QiyA1CjWseF6y6gXDwrm9QCwvRa/wwCkp8CBNyIqEX9kqmRqRIBsmlokyPwB "Haskell – Try It Online")
Simple brute force: try all up/right combinations, dropping those which intersect (we keep all positions we've visited in list `a`) and counting those which eventually hit positition `(0,0)` again.
The base case of the recursion is when we visit a position a second time (`elem(x,y)a`). The result is `0^0` = `1` when the position is `(0,0)` and counts towards the numbers of loops or `0` (`0^x`, with `x` non-zero) otherwise and doesn't increase the number of loops.
Edit: -8 bytes thanks to @xnor. 
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 44 bytes
```
×ƝṪ2*Ḥ_2Rḃ€2ċⱮØ½%³¬ẠƲƇịØ.Ṛ,Ø.¤ZÄZ%€ʋ€³ŒQẠ$€S
```
[Try it online!](https://tio.run/##y0rNyan8///w9GNzH@5cZaT1cMeSeKOghzuaHzWtMTrS/WjjusMzDu1VPbT50JqHuxYc23Ss/eHu7sMz9B7unKUDpA4tiTrcEqUKVHyqG0gc2nx0UiBQnQqQHfz//38THRMA "Jelly – Try It Online")
Works for 4,4, but has complexity \$O({2^m}^n)\$ so won’t scale that well. 
This works by finding all possible routes of up to \$mn\$ length, filtering out those that don’t end at 0,0, and then excluding those that pass the same point twice. 
[Answer]
# Java 8, 120 bytes
```
n->m->g(n,m,0,0);int g(int n,int m,int k,int l){return(l>>k)%2>0?k<1?1:0:g(n,m,(k+m)%(m*n),l|=1<<k)+g(n,m,k-~k%m-k%m,l);}
```
Port of [*@Arnauld*'s JavaScript answer](https://codegolf.stackexchange.com/a/181211/52210), and also only works for inputs where \$n\*m<32\$.
[Try it online.](https://tio.run/##jZKxboMwFEX3fIWFFMkuxgKSdAjE2Sp16JSx6uASghzbLwhMqihNx35AP7E/QoEwOJk6@Ppdnyc/Xct7cRTBfqvaTIu6Ri9CwnmC0L47Zo2Vmu0ayKw8AHsai/QZbF7kFf1f01hwjnZo1ULATcALDNTQkIYkkWBRgXsF2qsZVA2qybnKbVMB1pwrMo15uFZptI6W4fJ6BVa@IVNsHoBQ/bmK0lQR/4pU8KWmJugW1SS5tMmki1U271pmqLbCdtvxILfIdInxxlYSitc3JEifHiGb1xZHNCKJa2PXxrc0vqcz185u6eyezl07v7Uxfbybu3D9YsSXPqCbbKDOy47RNqfa5oYdGsvKLrXVgMH3qOcb30O/3z/I8yH/GH4CJmzHRFnqEwYyFoaM0y7tHw)
[Answer]
## CJam (50 chars)
```
q~]:M:!a{9Yb2/\f{_W=@.+M.%a+_)a#g"WAR"=~}}:R~e_We=
```
[Online demo](http://cjam.aditsu.net/#code=q~%5D%3AM%3A!a%7B9Yb2%2F%5Cf%7B_W%3D%40.%2BM.%25a%2B_)a%23g%22WAR%22%3D~%7D%7D%3AR~e_We%3D&input=3%205). This is a program which takes two inputs from stdin.
Finally we have an answer to the question
> 
> War, huh, what is it good for?
> 
> 
> 
---
### Dissection
```
q~]:M        e# Parse input, collect in array, store in M (for moduli)
:!a          e# Zero and wrap in array for starting position (0, 0)
{            e# Define recursive block R
  9Yb2/      e#   Push [[1 0][0 1]], an array of movements
  \f{        e#   For each of those movements, with the current path,
    _W=@.+   e#     Add the movement to the last position in the path
    M.%      e#     Apply the wrapping
    a+       e#     Add to one copy of the path
    _)a#     e#     And find its index in another copy
    g"WAR"=~ e#     Switch on the sign of the index:
             e#       If the sign is -1, position not found, make a recursive call
             e#       If the sign is 0, found at start, push -1 to the stack
             e#       If the sign is 1, we have a self-intersection. We push 10 to
             e#       the stack for no other reason than to make the bad joke above
  }
}:R
~            e# Execute R
e_We=        e# Count the -1s which we pushed as sentinels
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~54~~ 39 bytes
```
ḣ2æ.2ị³¤+4
‘Ç;¥¦%³Ç=4ƊÑÇị$?
çⱮØ½S
’Ñ0xÇ
```
[Try it online!](https://tio.run/##AVAAr/9qZWxsef//4bijMsOmLjLhu4vCs8KkKzQK4oCYw4c7wqXCpiXCs8OHPTTGisORw4fhu4skPwrDp@KxrsOYwr1TCuKAmcORMHjDh////zQsNA "Jelly – Try It Online")
I’ve posted this as a separate answer to my other Jelly one because it’s a completely different method. This is closer in principle to @Arnauld’s answer. It uses a recursive function that works through every possible path until it reaches a point it’s already got to, and then returns the result of a check whether it’s back to the start. I suspect a few more bytes could be shaved off. Now changed to using slice operator. It works well for up to 5x5. The recursion depth should be at most m x n.
]